Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
- Integrace prostředí
Počínaje terminálem 1.15 Preview se terminál Windows začal experimentálně podporovat některé funkce integrace prostředí. Tyto funkce usnadňují používání příkazového řádku. V dřívějších verzích jsme povolili prostředí, abychom terminálu řekli, co je aktuální pracovní adresář. Teď jsme přidali podporu dalších sekvencí, které vašemu prostředí umožní sémanticky popsat části výstupu terminálu jako "prompt", "command" nebo "output". Prostředí také může terminálu sdělit, jestli byl příkaz úspěšný nebo neúspěšný.
Toto je průvodce některými funkcemi integrace prostředí, které jsme zavedli v terminálové verzi 1.18. V budoucnu plánujeme vytvářet ještě více funkcí, takže rádi získáme další zpětnou vazbu o tom, jak je lidé používají.
Poznámka: Od terminálu 1.21 jsou značky nyní stabilní funkcí. Před verzí 1.21 byly značky povoleny pouze pro buildy Preview terminálu. Pokud používáte verzi terminálu před verzí 1.21,
showMarksOnScrollbarnastavení bylo pojmenovánoexperimental.showMarksOnScrollbaraautoMarkPromptsbylo pojmenovánoexperimental.autoMarkPrompts.
Jak to funguje?
Integrace prostředí funguje tak, že prostředí (nebo libovolná aplikace příkazového řádku) zapíše do terminálu speciální řídicí sekvence. Tyto řídicí sekvence nejsou vytištěny do terminálu – místo toho poskytují bity metadat, které terminál může použít, aby věděli více o tom, co se děje v aplikaci. Když tyto sekvence připnete do příkazového řádku prostředí, můžete prostředí průběžně poskytovat informace do terminálu, který zná jenom prostředí.
Pro následující sekvence:
-
OSCje řetězec"\x1b]"– řídicí znak následovaný řídicím znakem.] -
STje "ukončovací znak řetězce" a může být buď\x1b\(znak ESC, následovaný\) nebo\x7(znak BEL). - Mezery jsou jen ilustrativní.
- Řetězce jsou
<>parametry, které by měly být nahrazeny jinou hodnotou.
Příslušné podporované sekvence integrace prostředí v terminálové verzi 1.18 jsou následující:
-
OSC 133 ; A ST("FTCS_PROMPT") – začátek výzvy. -
OSC 133 ; B ST("FTCS_COMMAND_START") – začátek příkazového řádku (READ: konec příkazového řádku). -
OSC 133 ; C ST("FTCS_COMMAND_EXECUTED") – začátek výstupu příkazu / konec příkazového řádku. -
OSC 133 ; D ; <ExitCode> ST("FTCS_COMMAND_FINISHED") – konec příkazu.ExitCodePokudExitCodeje k dispozici, terminál bude považovat0za úspěch a cokoli jiného jako chybu. Pokud tento parametr vynecháte, terminál ponechá výchozí barvu.
Jak povolit integrační značky prostředí
Podpora těchto funkcí vyžaduje spolupráci mezi prostředím a terminálem. Abyste mohli tyto nové funkce používat, musíte v terminálu povolit nastavení i upravit výzvu prostředí.
Pokud chcete povolit tyto funkce v terminálu, budete chtít do nastavení přidat následující položky:
"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" }, },
]
Jak povolíte tyto značky v prostředí, se liší od prostředí po prostředí. Níže jsou uvedené kurzy pro CMD, PowerShell a Zsh.
PowerShell (pwsh.exe)
Pokud jste ještě nikdy nezměnili příkazový řádek PowerShellu, měli byste si nejdřív prohlédnout about_Prompts .
Budeme muset upravit vaši prompt stránku, abychom zajistili, že terminál řekneme o CWD a označíme výzvu odpovídajícími značkami. PowerShell také umožňuje zahrnout kód chyby z předchozího příkazu v 133;D sekvenci, který umožní terminálu automaticky obarvit značku na základě toho, jestli byl příkaz úspěšný nebo neúspěšný.
Do profilu PowerShellu přidejte následující položky:
$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 setup
Používáte oh-my-posh? Budete chtít mírně upravit předchozí příkaz, aby se původní výzva odložil, a pak ji přidat zpět doprostřed řídicích sekvencí integrace prostředí.
# 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
}
Příkazový řádek
Příkazový řádek z příkazového řádku z proměnné prostředí vysílaný z příkazového PROMPT řádku. CMD.exe přečte $e jako ESC znak. CMD.exe bohužel nemá způsob, jak na příkazovém řádku získat návratový kód předchozího příkazu, takže ve výzev CMD nemůžeme poskytnout informace o úspěchu nebo chybě.
Spuštěním příkazu můžete změnit výzvu pro aktuální instanci CMD.exe:
PROMPT $e]133;D$e\$e]133;A$e\$e]9;9;$P$e\$P$G$e]133;B$e\
Nebo můžete proměnnou nastavit z příkazového řádku pro všechny budoucí relace:
setx PROMPT $e]133;D$e\$e]133;A$e\$e]9;9;$P$e\$P$G$e]133;B$e\
Tyto příklady předpokládají, že váš aktuální PROMPT je právě $P$G. Místo toho se můžete rozhodnout, že chcete aktuální výzvu zabalit přibližně takto:
PROMPT $e]133;D$e\$e]133;A$e\$e]9;9;$P$e\%PROMPT%$e]133;B$e\
Bash
Následující skript můžete vytvořit do aktivního prostředí s integrovanými source příkazy nebo .bash ho přidat na konec prostředí ${HOME}/.bash_profile (pro přihlašovací prostředí) nebo ${HOME}/.bashrc (pro prostředí bez přihlášení) a povolit úplnou integraci bash prostředí s verzemi většími nebo rovnou bash-4.4 (kde PS0 byla původně implementována integrovaná proměnná).
Úplná integrace prostředí znamená, že každá ohlášená funkce terminálu funguje podle návrhu.
Poznámka:
Je třeba zdůraznit, že pokud jsou PROMPT_COMMANDk dispozici proměnné nebo PS2PS0PS1 proměnné již přiřazené k jakýmkoli jiným než výchozím hodnotám, které mohou vést k nepředvídatelným výsledkům. Nejprve by bylo lepší otestovat skript s prostředím "clean" spuštěním env --ignore-environment bash --noprofile --norc a získáním popsaného souboru, jak bylo uvedeno dříve.
# .bash_profile | .bashrc
function __set_ps1() {
local PS1_TMP="${__PS1_BASE}"
if [ ! -z "${__IS_WT}" ]; then
local __FTCS_CMD_FINISHED='\e]133;D;'"${1}"'\e\\'
PS1_TMP="\[${__FTCS_CMD_FINISHED}\]${__PS1_BASE}"
fi
printf '%s' "${PS1_TMP}"
}
function __prompt_command() {
# Must be first in the list otherwise the exit status will be overwritten.
local PS1_EXIT_STATUS=${?}
PS1="$(__set_ps1 ${PS1_EXIT_STATUS})"
}
# ---------------------------------------------------------------------------
# PROMPT (PS0..PS2).
# The given variable might be linked to a function detecting whether `bash`
# actually runs under `Microsoft Terminal` otherwise unexpected garbage might
# be displayed on the user screen.
__IS_WT='true'
printf -v __BASH_V '%d' ${BASH_VERSINFO[*]:0:2}
if [ ${__BASH_V} -ge 44 ]; then
__PS0_BASE=''
fi
# The following assignments reflect the default values.
__PS1_BASE='\s-\v\$ '
__PS2_BASE='> '
if [ ! -z "${__IS_WT}" ]; then
__FTCS_PROMPT='\e]133;A\e\\'
__FTCS_CMD_START='\e]133;B\e\\'
if [ ${__BASH_V} -ge 44 ]; then
__FTCS_CMD_EXECUTED='\e]133;C\e\\'
__PS0_BASE="\[${__FTCS_CMD_EXECUTED}\]"
fi
__PS1_BASE="\[${__FTCS_PROMPT}\]${__PS1_BASE}\[${__FTCS_CMD_START}\]"
# Required, otherwise the `PS2` prefix will split and corrupt a long
# command.
__PS2_BASE=''
fi
PROMPT_COMMAND=__prompt_command
if [ ${__BASH_V} -ge 44 ]; then
PS0="${__PS0_BASE}"
fi
# `PS1` is set with the `__prompt_command` function call.
PS2="${__PS2_BASE}"
Tím se zabalí veškerý sortiment proměnných bash výzvy (PS0PS1aPS2) s potřebnými sekvencemi, aby bylo možné dokončit integraci prostředí.
Kromě toho ${HOME}/.inputrc může být potřeba upravit také znaky "oznámení režimu úprav" a "změněné řádky":
# .inputrc
set mark-modified-lines Off
set show-mode-in-prompt Off
To by mělo vypadat, když všechno funguje správně:
$ env --ignore-environment bash --noprofile --norc
bash-5.2$ . /tmp/msft-terminal-bash.sh
bash-5.2$ echo "|${PS0}|"
|\[\e]133;C\e\\\]|
bash-5.2$ echo "|${PS1}|"
|\[\e]133;D;0\e\\\]\[\e]133;A\e\\\]\s-\v\$ \[\e]133;B\e\\\]|
bash-5.2$ echo "|${PS2}|"
||
Poznámka: Nevidíte tady vaše oblíbené prostředí? Pokud to zjistíte, můžete přispět řešením pro vaše upřednostňované prostředí.
Funkce integrace prostředí
Otevření nových karet ve stejném pracovním adresáři
Zobrazit značky pro každý příkaz na posuvníku
Automatické přeskakování mezi příkazy
Akce se používají scrollToMark tak, jak jsou definovány výše.
Výběr celého výstupu příkazu
V tomto obrázku selectOutput GIF použijeme akci vázanou k ctrl+g výběru celého výstupu příkazu.
Následující nastavení používá experimental.rightClickContextMenu k povolení místní nabídky v terminálu po kliknutí pravým tlačítkem myši. Pokud je tato integrace prostředí povolená, můžete kliknutím pravým tlačítkem na příkaz vybrat celý příkaz nebo jeho výstup.
Poslední návrhy příkazů
S povolenou integrací prostředí je možné uživatelské rozhraní Návrhy nakonfigurovat tak, aby zobrazoval také nedávné příkazy.
Tuto nabídku můžete otevřít pomocí následující akce:
{
"command": { "action": "showSuggestions", "source": "recentCommands", "useCommandline": true },
},
(Další informace najdete v dokumentaci návrhy)
Dodatečné zdroje
Windows Terminal