Freigeben über


Shell-Integration

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: Seit Terminal 1.21 sind Markierungen jetzt ein stabiles Feature. Vor 1.21 waren Markierungen nur für Preview -Builds von Terminal aktiviert. Wenn Sie eine Version von Terminal vor 1.21 verwenden, wurde die showMarksOnScrollbar-Einstellung experimental.showMarksOnScrollbar genannt, und autoMarkPrompts wurde experimental.autoMarkPrompts genannt.

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":
    {
        // 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" }, },
]

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

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
}

Oh Mein Posh-Setup

Oh-my-posh? Sie möchten die oben genannten Elemente leicht ändern, um die ursprüngliche Eingabeaufforderung zu entfernen, und fügen Sie sie dann in der Mitte der Escapesequenzen für die Shellintegration wieder hinzu.

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

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\

Bash

Sie können am Ende von ~/.bashrc Folgendes hinzufügen, um die Shell-Integration in bash zu aktivieren:

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

Dadurch wird das vorhandene $PS1 mit den erforderlichen Sequenzen umschlossen, um die Shell-Integration zu ermöglichen.

Hinweis: Sehen Sie Ihre bevorzugte Shell hier nicht? Wenn Sie eine Möglichkeit finden, können Sie gerne eine Lösung für Ihre bevorzugte Shell beitragen!

Shell-Integrationsfunktionen

Öffnen neuer Registerkarten im selben Arbeitsverzeichnis

Öffnen neuer Registerkarten im selben Arbeitsverzeichnis

Anzeigen von Markierungen für jeden Befehl in der Bildlaufleiste

Anzeigen von Markierungen für jeden Befehl in der Bildlaufleiste

Automatisches Springen zwischen Befehlen

Dies verwendet die scrollToMark-Aktionen, wie sie oben definiert wurden.

Automatisches Springen zwischen Befehlen

Auswählen der gesamten Ausgabe eines Befehls

In dieser GIF-Datei verwenden wir die selectOutput-Aktion, die an ctrl+g gebunden ist, um die gesamte Ausgabe eines Befehls auszuwählen. Auswählen der gesamten Ausgabe eines Befehls

Im Folgenden wird die experimental.rightClickContextMenu-Einstellung verwendet, um im Terminal ein Kontextmenü zu aktivieren, das mit der rechten Maustaste aufgerufen werden kann. Damit und mit aktivierter Shell-Integration können Sie mit der rechten Maustaste auf einen Befehl klicken, um den gesamten Befehl oder seine Ausgabe auszuwählen.

Auswählen des Befehls über das Kontextmenü (Rechtsklick)

Vorschläge der zuletzt verwendeten Befehle

Wenn die Shell-Integration aktiviert ist, kann die Vorschläge-Benutzeroberfläche so konfiguriert werden, dass auch Ihre zuletzt verwendeten Befehle angezeigt werden.

Die Vorschläge-Benutzeroberfläche mit zuletzt verwendeten Befehlen

Sie können dieses Menü mit der folgenden Aktion öffnen:

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

(Weitere Informationen finden Sie in der Dokumentation zu Vorschlägen.)

Zusätzliche Ressourcen