天天看點

vscode插件快餐教程(1) - 從寫指令開始vscode插件快餐教程(1) - 從寫指令開始

vscode插件快餐教程(1) - 從寫指令開始

大緻從2017年開始,vscode就越來越流行。vscode能夠流行起來,除了功能強大、微軟不斷更新給力之外,優秀的插件機制也是非常重要的一環。vscode中相當多的功能也是通過自身的插件機制實作的。

比起使用coffeescript為主要開發語言的atom IDE,vscode使用越來越有王者氣質的typescript做為主要的開發語言,這也為vscode插件開發提供了良好的助力。

随着插件機制的不斷完善,文檔、示例與腳手架工具等也日漸成熟。相關的文章與教程也非常豐富,現在寫vscode的plugin已經是件比較容易的事情了。

自己的業務開發,隻有自己最了解,作為程式員,寫自己的plugin來加速自己的開發效率,現在正是好時機。

vscode的plugin種類非常豐富,我們先從最傳統的定義新指令說起吧。

使用腳手架生成骨架

與其他主流前端工程一樣,我們通過腳手架來生成插件的骨架。微軟提供了基于腳手架生成工具yeoman的腳本。

vscode插件快餐教程(1) - 從寫指令開始vscode插件快餐教程(1) - 從寫指令開始

我們通過npm來安裝vscode plugin腳手架:

npm install -g yo generator-code           

然後我們就可以通過yo code指令來生成vscode plugin骨架代碼了。

yo code           

腳手架會提示選擇生成的plugin的類型:

_-----_     ╭──────────────────────────╮
    |       |    │   Welcome to the Visual  │
    |--(o)--|    │   Studio Code Extension  │
   `---------´   │        generator!        │
    ( _´U`_ )    ╰──────────────────────────╯
    /___A___\   /
     |  ~  |     
   __'.___.'__   
 ´   `  |° ´ Y ` 

? What type of extension do you want to create? (Use arrow keys)
 New Extension (TypeScript) 
  New Extension (JavaScript) 
  New Color Theme 
  New Language Support 
  New Code Snippets 
  New Keymap 
  New Extension Pack            

我們就選擇New Extension (Typescript)。關于其他選擇我們後面的文章會繼續介紹。

我們從最簡單的移動光标開始做起吧。比如寫一個将光标移動到編輯區首,比如一篇文章或代碼的首部,用emacs的指令叫做move-beginning-of-buffer。

光标移動指令實踐

同是編輯器,都有相似的功能。這種移動到文章首的功能,肯定不用我們自己開發,vscode早就為我們做好了。在vscode中定義了一大堆光标控制的指令,比如這條就叫做cursorTop。

  • cursorTop: 移動到文章首
  • cursorBottom: 移動到文章尾
  • cursorRight: 光标向右移,相當于emacs的forward-char
  • cursorLeft: 光标左移,相當于emacs的backward-char
  • cursorDown: 向下移一行,相當于emacs的next-line
  • cursorUp: 向上移一行,相當于emacs的previous-line
  • cursorLineStart: 移至行首,相當于emacs的move-beginning-of-line
  • cursorLineEnd: 移至行尾,相當于emacs的move-end-of-line

我們建立一個move.ts,用于實作光标移動的功能。我們先以移動到文章首為例。我們通過vscode.commands.executeCommand函數來執行指令。

例:

import * as vscode from 'vscode';

export function moveBeginningOfBuffer(): void {
    vscode.commands.executeCommand('cursorTop');
}           

在主檔案extension.ts中,我們先把move.ts這個包引入進來:

import * as move from './move';           

然後在activate函數中,注冊這個指令:

let disposable_begin_buffer = vscode.commands.registerCommand('extension.littleemacs.moveBeginningOfBuffer',
        move.moveBeginningOfBuffer);

    context.subscriptions.push(disposable_begin_buffer);           

