|
|
|
@ -1,7 +1,10 @@
|
|
|
|
|
Advanced fzf examples
|
|
|
|
|
======================
|
|
|
|
|
|
|
|
|
|
*(Last update: 2023/02/12)*
|
|
|
|
|
* *Last update: 2023/02/15*
|
|
|
|
|
* *Requires fzf 0.38.0 or above*
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
<!-- vim-markdown-toc GFM -->
|
|
|
|
|
|
|
|
|
@ -236,15 +239,13 @@ file called `rfv`.
|
|
|
|
|
# 1. Search for text in files using Ripgrep
|
|
|
|
|
# 2. Interactively narrow down the list using fzf
|
|
|
|
|
# 3. Open the file in Vim
|
|
|
|
|
IFS=: read -ra selected < <(
|
|
|
|
|
rg --color=always --line-number --no-heading --smart-case "${*:-}" |
|
|
|
|
|
fzf --ansi \
|
|
|
|
|
--color "hl:-1:underline,hl+:-1:underline:reverse" \
|
|
|
|
|
--delimiter : \
|
|
|
|
|
--preview 'bat --color=always {1} --highlight-line {2}' \
|
|
|
|
|
--preview-window 'up,60%,border-bottom,+{2}+3/3,~3'
|
|
|
|
|
)
|
|
|
|
|
[ -n "${selected[0]}" ] && vim "${selected[0]}" "+${selected[1]}"
|
|
|
|
|
--preview-window 'up,60%,border-bottom,+{2}+3/3,~3' \
|
|
|
|
|
--bind 'enter:become(vim {1} +{2})'
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
And run it with an initial query string.
|
|
|
|
@ -307,8 +308,12 @@ I know it's a lot to digest, let's try to break down the code.
|
|
|
|
|
position in the window
|
|
|
|
|
- `~3` makes the top three lines fixed header so that they are always
|
|
|
|
|
visible regardless of the scroll offset
|
|
|
|
|
- Once we selected a line, we open the file with `vim` (`vim
|
|
|
|
|
"${selected[0]}"`) and move the cursor to the line (`+${selected[1]}`).
|
|
|
|
|
- Instead of using shell script to process the final output of fzf, we use
|
|
|
|
|
`become(...)` action which was added in [fzf 0.38.0][0.38.0] to turn fzf
|
|
|
|
|
into a new process that opens the file with `vim` (`vim {1}`) and move the
|
|
|
|
|
cursor to the line (`+{2}`).
|
|
|
|
|
|
|
|
|
|
[0.38.0]: https://github.com/junegunn/fzf/blob/master/CHANGELOG.md#0380
|
|
|
|
|
|
|
|
|
|
### Using fzf as interactive Ripgrep launcher
|
|
|
|
|
|
|
|
|
@ -331,16 +336,14 @@ projects, and it will free up memory as you narrow down the results.
|
|
|
|
|
# 3. Open the file in Vim
|
|
|
|
|
RG_PREFIX="rg --column --line-number --no-heading --color=always --smart-case "
|
|
|
|
|
INITIAL_QUERY="${*:-}"
|
|
|
|
|
IFS=: read -ra selected < <(
|
|
|
|
|
FZF_DEFAULT_COMMAND="$RG_PREFIX $(printf %q "$INITIAL_QUERY")" \
|
|
|
|
|
fzf --ansi \
|
|
|
|
|
--disabled --query "$INITIAL_QUERY" \
|
|
|
|
|
--bind "change:reload:sleep 0.1; $RG_PREFIX {q} || true" \
|
|
|
|
|
--delimiter : \
|
|
|
|
|
--preview 'bat --color=always {1} --highlight-line {2}' \
|
|
|
|
|
--preview-window 'up,60%,border-bottom,+{2}+3/3,~3'
|
|
|
|
|
)
|
|
|
|
|
[ -n "${selected[0]}" ] && vim "${selected[0]}" "+${selected[1]}"
|
|
|
|
|
--preview-window 'up,60%,border-bottom,+{2}+3/3,~3' \
|
|
|
|
|
--bind 'enter:become(vim {1} +{2})'
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
![image](https://user-images.githubusercontent.com/700826/113684212-f9ff0a00-96ff-11eb-8737-7bb571d320cc.png)
|
|
|
|
@ -358,8 +361,6 @@ IFS=: read -ra selected < <(
|
|
|
|
|
|
|
|
|
|
### Switching to fzf-only search mode
|
|
|
|
|
|
|
|
|
|
*(Requires fzf 0.27.1 or above)*
|
|
|
|
|
|
|
|
|
|
In the previous example, we lost fuzzy matching capability as we completely
|
|
|
|
|
delegated search functionality to Ripgrep. But we can dynamically switch to
|
|
|
|
|
fzf-only search mode by *"unbinding"* `reload` action from `change` event.
|
|
|
|
@ -375,7 +376,6 @@ fzf-only search mode by *"unbinding"* `reload` action from `change` event.
|
|
|
|
|
# 3. Open the file in Vim
|
|
|
|
|
RG_PREFIX="rg --column --line-number --no-heading --color=always --smart-case "
|
|
|
|
|
INITIAL_QUERY="${*:-}"
|
|
|
|
|
IFS=: read -ra selected < <(
|
|
|
|
|
FZF_DEFAULT_COMMAND="$RG_PREFIX $(printf %q "$INITIAL_QUERY")" \
|
|
|
|
|
fzf --ansi \
|
|
|
|
|
--color "hl:-1:underline,hl+:-1:underline:reverse" \
|
|
|
|
@ -385,9 +385,8 @@ IFS=: read -ra selected < <(
|
|
|
|
|
--prompt '1. ripgrep> ' \
|
|
|
|
|
--delimiter : \
|
|
|
|
|
--preview 'bat --color=always {1} --highlight-line {2}' \
|
|
|
|
|
--preview-window 'up,60%,border-bottom,+{2}+3/3,~3'
|
|
|
|
|
)
|
|
|
|
|
[ -n "${selected[0]}" ] && vim "${selected[0]}" "+${selected[1]}"
|
|
|
|
|
--preview-window 'up,60%,border-bottom,+{2}+3/3,~3' \
|
|
|
|
|
--bind 'enter:become(vim {1} +{2})'
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
* Phase 1. Filtering with Ripgrep
|
|
|
|
@ -408,8 +407,6 @@ IFS=: read -ra selected < <(
|
|
|
|
|
|
|
|
|
|
### Switching between Ripgrep mode and fzf mode
|
|
|
|
|
|
|
|
|
|
*(Requires fzf 0.36.0 or above)*
|
|
|
|
|
|
|
|
|
|
[fzf 0.30.0][0.30.0] added `rebind` action so we can "rebind" the bindings
|
|
|
|
|
that were previously "unbound" via `unbind`.
|
|
|
|
|
|
|
|
|
@ -424,7 +421,6 @@ CTRL-F.
|
|
|
|
|
rm -f /tmp/rg-fzf-{r,f}
|
|
|
|
|
RG_PREFIX="rg --column --line-number --no-heading --color=always --smart-case "
|
|
|
|
|
INITIAL_QUERY="${*:-}"
|
|
|
|
|
IFS=: read -ra selected < <(
|
|
|
|
|
FZF_DEFAULT_COMMAND="$RG_PREFIX $(printf %q "$INITIAL_QUERY")" \
|
|
|
|
|
fzf --ansi \
|
|
|
|
|
--color "hl:-1:underline,hl+:-1:underline:reverse" \
|
|
|
|
@ -437,9 +433,8 @@ IFS=: read -ra selected < <(
|
|
|
|
|
--delimiter : \
|
|
|
|
|
--header '╱ CTRL-R (ripgrep mode) ╱ CTRL-F (fzf mode) ╱' \
|
|
|
|
|
--preview 'bat --color=always {1} --highlight-line {2}' \
|
|
|
|
|
--preview-window 'up,60%,border-bottom,+{2}+3/3,~3'
|
|
|
|
|
)
|
|
|
|
|
[ -n "${selected[0]}" ] && vim "${selected[0]}" "+${selected[1]}"
|
|
|
|
|
--preview-window 'up,60%,border-bottom,+{2}+3/3,~3' \
|
|
|
|
|
--bind 'enter:become(vim {1} +{2})'
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
- To restore the query string when switching between modes, we store the
|
|
|
|
|