公開日: · 更新日:
vscode-gitui: VSCodeでgituiを使う
GitUIとLazygitは、ターミナル上で動作する軽量でキーボード操作に適したGitクライアントです。エディター領域から直接開けるVSCode拡張機能「vscode-gitui」の開発過程を紹介します。
著者: gymynnym
vscode-gitui: VSCodeでgituiを使う
GitUI/Lazygitとは?
GitUIとLazygitは、ターミナル上で動作するTUI(Terminal User Interface) のGitクライアントです。GUIベースのGitクライアントよりも軽量かつ高速で、キーボード中心の操作に最適化されています。
VSCodeでもターミナルを開いてGitUIやLazygitを実行できますが、毎回ターミナルを開き、コマンドを入力し、パネルを切り替えるのは面倒でした。そこで、GitUI/Lazygitをエディター領域からすぐに開ける VSCode拡張機能(vscode-gitui) を作ってみました。
vscode-gituiのリポジトリ
https://github.com/gymynnym/vscode-gitui
試してみたい方は、VSCode MarketplaceまたはGitHub Releasesからインストールできます。
VSCodeVimユーザー向けのキーバインドも用意しています。詳細はリポジトリのREADMEをご覧ください。
開発の流れ
1. プロジェクトの作成
VSCode: Your First Extensionを参考にしました。
まず、次のコマンドでプロジェクトを作成します。
$ npx --package yo --package generator-code -- yo code
拡張機能の開発言語には TypeScript を選びました。
続いて、パッケージ化に使う vsce をインストールします。
$ pnpm add -D @vscode/vsce
// package.json
{
"scripts": {
"package": "vsce package"
}
}
2. コマンドの登録
この拡張機能では、次の2つのコマンドを登録します。
vscode-gitui.open: GitUI/Lazygitをエディター領域で開くコマンドvscode-gitui.reload: PATHからGitUI/Lazygitを再読み込みするコマンド
// src/extension.ts
export function activate(context: vscode.ExtensionContext) {
const disposables = [
vscode.commands.registerCommand('vscode-gitui.open', () => handleGitClientCommand(openGitClient)),
vscode.commands.registerCommand('vscode-gitui.reload', () => handleGitClientCommand(reloadGitClient)),
...
];
disposables.forEach((disposable) => context.subscriptions.push(disposable));
}
handleGitClientCommandは、GitUI/LazygitのコマンドがPATH上に存在するかを確認するユーティリティ関数です。詳細はextension.tsをご覧ください。
3. コマンドの実装
3-1. vscode-gitui.open
// src/commands/open.ts
async function openGitClient() {
const workspace = await getCurrentWorkspace();
const command = resolveGitCommand();
if (workspace) {
runCommandInTerminal(command, {
name: command,
cwd: workspace,
location: vscode.TerminalLocation.Editor,
});
}
}
async function getCurrentWorkspace(): Promise<string | undefined> {
const workspaceFolders = vscode.workspace.workspaceFolders;
if (!workspaceFolders || workspaceFolders.length === 0) {
throw new Error(ErrorMessage.WORKSPACE_NOT_FOUND);
}
if (workspaceFolders.length === 1) {
return workspaceFolders[0].uri.fsPath;
}
const pickedWorkspace = await vscode.window.showWorkspaceFolderPick({
placeHolder: 'Select a workspace folder to open gitui in',
ignoreFocusOut: true,
});
return pickedWorkspace?.uri.fsPath;
}
export { openGitClient };
openGitClient関数は、現在のワークスペースを確認し、GitUI/Lazygitのコマンドをエディター領域で実行します。
getCurrentWorkspace関数は、ワークスペースフォルダーのパスを返します。複数のフォルダーが開かれている場合は、ユーザーに選択を求めます。
3-2. vscode-gitui.reload
// src/commands/reload.ts
async function reloadGitClient() {
const command = resolveGitCommand();
const exists = await checkCommandExists(command);
if (exists) {
vscode.window.showInformationMessage(InfoMessage.COMMAND_FOUND(command));
} else {
vscode.window.showErrorMessage(ErrorMessage.COMMAND_NOT_FOUND(command));
}
}
reloadGitClient関数は、GitUI/LazygitのコマンドがPATH上に存在するかを確認し、その結果をメッセージで表示します。
checkCommandExistsは、コマンドの存在を確認するユーティリティ関数です。
Lazygit対応:GitHubにIssueが届いた!

実は、当初はGitUIだけに対応する予定でした。ところが、あるユーザーがLazygitへの対応を求めるIssueを立ててくれたことをきっかけに、Lazygitにも対応することになりました。
コマンドを選択するロジックの追加
上記のコードで使っているresolveGitCommand関数を、ユーザー設定に応じてGitUIまたはLazygitを選択するように変更しました。
まず、package.jsonのpropertiesに、Lazygitを使用するかどうかを指定する設定項目を追加します。
// package.json
{
"contributes": {
"configuration": {
"title": "vscode-gitui",
"properties": {
...
"vscode-gitui.useLazygit": {
"type": "boolean",
"default": false,
"description": "Enable if you want to use Lazygit instead of GitUI."
}
}
},
}
}
続いて、resolveGitCommandを次のように実装し、使用するGitクライアントを決定します。
// src/lib/command.ts
const GITUI_COMMAND = 'gitui';
const LAZYGIT_COMMAND = 'lazygit';
function resolveGitCommand(): string {
const useLazygit = vscode.workspace.getConfiguration('vscode-gitui').get<boolean>('useLazygit', false);
return useLazygit ? LAZYGIT_COMMAND : GITUI_COMMAND;
}
おわりに
VSCodeでGitUI/Lazygitを使える拡張機能を作ってみました。初めてのVSCode拡張機能の開発でしたが、比較的簡単に実装できました。開発中にGitHub Issueを通じてユーザーと直接やり取りできたことも、よい経験になりました。 皆さんも、自分のニーズに合ったVSCode拡張機能を作ってみてはいかがでしょうか。