在 Visual Studio Code 中實作小麥注音輸入法的實驗專案
2025 © McBopomofo Authors
這個專案嘗試在 Visual Studio Code 中,使用 VS Code 的 API,實作一套自動選字輸入法的功能。這個專案的結論是—技術上可行,但是實際上的使用體驗極差。
目前一些編輯器軟體,也是利用網頁技術打造的,VS Code 算是其中最普及者之一,因此,如果可以在 VS Code 中,介接之前的輸入法實作,就可以在所有可以使用 VS Code 的平台上,甚至只有瀏覽器,可以連到 https://vscode.dev 的平台上,都能使用小麥注音輸入法。
小麥輸入法的 TypeScript 版本為了可以相容於各種平台,所以在核心的演算法與狀態設計之外,像是鍵盤事件、以及使用者介面(怎樣處理字根輸入緩衝區、選字視窗等),都設計成抽象化的介面,讓不同平台可以實作這些介面。
像是,我們定義了自己的 Key 物件,在網頁與 Chrome OS 中,我們會收到 KeyboardEvent 物件,在 PIME 中,我們會透過 PIME 的跨 process 通訊協定,收到 Windows 平台的 VK Key 事件。只要將這些事件重新 map 成我們的 Key 物件,就可以讓核心的輸入法邏輯運作。
在輸出與 UI 部分,我們也設計成抽象介面,這個介面就只有更新 UI、送出文字與重設 UI 三個函數,不同平台就各自實作這三個函數,在網頁上就是操作 DOM,在 Chrome OS 輸入法中,則是操作 chrome.input.ime API,在 PIME 中則是專屬通訊協定,回傳輸入法的狀態。
在 VS Code 裡頭,如果要用一套 extension 當作輸入法,則是有另外一套輸入與輸出方式。
在 VS Code 中,extension 並不會直接拿到鍵盤事件,VS Code 會將鍵盤事件轉換成編輯命令(command),而每個 extension 想要處理什麼按鍵,其實是向編輯器註冊想要處理的命令。以一套輸入法可能要收到的命令,可能包括:
- type
- deleteLeft
- deleteRight
- cursorUp
- cursorDown
- cursorLeft
- cursorRight
- cursorPageUp
- cursorPageDown
type 命令,代表用戶打了任何可以列印的字元,其他命令則是編輯器的游標移動或刪除命令。我們註冊命令後,當收到命令時,就將命令轉換成 Key 物件,再送到輸入法邏輯上。
要查詢有哪些輸入命令,可以打開 VS Code 的 Keyboard Shortcuts 視窗,通常是跟
VS Code 所提供的UI 元件中,其實沒有特別適合製作輸入法的。嘗試幾種作法之後,在目前輸入的游標旁,加上 CSS 的 decoration,會比較合適。而由於 decoration 只能一行,為了可以顯示多行的內容,採取了比較間接的方式— CSS 的 decoration,可以放圖片,所以,我們可以將多行的文字塞入 SVG 中,再把 SVG 塞入 decoration 中。
實驗下來,效果不甚理想。問題在於 VS Code 中,按鍵的 binding 會被其他的 extension 以及用戶自己任意改變,根本無法保證哪個按鍵現在對應到哪一個命令,而一套輸入法需要的按鍵數量,比其他 extension 又多上許多,根本不能保證每個按鍵的行為都符合預期。
另外,我們所攔截到的,只是 VS Code 的 editor 區塊中的事件,但是在 VS Code 中,還有其他的部分,也都有打字的需求,尤其是在這個 AI 的時代,經常可能要跟 Coding Chatbot 聊天,但是我們攔截不到那些區域中的事件。
用 VS Code 中,打開整個專案,然後選取 src/extension.ts,按下 F5 即可測試。

