Tutoriel : activer l’intégration de l’interpréteur de commandes dans le Terminal Windows

À compter de la préversion du Terminal 1.15, le Terminal Windows a commencé à prendre en charge expérimentalement certaines fonctionnalités d’« intégration de l’interpréteur de commandes ». Ces fonctionnalités facilitent l’utilisation de la ligne de commande. Dans les versions antérieures, nous avons activé l’interpréteur de commandes pour indiquer au Terminal le répertoire de travail actuel. Nous avons désormais ajouté la prise en charge d’autres séquences pour permettre à l’interpréteur de commandes de décrire sémantiquement des parties de la sortie du terminal sous la forme d’« invite », de « commande » ou de « sortie ». L’interpréteur de commandes peut également indiquer au terminal si une commande a réussi ou échoué.

Il s’agit d’un guide de certaines fonctionnalités d’intégration de l’interpréteur de commandes déployées à partir du Terminal v1.18. Nous prévoyons de créer des fonctionnalités supplémentaires à l’avenir. Nous aimerions donc obtenir des commentaires supplémentaires sur la façon dont les utilisateurs les utilisent.

Remarque : les « marques » en particulier sont une fonctionnalité expérimentale. Elles sont activées uniquement pour les versions d’évaluation du terminal. Les paramètres de ces fonctionnalités sont susceptibles de changer dans une version ultérieure.

Comment cela fonctionne ?

L’intégration de l’interpréteur de commandes fonctionne ainsi : l’interpréteur de commandes (ou à toute application en ligne de commande) écrit des « séquences d’échappement » spéciales dans le terminal. Ces séquences d’échappement ne sont pas imprimées dans le terminal. Elles fournissent à la place des métadonnées que le terminal peut utiliser pour en savoir plus sur ce qui se passe dans l’application. En collant ces séquences dans l’invite de votre interpréteur de commandes, vous pouvez demander à l’interpréteur de commandes de fournir en continu des informations au terminal que seul l’interpréteur de commandes connaît.

Pour les séquences suivantes :

  • OSC est la chaîne "\x1b]" : un caractère d’échappement, suivi de ]
  • ST est le « terminateur de chaîne ». Il peut être \x1b\ (un caractère d’échappement, suivi de \) ou \x7 (le caractère d’appel)
  • Les espaces sont simplement illustratifs.
  • Les chaînes dans <> sont des paramètres qui doivent être remplacés par une autre valeur.

Voici les séquences pertinentes d’intégration d’interpréteur de commandes prises en charge à partir de Terminal v1.18 :

  • OSC 133 ; A ST ("FTCS_PROMPT") : début d’une invite.
  • OSC 133 ; B ST ("FTCS_COMMAND_START") : début d’une ligne de commande (READ : fin de l’invite).
  • OSC 133 ; C ST ("FTCS_COMMAND_EXECUTED") : début de la sortie de la commande/fin de la ligne de commande.
  • OSC 133 ; D ; <ExitCode> ST ("FTCS_COMMAND_FINISHED") : fin d’une commande. ExitCode Si ExitCode est fourni, le terminal traite 0 comme une « réussite » et tout autre résultat comme une erreur. En cas d’omission, le terminal laisse simplement la marque avec la couleur par défaut.

Guide pratique pour activer les marques d’intégration de l’interpréteur de commandes

La prise en charge de ces fonctionnalités nécessite une coopération entre votre interpréteur de commandes et le terminal. Vous devez à la fois activer les paramètres dans le terminal pour utiliser ces nouvelles fonctionnalités et modifier l’invite de votre interpréteur de commandes.

Pour activer ces fonctionnalités dans le terminal, vous devez ajouter les éléments suivants à vos paramètres :

"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 procédure pour activer ces marques dans votre interpréteur de commandes varie d’un interpréteur de commandes à l’autre. Vous trouverez ci-dessous des tutoriels sur CMD et PowerShell.

PowerShell (pwsh.exe)

Si vous n’avez jamais changé votre invite PowerShell auparavant, vous devez d’abord consulter about_Prompts.

Nous devons modifier votre prompt pour nous assurer que nous informons le Terminal du CWD et appliquons les marques appropriées à l’invite. PowerShell permet également d’inclure le code d’erreur de la commande précédente dans la séquence 133;D, ce qui permet au terminal de coloriser automatiquement la marque selon une commande ayant réussi ou échoué.

Ajoutez ce qui suit à votre profil 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
}

Invite de commandes

L’invite de commandes trouve l’invite dans la variable d’environnement PROMPT. CMD.exe lit $e en tant que caractère ESC. Malheureusement, CMD.exe n’est pas en mesure d’obtenir le code de retour de la commande précédente dans l’invite. Nous ne pouvons donc pas fournir d’informations indiquant une réussite/erreur dans les invites CMD.

Pour modifier l’invite pour l’instance CMD.exe actuelle, exécutez :

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

Vous pouvez également définir la variable à partir de la ligne de commande pour toutes les sessions futures :

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

Ces exemples supposent que votre PROMPT actuel est simplement $P$G. À la place, vous pouvez choisir d’inclure votre invite actuelle dans un wrapper de cette manière :

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

Remarque : vous ne voyez pas votre interpréteur de commandes favori ici ? Dans ce cas, n’hésitez pas à contribuer à l’ajout d’une solution d’une solution pour l’interpréteur de commandes de votre choix.

Démonstrations de l’intégration de l’interpréteur de commandes

Ouvrir de nouveaux onglets dans le même répertoire de travail

Open new tabs in the same working directory

Afficher les marques pour chaque commande dans la barre de défilement

Show marks for each command in the scrollbar

Saut automatique entre les commandes

Automatically jump between commands

Sélectionner la sortie entière d’une commande

Select the entire output of a command

Select the command using the right-click context menu