VSCode extension API 函数 provideCompletionItems() 可以从多个触发字符触发吗?

Can VSCode extension API funtion provideCompletionItems() trigger from multiple trigger characters?

我正在编写一个扩展,为基于 XML 的数据格式描述语言 (https://daffodil.apache.org/docs/dfdl/) 提供自动完成结果。我正在使用 VScode 扩展 API 函数 provideCompletionItems。我有许多作为属性的完成项。由于属性可以组合在一行上,例如:

<xs:element name="RGBA_Value" type="xs:hexBinary" dfdl:lengthKind="explicit" dfdl:lengthUnits="bytes" dfdl:length="4" />

或换行分隔:

<xs:element name="RGBA_Value"
type="xs:hexBinary"
dfdl:lengthKind="explicit"
dfdl:lengthUnits="bytes"
dfdl:length="4" />

我使用字符“ ”(space)和“\n”(换行符)作为定义为字符串数组的 provideCompletionItems 触发器的触发器。我尝试了各种方法来尝试组合字符串数组中的字符,但都没有成功。因此,我创建了两个大部分相同的 provideCompletionItems 函数,一个带有 ' ' (space) 触发器,一个带有 '\n'(换行)触发器。这两个函数都包含相同的 21 个完成项定义。我正在尝试找到不需要使用重复完成项的解决方案。任何帮助或指导将不胜感激。

@Mark 我根据你的建议更改了我的代码,这是一个简化版本:

    const elementDfdlAttributeProvider = vscode.languages.registerCompletionItemProvider(
        'plaintext',
        {
            provideCompletionItems(document: vscode.TextDocument, position: vscode.Position) {
                const wholeLine = document.lineAt(position).text.substr(0, position.character);
                console.log('in elementspacetrigger: ' + wholeLine);
                if(wholeLine.includes('"{')) {
                    return undefined;                   
                }
                const dfdlDefineFormat = new vscode.CompletionItem("dfdl:defineFormat");
                dfdlDefineFormat.insertText = new vscode.SnippetString('<dfdl:defineFormat name="" >\n\t\n</dfdl:defineFormat>\n[=14=]');
                dfdlDefineFormat.documentation = new vscode.MarkdownString("dfdl format name and configuration");
            
                const dfdlDefineEscape = new vscode.CompletionItem('dfdl:defineEscapeScheme');
                dfdlDefineEscape.insertText = new vscode.SnippetString('<dfdl:defineEscapeScheme name= >\n\t[=14=],/dfdl:defineEscapeScheme>\n');
                dfdlDefineEscape.documentation = new vscode.MarkdownString("dfdl escape character definition");
.
.
.
                const dfdlOutputNewLine = new vscode.CompletionItem('dfdl:outputNewLine=');
                dfdlOutputNewLine.insertText = new vscode.SnippetString("dfdl:outputNewLine=\"${1|%CR,%LF,%CR%LF,%NEL,%LS|}\"[=14=]");
                dfdlOutputNewLine.documentation = new vscode.MarkdownString("Specifies the character or characters that are used to replace the %NL; character class entity during unparse");
    
                //const wholeLine = document.lineAt(position).text.substr(0, position.character);
                if (wholeLine.includes('<xs:element name="') || (wholeLine.includes('<xs:element ref="'))) {
                    return [
                      xmlType,
                        minOccurs,
                        maxOccurs,
                        dfdlOccursCount,
                        dfdlOccursCountKind,
                        dfdlLength,
                        dfdlLengthKind,
                        dfdlLengthUnits,
                        dfdlLengthPattern,
                        xmlEncoding,
                        dfdlInputValueCalc,
                        dfdlOutputValueCalc,
                        dfdlAlignment,
                        dfdlAlignmentUnits,
                        dfdlTerminator,
                        dfdlOutputNewLine,
                    ];
                }
            }
        },

        ' ', '\n' // triggered whenever  ' ' or '\n' is typed
    );

完成函数适用于 space 个字符,但不适用于新的 line/linefeed。也许 VSCode 不喜欢 '\n'?

但如果我删除“ ”并只保留“\n”,那确实有效。

这不是数组。这对我有用:

'"', '$' // trigger intellisense/completion

const configCompletionProvider = vscode.languages.registerCompletionItemProvider (
      { pattern: '**/keybindings.json' },     // your pattern here
      {
        provideCompletionItems(document, position) {}
      },
      '"', '$'
)

同时 "$ 触发智能感知。

令人困惑的是触发字符的签名是:

...triggerCharacters: string[]

但我认为这意味着如果你有一个 array 触发字符,你可以像这样使用它:

...['.', '"'] 相当于 '.', '"'