iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 21
0
Software Development

自己用的工具自己做! 30天玩轉VS Code Extension之旅系列 第 21

Day21 | 把選取的程式碼轉換為snippet物件吧!

大家好,我是韋恩,今天是鐵人賽的二十一天,讓我們來幫專案實現將選中的程式碼加入snippet的功能吧!

Day21專案實作(一): 獲取選中的程式碼


在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裡面。

Day21專案實作(二): 將轉換程式碼字串轉化為snippet物件


  • 在VSCode裡設定User snippets

在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裡面還可以設定更多變數,我們之後會再做細部說明!

  • 在Extension裡面將程式碼轉為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使用:

  1. 提供給textEditor下面的insertSnippet方法,直接使用程式在文本插入程式碼片段。

  2. 提供給completetionItem自動補全物件,並在vscode註冊這個補全物件,提供VSCode這段程式的自動補全功能。

結語


好啦,今天,我們實作了抓取選取文字的功能,並且大致了解了code snippet的設定與snippet字串物件的用法與相關使用他的api與情境。

明天我們會繼續我們的專案實作,我們明天見,掰掰!


上一篇
Day20 | 初始專案與元件配置
下一篇
Day22 | 創建使用者的Snippet工作區
系列文
自己用的工具自己做! 30天玩轉VS Code Extension之旅36

尚未有邦友留言

立即登入留言