更多文章請戳VSCode插件開發全攻略系列目錄導航。
命令
我們在前面HelloWord章節中已經提到了命令寫法,這里再重溫一下。
context.subscriptions.push(vscode.commands.registerCommand('extension.sayHello', () => {
vscode.window.showInformationMessage('您執行了extension.sayHello命令!');
}));
然后在清單文件聲明:
"commands": [
{
"command": "extension.sayHello",
"title": "Hello World"
},
]
vscode.commands.registerCommand
是注冊命令的API,執行后會返回一個Disposable
對象,所有注冊類的API執行后都需要將返回結果放到context.subscriptions
中去。
回調函數參數
回調函數接收一個可選參數uri
:
- 當從資源管理器中右鍵執行命令時會把當前選中資源路徑uri作為參數傳過;
- 當從編輯器中右鍵菜單執行時則會將當前打開文件路徑URI傳過去;
- 當直接按
Ctrl+Shift+P
執行命令時,這個參數為空;
示例:
context.subscriptions.push(vscode.commands.registerCommand('extension.demo.getCurrentFilePath', (uri) => {
vscode.window.showInformationMessage(`當前文件(夾)路徑是:${uri ? uri.path : '空'}`);
}));
package.json
如下:
"menus": {
"editor/context": [
{
"when": "editorFocus",
"command": "extension.demo.getCurrentFilePath",
"group": "navigation"
}
],
"explorer/context": [
{
"command": "extension.demo.getCurrentFilePath",
"group": "navigation"
}
]
}
}
最終效果:
編輯器命令
除了上面的注冊普通命令之外,還有一個vscode.commands.registerTextEditorCommand
命令,文本編輯器命令與普通命令不同,它們僅在有被編輯器被激活時調用才生效,此外,這個命令可以訪問到當前活動編輯器textEditor
:
// 編輯器命令
context.subscriptions.push(vscode.commands.registerTextEditorCommand('extension.testEditorCommand', (textEditor, edit) => {
console.log('您正在執行編輯器命令!');
console.log(textEditor, edit);
}));
執行命令
這里先說一下vscode api的一個習慣設計,很多命令都是返回一個類似於Promise的Thenable
對象,如果發現api里面返回的是這個對象,說明這個方法不是直接返回結果的。
使用代碼執行某個命令:
vscode.commands.executeCommand('命令', 'params1', 'params2', ...).then(result => {
console.log('命令結果', result);
});
獲取所有命令
前面說到了執行命令,那我怎么知道某些操作它的命令是什么呢?
有2種方法,第一種通過代碼,getCommands
接收一個參數表示是否過濾內部命令,默認否:
// 獲取所有命令
vscode.commands.getCommands().then(allCommands => {
console.log('所有命令:', allCommands);
});
一般有上千個命令:
另外一種方法是直接打開快捷鍵設置,這里就能看到所有命令列表,右鍵可以復制命令:
復雜命令
vscode內部有一些復雜命令,所謂復雜命令,就是指一些需要特殊參數並且通常有返回值、執行一些諸如跳轉到定義、執行代碼高亮等特殊操作、這類命令有幾十個,作為插件開發者,很多時候你可能正需要這類命令,復雜命令列表參閱:https://code.visualstudio.com/docs/extensionAPI/vscode-api-commands
以下是演示如何在VS代碼中打開新文件夾的示例:
let uri = Uri.file('/some/path/to/folder');
commands.executeCommand('vscode.openFolder', uri).then(sucess => {
console.log(success);
});
菜單
一個菜單項的完整配置如下:
"contributes": {
"menus": {
"editor/title": [{
"when": "resourceLangId == markdown",
"command": "markdown.showPreview",
"alt": "markdown.showPreviewToSide",
"group": "navigation"
}]
}
}
editor/title
是key值,定義這個菜單出現在哪里;when
控制菜單合適出現;command
定義菜單被點擊后要執行什么操作;alt
定義備用命令,按住alt
鍵打開菜單時將執行對應命令;group
定義菜單分組;
出現的位置
目前插件可以給以下場景配置自定義菜單:
- 資源管理器上下文菜單 -
explorer/context
- 編輯器上下文菜單 -
editor/context
- 編輯標題菜單欄 -
editor/title
- 編輯器標題上下文菜單 -
editor/title/context
- 調試callstack視圖上下文菜單 -
debug/callstack/context
- SCM標題菜單 -
scm/title
- SCM資源組菜單 -
scm/resourceGroup/context
- SCM資源菜單 -
scm/resource/context
- SCM更改標題菜單 -
scm/change/title
- 左側視圖標題菜單 -
view/title
- 視圖項菜單 -
view/item/context
- 控制命令是否顯示在命令選項板中 -
commandPalette
其中,最常見的應該就explorer/context
和editor/context
了,這2個應該不用多做介紹。
editor/title
:
圖標在commands
里面配置,light和dark分別對應淺色和深色主題,如果不配置圖標則直接顯示文字:
"commands": [
{
"command": "extension.demo.testMenuShow",
"title": "這個菜單僅在JS文件中出現",
"icon": {
"light": "./images/tool-light.svg",
"dark": "./images/tool-light.svg"
}
}
]
editor/title/context
:
when
通過可選的when語句,VS Code
可以很好地控制什么時候顯示菜單項,當然,when語句語法不僅僅適用於菜單項的控制。
when語句語法有很多,這里列舉幾個常用的:
resourceLangId == javascript
:當編輯的文件是js文件時;resourceFilename == test.js
:當當前打開文件名是test.js
時;isLinux
、isMac
、isWindows
:判斷當前操作系統;editorFocus
:編輯器具有焦點時;editorHasSelection
:編輯器中有文本被選中時;view == someViewId
:當當前視圖ID等於someViewId
時;- 等等等
多個條件可以通過與或非進行組合,例如:editorFocus && isWindows && resourceLangId == javascript
。
有關when語句的更多完整語法請參考官方文檔:https://code.visualstudio.com/docs/getstarted/keybindings#_when-clause-contexts
alt
alt
很好理解,表示沒有按下alt鍵時,點擊右鍵菜單執行的是command
對應的命令,而按下了alt鍵后執行的是alt對應的命令。這里不做過多解釋。
group
組間排序
控制菜單的分組和排序。不同的菜單擁有不同的默認分組。
editor/context
中有這些默認組:
navigation
- 放在這個組的永遠排在最前面;1_modification
- 更改組;9_cutcopypaste
- 編輯組z_commands
- 最后一個默認組,其中包含用於打開命令選項板的條目。
除了navigation
是強制放在最前面之外,其它分組都是按照0-9、a-z的順序排列的,所以如果你想在1_modification
和9_cutcopypaste
插入一個新的組別的話,你可以定義一個諸如6_test
:
explorer/context
有這些默認組:
- navigation - 放在這個組的永遠排在最前面;
- 2_workspace - 與工作空間操作相關的命令。
- 3_compare - 與差異編輯器中的文件比較相關的命令。
- 4_search - 與在搜索視圖中搜索相關的命令。
- 5_cutcopypaste - 與剪切,復制和粘貼文件相關的命令。
- 7_modification - 與修改文件相關的命令。
在編輯器選項卡上下文菜單
有這些默認組:
- 1_close - 與關閉編輯器相關的命令。
- 3_preview - 與固定編輯器相關的命令。
在editor/title
有這些默認組:
- 1_diff - 與使用差異編輯器相關的命令。
- 3_open - 與打開編輯器相關的命令。
- 5_close - 與關閉編輯器相關的命令。
組內排序
默認同一個組的順序取決於菜單名稱,如果想自定義排序的話可以再組后面通過@<number>
的方式來自定義順序,例如:
"editor/context": [
{
"when": "editorFocus",
"command": "extension.sayHello",
// 強制放在navigation組的第2個
"group": "navigation@2"
},
{
"when": "editorFocus",
"command": "extension.demo.getCurrentFilePath",
// 強制放在navigation組的第1個
"group": "navigation@1"
}
]
如上,默認情況下,按照菜單名排序,sayHello
在getCurrentFilePath
的前面,但是通過自定義順序,把后者放到了前面。
快捷鍵
快捷鍵設置的寫法比較簡單,如下所示:
"contributes": {
"keybindings": [{
// 指定快捷鍵執行的操作
"command": "extension.sayHello",
// windows下快捷鍵
"key": "ctrl+f10",
// mac下快捷鍵
"mac": "cmd+f10",
// 快捷鍵何時生效
"when": "editorTextFocus"
}]
}
這個快捷鍵最終會出現在整個vscode快捷鍵設置界面:
如果您想了解更多有關快捷鍵綁定的詳細細節可以繼續閱讀官方文檔:https://code.visualstudio.com/docs/getstarted/keybindings