Compartir a través de


Integración del shell

A partir de Terminal 1.15 Preview, Terminal Windows ha empezado a admitir experimentalmente algunas características de "integración del shell". Estas características facilitan el uso de la línea de comandos. En versiones anteriores, se habilitó el shell para indicar al Terminal el directorio de trabajo actual. Ahora, hemos agregado compatibilidad con más secuencias para permitir que el shell describa semánticamente partes de la salida del terminal como un "símbolo del sistema", un "comando" o una "salida". El shell también puede indicar al terminal si un comando se ejecutó correctamente o no.

Esta es una guía de algunas de las características de integración del shell que hemos implementado a partir de Terminal v1.18. Estamos planeando crear incluso más características sobre estas en el futuro, por lo que nos encantaría recibir algunos comentarios adicionales sobre cómo los usuarios las usan.

Nota: a partir de Terminal 1.21, las marcas son una característica estable. Antes de la versión 1.21, las marcas solo estaban habilitadas para las compilaciones preliminares de Terminal. Si usa una versión de Terminal anterior a la 1.21, la configuración showMarksOnScrollbar se denominaba experimental.showMarksOnScrollbar, y la autoMarkPrompts se denominaba experimental.autoMarkPrompts.

¿Cómo funciona?

La integración de shell funciona haciendo que el shell (o cualquier aplicación de línea de comandos) escriba "secuencias de escape" especiales en el Terminal. Estas secuencias de escape no se imprimen en el Terminal, sino que proporcionan bits de metadatos que el terminal puede usar para tener más información sobre lo que sucede en la aplicación. Al colocar estas secuencias en el símbolo del sistema del shell, puede hacer que el shell proporcione continuamente información al terminal que solo conoce el shell.

En las secuencias siguientes:

  • OSC es la cadena "\x1b]", un carácter de escape, seguido de ].
  • ST es el "terminador de cadena" y puede ser \x1b\ (un carácter ESC, seguido de \) o \x7 (el carácter BEL).
  • Los espacios son meramente ilustrativos.
  • Las cadenas de <> son parámetros que deben reemplazarse por algún otro valor.

Las secuencias de integración del shell admitidas más importantes a partir de Terminal v1.18 son:

  • OSC 133 ; A ST ("FTCS_PROMPT"): el inicio de un símbolo del sistema.
  • OSC 133 ; B ST ("FTCS_COMMAND_START"): el inicio de una línea de comandos (READ: el final del símbolo del sistema).
  • OSC 133 ; C ST ("FTCS_COMMAND_EXECUTED"): el inicio de la salida del comando o el final de la línea de comandos.
  • OSC 133 ; D ; <ExitCode> ST ("FTCS_COMMAND_FINISHED"): el final de un comando. ExitCode Si se proporciona ExitCode, el Terminal tratará 0 como "correcto" y cualquier otra cosa como error. Si se omite, el terminal simplemente dejará la marca del color predeterminado.

Habilitación de marcas de integración del shell

La compatibilidad con estas características requiere la cooperación entre el shell y el Terminal. Para usar estas nuevas características, tendrá que habilitar la configuración en el Terminal y modificar el símbolo del sistema del shell.

Para habilitar estas características en el Terminal, puede agregar los siguientes valores a la configuración:

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

La forma de habilitar estas marcas en el shell varía de un shell a otro. A continuación, se muestran tutoriales para CMD y PowerShell.

PowerShell (pwsh.exe)

Si nunca ha cambiado el símbolo del sistema de PowerShell, primero debe consultar about_Prompts.

Tendremos que editar prompt para asegurarnos de que le indicamos al Terminal el CWD y marcaremos el símbolo del sistema con las marcas adecuadas. PowerShell también nos permite incluir el código de error del comando anterior en la secuencia 133;D, lo que permitirá al terminal colorear automáticamente la marca en función de si el comando se ha ejecutado correctamente o no.

Agregue lo siguiente al perfil de 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
}

Símbolo del sistema

Orígenes del símbolo del sistema que se solicitan desde la variable de entorno PROMPT. CMD.exe lee $e como carácter ESC. Por desgracia, CMD.exe no tiene una manera de obtener el código de retorno del comando anterior en el símbolo del sistema, por lo que no podemos proporcionar información de éxito o error en los mensajes de CMD.

Puede cambiar el símbolo del sistema de la instancia de CMD.exe actual mediante la ejecución de:

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

O bien, puede establecer la variable desde la línea de comandos para todas las sesiones futuras:

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

En estos ejemplos se supone que el valor actual de PROMPT es simplemente $P$G. En su lugar, puede optar por encapsular el símbolo del sistema actual con algo parecido a esto:

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

Bash

Puede agregar lo siguiente al final del ~/.bashrc para habilitar la integración del shell en Bash:

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

Esto ajustará el $PS1 existente con las secuencias necesarias para habilitar la integración del shell.

Nota: ¿No ve su shell favorito aquí? Si consigue descubrir el problema, no dude en aportar una solución para su shell favorito.

Características de integración del shell

Abrir nuevas pestañas en el mismo directorio de trabajo

Abrir nuevas pestañas en el mismo directorio de trabajo

Mostrar marcas para cada comando de la barra de desplazamiento

Mostrar marcas para cada comando de la barra de desplazamiento

Saltar automáticamente entre comandos

Esto usa las acciones scrollToMark tal y como se han definido anteriormente.

Saltar automáticamente entre comandos

Seleccionar la salida completa de un comando

En este gif, usamos la acción selectOutput enlazada a ctrl+g para seleccionar la salida completa de un comando. Seleccionar la salida completa de un comando

A continuación se usa la configuración experimental.rightClickContextMenu para habilitar un menú contextual con el botón derecho en el Terminal. Con esa integración de shell y habilitada, puede hacer clic con el botón derecho en un comando para seleccionar todo el comando o su salida.

Seleccionar el comando mediante el menú contextual de botón derecho

Sugerencias de comandos recientes

Con la integración de shell habilitada, la interfaz de usuario de sugerencias se puede configurar para mostrar también los comandos recientes.

Interfaz de usuario de sugerencias que muestra comandos recientes

Puede abrir este menú con la siguiente acción:

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

(Para obtener más información, consulte la documentación de sugerencias)

Recursos adicionales