[fish] Refactor __fzf_parse_commandline, remove __fzf_get_dir

The __fzf_get_dir function was called only once, and was basically a
single command in a while loop.
This commit is contained in:
bitraid 2025-02-13 12:46:49 +02:00 committed by Junegunn Choi
parent f232df2887
commit cbbd939a94

View File

@ -136,39 +136,41 @@ function fzf_key_bindings
end end
function __fzf_parse_commandline -d 'Parse the current command line token and return split of existing filepath, fzf query, and optional -option= prefix' function __fzf_parse_commandline -d 'Parse the current command line token and return split of existing filepath, fzf query, and optional -option= prefix'
set -l commandline (commandline -t) set -l dir '.'
set -l query
set -l commandline (commandline -t | string unescape -n)
# strip -option= from token if present # Strip -option= from token if present
set -l prefix (string match -r -- '^-[^\s=]+=' $commandline) set -l prefix (string match -r -- '^-[^\s=]+=' $commandline)
set commandline (string replace -- "$prefix" '' $commandline) set commandline (string replace -- "$prefix" '' $commandline)
# Enable home directory expansion of leading ~/ # Enable home directory expansion of leading ~/
set commandline (string replace -r -- '^~/' '\$HOME/' $commandline) set commandline (string replace -r -- '^~/' '\$HOME/' $commandline)
# escape special characters, except for the $ sign of valid variable names, # Escape special characters, except for the $ sign of valid variable names,
# so that after eval, the original string is returned, but with the # so that the original string with expanded variables is returned after eval.
# variable names replaced by their values.
set commandline (string escape -n -- $commandline) set commandline (string escape -n -- $commandline)
set commandline (string replace -r -a -- '\x5c\$(?=[\w])' '\$' $commandline) set commandline (string replace -r -a -- '\\\\\$(?=[\w])' '\$' $commandline)
# eval is used to do shell expansion on paths # eval is used to do shell expansion on paths
eval set commandline $commandline eval set commandline $commandline
# Combine multiple consecutive slashes into one, and unescape. # Combine multiple consecutive slashes into one.
set commandline (string replace -r -a -- '/+' '/' $commandline | string unescape -n) set commandline (string replace -r -a -- '/+' '/' $commandline)
if test -z "$commandline" if test -n "$commandline"
# Default to current directory with no --query # Strip trailing slash, unless $dir is root dir (/)
set dir '.' set dir (string replace -r -- '(?<!^)/$' '' $commandline)
set fzf_query ''
else
set dir (__fzf_get_dir $commandline)
# BUG: on combined expressions, if a left argument is a single `!`, the # Set $dir to the longest existing filepath
# builtin test command of fish will treat it as the ! operator. To while not test -d "$dir"
# overcome this, have the variable parts on the right. # If path is absolute, this can keep going until ends up at /
if test "." = "$dir" -a "./" != (string sub -l 2 -- $commandline) # If path is relative, this can keep going until entire input is consumed, dirname returns "."
# if $dir is "." but commandline is not a relative path, this means no file path found set dir (dirname -- $dir)
end
if test "$dir" = '.'; and test (string sub -l 2 -- $commandline) != './'
# If $dir is "." but commandline is not a relative path, this means no file path found
set fzf_query $commandline set fzf_query $commandline
else else
# Also remove trailing slash after dir, to "split" input properly # Also remove trailing slash after dir, to "split" input properly
@ -176,25 +178,7 @@ function fzf_key_bindings
end end
end end
echo -- $dir string escape -n -- "$dir" "$fzf_query" "$prefix"
string escape -- $fzf_query
echo -- $prefix
end
function __fzf_get_dir -d 'Find the longest existing filepath from input string'
set dir $argv
# 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 test ! -d "$dir"
# If path is absolute, this can keep going until ends up at /
# If path is relative, this can keep going until entire input is consumed, dirname returns "."
set dir (dirname -- "$dir")
end
string escape -n -- $dir
end end
end end