Skip to content
索引

languages

用于参与特定语言的编辑器功能,如智能感知、代码操作、代码诊断等

具体来说,就是参与代码补全、代码跳转或代码检查等功能

languages将所有UI和操作都准备就绪,只需要提供数据就能实现这类功能。例如,要创建一个悬停,只需提供一个函数,该函数可以通过文本文档和返回悬停信息的位置来调用。其余的工作,如跟踪鼠标、定位悬停、保持悬停稳定等,由vscode编辑器自行负责

js
languages.registerHoverProvider('javascript', {
  provideHover(document, position, token) {
    return {
      contents: ['Hover Content']
    }
  }
})
languages.registerHoverProvider('javascript', {
  provideHover(document, position, token) {
    return {
      contents: ['Hover Content']
    }
  }
})

注册是使用一个文档选择器完成的,它要么是一个语言id,比如javascript,要么是一个更复杂的过滤器,比如{language:'typescript',scheme:'file'}。将文档与这样的选择器进行匹配将得到一个分数,用于确定是否以及如何使用提供者。当分数相等时,最后一个提供程序获胜。对于允许完全算术的功能,如hover,分数仅检查为>0,对于其他功能,如IntelliSense,分数用于确定要求提供程序参与的顺序

registerCompletionItemProvider

注册一个completion provider ,直译为完成提供程序,其实指的是提供代码补全提示的程序,就像css中敲代码会提示css属性列表

可以为一种语言注册多个provider。在这种情况下,provider按分数排序,相同分数的provider将依次请求completion item(单项代码补全提示,一般来说代码提示都是一个列表,如css属性列表)。当一个provider或多个provider返回结果时,进程停止。失败的provider(rejected promise or exception)不会使整个操作失败

completion provider可以与一组触发器字符相关联。当输入触发器字符时,会请求补全,但只能从注册输入字符的提供程序中请求。因为触发字符应该不同于单词字符,所以一个常见的触发字符是. , 触发代码补全。

ts
import { languages, ExtensionContext } from "vscode"

export function activate(context: ExtensionContext) {

  context.subscriptions.push(languages.registerCompletionItemProvider('vue', {
    provideCompletionItems,
    resolveCompletionItem
  }, '.'))
}
import { languages, ExtensionContext } from "vscode"

export function activate(context: ExtensionContext) {

  context.subscriptions.push(languages.registerCompletionItemProvider('vue', {
    provideCompletionItems,
    resolveCompletionItem
  }, '.'))
}

以上就是一个最简单的completion provider ,可以看出有3个参数:

  • 第一个是要关联的文件类型
  • 第二个是一个对象,里面必须包含provideCompletionItemsresolveCompletionItem这2个方法
  • 第三个是触发代码补全提示的字符

上方例子中,关联的文件类型是vue文件,provideCompletionItemsresolveCompletionItem稍后我们将进行定义,按下.后触发代码提示

resolveCompletionItem

resolveCompletionItem(item: T, token: CancellationToken): ProviderResult<T>

给定一个completion item,填写更多数据,如文档注释或详细信息

编辑器将只解析一次completion item

请注意,当completion item已显示在UI中或已选择要插入的项时,才会调用此函数。因此,无法更改任何展示方式(标签、排序、筛选等)或(主要)插入行为(insertText)的属性

此函数可以填写额外的文本编辑。然而,这意味着在解析完成之前可能会插入一个completion item,在这种情况下,编辑器将尽最大努力去应用这些额外的文本编辑

ts
// 不做任何操作
function resolveCompletionItem(item: CompletionItem, token: CancellationToken) {
    return null
  }
// 不做任何操作
function resolveCompletionItem(item: CompletionItem, token: CancellationToken) {
    return null
  }

示例

ts
import { ExtensionContext, languages, CompletionItem, CompletionItemKind, TextDocument, Position, CancellationToken, CompletionContext } from "vscode"

export function activate(context: ExtensionContext) {
  function provideCompletionItems(document: TextDocument, position: Position, token: CancellationToken, context: CompletionContext) {
    const classNames = ["1111", "2222"]
    return classNames.map(className => {
      const completionItem = new CompletionItem(className, CompletionItemKind.Variable)
      completionItem.detail = className
      return completionItem
    })
  }

  function resolveCompletionItem(item: CompletionItem, token: CancellationToken) {
    return null
  }

  context.subscriptions.push( languages.registerCompletionItemProvider(
    "vue",
    {
      provideCompletionItems,
      resolveCompletionItem
    },
    "."
  ))
}
import { ExtensionContext, languages, CompletionItem, CompletionItemKind, TextDocument, Position, CancellationToken, CompletionContext } from "vscode"

