大家好,我是韋恩,今天是鐵人賽的二十一天,讓我們來幫專案實現將選中的程式碼加入snippet的功能吧!
在vscode裡面,其實提供了許多好用的api,幫助我們獲取vscode元件相關的資訊。
大家還記得嗎?前面介紹的window命名空間下面,可以取得當前active的元件,當時我們簡單示範了怎麼樣拿到開啟的terminal,並且執行指令。現在我們需要抓到編輯器的元件物件,可以使vscode.window.activeTextEditor
的api,拿到當前在active狀態的textEditor的物件。
讓我們先來拿到textEditor,檢查物件下面有什麼方法吧!
拿到editor物件後,我們馬上看到了感興趣的selection屬性,再繼續往下檢查selection的屬性與方法。
我們可以發現,selection物件會提供我們選中的position位置資訊,但是沒有辦法直接給文字。
需要將selection得到位置提供給當前的文件,才能得到程式碼字串。
現在我們轉而檢查textEditor下面的document物件中有沒有我們感興趣的方法
一點下去馬上發現,第一個跳出的方法就是getText,透過這個方法我們可以拿到當前選中的程式碼文字。
現在我們就可以把當前的selection傳給getText方法,拿到selection的程式碼文字,如下所示:
const textEditor = vscode.window.activeTextEditor;
const selectionCode = textEditor?.document.getText(textEditor.selection);
好的,現在讓我們呼叫實際的命令驗證一下結果吧!
我們先註冊一個getCodeSelection的command
{
...
"contributes": {
...
"commands": [
{
"command": "ithome30-code-manager.getCodeSelection",
"title": "Code Manager: Get Code Selection"
}
]
},
...
}
並於extension.ts中使用命令拿到codeSelection
import * as vscode from 'vscode';
import { registerTreeview } from './treeview';
export function activate(context: vscode.ExtensionContext) {
...
let getCodeSelection = vscode.commands.registerCommand('ithome30-code-manager.getCodeSelection', () => {
const textEditor = vscode.window.activeTextEditor;
const selectionCode = textEditor?.document.getText(textEditor.selection);
console.log(selectionCode);
});
context.subscriptions.push(createWorkspace, chooseWorkspace, getCodeSelection);
}
現在我們可以再使用快捷鍵打開Command Palette執行命令,但這樣實在有點麻煩,為什麼不直接選完文字後就打開一個選單執行命令呢?讓我們在editor上註冊一個menu並綁定上這個命令吧!
ㄧ樣是在Contribution Point:
{
...
"contributes": {
...
"menus": {
"editor/context": [
{
"command": "ithome30-code-manager.getCodeSelection",
"group": "navigation"
}
]
}
},
...
}
設定好選單後,讓我們執行我們的extension吧!
我們打開一個文件後,選取一段程式碼,按右鍵。
可以看到展開的選單上有我們的GetCode命令可以執行,現在就讓我們點擊獲取選中的這段文字吧!
點擊後,在我們的Debug Console下面,我們可以清楚看到先前選取的文字完整的顯示在console裡面。
在VSCode裡面,我們可以自由的定義User Snippet,讓我們點擊左上角的Code -> Preference -> User Snippets選項
選取後,會跳出一個下拉選單讓我們選取要創建哪種語言的snippet,這裡我們選取typescript。
選取後,就會打開全域的snippet設定,並有預設的snippet範例。
現在,將範例取消註解後,讓我們檢視範例和實際顯示在VSCode自動補全的文字!
我們可以清楚看到,在左邊物件Print to console
裡有一個prefix屬性,內容是log。當我們在prefix設定裡設定好內容文字,vscode會在我們於editor輸入與prefix的內容後,跳出提示。
最下面的description屬性,則會顯示為補全提示的標題內容。
程式碼片段的內容,位於body裡面,以一行一個字串的方式放在一個陣列裡。讀者可以看到,body裡面有$1、$2的語法,這是什麼呢?
當我們使用自動補全產生程式碼片段後,我們可以看到
鍵盤標光標的位置,會顯示在body字串的$1的位置,方便我們輸入要log的內容。
當我們再按下tab鍵,光標即會移動到$2的地方,讓我們於$2的位置輸入內容,是不是很方便呢?
註:Snippet物件可以定義同時多個光標位置,以上面的範例為例:
如果我們多定義一個$1
{ "Print to console": { "prefix": "log", "body": [ "$1 console.log('$1');", "$2" ], "description": "Log output to console" } }
就可以讓使用者同時輸入不同位置的內容喔!
好的,以上是snippet設定的簡單介紹,snippet裡面還可以設定更多變數,我們之後會再做細部說明!
好的,現在我們已經知道了一般使用者怎麼透過json的格式來讓vscode產生snippet的補全。
現在在VSCode裡面,我們的做法又是什麼呢?
讓我們使用vscode.SnippetString
物件,來產生提供給其他vscode相關api的snippet字串。
snippet字串物件的創建方法如下:
const snippet = new vscode.SnippetString('SnippetBodyValue');
我們可以先給一個預設值,創建出這個snippet字串物件。也可以先給空值,在使用底下的append方法再尾部追加文字或前面提到的$變數,vscode提供的各種設置snippet變數的方法,在這裡都可以使用相關的方法加上。
現在有了snippet字串,在vscode裡面,我們主要可以提供給兩種vscode的api使用:
提供給textEditor下面的insertSnippet方法,直接使用程式在文本插入程式碼片段。
提供給completetionItem自動補全物件,並在vscode註冊這個補全物件,提供VSCode這段程式的自動補全功能。
好啦,今天,我們實作了抓取選取文字的功能,並且大致了解了code snippet的設定與snippet字串物件的用法與相關使用他的api與情境。
明天我們會繼續我們的專案實作,我們明天見,掰掰!