Руководство. Открытие вкладки или области в одном каталоге в Терминале Windows

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

К сожалению, в Windows сложно определить текущий рабочий каталог (CWD) для процесса. Даже если бы мы смогли найти его, не все приложения на самом деле задают CWD при навигации. Примечательно, что Windows PowerShell не меняет свой CWD по мере того, как вы меняете каталог (cd), перемещаясь по файловой системе! Автоматическое дублирование CWD PowerShell почти всегда будет неправильным.

К счастью, существует обходной путь. Приложения могут создавать специальную escape-последовательность, чтобы сообщить Терминалу, каким должен быть CWD.

В этом руководстве описано следующее:

  • настроить оболочку для информирования Терминала о текущем рабочем каталоге;
  • использовать действие duplicateTab, чтобы открыть вкладку с тем же CWD;
  • использовать действие splitPane, чтобы открыть область с тем же CWD;
  • использовать контекстное меню вкладки для открытия вкладок или областей с тем же CWD.

Настройка оболочки

Чтобы сообщить Терминалу о CWD, вам нужно изменить оболочку, чтобы она создавала escape-последовательность при навигации по ОС. К счастью, в большинстве оболочек есть механизм для настройки запроса, который запускается после каждой команды. Это идеальный способ добавления таких выходных данных.

Windows

Командная строка: cmd.exe

cmd использует переменную среды %PROMPT% для настройки запроса. Вы можете легко добавить к запросу команду для установки CWD с помощью следующей команды:

set PROMPT=$e]9;9;$P$e\%PROMPT%

Это приведет к добавлению $e]9;9;$P$e\ к текущему запросу. Когда cmd оценивает этот запрос:

  • $e заменяется escape-символом;
  • $p заменяется текущим рабочим каталогом.

Обратите внимание, что приведенная выше команда будет работать только в текущем сеансе cmd.exe. Чтобы задать постоянное значение, ПОСЛЕ выполнения указанной выше команды выполните следующее:

setx PROMPT "%PROMPT%"

PowerShell — powershell.exe или pwsh.exe.

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

Добавьте следующее в профиль PowerShell:

function prompt {
  $loc = $executionContext.SessionState.Path.CurrentLocation;

  $out = ""
  if ($loc.Provider.Name -eq "FileSystem") {
    $out += "$([char]27)]9;9;`"$($loc.ProviderPath)`"$([char]27)\"
  }
  $out += "PS $loc$('>' * ($nestedPromptLevel + 1)) ";
  return $out
}

PowerShell с posh-git

Если вы используете posh-git, запрос уже будет изменен. В этом случае нужно добавить только необходимые выходные данные в уже измененный запрос. Следующий пример представляет собой слегка измененную версию этого примера из документации по ConEmu:

function prompt
{
  $loc = Get-Location

  $prompt = & $GitPromptScriptBlock

  $prompt += "$([char]27)]9;12$([char]7)"
  if ($loc.Provider.Name -eq "FileSystem")
  {
    $prompt += "$([char]27)]9;9;`"$($loc.ProviderPath)`"$([char]27)\"
  }

  $prompt
}

Использование PowerShell со Starship

Если вы используете Starship, запрос уже будет изменен. В этом случае нужно добавить только необходимые выходные данные в уже измененный запрос.

function Invoke-Starship-PreCommand {
  $loc = $executionContext.SessionState.Path.CurrentLocation;
  $prompt = "$([char]27)]9;12$([char]7)"
  if ($loc.Provider.Name -eq "FileSystem")
  {
    $prompt += "$([char]27)]9;9;`"$($loc.ProviderPath)`"$([char]27)\"
  }
  $host.ui.Write($prompt)
}

WSL

Дистрибутивы подсистемы Windows для Linux в качестве оболочки командной строки в основном используют Bash.

bash

Добавьте следующую строку в конец файла конфигурации .bash_profile:

PROMPT_COMMAND=${PROMPT_COMMAND:+"$PROMPT_COMMAND; "}'printf "\e]9;9;%s\e\\" "$(wslpath -w "$PWD")"'

Переменная PROMPT_COMMAND в Bash сообщает Bash, какую команду следует выполнить перед отображением запроса. Оператор printf — это то, что мы используем, чтобы добавить последовательность для установки рабочего каталога с использованием Терминала. Бит $(wslpath -w "$PWD") вызовет исполняемый файл wslpath для преобразования текущего каталога в путь, подобный пути в Windows. Бит ${PROMPT_COMMAND:+"$PROMPT_COMMAND; "} — это магическая команда Bash, которая позволяет убедиться, что мы добавляем эту команду к любой существующей команде (если вы уже задали PROMPT_COMMAND где-то еще).

zsh

Добавьте в конец файла .zshrc следующие строки:

keep_current_path() {
  printf "\e]9;9;%s\e\\" "$(wslpath -w "$PWD")"
}
precmd_functions+=(keep_current_path)

Обработчик precmd_functions сообщает zsh, какие команды следует выполнить перед отображением запроса. Оператор printf — это то, что мы используем, чтобы добавить последовательность для установки рабочего каталога с использованием Терминала. Бит $(wslpath -w "$PWD") вызовет исполняемый файл wslpath для преобразования текущего каталога в путь, подобный пути в Windows. При использовании precmd_functions+= обязательно добавьте функцию keep_current_path в любую существующую функцию, уже определенную для этого обработчика.

Fish

Если вы используете оболочку Fish, добавьте следующие строки в конец файла конфигурации, расположенного по пути ~/.config/fish/config.fish:

function storePathForWindowsTerminal --on-variable PWD
    if test -n "$WT_SESSION"
      printf "\e]9;9;%s\e\\" (wslpath -w "$PWD")
    end
end

Эта функция будет вызываться при каждом изменении текущего пути для подтверждения открытия текущего сеанса Терминалом Windows (проверка $WT_SESSION) и отправки команды операционной системы (OSC 9;9;) с эквивалентным путем Windows (wslpath -w) текущего пути.

MINGW

Для MINGW, Git Bash и Cygwin необходимо изменить PROMPT_COMMAND для WSL: измените wslpath на cygpath.

Добавьте следующую строку в конец файла .bashrc:

PROMPT_COMMAND=${PROMPT_COMMAND:+"$PROMPT_COMMAND; "}'printf "\e]9;9;%s\e\\" "`cygpath -w "$PWD" -C ANSI`"'

Примечание.

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

Использование действий для дублирования пути

Когда вы настроите оболочку, чтобы сообщить Терминалу о текущем каталоге, вы сможете легко открывать новые вкладки или области, используя этот путь.

Открытие новой вкладки с использованием duplicateTab

Чтобы открыть новую вкладку с использованием того же пути (и того же профиля), который используется текущим активным терминалом, используйте действие "Дублировать вкладку". Это привязано по умолчанию к CTRL+SHIFT+D, как показано ниже.

        { "command": "duplicateTab", "keys": "ctrl+shift+d" },

Дополнительные сведения см. здесь: duplicateTab.

Открытие новой области с использованием splitPane

Чтобы открыть новую область с использованием того же пути (и того же профиля), который используется текущим активным терминалом, используйте действие "Дублировать область". Сочетания клавиш по умолчанию для этого действия НЕТ. Простейшая форма этого действия:

        { "command": { "action": "splitPane", "splitMode": "duplicate" } },

Дополнительные сведения см. здесь: splitPane.

Использование меню для дублирования пути

Приведенные выше действия также доступны в контекстном меню вкладки под записями "Дублировать вкладку" и "Разделить область".

Image duplicate-tab-same-cwdImage split-pane-same-cwd