最後我們在package.json中給其綁定一個快捷鍵。'<'和'>'在鍵盤中是上排鍵,我們就不用它們了,比如綁定到alt-[上。

修改contributes部分如下:

"contributes": {
        "commands": [{
            "command": "extension.littleemacs.moveBeginningOfBuffer",
            "title": "move-beginning-of-buffer"
        }],
        "keybindings": [{
            "command": "extension.littleemacs.moveBeginningOfBuffer",
            "key": "alt+["
        }]
    }           

大功告成。我們用F5來啟動調試,就會啟動一個新的vscode界面。

我們在新開的vscode界面,打開指令視窗(F1或shift-cmd-p),輸入move-beginning-of-buffer就可以看到這個指令了:

vscode插件快餐教程(1) - 從寫指令開始vscode插件快餐教程(1) - 從寫指令開始

我們可以移到檔案中間的位置,按alt+[就會回到檔案頭。

目前完整的extension.ts的代碼為:

// The module 'vscode' contains the VS Code extensibility API
// Import the module and reference it with the alias vscode in your code below
import * as vscode from 'vscode';
import * as move from './move';

// this method is called when your extension is activated
// your extension is activated the very first time the command is executed
export function activate(context: vscode.ExtensionContext) {

    // Use the console to output diagnostic information (console.log) and errors (console.error)
    // This line of code will only be executed once when your extension is activated
    console.log('Congratulations, your extension "littleemacs" is now active!');

    // The command has been defined in the package.json file
    // Now provide the implementation of the command with registerCommand
    // The commandId parameter must match the command field in package.json
    let disposable_begin_buffer = vscode.commands.registerCommand('extension.littleemacs.moveBeginningOfBuffer',
        move.moveBeginningOfBuffer);

    context.subscriptions.push(disposable_begin_buffer);
}

// this method is called when your extension is deactivated
export function deactivate() {
    console.log('Plugin deactivated');
}           

對應的完整package.json為:

{
    "name": "littleemacs",
    "displayName": "littleemacs",
    "description": "Some operations just like emacs",
    "version": "0.0.1",
    "engines": {
        "vscode": "^1.33.0"
    },
    "categories": [
        "Other"
    ],
    "activationEvents": [
        "onCommand:extension.littleemacs.moveBeginningOfBuffer"
    ],
    "main": "./out/extension.js",
    "contributes": {
        "commands": [{
            "command": "extension.littleemacs.moveBeginningOfBuffer",
            "title": "move-beginning-of-buffer"
        }],
        "keybindings": [{
            "command": "extension.littleemacs.moveBeginningOfBuffer",
            "key": "alt+["
        }]
    },
    "scripts": {
        "vscode:prepublish": "yarn run compile",
        "compile": "tsc -p ./",
        "watch": "tsc -watch -p ./",
        "postinstall": "node ./node_modules/vscode/bin/install",
        "test": "yarn run compile && node ./node_modules/vscode/bin/test"
    },
    "devDependencies": {
        "typescript": "^3.3.1",
        "vscode": "^1.1.28",
        "tslint": "^5.12.1",
        "@types/node": "^10.12.21",
        "@types/mocha": "^2.2.42"
    }
}           

一個插件實作多條指令

一個不夠,我們再寫一個:

activate函數:

let disposable_begin_buffer = vscode.commands.registerCommand('extension.littleemacs.beginningOfBuffer',
        move.beginningOfBuffer);

    let disposable_end_buffer = vscode.commands.registerCommand('extension.littleemacs.endOfBuffer',
        move.endOfBuffer);

    context.subscriptions.push(disposable_begin_buffer);
    context.subscriptions.push(disposable_end_buffer);           

功能實作函數:

import * as vscode from 'vscode';

export function beginningOfBuffer(): void {
    vscode.commands.executeCommand('cursorTop');
}

export function endOfBuffer() {
    vscode.commands.executeCommand('cursorBottom');
}           

package.json:

"activationEvents": [
        "onCommand:extension.littleemacs.beginningOfBuffer",
        "onCommand:extension.littleemacs.endOfBuffer"
    ],
    "main": "./out/extension.js",
    "contributes": {
        "commands": [{
                "command": "extension.littleemacs.beginningOfBuffer",
                "title": "beginning-of-buffer"
            },
            {
                "command": "extension.littleemacs.endOfBuffer",
                "title": "end-of-buffer"
            }
        ],
        "keybindings": [{
                "command": "extension.littleemacs.beginningOfBuffer",
                "key": "alt+["
            },
            {
                "command": "extension.littleemacs.endOfBuffer",
                "key": "alt+]"
            }
        ]
    },           

繼續閱讀