Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get output from fzf in the terminal without executing it

Tags:

bash

terminal

fzf

fzf rocks! I want to use it to search bash history. When a match is found, I want it to be placed on the command line, but not executed so I can edit it further. (All of this is in a sourced bash function or script so it has access to my history.)

I have it almost working, but not quite.

This selects the command, but runs it immediately:

eval $(history | "$HOME/bin/fzf" +s | sed 's/ *[0-9]* *//')

This gets it into my clipboard, but when I paste it, it still ends with a blank and a newline so it executes immediately.

history | "$HOME/bin/fzf" +s | sed 's/ *[0-9]* *//' | xclip -se c

I also tried a couple of variations including

history | "$HOME/bin/fzf" +s | sed -e 's/ *[0-9]* *//' -e 's/$//' | xclip -se c

with the same result.

This actually works, but I still have to put it in the clipboard and then manually paste it.

history | "$HOME/bin/fzf" +s | sed -re 's/ *[0-9]* *//' | awk '{printf "%s", $0}' | xclip -se c

How can I do this in one step - without a manual paste?

I thought just leaving off the xclip would do it, but it doesn't work.

like image 844
Joe Avatar asked Jul 06 '17 06:07

Joe


2 Answers

fzf comes ready to install this functionality in fzf's key-bindings.bash mentioned by @sudavid4. The __fzf_history__ function searches bash history interactively using fzf.

In default history handling (though unnecessary with fzf's function), editing after selection is enabled by setting histverify. From man bash:

histverify

If set, and readline is being used, the results of history substitution are not immediately passed to the shell parser. Instead, the resulting line is loaded into the readline editing buffer, allowing further modification.

Finally, bash's builtin fc (learn more with help, not man), supports "Display[ing] or execut[ing] commands from the history list" in addition to the history builtin which focuses on "Display or manipulat[ion of] the history list."


Note also...

fzf's key-bind.bash snippet:

  # CTRL-R - Paste the selected command from history into the command line
  bind -m emacs-standard -x '"\C-r": __fzf_history__'
  bind -m vi-command -x '"\C-r": __fzf_history__'
  bind -m vi-insert -x '"\C-r": __fzf_history__'

A neighboring bash shopt (shell option) with related but different purpose:

histreedit

If set, and readline is being used, a user is given the opportunity to re-edit a failed history substitution.

like image 63
mcint Avatar answered Oct 02 '22 20:10

mcint


In the current fzf version, you can use ctrl-r to do it from the command line. From the readme:

CTRL-R - Paste the selected command from history onto the command-line

like image 38
M Imam Pratama Avatar answered Oct 02 '22 21:10

M Imam Pratama