次の方法で共有


シェル統合

ターミナル 1.15 プレビュー以降、Windows ターミナルは一部の "シェル統合" 機能を実験的にサポートするようになりました。 これらの機能により、コマンドラインが使いやすくなります。 以前のリリースでは、シェルが現在の作業ディレクトリをターミナルに伝えることができました。 今回、シェルがターミナル出力の一部を "プロンプト"、"コマンド"、または "出力" として意味的に記述できるように、より多くのシーケンスをサポートするようになりました。 また、シェルは、コマンドが成功したか失敗したかをターミナルに伝えることもできます。

これは、ターミナル v1.18 の時点でロールアウトされているシェル統合機能の一部についてのガイドです。 将来的には、これらに加えてさらに多くの機能を構築する予定です。そのため、どのように使っているかについて追加のフィードバックをお寄せください。

: ターミナル 1.21 の時点で、マークは安定した機能となっています。 1.21 より前では、マークはターミナルのプレビュー ビルドでのみ有効でした。 1.21 より前のバージョンのターミナルを使用している場合は、showMarksOnScrollbar 設定の名前は experimental.showMarksOnScrollbar で、autoMarkPrompts の名前は experimental.autoMarkPrompts となっています。

この処理のしくみ

シェル統合は、シェル (または任意のコマンド ライン アプリケーション) が特別な "エスケープ シーケンス" をターミナルに書き込むことで機能します。 これらのエスケープ シーケンスはターミナルに出力されません。代わりに、いくつかのメタデータが用意されています。ターミナルでこれを使うと、アプリケーションで何が起こっているかを詳しく把握できます。 これらのシーケンスをシェルのプロンプトに貼り付けることで、シェルのみが認識している情報をシェルからターミナルに継続的に提供することができます。

次のシーケンスの場合:

  • OSC は文字列 "\x1b]" (エスケープ文字) で、その後に ] が続きます。
  • ST は "文字列の終端記号" であり、\x1b\ (ESC 文字、その後に \ が続きます) または \x7 (BEL 文字) のいずれかになります。
  • スペースは単なる例です。
  • <> の文字列は、他の値に置き換える必要があるパラメーターです。

ターミナル v1.18 の時点でサポートされている関連するシェル統合シーケンスは次のとおりです。

  • OSC 133 ; A ST ("FTCS_PROMPT") - プロンプトの開始。
  • OSC 133 ; B ST ("FTCS_COMMAND_START") - コマンドラインの開始 (READ: プロンプトの終了)。
  • OSC 133 ; C ST ("FTCS_COMMAND_EXECUTED") - コマンド出力の開始またはコマンドラインの終了。
  • OSC 133 ; D ; <ExitCode> ST ("FTCS_COMMAND_FINISHED") - コマンドの終了。 ExitCode - ExitCode を指定すると、ターミナルは 0 を "成功" として扱い、それ以外はエラーとして扱います。 省略した場合、ターミナルはマークを既定の色のままにします。

シェル統合のマークを有効にする方法

これらの機能をサポートするには、シェルとターミナル間の連携が必要です。 これらの新機能を使うには、ターミナルでの設定を有効にすることと、シェルのプロンプトを変更することの両方が必要です。

ターミナルでこれらの機能を有効にするには、設定に以下を追加する必要があります。

"profiles":
{
    "defaults":
    {
        // Enable marks on the scrollbar
        "showMarksOnScrollbar": true,

        // Needed for both pwsh, CMD and bash shell integration
        "autoMarkPrompts": true,

        // Add support for a right-click context menu
        // You can also just bind the `showContextMenu` action
        "experimental.rightClickContextMenu": true,
    },
}
"actions":
[
    // Scroll between prompts
    { "keys": "ctrl+up",   "command": { "action": "scrollToMark", "direction": "previous" }, },
    { "keys": "ctrl+down", "command": { "action": "scrollToMark", "direction": "next" }, },

    // Add the ability to select a whole command (or its output)
    { "command": { "action": "selectOutput", "direction": "prev" }, },
    { "command": { "action": "selectOutput", "direction": "next" }, },

    { "command": { "action": "selectCommand", "direction": "prev" }, },
    { "command": { "action": "selectCommand", "direction": "next" }, },
]

シェルでこれらのマークを有効にする方法は、シェルによって異なります。 CMD、PowerShell、Zsh のチュートリアルを次に示します。

PowerShell (pwsh.exe)

PowerShell プロンプトを以前に変更したことがない場合は、最初に about_Prompts を確認する必要があります。

prompt を編集して、CWD についてターミナルに確実に伝え、プロンプトに適切なマークを付けるようにする必要があります。 PowerShell を使うと、133;D シーケンスに前のコマンドのエラー コードを含めることもできます。これにより、コマンドが成功したか失敗したかに基づいて、ターミナルが自動的にマークを色分けできるようになります。

PowerShell プロファイルに次の内容を追加します。

$Global:__LastHistoryId = -1

function Global:__Terminal-Get-LastExitCode {
  if ($? -eq $True) {
    return 0
  }
  $LastHistoryEntry = $(Get-History -Count 1)
  $IsPowerShellError = $Error[0].InvocationInfo.HistoryId -eq $LastHistoryEntry.Id
  if ($IsPowerShellError) {
    return -1
  }
  return $LastExitCode
}

