xmake-vscode plug-in development process record

Recent going to xmake write some IDE and editor integrated plug-in, found on the first studied under vscode plug-in development process vscode editor plugin easier to use, and completed xmake-vscode developing plug-ins.

Let's first look at a few final renderings:

Syntax highlighting and auto-completion

Status Bar

statusbar

To achieve the above effect, it is not complicated. First, let's briefly introduce the basic process of vscode plug-in development:

Install the plug-in development environment

Install cnpm

Due to the complicated domestic environment, it may be slow or unstable to install directly with npm, so cnpm is installed first to use Taobao's mirror source by default.

$ npm install -g cnpm --registry=https://registry.npm.taobao.org

Create an empty project

Install the yo tool through cnpm to create an empty project of the vscode plug-in

$ cnpm install -g yo generator-code
$ yo code

The general source code structure is as follows:

After choosing to create a project, there are four inputs and one choice:

  • Enter the name of your extension xmake-vscode
  • Enter a logo (use this for the file name created by the project) xmake-vscode
  • Enter a description of this extension
  • Enter a name to be used for publishing in the future (it corresponds to a name when publishing in the future) tboox
  • Is to ask if you want to create a git repository for version management

After creating the empty project, we can open it directly with vscode, and then debug, load and run:

After loading, hit F1 to open the command window and run the default hello world test command:


At this point, a short answer demo plug-in is done. Next, we briefly introduce how to publish this plug-in to the vscode market.

Create publisher

First of all, we need to register an account on marketplace.visualstudio.com and create a publisher, here I named it tboox

Then, we need to add a Personal Access Token to our account (Address:, https://[your name].visualstudio.com/_details/security/tokensnote that the Token is only displayed once, it is best to save a copy)

Next, we install the vsce tool to package, compile and release the plug-in project of vscode.

$ cnpm install -g vsce

After installing vsce, we first create a publisher, here is tboox, enter the token provided in the market account just now to bind.

$ vsce create-publisher (publisher name)

Build release

Finally, you only need to package or publish through the following commands. If you just create a local package, drag in the vscode load test, you can run it:

$ vsce package

This will generate a similar xmake-vscode-0.0.1.vslxplug-in package file, which can be loaded and run directly with vscode.

If we have developed the plug-in and want to publish it to the market, we can execute:

$ vsce publish [version]

At this time, we can see your plug - in on xmake-vscode on marketplace , and users can also search and install it directly through vscode.

Detailed plug-in development

Plug-in loading mechanism

The plug-in is triggered by the activationEvents configured in the extension.json of the project root directory, for example:

{
    "activationEvents": [
        "workspaceContains:xmake.lua",
        "onCommand:xmake.sayHello"
    ]
}

When vscode opens xmake.luathe directory or executes xmake.XXXrelated commands, it will trigger the loading of the xmake-vscode plug-in, and then call src/extension.tsthe activate entry function in it to load and initialize the plug-in.

export function activate(context: vscode.ExtensionContext) {
    
    

    let disposable = vscode.commands.registerCommand('xmake.sayHello', () => {
        vscode.window.showInformationMessage('Hello XMake!');
    });

    context.subscriptions.push(disposable);
}

The above code, when loading the plug-in, register the sayHellocommand to display the Hello XMake!prompt information.

Create custom output

vscode outputs its own log information by creating an OutputChannel, the code is as follows:

import * as vscode from 'vscode';

let log = vscode.window.createOutputChannel("xmake/log");
log.show();
log.appendLine("hello xmake!");

When creating, you can specify a label name to distinguish different output channels. The final result displayed is as follows:

It should be noted that the log.show()output must be executed before the output will be displayed, and the output behavior is refreshed with cache, and it will not output in real time, and it does not support color highlight output.

Create and control terminals

Before, xmake-vscode used channel to output the build information of xmake, and the effect was not very satisfactory, so later, it switched to the direct execution method of the terminal. You can see the following renderings:

How to control the terminal and execute your own commands is actually very simple:

let terminal = vscode.window.createTerminal({name: "xmake"});
terminal.show(true);
terminal.sendText("xmake");

The above code creates an independent terminal with a label named xmake, and then sends the execution command:, xmaketo let the terminal execute xmake to build the project, of course, if you want to display it, you still need to call it first terminal.show(true).

Add and read global configuration

Some global vscode configuration items have been added to xmake-vscode to control the behavior of the xmake-vscode plugin. The configuration list is described in the package.json file, for example:

{
    "configuration": {
        "type": "object",
        "title": "XMake configuration",
        "properties": {
            "xmake.logLevel": {
                "type": "string",
                "default": "normal",
                "description": "The Log Level: normal/verbose/minimal",
                "enum": [
                    "verbose",
                    "normal",
                    "minimal"
                ]
            },
            "xmake.buildDirectory": {
                "type": "string",
                "default": "${workspaceRoot}/build",
                "description": "The Build Output Directory"
            },
            "xmake.androidNDKDirectory": {
                "type": "string",
                "default": "",
                "description": "The Android NDK Directory"
            }
        }
    }
}

For the above configuration, three configuration items have been added, all under the xmake.domain, which can be easily found by directly searching for xmake related words in the vscode configuration.

Reading the configuration is also very convenient, just get the xmake related domain configuration and read it:

const config = vscode.workspace.getConfiguration('xmake');
config.get("buildDirectory");

Create status bar

The buttons on the status bar can respond to the commands created before, such as: xmake.sayHellowait, let's create a debug button on the status bar to debug and run the program built by xmake:

let debugButton = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 4.5);

