Overhaul fish functions (#759)
Replace the "temp file" workaround with the "read" function: it's simpler and faster. Use proper escaping, remove the custom function. The "file" widget uses last token as root for the "find" command. This replaces the equivalent of '**' completion in bash/zsh. The "$dir" non-expanded variable can be used in FZF_CTRL_T_COMMAND to set the root.
This commit is contained in:
parent
8a502af4c1
commit
0508e70f9b
31
README.md
31
README.md
@ -434,11 +434,36 @@ export FZF_DEFAULT_COMMAND='
|
||||
|
||||
It's [a known bug of fish](https://github.com/fish-shell/fish-shell/issues/1362)
|
||||
that it doesn't allow reading from STDIN in command substitution, which means
|
||||
simple `vim (fzf)` won't work as expected. The workaround is to store the result
|
||||
of fzf to a temporary file.
|
||||
simple `vim (fzf)` won't work as expected. The workaround is to use the `read`
|
||||
fish command:
|
||||
|
||||
```sh
|
||||
fzf > $TMPDIR/fzf.result; and vim (cat $TMPDIR/fzf.result)
|
||||
fzf | read -l result; and vim $result
|
||||
```
|
||||
|
||||
or, for multiple results:
|
||||
|
||||
```sh
|
||||
fzf -m | while read -l r; set result $result $r; end; and vim $result
|
||||
```
|
||||
|
||||
The globbing system is different in fish and thus `**` completion will not work.
|
||||
However, the `CTRL-T` command will use the last token on the commandline as the
|
||||
root folder for the recursive search. For instance, hitting `CTRL-T` at the end
|
||||
of the following commandline
|
||||
|
||||
```sh
|
||||
ls /var/
|
||||
```
|
||||
|
||||
will list all files and folders under `/var/`.
|
||||
|
||||
When using a custom `FZF_CTRL_T_COMMAND`, use the unexpanded `$dir` variable to
|
||||
make use of this feature. `$dir` defaults to `.` when the last token is not a
|
||||
valid directory. Example:
|
||||
|
||||
```sh
|
||||
set -l FZF_CTRL_T_COMMAND "command find -L \$dir -type f 2> /dev/null | sed '1d; s#^\./##'"
|
||||
```
|
||||
|
||||
License
|
||||
|
@ -1,52 +1,60 @@
|
||||
# Key bindings
|
||||
# ------------
|
||||
function fzf_key_bindings
|
||||
# Due to a bug of fish, we cannot use command substitution,
|
||||
# so we use temporary file instead
|
||||
if [ -z "$TMPDIR" ]
|
||||
set -g TMPDIR /tmp
|
||||
end
|
||||
|
||||
function __fzf_escape
|
||||
while read item
|
||||
echo -n (echo -n "$item" | sed -E 's/([ "$~'\''([{<>})])/\\\\\\1/g')' '
|
||||
# Store last token in $dir as root for the 'find' command
|
||||
function fzf-file-widget -d "List files and folders"
|
||||
set -l dir (commandline -t)
|
||||
# The commandline token might be escaped, we need to unescape it.
|
||||
set dir (eval "printf '%s' $dir")
|
||||
if [ ! -d "$dir" ]
|
||||
set dir .
|
||||
end
|
||||
end
|
||||
# Some 'find' versions print undesired duplicated slashes if the path ends with slashes.
|
||||
set dir (string replace --regex '(.)/+$' '$1' "$dir")
|
||||
|
||||
function fzf-file-widget
|
||||
# "-path \$dir'*/\\.*'" matches hidden files/folders inside $dir but not
|
||||
# $dir itself, even if hidden.
|
||||
set -q FZF_CTRL_T_COMMAND; or set -l FZF_CTRL_T_COMMAND "
|
||||
command find -L . \\( -path '*/\\.*' -o -fstype 'devfs' -o -fstype 'devtmpfs' -o -fstype 'proc' \\) -prune \
|
||||
-o -type f -print \
|
||||
-o -type d -print \
|
||||
-o -type l -print 2> /dev/null | sed 1d | cut -b3-"
|
||||
eval "$FZF_CTRL_T_COMMAND | "(__fzfcmd)" -m $FZF_CTRL_T_OPTS > $TMPDIR/fzf.result"
|
||||
and for i in (seq 20); commandline -i (cat $TMPDIR/fzf.result | __fzf_escape) 2> /dev/null; and break; sleep 0.1; end
|
||||
command find -L \$dir \\( -path \$dir'*/\\.*' -o -fstype 'devfs' -o -fstype 'devtmpfs' \\) -prune \
|
||||
-o -type f -print \
|
||||
-o -type d -print \
|
||||
-o -type l -print 2> /dev/null | sed '1d; s#^\./##'"
|
||||
|
||||
eval "$FZF_CTRL_T_COMMAND | "(__fzfcmd)" -m $FZF_CTRL_T_OPTS" | while read -l r; set result $result $r; end
|
||||
if [ -z "$result" ]
|
||||
commandline -f repaint
|
||||
return
|
||||
end
|
||||
|
||||
if [ "$dir" != . ]
|
||||
# Remove last token from commandline.
|
||||
commandline -t ""
|
||||
end
|
||||
for i in $result
|
||||
commandline -it -- (string escape $i)
|
||||
commandline -it -- ' '
|
||||
end
|
||||
commandline -f repaint
|
||||
rm -f $TMPDIR/fzf.result
|
||||
end
|
||||
|
||||
function fzf-history-widget
|
||||
history | eval (__fzfcmd) +s +m --tiebreak=index --toggle-sort=ctrl-r $FZF_CTRL_R_OPTS -q '(commandline)' > $TMPDIR/fzf.result
|
||||
and commandline -- (cat $TMPDIR/fzf.result)
|
||||
function fzf-history-widget -d "Show command history"
|
||||
history | eval (__fzfcmd) +s +m --tiebreak=index $FZF_CTRL_R_OPTS -q '(commandline)' | read -l result
|
||||
and commandline -- $result
|
||||
commandline -f repaint
|
||||
rm -f $TMPDIR/fzf.result
|
||||
end
|
||||
|
||||
function fzf-cd-widget
|
||||
function fzf-cd-widget -d "Change directory"
|
||||
set -q FZF_ALT_C_COMMAND; or set -l FZF_ALT_C_COMMAND "
|
||||
command find -L . \\( -path '*/\\.*' -o -fstype 'devfs' -o -fstype 'devtmpfs' -o -fstype 'proc' \\) -prune \
|
||||
-o -type d -print 2> /dev/null | sed 1d | cut -b3-"
|
||||
# Fish hangs if the command before pipe redirects (2> /dev/null)
|
||||
eval "$FZF_ALT_C_COMMAND | "(__fzfcmd)" +m $FZF_ALT_C_OPTS > $TMPDIR/fzf.result"
|
||||
[ (cat $TMPDIR/fzf.result | wc -l) -gt 0 ]
|
||||
and cd (cat $TMPDIR/fzf.result)
|
||||
command find -L . \\( -path '*/\\.*' -o -fstype 'devfs' -o -fstype 'devtmpfs' \\) -prune \
|
||||
-o -type d -print 2> /dev/null | sed 1d | cut -b3-"
|
||||
eval "$FZF_ALT_C_COMMAND | "(__fzfcmd)" +m $FZF_ALT_C_OPTS" | read -l result
|
||||
[ "$result" ]; and cd $result
|
||||
commandline -f repaint
|
||||
rm -f $TMPDIR/fzf.result
|
||||
end
|
||||
|
||||
function __fzfcmd
|
||||
set -q FZF_TMUX; or set FZF_TMUX 1
|
||||
|
||||
if [ $FZF_TMUX -eq 1 ]
|
||||
if set -q FZF_TMUX_HEIGHT
|
||||
echo "fzf-tmux -d$FZF_TMUX_HEIGHT"
|
||||
@ -68,4 +76,3 @@ function fzf_key_bindings
|
||||
bind -M insert \ec fzf-cd-widget
|
||||
end
|
||||
end
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user