获取 vscode registerCompletionItemProvider 以在带有 `word.` 触发器的 json 文件中工作 [英] Get vscode registerCompletionItemProvider to work in a json file with a `word.` trigger

查看:152
本文介绍了获取 vscode registerCompletionItemProvider 以在带有 `word.` 触发器的 json 文件中工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用此代码尝试在我的扩展程序中注册 CompletionProvider.它本质上是来自示例 completionProvider 示例的代码 https://github.com/microsoft/vscode-extension-samples/blob/master/completions-sample/src/extension.ts.

I am using this code to try to register a CompletionProvider in my extension. It is essentially the code from the sample completionProvider sample https://github.com/microsoft/vscode-extension-samples/blob/master/completions-sample/src/extension.ts.

我希望它由 .如在发射"中.在我最终在 keybindings.json 中的扩展命令中,但它在任何 json 文件中什么都不做.没有任何反应,没有错误.

I want it triggered by a . as in "launches." in my extension command in keybindings.json ultimately but it is doing nothing in any json file. Nothing happens, no error.

function activate(context) {

  loadLaunchSettings(context);
  activeContext = context;

  const configCompletionProvider = vscode.languages.registerCompletionItemProvider (
    { language: 'json', scheme: 'file' },   // tried scheme: 'untitled' too
    {
      // eslint-disable-next-line no-unused-vars
      provideCompletionItems(document, position, token, context) {

        // get all text until the `position` and check if it reads `"launches."`

        const linePrefix = document.lineAt(position).text.substr(0, position.character);
        if (!linePrefix.endsWith('\"launches.\"')) {  // tried without the escapes too
          return undefined;
        }

        return [
          new vscode.CompletionItem('log', vscode.CompletionItemKind.Text),
          new vscode.CompletionItem('warn', vscode.CompletionItemKind.Text),
          new vscode.CompletionItem('error', vscode.CompletionItemKind.Text),
        ];
      }
    },
    '.' // trigger
  );

  context.subscriptions.push(configCompletionProvider);
}

在这段代码中:

  {
    "key": "alt+f",
    "command": "launches."   <= provider completion options here
  },

我找不到任何有用的东西,并认为我密切关注示例,但没有关于键入 "launches." 或使用 Ctrl+空格触发智能感知.

I couldn't find anything helpful and thought I followed the sample closely but no completion suggestions either on typing "launches." or using Ctrl+Space to trigger intellisense.

我确实有这个设置:

  "editor.quickSuggestions": {
    "comments": true,
    "other": true,
    "strings": true   // <===
  },

我尝试了这里提出的各种替代方案来解决类似的问题:JSON 完成的自定义扩展在双引号中不起作用

And I tried various alternatives presented here to a similar problem: Custom Extension for JSON Completion Does Not Work in Double Quotes

仍然感到困惑 - 可以在 javascript 文件中使用,但不能在 json 文件中使用.有什么特别的我必须做才能在 json 文件中将 . 识别为触发字符(除了在 vscode.languages.registerCompletionItemProvider 中列出它,如下所示)?

Still baffled - works in a javascript file but not a json file. Is there something special I have to do to get a . recognised as a trigger character in a json file (other than listing it in the vscode.languages.registerCompletionItemProvider as below)?

我已将其精简为:

function activate(context) {

  loadLaunchSettings(context);
  activeContext = context;

  let docFilter = { scheme: 'file', language: 'json' };

  const configCompletionProvider = vscode.languages.registerCompletionItemProvider (
    // { language: 'json', pattern: './**/test.json' }, // does not work
    // 'javascript',                                    //  works
    // 'json',                                          // does not work
    docFilter,                                          // does not work
    {
       // eslint-disable-next-line no-unused-vars
      provideCompletionItems(document, position, token, context) {

        return [
          new vscode.CompletionItem('howdy1', vscode.CompletionItemKind.Text),
          new vscode.CompletionItem('howdy2', vscode.CompletionItemKind.Text),
          new vscode.CompletionItem('howdy3', vscode.CompletionItemKind.Text),
        ];
      }
    },
    "." // trigger
  );

    context.subscriptions.push(configCompletionProvider);
};
    

推荐答案

基于 Gamma11 关于什么是JSON 中的一个单词,整个字符串被认为是一个包含 " 字符的单词.

Based on the answer by Gamma11 about what is a word in JSON, the whole string is considered a word including the " chars.

