Tutorial: Aktivieren der Shellintegration im Windows-Terminal

Ab Terminal 1.15 Preview unterstützt das Windows-Terminal einige Features der „Shellintegration“ experimentell. Diese Features erleichtern die Verwendung der Befehlszeile. In früheren Versionen haben wir die Shell aktiviert, um dem Terminal mitzuteilen, was das aktuelle Arbeitsverzeichnis ist. Jetzt haben wir Unterstützung für weitere Sequenzen hinzugefügt, damit Ihre Shell Teile der Terminalausgabe semantisch als „Eingabeaufforderung“, „Befehl“ oder „Ausgabe“ beschreiben kann. Die Shell kann dem Terminal auch mitteilen, ob ein Befehl erfolgreich war oder fehlgeschlagen ist.

Dies ist ein Leitfaden zu einigen der Shellintegrationsfeatures, die wir ab Terminal v1.18 eingeführt haben. Wir planen, in Zukunft noch mehr Features zu erstellen, Daher würden wir uns freuen, zusätzliches Feedback zu erhalten, wie die Benutzer*innen sie verwenden.

Hinweis: Insbesondere sind „Markierungen“ weiterhin experimentell und nur für Vorschaubuilds des Terminals aktiviert. Die Einstellungen für diese Features können sich in einer zukünftigen Version ändern.

Wie funktioniert das?

Die Shellintegration funktioniert, indem die Shell (oder eine beliebige Befehlszeilenanwendung) spezielle „Escapesequenzen“ in das Terminal schreibt. Diese Escapesequenzen werden nicht im Terminal ausgegeben. Stattdessen stellen sie Metadaten-Bits bereit, die das Terminal verwenden kann, um mehr über die Vorgänge in der Anwendung zu erfahren. Indem Sie diese Sequenzen in die Eingabeaufforderung Ihrer Shell einfügen, können Sie die Shell dazu bringen, kontinuierlich Informationen an das Terminal bereitzustellen, die nur die Shell kennt.

Für die folgenden Sequenzen:

  • OSC ist die Zeichenfolge "\x1b]" – ein Escapezeichen gefolgt von ]
  • ST ist das „Zeichenfolgen-Abschlusszeichen“ und kann entweder \x1b\ (ein ESC-Zeichen, gefolgt von \) oder \x7 (das BEL-Zeichen) sein
  • Leerzeichen sind lediglich illustrativer Natur.
  • Zeichenfolgen in <> sind Parameter, die durch einen anderen Wert ersetzt werden sollten.

Die relevanten unterstützten Shellintegrationssequenzen ab Terminal v1.18 sind:

  • OSC 133 ; A ST ("FTCS_PROMPT") – Der Anfang einer Eingabeaufforderung.
  • OSC 133 ; B ST ("FTCS_COMMAND_START") – Der Anfang einer Befehlszeile (READ: das Ende der Eingabeaufforderung).
  • OSC 133 ; C ST ("FTCS_COMMAND_EXECUTED") – Der Anfang der Befehlsausgabe / das Ende der Befehlszeile.
  • OSC 133 ; D ; <ExitCode> ST ("FTCS_COMMAND_FINISHED") – das Ende eines Befehls. ExitCode Wenn ExitCode angegeben wird, behandelt das Terminal 0 als „Erfolg“ und alles andere als Fehler. Wenn nicht angegeben, belässt das Terminal nur die Markierung als Standardfarbe.

Aktivieren von Shellintegrationsmarkierungen

Die Unterstützung dieser Features erfordert eine Zusammenarbeit zwischen Ihrer Shell und dem Terminal. Sie müssen sowohl Einstellungen im Terminal aktivieren, um diese neuen Features verwenden zu können, als auch die Eingabeaufforderung Ihrer Shell ändern.

Um diese Features im Terminal zu aktivieren, sollten Sie Ihren Einstellungen Folgendes hinzufügen:

"profiles":
{
    "defaults":
    {
        // Marks in general
        "experimental.showMarksOnScrollbar": true,

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

        // Add support for a right-click context menu
        // You can also just bind the `showContextMenu` action
        "experimental.rightClickContextMenu": true,
    },
}
"actions":
[
    { "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)
    { "keys": "ctrl+shift+w", "command": { "action": "selectOutput", "direction": "prev" }, },
    { "keys": "ctrl+shift+s", "command": { "action": "selectOutput", "direction": "next" }, },

    { "keys": "ctrl+alt+shift+w", "command": { "action": "selectCommand", "direction": "prev" }, },
    { "keys": "ctrl+alt+shift+s", "command": { "action": "selectCommand", "direction": "next" }, },
]

Wie Sie diese Markierungen in Ihrer Shell aktivieren, variiert von Shell zu Shell. Im Folgenden finden Sie Tutorials für CMD und PowerShell.

PowerShell (pwsh.exe)

Wenn Sie Ihre PowerShell-Eingabeaufforderung noch nie geändert haben, sollten Sie zuerst about_Prompts lesen.

Wir müssen Ihre prompt bearbeiten, um sicherzustellen, dass wir das Terminal über das CWD informieren, und die Eingabeaufforderung mit den entsprechenden Markierungen markieren. PowerShell ermöglicht es uns auch, den Fehlercode des vorherigen Befehls in die Sequenz 133;D einzufügen, sodass das Terminal die Markierung automatisch färben kann, wenn der Befehl erfolgreich war oder fehlgeschlagen ist.

Fügen Sie Ihrem PowerShell-Profil Folgendes hinzu:

$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
}

Eingabeaufforderung

Eingabeaufforderungsquellen sind die Eingabeaufforderungen der Umgebungsvariablen PROMPT. CMD.exe liest $e als ESC-Zeichen. Leider hat CMD.exe keine Möglichkeit, den Rückgabecode des vorherigen Befehls in der Eingabeaufforderung abzurufen, sodass wir keine Erfolgs-/Fehlerinformationen in CMD-Eingabeaufforderungen bereitstellen können.

Sie können die Eingabeaufforderung für die aktuelle CMD.exe-Instanz ändern, indem Sie Folgendes ausführen:

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

Alternativ können Sie die Variable über die Befehlszeile für alle zukünftigen Sitzungen festlegen:

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

In diesen Beispielen wird davon ausgegangen, dass Ihr aktueller PROMPT nur $P$Gist. Sie können ihre aktuelle Eingabeaufforderung stattdessen wie folgt umschließen:

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

Hinweis: Sehen Sie Ihre bevorzugte Shell hier nicht? Wenn Sie es herausfinden, können Sie zu einer Lösung für Ihre bevorzugte Shell beitragen!

Shellintegrationsdemos

Öffnen neuer Registerkarten im selben Arbeitsverzeichnis

Open new tabs in the same working directory

Anzeigen von Markierungen für jeden Befehl in der Bildlaufleiste

Show marks for each command in the scrollbar

Automatisches Springen zwischen Befehlen

Automatically jump between commands

Auswählen der gesamten Ausgabe eines Befehls

Select the entire output of a command

Select the command using the right-click context menu