Examples of Language Service Plugin #1027
Replies: 4 comments 13 replies
-
Great! How can one switch from In Extension settings, I don't see any setting to choose a formatter.
|
Beta Was this translation helpful? Give feedback.
-
@johnsoncodehk Where could we find the implementation of this API to supplement the lack of jsDocs? Even better, examples of each of the available functions, or links to good examples of where they are used? |
Beta Was this translation helpful? Give feedback.
-
Hi, @johnsoncodehk [NG]:
[OK]:
|
Beta Was this translation helpful? Give feedback.
-
A working const { format, resolveConfigFile, resolveConfig } = require('prettier')
const { randomUUID } = require('crypto')
/**
*
* @param {string[]} languages
* @returns {import('@volar/vue-language-service-types').EmbeddedLanguageServicePlugin}
*/
module.exports = function volarPrettierPlugin(languages) {
const prettierConfig = resolveConfig.sync(resolveConfigFile.sync())
const makeUUID = () => `{{'${randomUUID()}'}}`
const uuidRegex = (() => {
const c = '[0-9a-f]'
return new RegExp(makeUUID().replace(new RegExp(c, 'g'), c), 'g')
})()
/** @type {import('@volar/vue-language-service-types').EmbeddedLanguageServicePlugin} */
return {
format(document, range, options) {
// I don't if what is return matters or not. It is `NullableResult<TextEdit[]>` after all.
if (!languages.includes(document.languageId)) return []
const originalText = document.getText()
let preFormattedText = originalText
const isHTML = document.languageId === 'html'
// Prettier breaks {{'...long line...'}} in <template> tags, without a good fix.
// {{'...shorter line...'}} {{'...shorter line...'}} doesn't appear to work.
// The only real another fix is <span> {{'...shorter line...'}} </span>
const noBreak = new Map()
if (isHTML) {
preFormattedText = preFormattedText
.replace(
/( *){{ *((['"])[^]+?\3) *}}( *)/g,
(raw, w1, content, bracket, w2) => {
const id = makeUUID()
raw = `{{ ${content} }}`
noBreak.set(id, raw)
return w1 + id + w2
}
)
// This one is opinionated, but I just put it here, anyway.
.replace(/> ?({{.+?}})/g, '> $1')
.replace(/({{.+?}}) ?</g, '$1 <')
}
let formattedText = format(preFormattedText, {
...prettierConfig,
tabWidth: options.tabSize,
useTabs: !options.insertSpaces,
filepath: document.uri
})
if (isHTML) {
formattedText = formattedText.replace(uuidRegex, (raw) => {
return noBreak.get(raw) || raw
})
} else {
formattedText = '\n' + formattedText
}
if (formattedText === originalText) return []
return [
{
range: {
start: document.positionAt(0),
end: document.positionAt(originalText.length)
},
newText: formattedText
}
]
}
}
}
module.exports = {
plugins: [
require('./volarPlugins/prettier')([
'html',
'css',
'scss',
'less',
'typescript',
'javascript'
])
]
} This itself also tells a bug... Without <script setup lang="ts">import { ref } from 'vue'
...
</script>
...
<style scoped>section {
...
}
</style> I suspect this is exactly the same issue as #1155, albeit some minor differences (that It appears that a fake filepath is generated at |
Beta Was this translation helpful? Give feedback.
-
Relate issues: #672, #734
Implementation version: 0.33.0
NOTE: This feature may change before 1.0
Checkout https://github.com/johnsoncodehk/volar/blob/master/packages/vue-language-service-types/src/index.ts for all available apis.
Disable built-in sass formatter
volar.config.js (It should be in same folder with tsconfig.json):
volarPlugins/disable-sass-format.ts (You need to build it to js by
tsc volarPlugins/disable-sass-format.ts --skipLibCheck
):Prettier
You could also check this example in https://github.com/johnsoncodehk/volar-starter.
package.json:
volar.config.js:
volarPlugins/prettier.ts:
prettyhtml
package.json:
volar.config.js:
volarPlugins/prettyhtml.ts:
If you have other plugin implementations, you can also share them here.
Beta Was this translation helpful? Give feedback.
All reactions