languages
用于参与特定语言的编辑器功能,如智能感知、代码操作、代码诊断等
具体来说,就是参与代码补全、代码跳转或代码检查等功能
languages
将所有UI和操作都准备就绪,只需要提供数据就能实现这类功能。例如,要创建一个悬停,只需提供一个函数,该函数可以通过文本文档和返回悬停信息的位置来调用。其余的工作,如跟踪鼠标、定位悬停、保持悬停稳定等,由vscode编辑器自行负责
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
可以与一组触发器字符相关联。当输入触发器字符时,会请求补全,但只能从注册输入字符的提供程序中请求。因为触发字符应该不同于单词字符,所以一个常见的触发字符是.
, 触发代码补全。
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个参数:
- 第一个是要关联的文件类型
- 第二个是一个对象,里面必须包含
provideCompletionItems
和resolveCompletionItem
这2个方法 - 第三个是触发代码补全提示的字符
上方例子中,关联的文件类型是vue
文件,provideCompletionItems
和resolveCompletionItem
稍后我们将进行定义,按下.
后触发代码提示
resolveCompletionItem
resolveCompletionItem(item: T
, token: CancellationToken
): ProviderResult<T>
给定一个completion item
,填写更多数据,如文档注释或详细信息
编辑器将只解析一次completion item
请注意,当completion item
已显示在UI中或已选择要插入的项时,才会调用此函数。因此,无法更改任何展示方式(标签、排序、筛选等)或(主要)插入行为(insertText)的属性
此函数可以填写额外的文本编辑。然而,这意味着在解析完成之前可能会插入一个completion item
,在这种情况下,编辑器将尽最大努力去应用这些额外的文本编辑
// 不做任何操作
function resolveCompletionItem(item: CompletionItem, token: CancellationToken) {
return null
}
// 不做任何操作
function resolveCompletionItem(item: CompletionItem, token: CancellationToken) {
return null
}
示例
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语法定义,运行以下代码查看所有图标示例
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是语言的名字