-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Ctrl-r history direct output #477
Comments
Haha thanks but I have no idea what's going on with ArchLinux stuff. Anyway the feature you asked is not implemented. It would be ideal if we could "choose" if we want to edit the line or not, like pressing CTRL-X instead of Enter will fire the command immediately. This should be possible in zsh using |
I would love this feature as well - if ctrl-x isn't bound to anything i also think that's an appropriate shortcut. I'll try my hand at adding this. |
For zsh, this is what we can do: diff --git a/shell/key-bindings.zsh b/shell/key-bindings.zsh
index ea65c0c..f1fb720 100644
--- a/shell/key-bindings.zsh
+++ b/shell/key-bindings.zsh
@@ -47,12 +47,18 @@ bindkey '\ec' fzf-cd-widget
fzf-history-widget() {
local selected num
setopt localoptions noglobsubst pipefail
- selected=( $(fc -l 1 | eval "$(__fzfcmd) +s --tac +m -n2..,.. --tiebreak=index --toggle-sort=ctrl-r $FZF_CTRL_R_OPTS -q ${(q)LBUFFER}") )
+ selected=( $(fc -l 1 | eval "$(__fzfcmd) +s --tac +m -n2..,.. --tiebreak=index --toggle-sort=ctrl-r --expect=ctrl-x $FZF_CTRL_R_OPTS -q ${(q)LBUFFER}") )
local ret=$?
if [ -n "$selected" ]; then
+ local accept=0
+ if [[ $selected[1] = ctrl-x ]]; then
+ accept=1
+ shift selected
+ fi
num=$selected[1]
if [ -n "$num" ]; then
zle vi-fetch-history -n $num
+ [[ $accept = 1 ]] && zle accept-line
fi
fi
zle redisplay but I couldn't find a solution for bash. |
@junegunn is it possible to swap |
@bananatranada If you want to set it up for yourself, just changing |
Having used zaw history, I prefer Ctrl-E to select for editing, and Enter to run directly. diff --git i/shell/key-bindings.zsh w/shell/key-bindings.zsh
index 6aacc7e..5b24df2 100644
--- i/shell/key-bindings.zsh
+++ w/shell/key-bindings.zsh
@@ -68,12 +68,18 @@ fzf-history-widget() {
local selected num
setopt localoptions noglobsubst noposixbuiltins pipefail 2> /dev/null
selected=( $(fc -rl 1 |
- FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} $FZF_DEFAULT_OPTS -n2..,.. --tiebreak=index --bind=ctrl-r:toggle-sort $FZF_CTRL_R_OPTS --query=${(qqq)LBUFFER} +m" $(__fzfcmd)) )
+ FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} $FZF_DEFAULT_OPTS -n2..,.. --tiebreak=index --bind=ctrl-r:toggle-sort --expect=ctrl-e $FZF_CTRL_R_OPTS --query=${(qqq)LBUFFER} +m" $(__fzfcmd)) )
local ret=$?
if [ -n "$selected" ]; then
+ local accept=0
+ if [[ $selected[1] = ctrl-e ]]; then
+ accept=1
+ shift selected
+ fi
num=$selected[1]
if [ -n "$num" ]; then
zle vi-fetch-history -n $num
+ [[ $accept = 0 ]] && zle accept-line
fi
fi
zle reset-prompt |
See #1492. |
Personally I prefer to always accept by default on "Enter" while I'd instead just select the item on prompt on tab (or maybe on side rows), so previous ideas applies with something like: diff --git a/shell/key-bindings.zsh b/shell/key-bindings.zsh
index 74ce9b7..f18ac5b 100755
--- a/shell/key-bindings.zsh
+++ b/shell/key-bindings.zsh
@@ -101,12 +101,18 @@ fzf-history-widget() {
local selected num
setopt localoptions noglobsubst noposixbuiltins pipefail no_aliases 2> /dev/null
selected=( $(fc -rl 1 | perl -ne 'print if !$seen{(/^\s*[0-9]+\s+(.*)/, $1)}++' |
- FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} $FZF_DEFAULT_OPTS -n2..,.. --tiebreak=index --bind=ctrl-r:toggle-sort $FZF_CTRL_R_OPTS --query=${(qqq)LBUFFER} +m" $(__fzfcmd)) )
+ FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} $FZF_DEFAULT_OPTS -n2..,.. --tiebreak=index --bind=ctrl-r:toggle-sort --expect=tab $FZF_CTRL_R_OPTS --query=${(qqq)LBUFFER} +m" $(__fzfcmd)) )
local ret=$?
if [ -n "$selected" ]; then
+ local select=0
+ if [[ $selected[1] == tab ]]; then
+ select=1
+ shift selected
+ fi
num=$selected[1]
if [ -n "$num" ]; then
zle vi-fetch-history -n $num
+ [[ $select == 0 ]] && zle accept-line
fi
fi
zle reset-prompt |
If you want to edit the command before execution, press Ctrl-E instead of Enter when selecting the entry. Taken from: junegunn#477
If you want to edit the command before execution, press Ctrl-E instead of Enter when selecting the entry. Taken from: junegunn#477
@junegunn fwiw - loads of people seem to want this functionality. How would you feel about landing the ZSH version to |
With the current fzf release 0.45.0, the workarounds presented here don't work because the logic in the selection has changed. I tried a couple of changes but could not get it done, can anyone help out? |
The diff below is based on the current version1, pressing ⌃ Control + X should allow the explanation# Ensure that the matched regex is assigned to the 'MATCH' variable, not 'BASH_REMATCH'.
no_bash_rematch
# Set 'ctrl-x' to complete 'fzf'.
--expect=ctrl-x
# This line checks if only one line is returned. If so, it means that the user either used the 'ctrl-x' key or the 'accept-or-print-query' action on an empty list.
# Please note that the use of the '--print-query' flag is not covered in this diff.
[[ $(sed -n '$=' <<<$selected) -eq 1 ]]
# This line removes the first line and applies a regex to the rest. The result will be automatically assigned to 'MATCH'.
# See regex discussion: https://github.com/junegunn/fzf/issues/3591
[[ $(sed '1d' <<<$selected) =~ ^[[:space:]]*[[:digit:]]+ ]]
# This line accepts the line only if the first line was 'ctrl-x'.
[[ $(sed 'q' <<<$selected) == "ctrl-x" ]] && zle accept-line --- a/shell/key-bindings.zsh
+++ b/shell/key-bindings.zsh
@@ -96,17 +96,17 @@ bindkey -M viins '\ec' fzf-cd-widget
# CTRL-R - Paste the selected command from history into the command line
fzf-history-widget() {
- local selected num
- setopt localoptions noglobsubst noposixbuiltins pipefail no_aliases 2> /dev/null
+ local selected
+ setopt localoptions noglobsubst noposixbuiltins pipefail no_aliases no_bash_rematch 2> /dev/null
selected="$(fc -rl 1 | awk '{ cmd=$0; sub(/^[ \t]*[0-9]+\**[ \t]+/, "", cmd); if (!seen[cmd]++) print $0 }' |
- FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} ${FZF_DEFAULT_OPTS-} -n2..,.. --scheme=history --bind=ctrl-r:toggle-sort,ctrl-z:ignore ${FZF_CTRL_R_OPTS-} --query=${(qqq)LBUFFER} +m" $(__fzfcmd))"
+ FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} ${FZF_DEFAULT_OPTS-} -n2..,.. --scheme=history --bind=ctrl-r:toggle-sort,ctrl-z:ignore ${FZF_CTRL_R_OPTS-} --query=${(qqq)LBUFFER} --expect=ctrl-x +m" $(__fzfcmd))"
local ret=$?
- if [ -n "$selected" ]; then
- num=$(awk '{print $1}' <<< "$selected")
- if [[ "$num" =~ '^[1-9][0-9]*\*?$' ]]; then
- zle vi-fetch-history -n ${num%\*}
- else # selected is a custom query, not from history
- LBUFFER="$selected"
+ if [[ -n $selected ]]; then
+ if [[ $(sed -n '$=' <<<"$selected") -eq 1 ]]; then
+ [[ $selected != "ctrl-x" ]] && LBUFFER="$selected"
+ elif [[ $(sed '1d' <<<"$selected") =~ ^[[:space:]]*[[:digit:]]+ ]]; then
+ zle vi-fetch-history -n "$MATCH"
+ [[ $(sed 'q' <<<"$selected") == "ctrl-x" ]] && zle accept-line
fi
fi
zle reset-prompt Footnotes |
A bit off topic here and I don't know if this is even a valid question for fzf. |
Thanks @LangLangBart for the diff and the explanation in #477 (comment) ❤️ Like in #477 (comment), I like the immediate execution of the command to be the default, and to edit the prompt by a shortcut (e.g. You can adapt @LangLangBart's code snippet like this: selected="$(fc -rl 1 | awk '{ cmd=$0; sub(/^[ \t]*[0-9]+\**[ \t]+/, "", cmd); if (!seen[cmd]++) print $0 }' |
- FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} ${FZF_DEFAULT_OPTS-} -n2..,.. --scheme=history --bind=ctrl-r:toggle-sort,ctrl-z:ignore ${FZF_CTRL_R_OPTS-} --query=${(qqq)LBUFFER} --expect=ctrl-x +m" $(__fzfcmd))"
+ FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} ${FZF_DEFAULT_OPTS-} -n2..,.. --scheme=history --bind=ctrl-r:toggle-sort,ctrl-z:ignore ${FZF_CTRL_R_OPTS-} --query=${(qqq)LBUFFER} --expect=ctrl-e +m" $(__fzfcmd))"
local ret=$?
if [[ $(sed -n '$=' <<<"$selected") -eq 1 ]]; then
- [[ $selected != "ctrl-x" ]] && LBUFFER="$selected"
+ [[ $selected == "ctrl-e" ]] && LBUFFER="$selected"
elif [[ $(sed '1d' <<<"$selected") =~ ^[[:space:]]*[[:digit:]]+ ]]; then
zle vi-fetch-history -n "$MATCH"
- [[ $(sed 'q' <<<"$selected") == "ctrl-x" ]] && zle accept-line
+ [[ $(sed 'q' <<<"$selected") != "ctrl-e" ]] && zle accept-line
fi |
May I request a noob summary? There's a lot of diffs flying around here and I'm not sure what I am supposed to do with them? Essentially I want to be able to press Enter to execute a selected command in the history and Tab to copy that command to the command line. How do I achieve this? |
@mbhall88 You can do what junegunn suggested in the previous comment, replacing
|
I'm using the latest version (0.53.0). What I was asking though is what am I supposed to do with the diff? For instance, I installed Am I supposed to add that function to my zsh profile and then apply the diff to it or something? Sorry for asking the silly question, just thought there might be some others like me who aren't quite sure what they're supposed to do. |
@mbhall88 I didn't expect you to install it from the precompiled binary. 😂 There was no "Binary releases" section in the readme before. It seems "Setting up shell integration" section in the readme has been changed and if you follow the instruction, the script for key bindings and completion would be generated and loaded whenever you launch a new shell. However, when this issue was open, the scripts should be sourced from the Note
What the comments here are saying is to apply the diff to the scripts in the # Change the working directory
# I supposed you downloaded the source code here. If you used a package manager, try `which fzf`.
cd fzf-0.53.0
# Save the patch to a file (`key-bindings.patch` for example).
# Apply the patch.
git apply key-bindings.patch
# Execute the install script.
./install Meanwhile, I decided to stay with the version 0.43.0 because:
... and I also hope this feature is supported officially. |
Please find here the current patch I'm using for version 0.53.0, adjusted to use Enter to execute the selected command and CTRL-E to edit the command --- fzf-0.53.0-key-bindings.zsh.ORIG 2024-07-05 07:31:11.836273594 +0200
+++ fzf-0.53.0-key-bindings.zsh 2024-07-05 07:46:33.741715361 +0200
@@ -106,26 +106,27 @@
# CTRL-R - Paste the selected command from history into the command line
fzf-history-widget() {
- local selected num
- setopt localoptions noglobsubst noposixbuiltins pipefail no_aliases 2> /dev/null
+ local selected
+ setopt localoptions noglobsubst noposixbuiltins pipefail no_aliases no_bash_rematch 2> /dev/null
# Ensure the associative history array, which maps event numbers to the full
# history lines, is loaded, and that Perl is installed for multi-line output.
if zmodload -F zsh/parameter p:history 2>/dev/null && (( ${#commands[perl]} )); then
selected="$(printf '%1$s\t%2$s\000' "${(vk)history[@]}" |
perl -0 -ne 'if (!$seen{(/^\s*[0-9]+\**\s+(.*)/, $1)}++) { s/\n/\n\t/gm; print; }' |
- FZF_DEFAULT_OPTS=$(__fzf_defaults "" "-n2..,.. --scheme=history --bind=ctrl-r:toggle-sort --highlight-line ${FZF_CTRL_R_OPTS-} --query=${(qqq)LBUFFER} +m --read0") \
+ FZF_DEFAULT_OPTS=$(__fzf_defaults "" "-n2..,.. --scheme=history --bind=ctrl-r:toggle-sort --highlight-line ${FZF_CTRL_R_OPTS-} --query=${(qqq)LBUFFER} --expect=ctrl-e +m --read0") \
FZF_DEFAULT_OPTS_FILE='' $(__fzfcmd))"
else
selected="$(fc -rl 1 | awk '{ cmd=$0; sub(/^[ \t]*[0-9]+\**[ \t]+/, "", cmd); if (!seen[cmd]++) print $0 }' |
- FZF_DEFAULT_OPTS=$(__fzf_defaults "" "-n2..,.. --scheme=history --bind=ctrl-r:toggle-sort --highlight-line ${FZF_CTRL_R_OPTS-} --query=${(qqq)LBUFFER} +m") \
+ FZF_DEFAULT_OPTS=$(__fzf_defaults "" "-n2..,.. --scheme=history --bind=ctrl-r:toggle-sort --highlight-line ${FZF_CTRL_R_OPTS-} --query=${(qqq)LBUFFER} --expect=ctrl-e +m") \
FZF_DEFAULT_OPTS_FILE='' $(__fzfcmd))"
fi
local ret=$?
- if [ -n "$selected" ]; then
- if num=$(awk '{print $1; exit}' <<< "$selected" | grep -o '^[1-9][0-9]*'); then
- zle vi-fetch-history -n $num
- else # selected is a custom query, not from history
- LBUFFER="$selected"
+ if [[ -n $selected ]]; then
+ if [[ $(sed -n '$=' <<<"$selected") -eq 1 ]]; then
+ [[ $selected == "ctrl-e" ]] && LBUFFER="$selected"
+ elif [[ $(sed '1d' <<<"$selected") =~ ^[[:space:]]*[[:digit:]]+ ]]; then
+ zle vi-fetch-history -n "$MATCH"
+ [[ $(sed 'q' <<<"$selected") != "ctrl-e" ]] && zle accept-line
fi
fi
zle reset-prompt Slowly thinking to pin it to this version, not to have to adjust and reapply the patch every time a new version is released ;-) |
Firs congratulations for make it to ArchLinux Community repo and second, I know I see that answer, but I did not make a mark (so mad at myself). How to make _ctrl-r_ commandline output without option to edit command and just directly start command.
Thank you and all the best, Boris
The text was updated successfully, but these errors were encountered: