summaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorbitraid <bitraid@protonmail.ch>2024-11-08 09:44:34 +0200
committerJunegunn Choi <junegunn.c@gmail.com>2024-11-18 19:08:34 +0900
commit4d357d10639017d19fd42cf55bf8b03c7889c890 (patch)
treea9dd67e4dde44f9696127313758a75125c643cda /shell
parent961ae1541cb1735191c433f11d2f422e3b9cd452 (diff)
downloadfzf-4d357d10639017d19fd42cf55bf8b03c7889c890.tar.gz
[fish] Improve commandline parsing
- Enable using unescaped quotes for exact-match, exact-boundary-match. - Enable suffix-exact-match. - Enable inverse-exact-match, inverse-prefix/suffix-exact-match. - Allow searching for double quotes and backslashes. - Combine multiple consecutive slashes into one. - Workaround for test command bug, allowing $dir or $commandline be a single `!`.
Diffstat (limited to 'shell')
-rw-r--r--shell/key-bindings.fish34
1 files changed, 22 insertions, 12 deletions
diff --git a/shell/key-bindings.fish b/shell/key-bindings.fish
index 11686b1a..f2095783 100644
--- a/shell/key-bindings.fish
+++ b/shell/key-bindings.fish
@@ -36,10 +36,10 @@ function fzf_key_bindings
test -n "$FZF_TMUX_HEIGHT"; or set FZF_TMUX_HEIGHT 40%
begin
- set -lx FZF_DEFAULT_OPTS (__fzf_defaults "--reverse --walker=file,dir,follow,hidden --scheme=path --walker-root='$dir'" "$FZF_CTRL_T_OPTS")
+ set -lx FZF_DEFAULT_OPTS (__fzf_defaults "--reverse --walker=file,dir,follow,hidden --scheme=path --walker-root=$dir" "$FZF_CTRL_T_OPTS")
set -lx FZF_DEFAULT_COMMAND "$FZF_CTRL_T_COMMAND"
set -lx FZF_DEFAULT_OPTS_FILE ''
- eval (__fzfcmd)' -m --query "'$fzf_query'"' | while read -l r; set result $result $r; end
+ eval (__fzfcmd) -m --query=$fzf_query | while read -l r; set -a result $r; end
end
if [ -z "$result" ]
commandline -f repaint
@@ -98,10 +98,10 @@ function fzf_key_bindings
test -n "$FZF_TMUX_HEIGHT"; or set FZF_TMUX_HEIGHT 40%
begin
- set -lx FZF_DEFAULT_OPTS (__fzf_defaults "--reverse --walker=dir,follow,hidden --scheme=path --walker-root='$dir'" "$FZF_ALT_C_OPTS")
+ set -lx FZF_DEFAULT_OPTS (__fzf_defaults "--reverse --walker=dir,follow,hidden --scheme=path --walker-root=$dir" "$FZF_ALT_C_OPTS")
set -lx FZF_DEFAULT_OPTS_FILE ''
set -lx FZF_DEFAULT_COMMAND "$FZF_ALT_C_COMMAND"
- eval (__fzfcmd)' +m --query "'$fzf_query'"' | read -l result
+ eval (__fzfcmd) +m --query=$fzf_query | read -l result
if [ -n "$result" ]
cd -- $result
@@ -152,9 +152,18 @@ function fzf_key_bindings
set -l prefix (string match -r -- '^-[^\s=]+=' $commandline)
set commandline (string replace -- "$prefix" '' $commandline)
+ # escape special characters, except for the $ sign of valid variable names,
+ # so that after eval, the original string is returned, but with the
+ # variable names replaced by their values.
+ set commandline (string escape -n -- $commandline)
+ set commandline (string replace -r -a '\x5c\$(?=[\w])' '\$' -- $commandline)
+
# eval is used to do shell expansion on paths
eval set commandline $commandline
+ # Combine multiple consecutive slashes into one
+ set commandline (string replace -r -a '/+' '/' -- $commandline)
+
if [ -z $commandline ]
# Default to current directory with no --query
set dir '.'
@@ -162,27 +171,28 @@ function fzf_key_bindings
else
set dir (__fzf_get_dir $commandline)
- if [ "$dir" = "." -a (string sub -l 1 -- $commandline) != '.' ]
+ # BUG: on combined expressions, if a left argument is a single `!`, the
+ # builtin test command of fish will treat it as the ! operator. To
+ # overcome this, have the variable parts on the right.
+ if test "." = "$dir" -a "." != (string sub -l 1 -- $commandline)
# if $dir is "." but commandline is not a relative path, this means no file path found
set fzf_query $commandline
else
# Also remove trailing slash after dir, to "split" input properly
- set fzf_query (string replace -r "^$dir/?" -- '' "$commandline")
+ set fzf_query (string replace -r "^$dir/?" '' -- $commandline)
end
end
- echo $dir
- echo $fzf_query
+ echo (string escape -- $dir)
+ echo (string escape -- $fzf_query)
echo $prefix
end
function __fzf_get_dir -d 'Find the longest existing filepath from input string'
set dir $argv
- # Strip all trailing slashes. Ignore if $dir is root dir (/)
- if [ (string length -- $dir) -gt 1 ]
- set dir (string replace -r '/*$' -- '' $dir)
- end
+ # Strip trailing slash, unless $dir is root dir (/)
+ set dir (string replace -r '(?<!^)/$' '' -- $dir)
# Iteratively check if dir exists and strip tail end of path
while [ ! -d "$dir" ]