開発ノート@HarikoApps

HarikoApps: https://hariko.sprkls.me

2024-06-06

VSCodeで任意のシェルコマンドを新しいエディタビューで実行する(拡張機能は使わずに) #4

VSCodeはカスタムすれば割と快適ではあるのですがUnixコマンドとの統合がいまいちです。Emacsだと M-! のようなコマンドで簡単にエディタから直接シェルコマンドを実行できるのですが、VSCodeだとそこまで簡単にはいきません。今回lazydockerというDockerコンテナを簡単に管理できるコマンドをVSCode内で扱いたいと思い、Emacsのようにエディタのビューの中で実行できないか調べてみました。

まず、VSCodeのコマンドに使えそうなものがないか調べてみます。Keybindings設定のGUIからterminalなどのワードで検索すると、
Terminal: Create New Terminal in Editor Area
workbench.action.createTerminalEditor
という、エディタビューでターミナルを開いてくれそうなコマンドが見つかりました。標準(下から出てくるやつです)のターミナルには文字列を送信したりできることは知っていたので、同じようにエディタービューで開いたターミナルで任意のコマンドを実行できれば話は早そうです。

次にこのコマンドに渡せるオプションを調べてみます。VSCodeのコマンドリファレンスのようなものはなさそうなので、`createTerminalEditor` でGitHubのVSCodeリポジトリを検索してみるとそれらしい箇所がいくつかヒットしました。検索結果を一つ一つ見ていくと、ここでコマンドの定義が行われているようです

コマンド定義の run オプションを見ると型なども明記されているので、それを辿っていくと次のようなキーバインド定義で任意のコマンドを実行できることがわかりました。
  {
    "key": "{任意のキーバインド}",
    "name": "lazydocker",
    "type": "command",
    "command": "workbench.action.createTerminalEditor",
    "args": {
      "location": 2,
      "config": {
        "name": "lazydocker",
        "executable": "lazydocker"
      }
    }
  }
これでキーバインドを定義する必要はありますが、Emacsのように任意のコマンドをエディタエリアで実行できるようになりました!
これは色々応用が効きそうで個人的にはかなり嬉しい発見でした。
(ちなみに `workbench.action.createTerminalEditorSide` という今いるのとは別の場所にターミナルのエディタビューをを開いてくれるコマンドもあるのですがこちらは引数を受け取ってくれません。どちらかというとこちらが使いたい)

追記)
workbench.action.createTerminalEditorSideの定義を見ていると `"location": { "viewColumn": -2 }` をargsに渡してやると同等の挙動にできそうなことが分かりました。なので以下のような設定で、今いるエディタとは別の箇所にターミナルを開いてくれます。これは便利。

  {
    "key": "{任意のキーバインド}",
    "name": "lazydocker",
    "type": "command",
    "command": "workbench.action.createTerminalEditor",
    "args": {
      "location": { "viewColumn": -2 }, // -1:現在のタブグループ, -2:横のタブグループ, -3:新しいウィンドウ
      "config": {
        "name": "lazydocker",
        "executable": "lazydocker"
      }
    }
  }
追記)
最初shの上でlazydockerを動かさないといけないという先入観からargs>config内を下のように書いていましたが、executableにそのまま指定しても動作したので修正しました。PATHに入ってないコマンドを起動したい時などはshを経由して起動する技も使えるのでメモがわりにおいておきます。
            "config": {
              "name": "lazydocker",
              "executable": "sh",
              "args": ["-c", "lazydocker"],
            }
Updated at