如果您调整完成项应替换的范围,而不是在该位置查找当前单词,则它起作用.

It works if you adjust the range the completion item should replace, and not look for the current word at the position.

  context.subscriptions.push(vscode.languages.registerCompletionItemProvider (
    { language: 'json', scheme: 'file' },
    // 'json',
    {
      // eslint-disable-next-line no-unused-vars
      provideCompletionItems(document, position, token, context) {

        // get all text until the `position` and check if it reads `"launches.`

        const linePrefix = document.lineAt(position).text.substr(0, position.character);
        if (!linePrefix.endsWith('"launches.')) {
          return undefined;
        }
        let myitem = (text) => {
          let item = new vscode.CompletionItem(text, vscode.CompletionItemKind.Text);
          item.range = new vscode.Range(position, position);
          return item;
        }
        return [
          myitem('log'),
          myitem('warn'),
          myitem('error'),
        ];
      }
    },
    '.' // trigger
  ));


编辑:

同样有效但不好看的是

        return [
          new vscode.CompletionItem('"launches.log"', vscode.CompletionItemKind.Text),
          new vscode.CompletionItem('"launches.warn"', vscode.CompletionItemKind.Text),
          new vscode.CompletionItem('"launches.error"', vscode.CompletionItemKind.Text),
        ];


编辑:

只是为了在任何输入的 . 上提供补全,我只是删除了 . 前面的测试 (endsWith).

Just to supply a completion on any . typed I just removed the test (endsWith) of what was in front of the ..

要查看是否调用了完成提供程序,我将使用 CompletionItems 在返回上放置一个 LogPoint 断点.

To see if the completion provider is called I place a LogPoint breakpoint on the return with the CompletionItems.

CompletionItem 的文档非常简洁.

来自CompletionItem的文档:

仅从标签创建完成项就足够了.在这种情况下,完成项将替换单词,直到光标带有给定的标签或 insertText.否则使用给定的编辑.

It is sufficient to create a completion item from just a label. In that case the completion item will replace the word until the cursor with the given label or insertText. Otherwise the given edit is used.

尽管他们在正文中讨论了 edittextEdit 文档告诉您它已被弃用,您需要使用 insertText 和<代码>范围.但是 additionalTextEdits 没有被弃用 (??)

Although they talk about an edit in the main text, the textEdit doc tells you it is deprecated and you need to use insertText and range. But the additionalTextEdits are not deprecated (??)

range 属性不太很清楚 insertingreplaceing 范围是如何使用的,以及对你有什么影响可以通过某种方式设置来实现.

The range property is not very clear how an inserting and replacing range are used and what effect you can achieve by setting it a certain way.

省略时,当前单词的范围用作替换范围,插入范围使用当前单词的开头到当前位置.

When omitted, the range of the current word is used as replace-range and as insert-range the start of the current word to the current position is used.

然后部分问题是 " 是 JSON 文件单词的一部分.正如 Gamme11 所指出的,如果您出于某种奇怪的原因将这些 " 添加到它在某些情况下有效的标签中.将 insertText 设置为相同的内容不起作用,可能是因为默认的 range 选择不正确.

And then part of the problem is that " is part of a word for JSON files. And as Gamme11 has pointed out if you, for some odd reason, add these "'s to the label it works in some cases. Setting the insertText with the same content does not work, probably because the default range is chosen incorrectly.

如果你自己设置range,你就绕过了奇怪的默认行为.

If you set the range yourself you bypass the strange default behavior.

因为我们想在光标位置插入新的东西,只需将 range 设置为光标位置的空范围即可.

Because we want to insert new stuff at the position of the cursor just set range to an empty range at the cursor position.

  context.subscriptions.push(vscode.languages.registerCompletionItemProvider (
    // { language: 'json', scheme: 'file' },
    'json',
    {
      // eslint-disable-next-line no-unused-vars
      provideCompletionItems(document, position, token, context) {
        let myitem = (text) => {
          let item = new vscode.CompletionItem(text, vscode.CompletionItemKind.Text);
          item.range = new vscode.Range(position, position);
          return item;
        }
        return [
          myitem('howdy1'),
          myitem('howdy2'),
          myitem('howdy3'),
        ];
      }
    },
    '.' // trigger
  ));

这篇关于获取 vscode registerCompletionItemProvider 以在带有 `word.` 触发器的 json 文件中工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