function prompt {

  # First, emit a mark for the _end_ of the previous command.

  $gle = $(__Terminal-Get-LastExitCode);
  $LastHistoryEntry = $(Get-History -Count 1)
  # Skip finishing the command if the first command has not yet started
  if ($Global:__LastHistoryId -ne -1) {
    if ($LastHistoryEntry.Id -eq $Global:__LastHistoryId) {
      # Don't provide a command line or exit code if there was no history entry (eg. ctrl+c, enter on no command)
      $out += "`e]133;D`a"
    } else {
      $out += "`e]133;D;$gle`a"
    }
  }


  $loc = $($executionContext.SessionState.Path.CurrentLocation);

  # Prompt started
  $out += "`e]133;A$([char]07)";

  # CWD
  $out += "`e]9;9;`"$loc`"$([char]07)";

  # (your prompt here)
  $out += "PWSH $loc$('>' * ($nestedPromptLevel + 1)) ";

  # Prompt ended, Command started
  $out += "`e]133;B$([char]07)";

  $Global:__LastHistoryId = $LastHistoryEntry.Id

  return $out
}

Oh My Posh のセットアップ

oh-my-posh を使用していますか? 上記を少し変更して、元のプロンプトを隠し、シェル統合エスケープ シーケンスの途中に追加し直します。

# initialize oh-my-posh at the top of your profile.ps1
oh-my-posh init pwsh --config "$env:POSH_THEMES_PATH\gruvbox.omp.json" | Invoke-Expression
# then stash away the prompt() that oh-my-posh sets
$Global:__OriginalPrompt = $function:Prompt

function Global:__Terminal-Get-LastExitCode {
  if ($? -eq $True) { return 0 }
  $LastHistoryEntry = $(Get-History -Count 1)
  $IsPowerShellError = $Error[0].InvocationInfo.HistoryId -eq $LastHistoryEntry.Id
  if ($IsPowerShellError) { return -1 }
  return $LastExitCode
}

function prompt {
  $gle = $(__Terminal-Get-LastExitCode);
  $LastHistoryEntry = $(Get-History -Count 1)
  if ($Global:__LastHistoryId -ne -1) {
    if ($LastHistoryEntry.Id -eq $Global:__LastHistoryId) {
      $out += "`e]133;D`a"
    } else {
      $out += "`e]133;D;$gle`a"
    }
  }
  $loc = $($executionContext.SessionState.Path.CurrentLocation);
  $out += "`e]133;A$([char]07)";
  $out += "`e]9;9;`"$loc`"$([char]07)";
  
  $out += $Global:__OriginalPrompt.Invoke(); # <-- This line adds the original prompt back

  $out += "`e]133;B$([char]07)";
  $Global:__LastHistoryId = $LastHistoryEntry.Id
  return $out
}

コマンド プロンプト

コマンド プロンプトは、PROMPT 環境変数からプロンプトを取得します。 CMD.exe は $eESC 文字として読み取ります。 残念ながら、CMD.exe には、プロンプトで前のコマンドのリターン コードを取得する方法がないため、CMD プロンプトで成功またはエラーの情報を提供することはできません。

以下を実行することで、現在の CMD.exe インスタンスのプロンプトを変更できます。

PROMPT $e]133;D$e\$e]133;A$e\$e]9;9;$P$e\$P$G$e]133;B$e\

または、今後のすべてのセッションに対してコマンドラインから変数を設定できます。

setx PROMPT $e]133;D$e\$e]133;A$e\$e]9;9;$P$e\$P$G$e]133;B$e\

これらの例では、現在の PROMPT が単なる $P$G であると仮定しています。 代わりに、現在のプロンプトを次のようなもので囲むこともできます。

PROMPT $e]133;D$e\$e]133;A$e\$e]9;9;$P$e\%PROMPT%$e]133;B$e\

Bash

~/.bashrc の末尾に次を追加することで bash においてシェル統合を有効にできます。

PS1="\[\033]133;D;\007\]\[\033]133;A;\007\]$PS1\[\033]133;B;\007\]"

これは、シェル統合を有効にするために必要なシーケンスで既存の $PS1 をラップします。

: お気に入りのシェルがここに表示されていない場合 そのようなことが判明した場合は、気軽にお気に入りのシェルのソリューションのコントリビューションを行ってください。

シェル統合の機能

同じ作業ディレクトリ内で新しいタブを開く

同じ作業ディレクトリ内で新しいタブを開く

スクロールバーに各コマンドのマークを表示する

スクロールバーに各コマンドのマークを表示する

コマンド間を自動的にジャンプする

これは、先ほど定義した scrollToMark アクションを使用します。

コマンド間を自動的にジャンプする

コマンドの出力全体を選ぶ

この gif では、ctrl+g にバインドされた selectOutput アクションを使用して、コマンドの出力全体を選択しています。 コマンドの出力全体を選ぶ

以下では experimental.rightClickContextMenu 設定を使用してターミナル内での右クリック ショートカット メニューを有効にしています。 これとシェル統合が有効であれば、コマンドを右クリックして、コマンド全体またはその出力を選択できます。

右クリックのコンテキスト メニューを使ってコマンドを選ぶ

最近のコマンド候補

シェル統合が有効であれば、最近のコマンドも表示するように候補 UI を構成できます。

内部に最近のコマンドを表示している候補 UI

このメニューは、以下の操作で開くことができます。

{
    "command": { "action": "showSuggestions", "source": "recentCommands", "useCommandline": true },
},

(詳細については、提案に関するドキュメントを参照してください)

その他のリソース