πͺ INTRO
If you want to integrate fzf
with rg
, fd
, bat
to fuzzy find files, directories or ripgrep the content of a file and preview using bat
, but the fzf document only has commands for Linux shell (bash,...), and you want to achieve that on your Windows Machine using Powershell, this post may be for you.
π« INTRODUCTION FOR THOSE MENTIONED CLI TOOL
-
fzf
: πΈ A command-line fuzzy finder -
ripgrep
(rg): ripgrep recursively searches directories for a regex pattern while respecting your gitignore -
fd
: A simple, fast and user-friendly alternative to 'find' -
bat
: A cat(1) clone with wings. -
eza
(optional): A modern, maintained replacement for ls
NOTE
You can install those tool via
scoop
orChocolatey
for easy installation and update.
π» COMMANDS
NOTE
fzf
usesCMD
for external command, notPowershell
orpwsh
.I won't explain the commands in details.
1οΈβ£ Find files / directories
Preview
- Find files
- Find directories
Command
fd --type file --follow --hidden --exclude .git |
fzf --prompt 'Files> ' `
--header-first `
--header 'CTRL-S: Switch between Files/Directories' `
--bind 'ctrl-s:transform:if not "%FZF_PROMPT%"=="Files> " (echo ^change-prompt^(Files^> ^)^+^reload^(fd --type file^)) else (echo ^change-prompt^(Directory^> ^)^+^reload^(fd --type directory^))' `
--preview 'if "%FZF_PROMPT%"=="Files> " (bat --color=always {} --style=plain) else (eza -T --colour=always --icons=always {})'
- The command above pipes the output of
fd
(find files) tofzf
. Press Ctrl + S to change the mode to find directories. The preview pane usingbat
to preview file's content is on the right side, andeza
for directory tree. - You can use
tree
command on Windows instead ofeza
in the last argument. But it wouldn't be colourful and have files icons.
- eza -T --colour=always --icons=always {}
+ tree /A {}
2οΈβ£ Ripgrep content + fzf
Preview
- Ripgrep
- Fzf
Command
$INITIAL_QUERY = "${*:-}"
$RG_PREFIX = "rg --column --line-number --no-heading --color=always --smart-case"
"" |
fzf --ansi --disabled --query "$INITIAL_QUERY" `
--bind "start:reload:$RG_PREFIX {q}" `
--bind "change:reload:sleep 0.1 & $RG_PREFIX {q} || rem" `
--bind 'ctrl-s:transform:if not "%FZF_PROMPT%" == "1. ripgrep> " (echo ^rebind^(change^)^+^change-prompt^(1. ripgrep^> ^)^+^disable-search^+^transform-query:echo ^{q^} ^> %TEMP%\rg-fzf-f ^& cat %TEMP%\rg-fzf-r) else (echo ^unbind^(change^)^+^change-prompt^(2. fzf^> ^)^+^enable-search^+^transform-query:echo ^{q^} ^> %TEMP%\rg-fzf-r ^& cat %TEMP%\rg-fzf-f)' `
--color "hl:-1:underline,hl+:-1:underline:reverse" `
--delimiter ":" `
--prompt '1. ripgrep> ' `
--preview-label "Preview" `
--header 'CTRL-S: Switch between ripgrep/fzf' `
--header-first `
--preview 'bat --color=always {1} --highlight-line {2} --style=plain' `
--preview-window 'up,60%,border-bottom,+{2}+3/3'
- The command above use
ripgrep
to find the content of the file and preview usingbat
. Then you can find more specifically by pressing Ctrl + S to switch tofzf
mode. Press Ctrl + S again to back to the first step (ripgrep
).
βοΈ ADVANCED USE
You can put them all in a function, choose what to do with the output of the command, like Set-Location
, or open the file / directory in your editor. Just open your $PROFILE
file using your editor (ex: nvim $PROFILE
).
Take my config as reference (require PsReadLine
- may be builtin - to config keyboard shortcut to fast call function).
$env:FZF_DEFAULT_OPTS=@"
--layout=reverse
--cycle
--scroll-off=5
--border
--preview-window=right,60%,border-left
--bind ctrl-u:preview-half-page-up
--bind ctrl-d:preview-half-page-down
--bind ctrl-f:preview-page-down
--bind ctrl-b:preview-page-up
--bind ctrl-g:preview-top
--bind ctrl-h:preview-bottom
--bind alt-w:toggle-preview-wrap
--bind ctrl-e:toggle-preview
"@
function _open_path
{
param (
[string]$input_path
)
if (-not $input_path)
{
return
}
Write-Output "[ ] cd"
Write-Output "[*] nvim"
$choice = Read-Host "Enter your choice"
if ($input_path -match "^.*:\d+:.*$")
{
$input_path = ($input_path -split ":")[0]
}
switch ($choice)
{
{$_ -eq "" -or $_ -eq " "}
{
if (Test-Path -Path $input_path -PathType Leaf)
{
$input_path = Split-Path -Path $input_path -Parent
}
Set-Location -Path $input_path
}
default
{ nvim $input_path
}
}
}
function _get_path_using_fd
{
$input_path = fd --type file --follow --hidden --exclude .git |
fzf --prompt 'Files> ' `
--header-first `
--header 'CTRL-S: Switch between Files/Directories' `
--bind 'ctrl-s:transform:if not "%FZF_PROMPT%"=="Files> " (echo ^change-prompt^(Files^> ^)^+^reload^(fd --type file^)) else (echo ^change-prompt^(Directory^> ^)^+^reload^(fd --type directory^))' `
--preview 'if "%FZF_PROMPT%"=="Files> " (bat --color=always {} --style=plain) else (eza -T --colour=always --icons=always {})'
return $input_path
}
function _get_path_using_rg
{
$INITIAL_QUERY = "${*:-}"
$RG_PREFIX = "rg --column --line-number --no-heading --color=always --smart-case"
$input_path = "" |
fzf --ansi --disabled --query "$INITIAL_QUERY" `
--bind "start:reload:$RG_PREFIX {q}" `
--bind "change:reload:sleep 0.1 & $RG_PREFIX {q} || rem" `
--bind 'ctrl-s:transform:if not "%FZF_PROMPT%" == "1. ripgrep> " (echo ^rebind^(change^)^+^change-prompt^(1. ripgrep^> ^)^+^disable-search^+^transform-query:echo ^{q^} ^> %TEMP%\rg-fzf-f ^& cat %TEMP%\rg-fzf-r) else (echo ^unbind^(change^)^+^change-prompt^(2. fzf^> ^)^+^enable-search^+^transform-query:echo ^{q^} ^> %TEMP%\rg-fzf-r ^& cat %TEMP%\rg-fzf-f)' `
--color "hl:-1:underline,hl+:-1:underline:reverse" `
--delimiter ":" `
--prompt '1. ripgrep> ' `
--preview-label "Preview" `
--header 'CTRL-S: Switch between ripgrep/fzf' `
--header-first `
--preview 'bat --color=always {1} --highlight-line {2} --style=plain' `
--preview-window 'up,60%,border-bottom,+{2}+3/3'
return $input_path
}
function fdg
{
_open_path $(_get_path_using_fd)
}
function rgg
{
_open_path $(_get_path_using_rg)
}
# SET KEYBOARD SHORTCUTS TO CALL FUNCTION
Set-PSReadLineKeyHandler -Key "Ctrl+f" -ScriptBlock {
[Microsoft.PowerShell.PSConsoleReadLine]::RevertLine()
[Microsoft.PowerShell.PSConsoleReadLine]::Insert("fdg")
[Microsoft.PowerShell.PSConsoleReadLine]::AcceptLine()
}
Set-PSReadLineKeyHandler -Key "Ctrl+g" -ScriptBlock {
[Microsoft.PowerShell.PSConsoleReadLine]::RevertLine()
[Microsoft.PowerShell.PSConsoleReadLine]::Insert("rgg")
[Microsoft.PowerShell.PSConsoleReadLine]::AcceptLine()
}
π LAST WORDS
- You can read more on document of those tool for further use (custom fzf layout, color schemes,...)
- Please change the command according to your demands.
- Read more about the amazing tool
PSFzf
, a PowerShell wrapper around the fuzzy finder fzf. - By the way you can come visit my windows dotfiles and grab some stuff you like π.
- My English is not good and this is the first time I write a post in English. If there are any mistakes, please forgive me.
- Thank you.
Top comments (1)
π₯