summaryrefslogtreecommitdiffstats
path: root/shell/key-bindings.fish
diff options
context:
space:
mode:
authorJohn Nguyen <ipwnponies@users.noreply.github.com>2017-06-25 05:16:15 -0700
committerJunegunn Choi <junegunn.c@gmail.com>2017-06-25 21:16:15 +0900
commit70cfa6af13e56bf50c70c46e62085f9d9b52f909 (patch)
treee98dad66f05dc079d5b53512a00283d0f0616db7 /shell/key-bindings.fish
parentdbcaec59ae0ebf1489860968d8fb186972f00ffb (diff)
[fish] Accept starting dir for <M-c> key binding (#944)
This also modifies <C-t> behaviour. The longest file path in the input is used as root directory for `find` command. The remainder of the input is passed to fzf's --query as a initial search parameters.
Diffstat (limited to 'shell/key-bindings.fish')
-rw-r--r--shell/key-bindings.fish75
1 files changed, 62 insertions, 13 deletions
diff --git a/shell/key-bindings.fish b/shell/key-bindings.fish
index 03b543ea..803d0a93 100644
--- a/shell/key-bindings.fish
+++ b/shell/key-bindings.fish
@@ -4,14 +4,9 @@ function fzf_key_bindings
# Store current 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
- # Some 'find' versions print undesired duplicated slashes if the path ends with slashes.
- set dir (string replace --regex '(.)/+$' '$1' "$dir")
+ set -l commandline (__fzf_parse_commandline)
+ set -l dir $commandline[1]
+ set -l fzf_query $commandline[2]
# "-path \$dir'*/\\.*'" matches hidden files/folders inside $dir but not
# $dir itself, even if hidden.
@@ -24,7 +19,7 @@ function fzf_key_bindings
set -q FZF_TMUX_HEIGHT; or set FZF_TMUX_HEIGHT 40%
begin
set -lx FZF_DEFAULT_OPTS "--height $FZF_TMUX_HEIGHT --reverse $FZF_DEFAULT_OPTS $FZF_CTRL_T_OPTS"
- eval "$FZF_CTRL_T_COMMAND | "(__fzfcmd)" -m" | while read -l r; set result $result $r; end
+ eval "$FZF_CTRL_T_COMMAND | "(__fzfcmd)' -m --query "'$fzf_query'"' | while read -l r; set result $result $r; end
end
if [ -z "$result" ]
commandline -f repaint
@@ -51,15 +46,26 @@ function fzf_key_bindings
end
function fzf-cd-widget -d "Change directory"
+ set -l commandline (__fzf_parse_commandline)
+ set -l dir $commandline[1]
+ set -l fzf_query $commandline[2]
+
set -q FZF_ALT_C_COMMAND; or set -l FZF_ALT_C_COMMAND "
- command find -L . -mindepth 1 \\( -path '*/\\.*' -o -fstype 'sysfs' -o -fstype 'devfs' -o -fstype 'devtmpfs' \\) -prune \
- -o -type d -print 2> /dev/null | cut -b3-"
+ command find -L \$dir -mindepth 1 \\( -path \$dir'*/\\.*' -o -fstype 'sysfs' -o -fstype 'devfs' -o -fstype 'devtmpfs' \\) -prune \
+ -o -type d -print 2> /dev/null | sed 's@^\./@@'"
set -q FZF_TMUX_HEIGHT; or set FZF_TMUX_HEIGHT 40%
begin
set -lx FZF_DEFAULT_OPTS "--height $FZF_TMUX_HEIGHT --reverse $FZF_DEFAULT_OPTS $FZF_ALT_C_OPTS"
- eval "$FZF_ALT_C_COMMAND | "(__fzfcmd)" +m" | read -l result
- [ "$result" ]; and cd $result
+ eval "$FZF_ALT_C_COMMAND | "(__fzfcmd)' +m --query "'$fzf_query'"' | read -l result
+
+ if [ -n "$result" ]
+ cd $result
+
+ # Remove last token from commandline.
+ commandline -t ""
+ end
end
+
commandline -f repaint
end
@@ -82,4 +88,47 @@ function fzf_key_bindings
bind -M insert \cr fzf-history-widget
bind -M insert \ec fzf-cd-widget
end
+
+ function __fzf_parse_commandline -d 'Parse the current command line token and return split of existing filepath and rest of token'
+ # eval is used to do shell expansion on paths
+ set -l commandline (eval "printf '%s' "(commandline -t))
+
+ if [ -z $commandline ]
+ # Default to current directory with no --query
+ set dir '.'
+ set fzf_query ''
+ else
+ set dir (__fzf_get_dir $commandline)
+
+ if [ "$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")
+ end
+ end
+
+ echo $dir
+ echo $fzf_query
+ 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
+
+ # Iteratively check if dir exists and strip tail end of path
+ while [ ! -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
+
+ echo $dir
+ end
+
end