美文网首页
vscode插件快餐教程(5) - 代码补全

vscode插件快餐教程(5) - 代码补全

作者: Jtag特工 | 来源:发表于2019-05-26 18:45 被阅读0次

    vscode插件快餐教程(5) - 代码补全

    上节我们介绍了lsp的基本框架和协议的三次握手。
    下面我们先学习一个最简单的功能协议:给vscode发送一条通知。

    LSP窗口消息

    在LSP协议中,跟窗口相关的协议有三条:

    • window/ShowMessage Notification
    • window/showMessage Request
    • window/logMessage Notification

    我们可以使用Connection.window.sendxxxMessage函数来向客户端发送消息。
    根据消息程度的不同,分为Information, Warning和Error三个级别。

    举个例子,我们可以在onInitialized,也就是客户端与服务端三次握手一切就绪之后,向客户端发一个消息。

    connection.onInitialized(() => {
        connection.window.showInformationMessage('Hello World! form server side');
    });
    

    显示结果如下:


    showMessage

    代码补全

    我们用窗口通知热热身,测试一下链路通不通。下面我们就直奔我们最感兴趣的主题之一:代码补全。

    代码补全的形式其实也很简单,输入是一个TextDocumentPositionParams,输出是一个CompletionItem的数组,这个函数注册到connection.onCompletion中:

    connection.onCompletion(
        (_textDocumentPosition: TextDocumentPositionParams): CompletionItem[] => {});
    

    代码补全中用到的主要数据结构如下图所示:


    代码补全.png

    其中kind属性由一个枚举定义:


    CompletionItemKind.png

    大家不要被吓到,我们通过一个简单的例子看一下,其实基本实现方法还是很简单的:

    connection.onCompletion(
        (_textDocumentPosition: TextDocumentPositionParams): CompletionItem[] => {
            connection.console.log('[xulun]Position:' + _textDocumentPosition.textDocument);
    
            return [
                {
                    label: 'TextView',
                    kind: CompletionItemKind.Text,
                    data: 1
                },
                {
                    label: 'Button',
                    kind: CompletionItemKind.Text,
                    data: 2
                },
                {
                    label: 'ListView',
                    kind: CompletionItemKind.Text,
                    data: 3
                }
            ];
        }
    )
    

    补全的详细信息

    除了补全信息textDocument/completion之外,lsp还支持completionItem/resolve请求,输入和输出都是CompletionItem,返回进一步的信息。
    通过connection.onCompletionResolve方法可以注册对于completionItem/resolve请求的支持:

    connection.onCompletionResolve(
        (item: CompletionItem): CompletionItem => {
            if (item.data === 1) {
                item.detail = 'TextView';
                item.documentation = 'TextView documentation';
            } else if (item.data === 2) {
                item.detail = 'Button';
                item.documentation = 'JavaScript documentation';
            } else if (item.data === 3) {
                item.detail = 'ListView';
                item.documentation = 'ListView documentation';
            }
            return item;
        }
    )
    

    运行效果如下:


    ListView

    使用参数中的补全位置信息

    输入参数中会带有发出补全申请的位置信息,我们可以根据这个信息来控制补全的信息。
    我们以一个例子来说明下:

    connection.onCompletion(
        (_textDocumentPosition: TextDocumentPositionParams): CompletionItem[] => {
            
            return [
                {
                    label: 'TextView' + _textDocumentPosition.position.character,
                    kind: CompletionItemKind.Text,
                    data: 1
                },
                {
                    label: 'Button' + _textDocumentPosition.position.line,
                    kind: CompletionItemKind.Text,
                    data: 2
                },
                {
                    label: 'ListView',
                    kind: CompletionItemKind.Text,
                    data: 3
                }
            ];
        }
    )
    

    我们此时不光补全一个控件名,还将当前的行号或列号增加其中。
    下面是补全Button的运行情况,会增加当前的行号到补全信息中,我们在934行触发补全,于是补全提示的信息变成Button933:


    补全带列号

    相关文章

      网友评论

          本文标题:vscode插件快餐教程(5) - 代码补全

          本文链接:https://www.haomeiwen.com/subject/wikkzqtx.html