Поделиться через


Интеграция оболочки

Начиная с предварительной версии терминала 1.15, Терминал Windows начал экспериментально поддерживать некоторые функции интеграции оболочки. Эти функции упрощают использование командной строки. В предыдущих выпусках мы включили оболочку, чтобы сообщить терминалу, что такое текущий рабочий каталог. Теперь мы добавили поддержку дополнительных последовательностей, чтобы разрешить оболочке семантику описывать части выходных данных терминала как "запрос", "команда" или "выходные данные". Оболочка также может сообщить терминалу о том, выполнена ли команда успешно или не выполнена.

Это руководство по некоторым функциям интеграции оболочки, которые мы развернули в терминале версии 1.18. Мы планируем создать еще больше функций на основе этих в будущем, поэтому мы хотели бы получить дополнительные отзывы о том, как люди используют их.

Примечание. По состоянию на терминал 1.21 метки теперь являются стабильной функцией. До версии 1.21 метки были включены только для предварительных сборок терминала. Если вы используете версию терминала до версии 1.21, showMarksOnScrollbar параметр был назван experimental.showMarksOnScrollbarи autoMarkPrompts был назван experimental.autoMarkPrompts.

Как это работает?

Интеграция оболочки выполняется с помощью оболочки (или любого приложения командной строки) записи специальных escape-последовательностей в терминал. Эти escape-последовательности не печатаются в терминале. Вместо этого они предоставляют биты метаданных, которые терминал может использовать для получения дополнительных данных о том, что происходит в приложении. Приклеив эти последовательности в запрос оболочки, вы можете постоянно предоставлять сведения терминалу, который знает только оболочка.

Для следующих последовательностей:

  • OSC"\x1b]" строка — escape-символ, за которым следует]
  • ST является строковым терминатором и может быть либо \x1b\ (символ ESC, за которым следует \) или \x7 (символ BEL)
  • Пробелы просто иллюстрируют.
  • Строки являются <> параметрами, которые должны быть заменены другим значением.

Соответствующие поддерживаемые последовательности интеграции оболочки в терминале версии 1.18:

  • OSC 133 ; A ST("FTCS_PROMPT") — начало запроса.
  • OSC 133 ; B ST("FTCS_COMMAND_START") — начало командной строки (READ: конец запроса).
  • OSC 133 ; C ST("FTCS_COMMAND_EXECUTED") — начало выходных данных команды / конец командной строки.
  • OSC 133 ; D ; <ExitCode> ST("FTCS_COMMAND_FINISHED") — конец команды. ExitCode Если ExitCode задано, терминал будет рассматриваться 0 как "успешно" и что-либо другое как ошибка. Если не указано, терминал просто оставляет метку цвета по умолчанию.

Включение меток интеграции оболочки

Для поддержки этих функций требуется сотрудничество между оболочкой и терминалом. Вам потребуется включить параметры в терминале для использования этих новых функций, а также изменить запрос оболочки.

Чтобы включить эти функции в терминале, необходимо добавить следующие параметры:

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

Включение этих меток в оболочке зависит от оболочки до оболочки. Ниже приведены руководства по CMD и PowerShell.

PowerShell (pwsh.exe)

Если вы никогда раньше не меняли запрос PowerShell, вам следует сначала проверить about_Prompts.

Мы должны изменить свой prompt код, чтобы убедиться, что мы расскажем терминалу о CWD, и пометьте запрос с соответствующими метками. PowerShell также позволяет включить код ошибки из предыдущей команды в 133;D последовательность, что позволит терминалу автоматически раскрасить метку, если команда успешно выполнена или завершилась ошибкой.

Добавьте следующее в профиль 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 среды. CMD.exe читается $e как ESC символ. К сожалению, CMD.exe не имеет способа получить код возврата предыдущей команды в командной строке, поэтому мы не можем предоставить сведения об успешном выполнении или ошибке в запросах CMD.

Чтобы изменить запрос для текущего экземпляра CMD.exe, выполните следующую команду:

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

Кроме того, можно задать переменную из командной строки для всех будущих сеансов:

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

В этих примерах предполагается, что текущий является PROMPT справедливым $P$G. Вместо этого можно создать оболочку текущего запроса следующим образом:

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

Bash

Чтобы включить интеграцию оболочки ~/.bashrc в bash, можно добавить следующее:

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

Это приведет к переносу существующих $PS1 с помощью необходимых последовательностей для включения интеграции оболочки.

Примечание. Не видите любимую оболочку здесь? Если вы считаете это, вы можете внести свой вклад в решение для предпочитаемой оболочки!

Функции интеграции оболочки

Открытие новых вкладок в том же рабочем каталоге

Открытие новых вкладок в том же рабочем каталоге

Отображение меток для каждой команды на полосе прокрутки

Отображение меток для каждой команды на полосе прокрутки

Автоматическое переход между командами

В этом случае используются scrollToMark действия, определенные выше.

Автоматическое переход между командами

Выбор всего выходных данных команды

В этом GIF-файле мы используем действие, привязанное selectOutput к ctrl+g выбору всего выходных данных команды. Выбор всего выходных данных команды

В следующем примере используется experimental.rightClickContextMenu параметр для включения контекстного меню правой кнопкой мыши в терминале. С включенной интеграцией оболочки можно щелкнуть правой кнопкой мыши команду, чтобы выбрать всю команду или ее выходные данные.

Выберите команду с помощью контекстного меню правой кнопкой мыши

Последние предложения команд

С включенной интеграцией оболочки пользовательский интерфейс предложений можно настроить для отображения последних команд.

Пользовательский интерфейс предложений с последними командами в нем

Это меню можно открыть с помощью следующего действия:

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

(Дополнительные сведения см. в разделеДокументация по предложениям)

Дополнительные ресурсы