本文介绍了实现转到定义时如何获取当前文本/符号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用语言服务器协议开发我的第一个 vscode 扩展,我需要获取文本是 右键单击​​ ->转到定义被触发

I'm working on my first vscode extension using Language Server Protocol, I need to get the text were the Right click -> Go to definition was triggered

我当前的 onDefinition 方法只接收 textPosition

My current onDefinition method receives only the textPosition

export default class DefinitionFinder extends Handler {
    constructor(
        protected connection: Connection,
        private refManager: ReferenceManager)
    {
        super();

        this.connection.onDefinition(async (textPosition) => {
            return this.handleErrors(
                this.getDefinition(textPosition), undefined) as Promise<Definition>;
        });
    }

private async getDefinition(textPosition: TextDocumentPositionParams): Promise<Location[]> {
    const text = "funABC";

    // instead of hardcoded value I need to get the text/symbol
    // that is going to be use to go to definition

    return this.refManager.getDefinitionLocations(text);
}

TextDocumentPositionParams 只包含 documentUriline(number)character(number)

这是否意味着每次调用 onDefinition 时我都需要打开文档,转到行和字符并获取当前单词?

Does that mean that on each call to onDefinition I need to open the document, go to the line and character and get the current word ?

export interface TextDocumentPositionParams {
    /**
     * The text document.
     */
    textDocument: TextDocumentIdentifier;
    /**
     * The position inside the text document.
     */
    position: Position;
}

export interface TextDocumentIdentifier {
    /**
     * The text document's uri. (string)
     */
    uri: DocumentUri;
}

export declare namespace Position {
    /**
     * Creates a new Position literal from the given line and character.
     * @param line The position's line.
     * @param character The position's character.
     */

推荐答案

这就是我最终实现转到定义"时获取单词/符号的逻辑的方式.在语言服务器上请求

This is how I ended up implementing the logic to get the word/symbol when "Go To Definition" is requested on a Language Server

我决定返回一个 LocationLink,它也显示为单词/符号上的超链接

I decided to return a LocationLink which also appears as a hyperlink over the word/symbol

this.connection.onDefinition(async (textPosition) => {
    return this.handleErrors(
        this.getDefinitionLink(textPosition), undefined) as Promise<LocationLink[]>;
});

此方法从文档中获取符号,然后在 refManager 中查看其定义

This method get the symbol from the document and then look its definition in the refManager

private async getDefinitionLink(textPosition: TextDocumentPositionParams): Promise<LocationLink[]> {
    const symbol = this.getSymbolAtPosition(textPosition.position, textPosition.textDocument.uri);

    return this.refManager.getDefinitionLink(symbol);
}

这是提取当前单词的实际逻辑,无论它是否在中间单击.

This is the actual logic to extract the current word no matter if it was click in the middle of it.


let TokenSeparatorsXML = /[\t= <>"]/;

public getSymbolAtPosition(position: Position, documentUri: string): string {
    const range = {
        start: { line: position.line, character: 0},
        end: { line: position.line, character: Number.MAX_VALUE  }
    };
    //get the whole line
    const txtDoc = this.refManager.getDocument(documentUri)!;

    const context = txtDoc.getText(range);
    const offset = position.character ;

    let start = offset-1;

    while ((start > 0) && !context[start].match(this.TokenSeparatorsXML))
    {
        start--;
    }

    let end = offset;

    while ((end < context.length) && !context[end].match(this.TokenSeparatorsXML))
    {
        end++;
    }

    const symbol = context.substr(start + 1, end - start - 1);

    console.log(`${start}->${end}- symbol: ${symbol}`);

    return symbol;
}

就我而言,标记分隔符非常窄,但您应该考虑使用单词模式 https://code.visualstudio.com/api/language-extensions/language-configuration-guide#word-pattern

In my case the token separators are very narrow but you should consider using the word pattern https://code.visualstudio.com/api/language-extensions/language-configuration-guide#word-pattern

可以在此处找到扩展的完整代码 - https://github.com/mauriciogracia/petrel-xml

The full code of the extension can be found here - https://github.com/mauriciogracia/petrel-xml

这篇关于实现转到定义时如何获取当前文本/符号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-21 14:43