debugButton.command = 'xmake.onDebug';
debugButton.text = `$(bug)`;
debugButton.tooltip = "Debug the given target";
debugButton.show();

The second parameter 4.5 in createStatusBarItem is used to control the layout order of the buttons on the status bar. After creation, set some basic properties. Here the text of the button $(bug)is displayed directly by setting an icon, which is more intuitive.

For more icons that are built-in support for vscode, you can find them from octicons .

Click this button to trigger the xmake.onDebugcommand, and then execute the xmake run -dcommand on the terminal to run the debugger.

Add option input list

On the status bar of xmake-vscode , we also added several quick configuration status buttons to quickly switch between different platforms, architectures, and compilation modes, such as:

At this time, you need to have the support of an option selection list. After clicking the button, list several options that can be selected, and then choose to switch. Then how to create this option list, directly upload the code:


// 初始化选项列表清单
let items: vscode.QuickPickItem[] = [];
items.push({label: "linux", description: "The Linux Platform"});
items.push({label: "macosx", description: "The MacOS Platform"});
items.push({label: "windows", description: "The Windows Platform"});
items.push({label: "android", description: "The Android Platform"});
items.push({label: "iphoneos", description: "The iPhoneOS Platform"});
items.push({label: "watchos", description: "The WatchOS Platform"});
items.push({label: "mingw", description: "The MingW Platform"});
items.push({label: "cross", description: "The Cross Platform"});

// 显示选项列表,提示用户选择
const chosen: vscode.QuickPickItem|undefined = await vscode.window.showQuickPick(items);
if (chosen) {

    // 获取选择后的结果,然后更新状态栏按钮文本
    platButton.text = chosen.label;
}

Custom syntax highlighting

Syntax highlighting can be done through the configuration file, without writing code, of course, it can also be dynamically configured in the code, which is a little more cumbersome.

xmake-vscode needs to process the syntax highlighting of the project xmake.lua description file, so here a language type called xmake is first defined in package.json, if the editor opens the xmake.luafile, it will be syntax highlighted .

{
    "contributes": {
        "languages": [
            {
                "id": "xmake",
                "filenames": [
                    "xmake.lua"
                ],
                "aliases": [
                    "XMake"
                ],
                "configuration": "./languages/xmake-configuration.json"
            }
        ],
        "grammars": [
            {
                "language": "xmake",
                "scopeName": "source.xmake",
                "path": "./languages/xmake-grammars.json"
            }
        ]
    }
}

The descriptions related to syntax highlighting are all placed in /languages/xmake-grammars.jsonjson to describe, we can also use xml format to describe, but this is not very readable.

xmake-grammars.jsonWe extracted the description rules in Lua's grammars file, because xmake.luait is based on Lua grammar. For example, we match 'xxx'the rules of single-quoted strings and perform the highlighted output of the strings.

{
    "begin": "'",
    "beginCaptures": {
        "0": {
            "name": "punctuation.definition.string.begin.xmake"
        }
    },
    "end": "'",
    "endCaptures": {
        "0": {
            "name": "punctuation.definition.string.end.xmake"
        }
    },
    "name": "string.quoted.single.xmake",
    "patterns": [
        {
            "include": "#escaped_char"
        }
    ]
}

Realization of auto-completion

The automatic prompting and completion of the code is troublesome. You need to write a custom class and register it through languages:

vscode.languages.registerCompletionItemProvider("xmake", new Completion());

Here we define a Completion class and register it to the xmake language. The xmake language definition is the configuration in package.json just mentioned.

Then we implement this Completion class:

export class Completion implements vscode.CompletionItemProvider {

    // 匹配当前输入,提供需要补全的候选文本列表
    public provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): Thenable<vscode.CompletionItem[]> {

        // 获取当前输入的单词文本
        let wordAtPosition = document.getWordRangeAtPosition(position);
        var currentWord = '';
        if (wordAtPosition && wordAtPosition.start.character < position.character) {
            var word = document.getText(wordAtPosition);
            currentWord = word.substr(0, position.character - wordAtPosition.start.character);
        }

        // 猜测匹配结果,返回候选列表
        return new Promise(function (resolve, reject) {
    
    
            Promise.all([
                getLuaKeywordsSuggestions(currentWord),
                getXMakeCommandsSuggestions(currentWord)
            ]).then(function (results) {
    
    
                var suggestions = Array.prototype.concat.apply([], results);
                resolve(suggestions);
            }).catch(err => { reject(err); });
        });
    }

    // 这里可以对刚刚返回的候选文本列表在做二次处理,例如:增加详细的文档描述信息
    public resolveCompletionItem(item: vscode.CompletionItem, token: vscode.CancellationToken): Thenable<vscode.CompletionItem> {

        // 对每个候选文本增加文档描述
        return new Promise(function (resolve, reject) {
    
     
            item.documentation = "xxxxxxxxxxx";
            resolve(item);
         });
    }
}

There is a lot of code in this part, so I won’t post it completely. For complete implementation, please refer to: completion.ts

Conclusion

Some of the vscode plug-in codes described in this article are from xmake-vscode , and interested students can directly refer to the source code and write their own plug-ins.

Original source: http://tboox.org/cn/2017/10/11/xmake-vscode/

Guess you like

Origin blog.csdn.net/waruqi/article/details/78561577