Shell 整合
從終端機 1.15 預覽版起,Windows 終端機已開始實驗性地支援一些「殼層整合」功能。 這些功能可讓命令列更易於使用。 在先前的版本,我們會啟用殼層來告訴終端機目前的工作目錄是什麼。 現在,我們新增了更多序列的支援,允許殼層以語意方式將終端機輸出的部分描述為「提示」、「命令」或「輸出」。 殼層也可以告訴終端機命令是成功或失敗。
這是我們在終端機 1.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") - 命令列的開頭 (讀取:提示的結尾)。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
}
哦, 我的 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讀取 $e
為 ESC
字元。 可惜的是,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中 selectOutput
,我們使用系結至的動作來 ctrl+g
選取命令的整個輸出。
下列會 experimental.rightClickContextMenu
使用 設定,在終端機中啟用以滑鼠右鍵按下操作功能表。 啟用該和殼層整合之後,您可以以滑鼠右鍵按下命令,以選取整個命令或其輸出。
最近的命令建議
啟用殼層整合后,可以將建議UI設定為也顯示您最近的命令。
您可以使用下列動作來開啟此選單:
{
"command": { "action": "showSuggestions", "source": "recentCommands", "useCommandline": true },
},
(如需詳細資訊,請參閱 建議檔案 )