はじめに
「VSCodeでいちいちコマンドをコピペしてターミナルで実行するのめんどくさい…」
そんな悩みを持つ開発者は多いはずです。実際、検索数から見ても:
■検索ワード(月間検索数)
- 1000~1万: "vscode ターミナル"
- 100~1000: "vscode コマンド プロンプト", "vscode powershell", "vscode gitbash"
- 10~100: "vscode ターミナル 実行", "vscode cmd"ターミナル実行の効率化は、多くの開発者が求めている機能です。
本記事では、カーソル行または選択テキストをショートカットキー一発でターミナル実行できるTypeScriptマクロの実装方法を完全解説します。
この記事で分かること
- ターミナル実行マクロの実装方法
- cmd/PowerShell/Git Bashの使い分け
- 単一行・複数行コマンドの実行方法
- キーバインド設定のベストプラクティス
- 実践的な使用例とワークフロー
- トラブルシューティング
こんな人におすすめ
- コマンドをメモ帳に保存している人
- コマンド実行のたびにコピペしている人
- よく使うコマンドをすぐ実行したい人
- 複数のターミナル(cmd/PS/GitBash)を使い分けたい人
解決できる課題
従来の問題点
1. コピペの手間
1. コマンドを選択
2. Ctrl+Cでコピー
3. ターミナルをクリック
4. Ctrl+Vで貼り付け
5. Enter押下2. コマンド管理の煩雑さ
- よく使うコマンドをどこに保存?
- 過去のコマンド履歴を探すのが大変
- プロジェクトごとのコマンド集が散在
3. ターミナル切り替えの手間
- cmd、PowerShell、Git Bashを使い分け
- それぞれでコマンド入力が必要
この機能で実現できること
ショートカットキー一発で実行!
Before:
選択 → コピー → ターミナル切替 → 貼り付け → Enter(5ステップ)
After:
Ctrl+Shift+1(1ステップ)複数コマンドも順次実行
# 3行を選択してCtrl+Shift+1
cd /d C:\projects
npm install
npm run dev
# → 自動で順次実行!機能仕様
基本機能
| 機能 | 説明 |
|---|---|
| 単一行実行 | カーソル行を実行 |
| 複数行実行 | 選択範囲を行ごとに順次実行 |
| 空行スキップ | 空行は自動で除外 |
| ターミナル管理 | 専用ターミナルを自動作成・再利用 |
ショートカットキー
| キー | 機能 | ターミナル |
|---|---|---|
| Ctrl+Shift+1 | CMD実行 | コマンドプロンプト |
| Ctrl+Shift+2 | PS実行 | PowerShell |
| Ctrl+Shift+3 | Bash実行 | Git Bash |
動作フロー
1. テキスト未選択の場合
↓
カーソル行の文字列全体を取得
↓
ターミナルで実行
2. テキスト選択の場合
↓
選択範囲を行ごとに分割
↓
空行を除外
↓
各行を順次実行(100ms待機)TypeScript実装コード
ファイル構成
src/
├── extension.ts # コマンド登録
└── macros/
└── runInTerminal.ts # ターミナル実行機能runInTerminal.ts(完全版)
import * as vscode from 'vscode';
/**
* ターミナルのタイプ
*/
export enum TerminalType {
CMD = 'cmd',
PowerShell = 'powershell',
GitBash = 'gitbash'
}
/**
* コマンドプロンプトで実行
*/
export async function runInCmd() {
await runInTerminal(TerminalType.CMD);
}
/**
* PowerShellで実行
*/
export async function runInPowerShell() {
await runInTerminal(TerminalType.PowerShell);
}
/**
* Git Bashで実行
*/
export async function runInGitBash() {
await runInTerminal(TerminalType.GitBash);
}
/**
* 指定されたターミナルでコマンド実行
*/
async function runInTerminal(terminalType: TerminalType) {
const editor = vscode.window.activeTextEditor;
if (!editor) {
vscode.window.showWarningMessage('アクティブなエディタがありません');
return;
}
// コマンド取得
const commands = getCommandsToExecute(editor);
if (commands.length === 0) {
vscode.window.showWarningMessage('実行するコマンドがありません');
return;
}
// ターミナル取得または作成
const terminal = getOrCreateTerminal(terminalType);
terminal.show();
// コマンド実行(複数行の場合は順次実行)
for (const command of commands) {
const trimmedCommand = command.trim();
if (trimmedCommand) {
terminal.sendText(trimmedCommand, true);
// 複数コマンド実行時は少し待機
if (commands.length > 1) {
await sleep(100);
}
}
}
// 実行完了メッセージ
const terminalName = getTerminalDisplayName(terminalType);
const message = commands.length === 1
? `${terminalName}でコマンドを実行しました`
: `${terminalName}で${commands.length}個のコマンドを実行しました`;
vscode.window.showInformationMessage(message);
}
/**
* 実行するコマンドを取得
*/
function getCommandsToExecute(editor: vscode.TextEditor): string[] {
const selection = editor.selection;
const document = editor.document;
// テキストが選択されている場合
if (!selection.isEmpty) {
const selectedText = document.getText(selection);
// 複数行の場合は行ごとに分割
const lines = selectedText.split(/\r?\n/);
// 空行を除外してコマンドリストを作成
return lines
.map(line => line.trim())
.filter(line => line.length > 0);
}
// テキスト未選択の場合は現在行を取得
const currentLine = document.lineAt(selection.active.line);
const lineText = currentLine.text.trim();
return lineText.length > 0 ? [lineText] : [];
}
/**
* ターミナルを取得または作成
*/
function getOrCreateTerminal(terminalType: TerminalType): vscode.Terminal {
const terminalName = getTerminalName(terminalType);
// 既存のターミナルを探す
const existingTerminal = vscode.window.terminals.find(
t => t.name === terminalName
);
if (existingTerminal) {
return existingTerminal;
}
// 新規ターミナルを作成
return createTerminal(terminalType);
}
/**
* 新しいターミナルを作成
*/
function createTerminal(terminalType: TerminalType): vscode.Terminal {
const name = getTerminalName(terminalType);
let shellPath: string | undefined;
let shellArgs: string[] | undefined;
switch (terminalType) {
case TerminalType.CMD:
shellPath = 'cmd.exe';
break;
case TerminalType.PowerShell:
shellPath = 'powershell.exe';
break;
case TerminalType.GitBash:
// Git Bashの一般的なパス
shellPath = 'C:\\Program Files\\Git\\bin\\bash.exe';
// 見つからない場合の代替パス
if (!require('fs').existsSync(shellPath)) {
shellPath = 'C:\\Program Files (x86)\\Git\\bin\\bash.exe';
}
shellArgs = ['--login', '-i'];
break;
}
return vscode.window.createTerminal({
name: name,
shellPath: shellPath,
shellArgs: shellArgs
});
}
/**
* ターミナル名を取得
*/
function getTerminalName(terminalType: TerminalType): string {
switch (terminalType) {
case TerminalType.CMD:
return 'My Macros - CMD';
case TerminalType.PowerShell:
return 'My Macros - PowerShell';
case TerminalType.GitBash:
return 'My Macros - Git Bash';
}
}
/**
* ターミナル表示名を取得
*/
function getTerminalDisplayName(terminalType: TerminalType): string {
switch (terminalType) {
case TerminalType.CMD:
return 'コマンドプロンプト';
case TerminalType.PowerShell:
return 'PowerShell';
case TerminalType.GitBash:
return 'Git Bash';
}
}
/**
* 待機用ヘルパー関数
*/
function sleep(ms: number): Promise {
return new Promise(resolve => setTimeout(resolve, ms));
} extension.ts(コマンド登録)
import * as vscode from 'vscode';
import { runInCmd, runInPowerShell, runInGitBash } from './macros/runInTerminal';
export function activate(context: vscode.ExtensionContext) {
console.log('my-macros extension is now active');
// コマンド登録
const commands = [
// ターミナル実行
vscode.commands.registerCommand('myMacros.runInCmd', runInCmd),
vscode.commands.registerCommand('myMacros.runInPowerShell', runInPowerShell),
vscode.commands.registerCommand('myMacros.runInGitBash', runInGitBash),
];
commands.forEach(command => context.subscriptions.push(command));
}
export function deactivate() {}package.json(設定ファイル)
{
"name": "my-macros",
"displayName": "My Macros",
"version": "0.0.2",
"contributes": {
"commands": [
{
"command": "myMacros.runInCmd",
"title": "Run in Command Prompt",
"category": "My Macros"
},
{
"command": "myMacros.runInPowerShell",
"title": "Run in PowerShell",
"category": "My Macros"
},
{
"command": "myMacros.runInGitBash",
"title": "Run in Git Bash",
"category": "My Macros"
}
],
"keybindings": [
{
"command": "myMacros.runInCmd",
"key": "ctrl+shift+1",
"when": "editorTextFocus"
},
{
"command": "myMacros.runInPowerShell",
"key": "ctrl+shift+2",
"when": "editorTextFocus"
},
{
"command": "myMacros.runInGitBash",
"key": "ctrl+shift+3",
"when": "editorTextFocus"
}
]
}
}コードの詳細解説
1. Enum定義
export enum TerminalType {
CMD = 'cmd',
PowerShell = 'powershell',
GitBash = 'gitbash'
}ポイント:
- 型安全にターミナルタイプを管理
- 文字列のタイポを防止
- IntelliSenseが効く
2. コマンド取得ロジック
function getCommandsToExecute(editor: vscode.TextEditor): string[] {
const selection = editor.selection;
// 選択されている場合
if (!selection.isEmpty) {
const selectedText = document.getText(selection);
const lines = selectedText.split(/\r?\n/);
return lines
.map(line => line.trim())
.filter(line => line.length > 0);
}
// 未選択の場合は現在行
const currentLine = document.lineAt(selection.active.line);
return currentLine.text.trim().length > 0 ? [currentLine.text.trim()] : [];
}機能:
- 選択範囲の検知
- 行単位で分割
- 空行の自動除外
- trim()でホワイトスペース除去
3. ターミナル管理
function getOrCreateTerminal(terminalType: TerminalType): vscode.Terminal {
const terminalName = getTerminalName(terminalType);
// 既存ターミナルを検索
const existingTerminal = vscode.window.terminals.find(
t => t.name === terminalName
);
if (existingTerminal) {
return existingTerminal;
}
// 新規作成
return createTerminal(terminalType);
}メリット:
- ターミナルの再利用
- メモリ効率の向上
- ターミナルの乱立防止
4. 複数コマンドの順次実行
for (const command of commands) {
terminal.sendText(command, true);
if (commands.length > 1) {
await sleep(100); // 100ms待機
}
}100ms待機の理由:
- コマンドの確実な実行
- 先行コマンドの完了待ち
- ターミナルの処理負荷軽減
使い方
基本的な使い方
1. 単一コマンドの実行
# test_commands.txt
npm run dev1. カーソルを行に配置
2. Ctrl+Shift+2(PowerShellで実行)
3. → PowerShellが開いて自動実行!2. 複数コマンドの実行
# deploy.txt
cd /d C:\projects\my-app
git pull origin main
npm install
npm run build
npm run deploy1. 全行を選択(Ctrl+A)
2. Ctrl+Shift+1(CMDで実行)
3. → 5つのコマンドが順次実行!実践的な活用例
開発環境セットアップ
# setup_dev.txt
cd /d C:\projects
git clone https://github.com/user/repo.git
cd repo
npm install
code .選択 → Ctrl+Shift+1で一括セットアップ!定型作業の自動化
# daily_tasks.txt
cd /d C:\projects\app
git fetch origin
git status
npm run test毎朝Ctrl+Shift+1で健全性チェック!Docker操作
# docker_commands.txt
docker-compose down
docker-compose build
docker-compose up -d
docker-compose logs -fCtrl+Shift+2で一括操作!キーバインドのカスタマイズ
keybindings.json での変更
// ショートカットキーを変更
[
{
"key": "ctrl+alt+1",
"command": "myMacros.runInCmd",
"when": "editorTextFocus"
},
{
"key": "ctrl+alt+2",
"command": "myMacros.runInPowerShell",
"when": "editorTextFocus"
},
{
"key": "ctrl+alt+3",
"command": "myMacros.runInGitBash",
"when": "editorTextFocus"
}
]コンテキストによる制限
// Markdownファイルでのみ有効
{
"key": "ctrl+shift+1",
"command": "myMacros.runInCmd",
"when": "editorTextFocus && resourceExtname == '.md'"
}// 特定のワークスペースでのみ有効
{
"key": "ctrl+shift+1",
"command": "myMacros.runInCmd",
"when": "editorTextFocus && workspaceFolderCount > 0"
}メリット・デメリット
メリット
1. 圧倒的な時短効果
- コピペ操作の削減: 5ステップ → 1ステップ
- よく使うコマンドを即実行
- 複数コマンドも一括処理
2. コマンド集の一元管理
.txtまたは.mdで管理- プロジェクトごとにファイル作成
- Gitで履歴管理
3. ターミナルの使い分けが簡単
- cmd/PS/Bashを自在に切替
- ターミナル固有のコマンドも対応
- ターミナルの再利用で効率化
4. 学習コストが低い
- 直感的な操作
- 既存のメモをそのまま活用
- エディタ感覚で編集可能
デメリット
1. 初期セットアップが必要
- TypeScript環境の構築
- 拡張機能のインストール
2. 対話的なコマンドは非対応
npm initなどの入力待ちコマンドsshでのパスワード入力
3. エラーハンドリングが弱い
- コマンド失敗時も次へ進む
- 自動リトライ機能なし
総評
デメリットを大きく上回る効率化が可能
特に、頻繁にコマンド実行する開発者には必須の機能です。
応用テクニック
1. プロジェクト別コマンド集
project-commands/
├── backend/
│ ├── dev.txt
│ ├── test.txt
│ └── deploy.txt
└── frontend/
├── dev.txt
├── build.txt
└── deploy.txt使い方:
1. dev.txtを開く
2. Ctrl+A → Ctrl+Shift+2
3. → 開発環境が起動!2. エイリアス定義ファイル
# aliases.txt(Git Bash用)
alias ll='ls -la'
alias gs='git status'
alias gp='git pull'
alias gb='git branch'起動時にCtrl+Shift+3で一括登録!3. 環境変数設定
# env_setup.ps1(PowerShell用)
$env:NODE_ENV="development"
$env:API_KEY="your-api-key"
$env:DEBUG="true"Ctrl+Shift+2で環境変数を一括設定!4. ドキュメント化
# コマンド集
## 開発環境起動
cd /d C:\projects
npm run dev
## ビルド
npm run build
## デプロイ
npm run deployMarkdownで管理 + 実行可能!トラブルシューティング
Git Bashが起動しない
エラー:
Failed to launch terminal解決策:
// runInTerminal.ts
case TerminalType.GitBash:
// パスを環境に合わせて修正
shellPath = 'C:\\Program Files\\Git\\bin\\bash.exe';
// または
shellPath = 'C:\\Program Files (x86)\\Git\\bin\\bash.exe';
// または
shellPath = 'C:\\git\\bin\\bash.exe';
break;コマンドが実行されない
原因1: 空行が含まれる
→ trim() と filter() で除外済み
原因2: ターミナルが閉じている
→ 自動で再作成されるはずだが、手動で閉じた場合は再実行
原因3: パスに空白が含まれる
# NG
cd C:\Program Files\app
# OK
cd "C:\Program Files\app"複数コマンドが途中で止まる
原因: コマンド実行時間が長い
解決策: 待機時間を調整
// 100ms → 500msに変更
if (commands.length > 1) {
await sleep(500);
}キーバインドが効かない
確認ポイント:
- when条件の確認
"when": "editorTextFocus"
// エディタにフォーカスがあるか?- 競合の確認
Ctrl+Shift+P → "Preferences: Open Keyboard Shortcuts"
→ Ctrl+Shift+1で検索- 拡張機能の有効化確認
Ctrl+Shift+P → "Extensions: Show Installed Extensions"
→ My Macros が有効か確認パフォーマンス最適化
ターミナルの再利用
// ターミナル名で識別して再利用
function getOrCreateTerminal(terminalType: TerminalType): vscode.Terminal {
const terminalName = getTerminalName(terminalType);
const existingTerminal = vscode.window.terminals.find(
t => t.name === terminalName
);
return existingTerminal || createTerminal(terminalType);
}メリット:
- 新規作成のオーバーヘッド削減
- 環境変数の保持
- 作業ディレクトリの維持
非同期処理の最適化
// 並列実行は避ける(コマンドの依存関係のため)
for (const command of commands) {
await terminal.sendText(command, true);
// 順次実行を保証
}まとめ
VSCodeでショートカット一発でターミナル実行できるTypeScriptマクロを実装しました。
得られる効果:
- コマンド実行が5ステップ → 1ステップに
- よく使うコマンドを即座に実行
- 複数コマンドの一括実行
- cmd/PowerShell/Git Bashの使い分けが簡単
こんな人に最適:
- 頻繁にコマンド実行する開発者
- コマンドをメモ帳管理している人
- 作業を効率化したい人
- 複数のターミナルを使い分ける人
次のステップ:
- 環境構築(TypeScript + VSCode拡張)
- コード実装(この記事のコードをコピー)
- パッケージ化してインストール
- よく使うコマンド集を作成
- ショートカットで爆速実行!
ぜひ実装して、開発効率を劇的に向上させてください!
関連記事
TypeScript拡張機能の開発環境構築

サクラエディタからVSCodeへのマクロ移行

タグ: #VSCode #TypeScript #マクロ #ターミナル #コマンド実行 #生産性向上 #自動化
コメント