Существуют некоторые инструменты и программы, которые позволяют получить больше от командной строки Windows, делая опыт и рабочие процессы более плавными. С помощью всего нескольких дополнительных инструментов мы можем улучшить навигацию по папкам, поиск файлов и операции с git без запоминания большого количества различных команд. Кроме того, все используемые здесь инструменты доступны в среде Linux (а вместе с ней и в WSL), что значительно упрощает переключение между экземпляром WSL и Windows.
Оглавление
- 1. Предварительные условия
- 1.1. Терминал Windows
- 1.2. PowerShell
- 2. Инструменты
- 2.1. Scoop
- 2.2. fd
- 2.3. fzf
- 2.4. lazygit
- 2.5. lazydocker
- 2.6. ripgrep
- 2.7. ZLocation
- 2.8. PSFzf
- 3. Настройка профиля PowerShell
- 4. Использование с помощью fzf
- 5. Заключение
1. Предварительные условия
1.1. Терминал Windows
Мы будем использовать Windows Terminal, но это не обязательно. Подойдет любой другой эмулятор терминала, но Windows Terminal в последнее время набирает популярность.
Установите и скачайте отсюда https://github.com/microsoft/terminal#installing-and-running-windows-terminal.
Рекомендуемый способ — через Windows Store для получения автоматических обновлений.
1.2. PowerShell
Чтобы скачать PowerShell, посетите сайт https://aka.ms/powershell-release?tag=stable и обновите его до последней версии. Все приведенные здесь шаги используют PowerShell 7.1.3. После установки вы должны увидеть PowerShell в выпадающем списке Windows Terminal. Рекомендуется использовать его в качестве оболочки по умолчанию.
Установленную версию можно проверить с помощью:
$PSVersionTable | Select-Object PSVersion
2. Инструменты
Откройте Терминал Windows, выберите PowerShell и следуйте инструкциям. Каждый инструмент имеет обширную документацию с большим количеством примеров. Я предложу лишь несколько, но обязательно ознакомьтесь с ними подробно.
2.1. Scoop
Scoop — это замечательный инструмент для начала работы. Его можно рассматривать как альтернативу Chocolatey, однако Scoop больше ориентирован на инструменты командной строки разработчика и процесс их установки.
Чтобы установить его и добавить extras
bucket, используйте следующее:
# Download installer script and run it
Invoke-Expression (New-Object System.Net.WebClient).DownloadString('https://get.scoop.sh')
# Add 'extras' bucket (has other useful tools)
scoop bucket add extras
# List all installed apps
scoop list
Следующими на очереди идут инструменты для установки с помощью Scoop:
2.2. fd
fd используется как альтернатива команде find. Она очень быстрая, позволяет использовать regex-сопоставление, фильтровать по файлам или каталогам и уважать игнорируемые файлы (.ignore
, .gitignore
и т.д.).
# Install fd using scoop
scoop install fd
# Search current dir recursively for file containing "index" in the name
fd index
# Search file containing "index" in the name in the "./projects" subfolder
fd index ./projects
# Get all directories recursively
fd -t dll
2.3. fzf
fzf — это сверхбыстрый нечеткий фильтр/искатель. Он запускает интерактивный искатель с результатами, которые передаются в него по трубопроводу, и записывает выбранный элемент в STDOUT
. Если не использовать pipe, fzf получит список файлов (используя find).
Существует синтаксис поиска для сужения результатов, так что проверьте его, чтобы еще больше улучшить рабочий процесс.
# Install fzf using scoop
scoop install fzf
# Search (using fd) all files with md extension, filter it and open result
# in notepad
fd -e md | fzf | %{ notepad $_ }
? Позже мы будем использовать fzf с другими инструментами, которые могут использовать STDOUT и делать что-то с выбранным результатом.
2.4. lazygit
lazygit — это замечательный терминальный пользовательский интерфейс для git. Он помогает работать с командами git, предлагая простой пользовательский интерфейс, меню, интерактивный rebase, последние ветки, прокрутку журналов и diffs.
# Install lazygit using scoop
scoop install lazygit
# Run it, q to exit
lazygit
? lazygit даже поддерживает события мыши (и работает в Windows Terminal > v.1.9), что означает, что вы можете даже кликать в инструменте.
2.5. lazydocker
lazydocker разработан тем же автором, что и lazygit. Он предлагает аналогичный пользовательский интерфейс, но для управления Docker. Просматривайте состояния, журналы, тома и выполняйте обычные операции (перезапуск, удаление и т.д…), не заучивая все параметры наизусть.
# Install lazydocker using scoop
scoop install lazydocker
# Run it, q to exit
lazydocker
2.6. ripgrep
ripgrep — это инструмент для рекурсивного поиска текстового содержимого в текущем каталоге (с использованием regex) с соблюдением игнорируемых файлов (.ignore
, .gitignore
и т.д…).
# Install ripgrep using scoop
scoop install ripgrep
# Search existing directory for files that contain word "async"
rg async
# Specify file to search in
rg async ./userService.ts
2.7. ZLocation
ZLocation запоминает каталоги, по которым вы часто перемещаетесь, и ранжирует их. Через некоторое время он позволит вам переходить по каталогам с небольшим количеством букв. Вы можете задать больше букв (или regex), чтобы сузить поиск.
# Install
Install-Module ZLocation -Scope CurrentUser
# Get module up and running
Import-Module ZLocation
# Navigate to some directories to make ZL learn
cd C:/Windows
cd C:/Users/
# Switch between using z
z win
z u
# List all in history
z
# Return to previous location
z -
? Для того, чтобы ZLocation работал каждый раз при запуске PowerShell, нам нужно добавить его в профиль. Это описано в следующем разделе.
2.8. PSFzf
PSFzf обертывает fzf (мы установили его через scoop) и позволяет лучше использовать его в PS с помощью нескольких удобных утилит. Есть несколько хороших вспомогательных функций (с псевдонимами), которые облегчают выполнение других задач, использующих fzf. Мы включим их в следующем разделе.
# Install from PowerShell Gallery
Install-Module PSFzf
# Use it to switch directories
Get-ChildItem . -Attributes Directory | Invoke-Fzf | Set-Location
# Open VS code with selected file
Get-ChildItem . -Recurse -Attributes !Directory | Invoke-Fzf | % { code $_ }
# Use fd to get desired input to fzf and start VSCode with selected file
fd -e md | Invoke-Fzf | % { code $_ }
3. Настройка профиля PowerShell
Теперь нам нужно выполнить некоторые дополнительные настройки, чтобы все работало для каждого экземпляра PS. Мы также создадим несколько псевдонимов из модуля PSFzf.
Вы можете вызвать
Enable-PsFzfAliases
, чтобы установить все псевдонимы, но я предпочитаю вручную устанавливать только те, которые я использую.
Профили — это просто сценарии, которые запускаются при создании оболочки. Их несколько, но я бы предложил использовать $profile.CurrentUserAllHosts
, чтобы у вас был одинаковый опыт на всех хостах. Вы также можете использовать $profile
, который будет использовать CurrentUserCurrentHost
.
Более подробную информацию можно найти здесь: https://devblogs.microsoft.com/scripting/understanding-the-six-powershell-profiles/
# Check if we have PowerShell profile created
Test-Path $profile.CurrentUserAllHosts
# This will create file if it doesn't exist
echo $null >> $profile.CurrentUserAllHosts
# Open our profile file in VSCode (or use preferred editor)
code $profile.CurrentUserAllHosts
У вас будет открыт редактор с готовым к настройке файлом профиля PowerShell.
Если ваш профиль уже настроен, вы можете добавить это в него. Я добавил комментарии, чтобы описать, что делает каждая строка.
Вставьте следующее в открытый редактор:
# To make ZLocation module work in every PowerShell instance.
Import-Module ZLocation
# PSFzf has undocumented option to use fd executable for
# file and directory searching. This enables that option.
Set-PsFzfOption -EnableFd:$true
# Custom function to SetLocation, because PSFzf uses
# Get-ChildItem which doesn't use fd and doesn't use
# ignore files. Invoke-FuzzySetLocation is defined here
# https://github.com/kelleyma49/PSFzf/blob/b97263a30addd9a2c84a8603382c92e4e6de0eeb/PSFzf.Functions.ps1#L142
#
# This implementation is for setting FileSystem location
# and implementation uses parts of
# https://github.com/kelleyma49/PSFzf/blob/b97263a30addd9a2c84a8603382c92e4e6de0eeb/PSFzf.Base.ps1#L20
# https://github.com/kelleyma49/PSFzf/blob/b97263a30addd9a2c84a8603382c92e4e6de0eeb/PSFzf.Base.ps1#L35
function Invoke-FuzzySetLocation2() {
param($Directory = $null)
if ($null -eq $Directory) {
$Directory = $PWD.Path
}
$result = $null
try {
# Color output from fd to fzf if running in Windows Terminal
$script:RunningInWindowsTerminal = [bool]($env:WT_Session)
if ($script:RunningInWindowsTerminal) {
$script:DefaultFileSystemFdCmd = "fd.exe --color always . {0}"
}
else {
$script:DefaultFileSystemFdCmd = "fd.exe . {0}"
}
# Wrap $Directory in quotes if there is space (to be passed in fd)
if ($Directory.Contains(' ')) {
$strDir = """$Directory"""
}
else {
$strDir = $Directory
}
# Call fd to get directory list and pass to fzf
Invoke-Expression (($script:DefaultFileSystemFdCmd -f '--type directory {0} --max-depth 1') -f $strDir) | Invoke-Fzf | ForEach-Object { $result = $_ }
}
catch {
}
if ($null -ne $result) {
Set-Location $result
}
}
# Show tips about newly added commands
function Get-Tips {
$tips = @(
[pscustomobject]@{
Command = 'fcd'
Description = 'navigate to subdirectory'
},
[pscustomobject]@{
Command = 'ALT+C'
Description = 'navigate to deep subdirectory'
},
[pscustomobject]@{
Command = 'z'
Description = 'ZLocation'
},
[pscustomobject]@{
Command = 'fz'
Description = 'ZLocation through fzf'
},
[pscustomobject]@{
Command = 'fe'
Description = 'fuzzy edit file'
},
[pscustomobject]@{
Command = 'fh'
Description = 'fuzzy invoke command from history'
},
[pscustomobject]@{
Command = 'fkill'
Description = 'fuzzy stop process'
},
[pscustomobject]@{
Command = 'fd'
Description = 'find https://github.com/sharkdp/fd#how-to-use'
},
[pscustomobject]@{
Command = 'rg'
Description = 'find in files https://github.com/BurntSushi/ripgrep/blob/master/GUIDE.md'
}
)
Write-Output $tips | Format-Table
}
# Define aliases to call fuzzy methods from PSFzf
New-Alias -Scope Global -Name fcd -Value Invoke-FuzzySetLocation2 -ErrorAction Ignore
New-Alias -Scope Global -Name fe -Value Invoke-FuzzyEdit -ErrorAction Ignore
New-Alias -Scope Global -Name fh -Value Invoke-FuzzyHistory -ErrorAction Ignore
New-Alias -Scope Global -Name fkill -Value Invoke-FuzzyKillProcess -ErrorAction Ignore
New-Alias -Scope Global -Name fz -Value Invoke-FuzzyZLocation -ErrorAction Ignore
4. Использование с помощью fzf
Настоящая сила fzf проявляется, когда его результат передается в другую операцию. Его можно использовать для открытия файла или изменения каталога (если входными данными для fzf является список каталогов/файлов), завершения процесса, навигации по истории команд и т.д…
? В PSFzf есть больше команд, чем те, что описаны здесь. Их также можно использовать как основу для собственных команд.
# Call fe to get list of files to edit in current directory (or pass dir as param)
# After selecting file it will open VS Code (or set $env:EDITOR variable to executable)
fe
fe ./services
# List recent commands executed and search through them
fh
fh curl
# Find process to kill
fkill
# CHANGING DIRECTORY
# List one depth folders and change to it (respects ignore files)
fcd
# Get from recently navigated locations
z
z proj
# Using "z" by itself works, but if you need more control try
# which will list all frequent locations and give you fzf to change into
fz
# <Alt+C> - similar to fcd but lists all subdirectories
? Вызвать
tips
для быстрого ознакомления с недавно добавленными функциями. Эта функция определяется в профиле.
PS C:> tips
Command Description
------- -----------
fcd navigate to subdirectory
ALT+C navigate to deep subdirectory
z ZLocation
fz ZLocation through fzf
fe fuzzy edit file
fh fuzzy invoke command from history
fkill fuzzy stop process
fd find https://github.com/sharkdp/fd#how-to-use
rg find in files https://github.com/BurntSushi/ripgrep/blob/master/GUIDE.md
5. Заключение
Такие операции, как навигация по каталогам, история операций и редактирование файлов, относятся к основным командам, которые вы будете выполнять в терминале. С помощью нескольких инструментов и псевдонимов, добавленных в PowerShell, мы сделали базовый опыт гораздо более приятным и гибким. Предложите другие инструменты в комментариях.