防止 CompletionItem 列表插入第一个值

Prevent CompletionItem list from inserting first value

我有一个片段:

'color: ${1|initial,inherit|};'

这样注册的(减去不必要的代码):

const cssPropertyProvider = languages.registerCompletionItemProvider('mjml', {
  provideCompletionItems(document, position) {
    const snippetCompletion = new CompletionItem(attr.prefix)

    snippetCompletion.documentation = new MarkdownString(attr.description)
    snippetCompletion.insertText = new SnippetString(attr.body)

    return snippetCompletion
  }
})

subscriptions.push(cssPropertyProvider)

这会在选择 CompletionItem 时自动插入第一个列表项 (initial):

有什么办法可以避免这种情况吗?


本质上,我想要与占位符相同的功能,但有一个列表:

'color: ${1:initial};'


VSCode docs on lists and placeholders
VSCode docs on registerCompletionItemProvider

我不得不放弃 list/placeholder 方式并单独存储建议:

body: 'color: ;',
values: ['initial', 'inherit'],

然后,将此命令分配给原始建议 (cssPropertyProvider):

snippetCompletion.command = {
    command: 'editor.action.triggerSuggest',
    title: '',
}

并添加一个单独的完成提供程序来覆盖这个:

const cssValueProvider = languages.registerCompletionItemProvider('mjml', {
    provideCompletionItems(document, position) {
        const snippetCompletions: ProviderResult<CompletionItem[] | CompletionList> = []

        cssProperties.forEach((prop) => {
            const formattedBody = prop.body.split('').join('')

            // Ensure the line includes the relevant CSS property
            if (!document.lineAt(position).text.includes(formattedBody)) return

            prop.values.forEach((val) => {
                const snippetCompletion = new CompletionItem(val)

                // Sets the suggestion icon to the little orange thing
                snippetCompletion.kind = 11 // 11 = Value
                // Ensure tab-stops () are handled
                snippetCompletion.insertText = new SnippetString(val)

                snippetCompletions.push(snippetCompletion)
            })
        })

        return snippetCompletions
    },
})

此外,仅针对我的特定用例,我必须在 cssPropertyProvider 中添加一个检查,以防止 属性 建议显示在值建议上方:

const cssPropertyProvider = languages.registerCompletionItemProvider('mjml', {
    provideCompletionItems(document, position) {
        const { text: lineText } = document.lineAt(position)
        const lastLineChar = lineText[position.character]

        if (lastLineChar === ';') return
...

结果: