Open ri-aje opened 3 years ago
Thanks for the suggestion. I wasn't aware of operate-and-get-next
, hence not implemented here. I like the idea but I can't immediately see how we can correctly implement the behavior.
These two steps are easy:
Accept the current line for execution
and fetch the next line
diff --git a/shell/key-bindings.bash b/shell/key-bindings.bash
index 0cfc423..514d7ff 100644
--- a/shell/key-bindings.bash
+++ b/shell/key-bindings.bash
@@ -45,13 +45,21 @@ __fzf_cd__() {
}
__fzf_history__() {
- local output
+ local output key no cmd
output=$(
builtin fc -lnr -2147483648 |
last_hist=$(HISTTIMEFORMAT='' builtin history 1) perl -n -l0 -e 'BEGIN { getc; $/ = "\n\t"; $HISTCMD = $ENV{last_hist} + 1 } s/^[ *]//; print $HISTCMD - $. . "\t$_" if !$seen{$_}++' |
- FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} $FZF_DEFAULT_OPTS -n2..,.. --tiebreak=index --bind=ctrl-r:toggle-sort,ctrl-z:ignore $FZF_CTRL_R_OPTS +m --read0" $(__fzfcmd) --query "$READLINE_LINE"
+ FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} $FZF_DEFAULT_OPTS -n2..,.. --tiebreak=index --bind=ctrl-r:toggle-sort,ctrl-z:ignore $FZF_CTRL_R_OPTS +m --read0" $(__fzfcmd) --query "$READLINE_LINE" --expect ctrl-o
) || return
- READLINE_LINE=${output#*$'\t'}
+ key=${output%%$'\n'*}
+ output=${output#*$'\n'}
+ no=${output%$'\t'*}
+ cmd=${output#*$'\t'}
+ if [ "$key" = ctrl-o ]; then
+ cmd=$(history -p "!$(( no + 1 ))" 2> /dev/null)
+ fc -s "$no"
+ fi
+ READLINE_LINE=$cmd
if [ -z "$READLINE_POINT" ]; then
echo "$READLINE_LINE"
else
But after that, we need to programmatically move the current position to the point in the command history so that we can proceed with the subsequent commands.
Thanks for the suggestion. I wasn't aware of
operate-and-get-next
, hence not implemented here. I like the idea but I can't immediately see how we can correctly implement the behavior.These two steps are easy:
Accept the current line for execution
and fetch the next line
diff --git a/shell/key-bindings.bash b/shell/key-bindings.bash index 0cfc423..514d7ff 100644 --- a/shell/key-bindings.bash +++ b/shell/key-bindings.bash @@ -45,13 +45,21 @@ __fzf_cd__() { } __fzf_history__() { - local output + local output key no cmd output=$( builtin fc -lnr -2147483648 | last_hist=$(HISTTIMEFORMAT='' builtin history 1) perl -n -l0 -e 'BEGIN { getc; $/ = "\n\t"; $HISTCMD = $ENV{last_hist} + 1 } s/^[ *]//; print $HISTCMD - $. . "\t$_" if !$seen{$_}++' | - FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} $FZF_DEFAULT_OPTS -n2..,.. --tiebreak=index --bind=ctrl-r:toggle-sort,ctrl-z:ignore $FZF_CTRL_R_OPTS +m --read0" $(__fzfcmd) --query "$READLINE_LINE" + FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} $FZF_DEFAULT_OPTS -n2..,.. --tiebreak=index --bind=ctrl-r:toggle-sort,ctrl-z:ignore $FZF_CTRL_R_OPTS +m --read0" $(__fzfcmd) --query "$READLINE_LINE" --expect ctrl-o ) || return - READLINE_LINE=${output#*$'\t'} + key=${output%%$'\n'*} + output=${output#*$'\n'} + no=${output%$'\t'*} + cmd=${output#*$'\t'} + if [ "$key" = ctrl-o ]; then + cmd=$(history -p "!$(( no + 1 ))" 2> /dev/null) + fc -s "$no" + fi + READLINE_LINE=$cmd if [ -z "$READLINE_POINT" ]; then echo "$READLINE_LINE" else
But after that, we need to programmatically move the current position to the point in the command history so that we can proceed with the subsequent commands.
thanks. as for the second ctrl-o
and beyond, I suspect it's some bash internal keeping track of the history index, that is reset on every use of ctrl-r
/ctrl-o
, for otherwise, bash doesn't have necessary info to be smart enough to differentiate the case where a command is prepared by previous ctrl-o
vs. the case when the same command is typed up. without an internal index, bash would also have trouble going back to the correct history point based on a command modified from previous ctrl-o
result.
I am guessing this might be the internal state. if you can somehow call rl_operate_and_get_next
for the job, maybe you can ride on bash behavior for free? I am not sure if it's doable inside fzf, just some ideas.
+1 I was looking for this... Yep it will be very helpful, thanks!
Also, at the very least it should be possible with fzf-tmux while using popup window, as fzf can send keys to the "current pane" to execute the command...
+1 for me as well. Long ago, when I first learned about CTRL+R in general, my life improved vastly. Then, years later, when I learned about CTRL+O's enhancement of CTRL+R, my life again improved vastly. Then a few years ago I learned about fzf and my life improved vastly.
Then when I tried my typical CTRL+O sequences and that fzf didn't support it, I was saddened. I'm hopeful it can be added back!
man fzf
)Info
Problem / Steps to reproduce
bash
ctrl-o
operate-and-get-next
stops working once I sourcesource ~/.fzf.bash
which is auto generated by fzf and replaces the defaultctrl-r
by the__fzf_history__
function.fzf
ctrl-r
behaviorbash --noprofile --norc
source ~/.fzf.bash
export FZF_CTRL_R_OPTS="--bind=ctrl-o:accept"
, I don't see anaccept-and-execute
event, andexecute(...)
isn't what I want either.cd ~
ls
ctrl-r
cd ~
commandctrl-o
, notice fzf exits and command line is populated withcd ~
, but no execution happens.ctrl-o
again, notice it executescd ~
, then populatescd ~
again.for comparison, here is vanilla bash
ctrl-r
behaviorbash --noprofile --norc
cd ~
ls
ctrl-r
cd ~
commandctrl-o
, notice the history search exits and the command is executed, andls
is auto populated, ready for execution.ctrl-o
will executels
and further chain up remaining next commands, eventualy giving a walking through previous sequence effect. this works even when I modify the commands (except the first one found in history which has to be executed as is byctrl-o
).is there anyway to keep bash original
ctrl-o
behavior? I do like fzf to search history, but thectrl-o
auto sequencing behavior is very useful, e.g., in edit-compile-run cycles. thanks.for reference, here is some explanation about bash behavior, I found it on http://web.mit.edu/gnu/doc/html/features_7.html