语言服务器语义标记

问题描述 投票:0回答:2

在语言服务器协议规范中,语义标记响应有一个数据字段,它是标记的整数数组。

export interface SemanticTokens {
    /**
     * The actual tokens.
     */
    data: uinteger[];
}

在所有示例中,语义标记都是在客户端使用 SemanticTokensBuilder 完成的,SemanticTokensBuilder 为每个标记类型指定行和列范围。你如何做服务器端?当 VSCode 发送“textDocument/semanticTokens/full”方法时,语言服务器返回什么?

visual-studio-code language-server-protocol
2个回答
5
投票

通过查看示例也许最容易解释。此示例改编自 https://microsoft.github.io/language-server-protocol/specifications/specification-3-17/#textDocument_semanticTokens

假设您的文件具有内容

\n\n     foo  bars\n\n  bazzled\n
,即用空格呈现,它看起来像这样:



     foo  bars

  bazzled

在以下位置有三个标记(使用 0 索引):

  1. foo
    ,第 2 行,第 5 个字符
  2. bars
    ,第 2 行,第 10 个字符
  3. bazzled
    ,第 5 行,第 2 个字符

这是服务器可以响应的一个可能的有效

data

// 1st token,  2nd token,  3rd token
[  2,5,3,0,3,  0,5,4,1,0,  3,2,7,2,0 ]

这只是以下信息的压缩形式:

[ { deltaLine: 2, deltaStartChar: 5, length: 3, tokenType: 0, tokenModifiers: 3 },  // first token
  { deltaLine: 0, deltaStartChar: 5, length: 4, tokenType: 1, tokenModifiers: 0 },  // second token
  { deltaLine: 3, deltaStartChar: 2, length: 7, tokenType: 2, tokenModifiers: 0 }   // third token
]

也就是说,每组 5 个连续元素对应一个 token。这 5 个元素按顺序具有以下含义:

  1. deltaLine
    :此标记与上一个标记之间的行差异
  2. deltaStartChar
    :此标记与前一个标记之间的起始字符差异(如果前一个标记位于同一行),或者只是此标记的起始字符(如果前一个标记位于不同行)
  3. length
    :这个token的长度
  4. tokenType
    :令牌类型图例的索引
  5. tokenModifiers
    :令牌修饰符的位标志

因此,例如,第二个标记具有

deltaLine = 0
,表示它与第一个标记在同一行,而
deltaStartChar = 5
表示它在第一个标记开始后 5 个字符开始。第一个标记之前没有标记,因此它的位置被视为绝对位置。

tokenType
是令牌类型图例的索引,它是在协议初始化握手期间建立的。令牌修饰符的图例也在初始化握手期间建立。

虽然上面的

tokenModifiers
值只是一个整数,但它会被解释为一个位向量,其中每个位指示相应的修饰符是打开还是关闭。例如,上面为第一个标记 (
foo
) 分配了修饰符
0b11
,表示第 0 个和第 1 个标记修饰符都处于活动状态,所有其他修饰符不适用于该标记。


0
投票

我在 Github 上找到了维护者的这个答案,很有用。

如果它被移动,链接将不再有效或以某种方式消失, 这里简要介绍一下要点:

connection.onInitialize((params: InitializeParams): InitializeResult => {
    return {
        capabilities: {
            semanticTokensProvider: {
                legend: {
                    // set your tokens here
                    tokenTypes: [], 
                    tokenModifiers: [],
                }
            }
        }
    };
});

connection.onRequest("textDocument/semanticTokens/full", (params: SemanticTokensParams) => {
    // Implement your logic to provide semantic tokens for the given document here.
    // You should return the semantic tokens as a response.
    const semanticTokens = computeSemanticTokens(params.textDocument.uri);
    return semanticTokens;
});

function computeSemanticTokens(params: string): SemanticTokens {
    return { data: [] };
}

© www.soinside.com 2019 - 2024. All rights reserved.