export function activate(context: ExtensionContext) {
  function provideCompletionItems(document: TextDocument, position: Position, token: CancellationToken, context: CompletionContext) {
    const classNames = ["1111", "2222"]
    return classNames.map(className => {
      const completionItem = new CompletionItem(className, CompletionItemKind.Variable)
      completionItem.detail = className
      return completionItem
    })
  }

  function resolveCompletionItem(item: CompletionItem, token: CancellationToken) {
    return null
  }

  context.subscriptions.push( languages.registerCompletionItemProvider(
    "vue",
    {
      provideCompletionItems,
      resolveCompletionItem
    },
    "."
  ))
}

CompletionItemKind

每种completion item都有不同图标,使用ts的enum语法定义,运行以下代码查看所有图标示例

ts
import { ExtensionContext, languages, CompletionItem, CompletionItemKind, TextDocument, Position, CancellationToken, CompletionContext } from "vscode"

export function activate(context: ExtensionContext) {
  console.log("地涌了")
  function provideCompletionItems(document: TextDocument, position: Position, token: CancellationToken, context: CompletionContext) {
    const classNames = new Array(27).fill("test")
    const { Class, Color, Constant, Constructor, Enum, EnumMember, Event, Field, File, Folder, Function, Interface, Issue, Keyword, Method, Module, Operator, Property, Reference, Snippet, Struct, Text, TypeParameter, Unit, User, Value, Variable } = CompletionItemKind
    const iconNumArr = [Class, Color, Constant, Constructor, Enum, EnumMember, Event, Field, File, Folder, Function, Interface, Issue, Keyword, Method, Module, Operator, Property, Reference, Snippet, Struct, Text, TypeParameter, Unit, User, Value, Variable]
    const iconTitleArr = ["Class", "Color", "Constant", "Constructor", "Enum", "EnumMember", "Event", "Field", "File", "Folder", "Function", "Interface", "Issue", "Keyword", "Method", "Module", "Operator", "Property", "Reference", "Snippet", "Struct", "Text", "TypeParameter", "Unit", "User", "Value", "Variable"]
    return classNames.map((item, index) => {
      const completionItem = new CompletionItem({ label: iconTitleArr[index], description: item }, iconNumArr[index])
      completionItem.detail = "CompletionItemKind名为:" + iconTitleArr[index] + "CompletionItemKind值为:" + iconNumArr[index]
      return completionItem
    })
  }

  function resolveCompletionItem(item: CompletionItem, token: CancellationToken) {
    return null
  }

  // 第一个参数表示在什么文件里提供代码补全,第二个参数是代码补全的内容,第三个参数是如何触发
  context.subscriptions.push(
    languages.registerCompletionItemProvider(
      ["html", "vue-html", "vue"],
      {
        provideCompletionItems,
        resolveCompletionItem
      },
      ""
    )
  )
}
import { ExtensionContext, languages, CompletionItem, CompletionItemKind, TextDocument, Position, CancellationToken, CompletionContext } from "vscode"

export function activate(context: ExtensionContext) {
  console.log("地涌了")
  function provideCompletionItems(document: TextDocument, position: Position, token: CancellationToken, context: CompletionContext) {
    const classNames = new Array(27).fill("test")
    const { Class, Color, Constant, Constructor, Enum, EnumMember, Event, Field, File, Folder, Function, Interface, Issue, Keyword, Method, Module, Operator, Property, Reference, Snippet, Struct, Text, TypeParameter, Unit, User, Value, Variable } = CompletionItemKind
    const iconNumArr = [Class, Color, Constant, Constructor, Enum, EnumMember, Event, Field, File, Folder, Function, Interface, Issue, Keyword, Method, Module, Operator, Property, Reference, Snippet, Struct, Text, TypeParameter, Unit, User, Value, Variable]
    const iconTitleArr = ["Class", "Color", "Constant", "Constructor", "Enum", "EnumMember", "Event", "Field", "File", "Folder", "Function", "Interface", "Issue", "Keyword", "Method", "Module", "Operator", "Property", "Reference", "Snippet", "Struct", "Text", "TypeParameter", "Unit", "User", "Value", "Variable"]
    return classNames.map((item, index) => {
      const completionItem = new CompletionItem({ label: iconTitleArr[index], description: item }, iconNumArr[index])
      completionItem.detail = "CompletionItemKind名为:" + iconTitleArr[index] + "CompletionItemKind值为:" + iconNumArr[index]
      return completionItem
    })
  }

  function resolveCompletionItem(item: CompletionItem, token: CancellationToken) {
    return null
  }

  // 第一个参数表示在什么文件里提供代码补全,第二个参数是代码补全的内容,第三个参数是如何触发
  context.subscriptions.push(
    languages.registerCompletionItemProvider(
      ["html", "vue-html", "vue"],
      {
        provideCompletionItems,
        resolveCompletionItem
      },
      ""
    )
  )
}

提供基本语法

language-configuration.json

控制语言的标点符号

language.tmLanguage.json

控制匹配的关键字,文件名中的language是语言的名字

Released under the MIT License.