Issue 3914 enhance Ctrl-t [bash shell]
Implementation of issues/3914 but only for bash shell.
Modify Ctrl-t behaviour in the following way (bash shell):
- Change the default setting (current dir) to present first the files and directories of depth 0 in order of decreasing modification time (as in
ls -t1) - If the cursor follows immediately a word which is a path to an existing dir, fzf this dir instead of the current.
Issue #3914
so, I've tried it.
https://github.com/user-attachments/assets/242eb8ab-d434-4508-9c52-ac665a5b76d4
I picked your patch and modified the key-bindings.bash file directly, to test it.
diff --git a/key-bindings.bash b/key-bindings.bash
index 2da32cb..4a7bb99 100755
--- a/key-bindings.bash
+++ b/key-bindings.bash
@@ -25,34 +25,59 @@ __fzf_defaults() {
echo "${FZF_DEFAULT_OPTS-} $2"
}
-__fzf_select__() {
- FZF_DEFAULT_COMMAND=${FZF_CTRL_T_COMMAND:-} \
- FZF_DEFAULT_OPTS=$(__fzf_defaults "--reverse --walker=file,dir,follow,hidden --scheme=path" "${FZF_CTRL_T_OPTS-} -m") \
- FZF_DEFAULT_OPTS_FILE='' $(__fzfcmd) "$@" |
- while read -r item; do
- printf '%q ' "$item" # escape special chars
- done
-}
-
__fzfcmd() {
[[ -n "${TMUX_PANE-}" ]] && { [[ "${FZF_TMUX:-0}" != 0 ]] || [[ -n "${FZF_TMUX_OPTS-}" ]]; } &&
echo "fzf-tmux ${FZF_TMUX_OPTS:--d${FZF_TMUX_HEIGHT:-40%}} -- " || echo "fzf"
}
-fzf-file-widget() {
- local selected="$(__fzf_select__ "$@")"
- READLINE_LINE="${READLINE_LINE:0:$READLINE_POINT}$selected${READLINE_LINE:$READLINE_POINT}"
- READLINE_POINT=$(( READLINE_POINT + ${#selected} ))
+# Override defaults for improved ctrl-t experience
+__fzf_find() {
+ command ls -1t $1;
+ command find -L $1 -mindepth 2 \( -path '*/\.*' -o -fstype 'sysfs' -o -fstype 'devfs' -o -fstype 'devtmpfs' -o -fstype 'proc' \) -prune \
+ -o -type f -printf '%P\n' \
+ -o -type d -printf '%P\n' \
+ -o -type l -printf '%P\n' 2> /dev/null
}
-__fzf_cd__() {
- local dir
- dir=$(
- FZF_DEFAULT_COMMAND=${FZF_ALT_C_COMMAND:-} \
- FZF_DEFAULT_OPTS=$(__fzf_defaults "--reverse --walker=dir,follow,hidden --scheme=path" "${FZF_ALT_C_OPTS-} +m") \
- FZF_DEFAULT_OPTS_FILE='' $(__fzfcmd)
- ) && printf 'builtin cd -- %q' "$(builtin unset CDPATH && builtin cd -- "$dir" && builtin pwd)"
+__fzf_select__() {
+ local cmd opts
+ local dir=$1
+ shift
+ cmd="${FZF_CTRL_T_COMMAND:-"__fzf_find $dir"}"
+ opts="--height ${FZF_TMUX_HEIGHT:-40%} --bind=ctrl-z:ignore --reverse $FZF_DEFAULT_OPTS $FZF_CTRL_T_OPTS -m"
+ eval "$cmd" |
+ FZF_DEFAULT_OPTS="$opts" $(__fzfcmd) "$@" |
+ while read -r item; do
+ if [ "$dir" == "." ]; then
+ printf '%q ' "$item" # escape special chars
+ else
+ printf '%q/%q ' "$dir" "$item"
+ fi
+ done
+}
+
+fzf-file-widget() {
+ local trailing_spaces=$(echo -n "${READLINE_LINE:0:$READLINE_POINT}" | sed "s/^.*\S//")
+ local word=$(echo -n "${READLINE_LINE:0:$READLINE_POINT}" | sed "s/\s*$//"| awk '{print $NF}')
+ local dir=$(echo "${word/#\~/$HOME}" | sed "s#/\+#/#g; s#/\$##")
+ if [[ $READLINE_POINT -eq 0 || -n "$trailing_spaces" || ! -d "$dir" ]]; then
+ local maybe_space=""
+ [[ $READLINE_POINT -gt 0 && -z "$trailing_spaces" ]] && maybe_space=" "
+ local selected="$(__fzf_select__ . "$@")"
+ if [ -n "$selected" ]; then
+ READLINE_LINE="${READLINE_LINE:0:$READLINE_POINT}$maybe_space$selected${READLINE_LINE:$READLINE_POINT}"
+ READLINE_POINT=$((READLINE_POINT + ${#maybe_space} + ${#selected}))
+ fi
+ else
+ local selected="$(__fzf_select__ "$dir" "$@")"
+ if [ -n "$selected" ]; then
+ local pre_word=$((READLINE_POINT - ${#word}))
+ READLINE_LINE="${READLINE_LINE:0:$pre_word}$selected${READLINE_LINE:$READLINE_POINT}"
+ READLINE_POINT=$((pre_word + ${#selected}))
+ fi
+ fi
}
+# end of non default section
if command -v perl > /dev/null; then
__fzf_history__() {
I do ctrl+t with ls vim-plugins/ and ctrl+t, I still see entries from the same directory (cwd) instead of the subdirectory vim-plugins like I expected.
Also made sure I am using your code only, not the old version.
I checked if it is updated to new function
$ type fzf-file-widget
fzf-file-widget is a function
fzf-file-widget ()
{
local trailing_spaces=$(echo -n "${READLINE_LINE:0:$READLINE_POINT}" | sed "s/^.*\S//");
local word=$(echo -n "${READLINE_LINE:0:$READLINE_POINT}" | sed "s/\s*$//" | awk '{print $NF}');
local dir=$(echo "${word/#\~/$HOME}" | sed "s#/\+#/#g; s#/\$##");
if [[ $READLINE_POINT -eq 0 || -n "$trailing_spaces" || ! -d "$dir" ]]; then
local maybe_space="";
[[ $READLINE_POINT -gt 0 && -z "$trailing_spaces" ]] && maybe_space=" ";
local selected="$(__fzf_select__ . "$@")";
if [ -n "$selected" ]; then
READLINE_LINE="${READLINE_LINE:0:$READLINE_POINT}$maybe_space$selected${READLINE_LINE:$READLINE_POINT}";
READLINE_POINT=$((READLINE_POINT + ${#maybe_space} + ${#selected}));
fi;
else
local selected="$(__fzf_select__ "$dir" "$@")";
if [ -n "$selected" ]; then
local pre_word=$((READLINE_POINT - ${#word}));
READLINE_LINE="${READLINE_LINE:0:$pre_word}$selected${READLINE_LINE:$READLINE_POINT}";
READLINE_POINT=$((pre_word + ${#selected}));
fi;
fi
}
@phanirithvij Thanks for testing :) What version of fzf (commit hash) you're based on?
https://github.com/junegunn/fzf/blob/v0.57.0/shell/key-bindings.bash
sorry, I meant to say 0.57.0 tag