Share via


Esercitazione: Abilitare l'integrazione della shell nel Terminale Windows

A partire da Terminale 1.15 Anteprima, il Terminale Windows ha iniziato a supportare in modo sperimentale alcune funzionalità di "integrazione della shell". Queste funzionalità semplificano l'uso della riga di comando. Nelle versioni precedenti veniva abilitata la shell per indicare al terminale la directory di lavoro corrente. Ora è stato aggiunto il supporto per altre sequenze per consentire alla shell di descrivere semanticamente parti dell'output del terminale come "prompt", "comando" o "output". La shell può anche indicare al terminale se un comando ha avuto esito positivo o negativo.

Questa è una guida ad alcune delle funzionalità di integrazione della shell implementate a partire da Terminale v1.18. Stiamo pianificando di creare ancora più funzionalità in futuro, quindi ci piacerebbe ottenere un feedback aggiuntivo sul modo in cui le persone le usano.

Nota: in particolare, i "contrassegni" sono ancora sperimentali e sono abilitati solo per le build di anteprima del Terminale. Le impostazioni per queste funzionalità potrebbero cambiare in una versione futura.

Come funziona?

L'integrazione della shell funziona con la shell (o qualsiasi applicazione della riga di comando) per scrivere "sequenze di escape" speciali nel terminale. Queste sequenze di escape non vengono stampate nel terminale, ma forniscono bit di metadati che il terminale può usare per saperne di più su cosa sta succedendo nell'applicazione. Se si aggiungono queste sequenze al prompt della shell, è possibile che la shell fornisca continuamente informazioni al terminale che solo la shell conosce.

Per le sequenze seguenti:

  • OSC è "\x1b]" per la stringa: un carattere di escape, seguito da ]
  • ST è il carattere di terminazione stringa e può essere \x1b\ (un carattere ESC, seguito da \) o \x7 (il carattere BEL)
  • Gli spazi sono semplicemente illustrativi.
  • Le stringhe in <> sono parametri che devono essere sostituiti da un altro valore.

Le sequenze di integrazione della shell supportate pertinenti a partire da Terminale v1.18 sono:

  • OSC 133 ; A ST ("FTCS_PROMPT") - L'inizio di un prompt.
  • OSC 133 ; B ST ("FTCS_COMMAND_START") - L'inizio di una riga di comando (READ: la fine del prompt).
  • OSC 133 ; C ST ("FTCS_COMMAND_EXECUTED") - L'inizio dell'output del comando/la fine della riga di comando.
  • OSC 133 ; D ; <ExitCode> ST ("FTCS_COMMAND_FINISHED") - La fine di un comando. ExitCode Se ExitCode viene specificato, il terminale considererà 0 come "esito positivo" e qualsiasi altro elemento come errore. Se omesso, il terminale lascerà solo il segno di colore predefinito.

Come abilitare i contrassegni di integrazione della shell

Il supporto di queste funzionalità richiede la cooperazione tra la shell e il terminale. È necessario abilitare entrambe le impostazioni nel terminale per usare queste nuove funzionalità, nonché modificare il prompt della shell.

Per abilitare queste funzionalità nel terminale, è necessario aggiungere quanto segue alle impostazioni:

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

La modalità di abilitazione di questi contrassegni nella shell varia da shell a shell. Di seguito sono riportate le esercitazioni per CMD e PowerShell.

PowerShell (pwsh.exe)

Se il prompt di PowerShell non è mai stato modificato in precedenza, è consigliabile consultare prima about_Prompts.

È necessario modificare il file prompt per assicurarsi che il terminale sia in grado di comunicare con la CWD e contrassegnare il prompt con i contrassegni appropriati. PowerShell consente anche di includere il codice di errore del comando precedente nella sequenza 133;D, che consentirà al terminale di colorare automaticamente il contrassegno in base all'esito positivo o negativo del comando.

Aggiungere quanto segue al profilo di 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
}

Prompt dei comandi

Le origini del prompt dei comandi vengono richieste dalla variabile di ambiente PROMPT. CMD.exe legge $e come carattere ESC. Sfortunatamente, CMD.exe non ha un modo per ottenere il codice restituito del comando precedente nel prompt, quindi non è possibile fornire informazioni sull'esito positivo/negativi nei prompt CMD.

È possibile modificare il prompt dell'istanza CMD.exe corrente eseguendo:

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

In alternativa, è possibile impostare la variabile dalla riga di comando per tutte le sessioni future:

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

Questi esempi presuppongono che l'oggetto corrente PROMPT sia solo $P$G. È invece possibile scegliere di eseguire il wrapping del prompt corrente con un messaggio simile al seguente:

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

Nota: la shell preferita non è indicata qui? Se la si scopre, è possibile contribuire a una soluzione per la shell preferita.

Demo di integrazione della shell

Aprire nuove schede nella stessa directory di lavoro

Open new tabs in the same working directory

Mostrare segni per ogni comando nella barra di scorrimento

Show marks for each command in the scrollbar

Passare automaticamente tra i comandi

Automatically jump between commands

Selezionare l'intero output di un comando

Select the entire output of a command

Select the command using the right-click context menu