Edit commands/pipelines with fzf, and view live output while editing.
This is a rewrite of Daniel Grey’s fantastic fzrepl written for zsh instead of bash. This version uses the selections window for command line args instead of input. It gives you quick access to shell history, stored arguments, and help pages, so you have no excuse for getting the syntax wrong for a particular command. This makes it very useful for data processing pipelines with tools such as sed, awk & miller which, though powerful, can be hard to remember how to use.
fzfrepl -c "CMD" [OPTION]... [FILE]
Interactively edit stdin using stream filters like awk, sed, jq, mlr. Uses STDIN if no FILE is supplied.
OPTIONS:
-c, --cmd CMDSTR
command string to filter input ({q} & {f} are replaced by query string & SOURCES)
-q, --query QUERY
default query string to use (i.e. initial prompt input)
-o, --output [o|q]
output the command output (o) or just the query string (q)
(by default the command with embedded query string is output)
-H1, --helpcmd1 CMDSTR
command for displaying help when alt-h is pressed (default: “CMD –help”)
-H2, --helpcmd2 CMDSTR
command for displaying more help when ctrl-h is pressed (default: “man CMD”)
-r, --remove REGEX
regexp for filtering out shell history items (e.g. ‘-i’ for sed)
-d, --header
show filename, size & permissions at top of preview window
-n, --numlines N
No. of lines piped to preview command (all by default). Useful for large files.
-N, --no-file-subst
don’t replace {s} with SOURCE(s)
-i, --ignore-stdin
ignore any input from STDIN (STDIN is also ignored if there are SOURCE args)
-h, --help
show this help text
Three different selection menus are available via keybindings alt-1/2/3, which can be
altered by setting the $FZFREPL_MENU1/2/3 variables to files containing menu entries.
The default values for these menus are as follows:
$FZFREPL_MENU1 (alt-1) is set to $FZFREPL_HISTORY which should be a file to load/save query history
for the current command.
$FZFREPL_MENU2 (alt-2) is set to ${FZFREPL_DIR}/CMD_queries which is used to save the current query
when ctrl-s is pressed (this can be changed by setting $FZFREPL_SAVE_MENU).
$FZFREPL_MENU3 (alt-3) is set to a temporary file in which items extracted from shell history are
saved.
On startup $FZFREPL_MENU1 is loaded. Pressing ctrl-s will save a query to $FZFREPL_MENU2 (reload it
to see the saved query), and when a query is accepted (by pressing ctrl-j) it is save to $FZFREPL_HISTORY.
Output files are saved to $FZFREPL_DATADIR/fzfrepl-$$-CMD.out, and the command line is saved to
$FZFREPL_DATADIR/fzfrepl-$$-CMD.cmd (where $$ is the PID, and CMD is the command name). These files
are used by recursive calls to fzfrepl via fzftoolmenu (alt-j/k).
To alter fzf options set $FZFREPL_DEFAULT_OPTS, e.g. FZFREPL_DEFAULT_OPTS="--preview-window=down:50%
”
See below for more info about these variables.
- Test glob patterns interactively: $ FZFREPL_PRECMD=”setopt extendedglob” fzfrepl -c “ls {q}” -N -i -H1 “man zshexpn”
- Test parameter expansion interactively: $ fzfrepl -c “print - {q}” -N -i -H1 “man zshexpn”
- Test awk commands interactively: $ echo ‘foo bar’ | fzfrepl -o o -c ‘awk {q}’ -q ‘{print}’
- Test sed commands interactively: $ echo ‘hello world’ | fzfrepl -o o -q p ‘sed -n {q}’
- Test grep commands interactively: $ fzfrepl -c ‘grep {q} {s}’ /path/to/files/*.txt
- Test sqlite3 commands interatively, and then test mlr stats2 commands interactively on the output of sqlite3: $ fzfrepl -o o -c ‘sqlite3 -csv {s} {q}’ mydatabase.db | mlr -o -c ‘mlr {q}’ -q ‘–csv stats2’
- Test feedgnuplot options interactively: $ seq 5 | awk ‘{print 2*$1,$1*$1}’ | fzfrepl -c “feedgnuplot –terminal \"dumb ${COLUMNS},${LINES}\" –exit {q}”
Here is a more advanced example which is useful for building/debugging ffmpeg filtergraphs. You need to have ffmpeg, graph2dot and graph-easy installed. The preview window will display a diagram of the filtergraph entered at the prompt (the current query string). You can store useful filtergraphs in the ~/.fzfrepl/ffmpeg_filters file, and browse them by pressing Alt+2:
FZFREPL_HISTORY=~/.fzfrepl/ffmpeg_filters_history FZFREPL_MENU2=~/.fzfrepl/ffmpeg_filters fzfrepl -i -H1 “ffmpeg -filters” -H2 “man ffmpeg-filters” -o q -c “echo "{q}"|graph2dot|graph-easy –boxart”
RET | copy current selection to prompt |
ctrl-t | toggle preview window (to reveal the full header which lists keybindings) |
ctrl-/ | rotate preview window (between vertical and horizontal positions) |
ctrl-j | accept query string and print command line or its output (if -o option was used) |
alt-j | pipe output to fzftoolmenu (if available). See pipelines section below. |
alt-k | pipe output to fzftoolmenu (if available), and quit. See pipelines section below. |
alt-w | Copy query string to clipboard |
ctrl-k | kill line |
home | move pointer back to first selection |
alt-1 | Load 1st selections menu from $FZFREPL_MENU1 (set to $FZFREPL_HISTORY by default) |
alt-2 | Load 2nd selections menu from $FZFREPL_MENU2 (set to ~/.fzfrepl/CMD_menu by default) |
alt-3 | Load 3rd selections menu from $FZFREPL_MENU3 (set to file containing filtered shell history by default) |
ctrl-s | Save current query string into the file at $FZFREPL_SAVE_MENU |
alt-h | Show main help page (see the -H1 option in the usage section) |
ctrl-h | Show alternate help page (see the -H2 option in the usage section) |
ctrl-v | View full input with $PAGER |
alt-v | View output with $PAGER (using all input lines, and full screen) |
$FZFREPL_DIR | Directory used by default for history & stored menu files (default: ~/.fzfrepl) |
$FZFREPL_DATADIR | Directory used for storing input, output & command files (default /tmp) |
$FZFREPL_HISTORY | File containing history of input lines for current base command (default: $FZFREPL_DIR/CMD_history) |
$FZFREPL_DEFAULT_OPTS | Options for fzf which override or add to the default ones |
$FZFREPL_HEADER | Set this to change the header text displayed above/below the prompt |
$FZFREPL_MENU1 | File containing entries for default menu (alt-1). Default value is $FZFREPL_HISTORY |
$FZFREPL_MENU2 | File containing entries for menu 2 (alt-2). Default value is ${FZFREPL_DIR}/CMD_queries where CMD is the base command |
$FZFREPL_MENU3 | File containing entries for menu 3 (alt-3). Default value is temp file populated with items extracted from shell history |
$FZFREPL_SAVE_MENU | File where queries are saved when ctrl-s is pressed, by default this is set to $FZFREPL_MENU2 |
$FZFREPL_PRECMD | Command string to be run before evaluating CMDSTR, e.g. for setting shell options. This does not take effect if input is piped to STDIN |
Note: $FZF_DEFAULT_OPTS are applied first, followed by the fzfrepl specific options defined in the source file, followed by $FZFREPL_DEFAULT_OPTS. The following options cannot be overridden: –query, –sync, –ansi, –print-query, –history, –preview
You can use fzfrepl in a pipeline; it accepts input on STDIN, and sends output to STDOUT if the “-o o” option is used. Alternatively if you have fzftool installed you can create a pipeline which uses fzfrepl at each stage. If you press alt-j/k you will be prompted for the next command in the pipeline using fzftool, which could be another invocation of fzfrepl from which you could again press alt-j/k to extend the pipeline further. At each stage the output file will be saved to ${FZFREPL_DATADIR}/fzfrepl-$$-CMD.out where $$ is the PID of the command (also displayed to the left of the fzfrepl query prompt), and CMD is the base command name. Also the pipeline of fzfrepl commands that led upto the current invocation will be saved to ${FZFREPL_DATADIR}/fzfrepl-$$-CMD.cmd The input to the current fzfrepl invocation is stored in ${FZFREPL_DATADIR}/fzfrepl-$$-CMD.in
- For commands such as sqlite3 where the filename comes before the other arguments you can use “{s}” in the command string which will be replaced by the FILE arg.
- When used in conjuction with fzftool you can save the output by first viewing it with a pager (e.g. less), and then using the pagers facility to save its input to a file.
- Store fzfrepl commands in global aliases (which can be used in a pipeline) so you don’t have to memorize them,
examples:
- alias -g fzfglob=’${~${fzfglob::=$(fzfrepl -o q -c “ls {q}” -N -i -H1 “man zshexpn”|sed “s/ \# .*\$//”)}}’ (for finding & testing glob patterns)
- alias -g mlrfzf ‘fzfrepl -c “mlr {q}” -q ” –csv”’ (for processing csv files)
- For large text/csv files use the –numlines option to limit the number of lines used for the preview so you don’t have to wait ages for it to refresh. This will not affect the overal output (seen by pressing alt-v). Note however that this option is not useful for json, xml or other filetypes that need to be parsed in their entirety.
- It is tempting put extra quotes around the {q} in the command string, e.g. -c “awk ‘{q}’”. However this causes problems if you want to use quotes within the query itself. It’s usually better to just add the required quotes at the prompt.
- If your initial query string starts with a -, put a space before it on the command line, e.g. -q ’ –csv’ so that it doesn’t get mistaken for another fzfrepl option by the option parsing code.
- If both the fzf prompt and query selections list are empty no preview will be generated. In this case you can type a single space to generate a preview.
- Lines of the $FZFREPL_MENU2 file can have comments appended to help you remember what they do (and make searching the selections window easier). However you may need to delete any comment before accepting the command line or it may comment out the input redirection. For certain command such as awk & sed you can avoid this problem by keeping the comment within the quotes of the command, e.g: sed -n “1,10p #print first 10 lines”. Press ctrl-s to store the current query string into the $FZFREPL_MENU2 file.
- If you prefer to always see all available selections (i.e. don’t filter them with the query string) you can set the value of $FZFREPL_DEFAULT_OPTS to include ‘–phony’.
Copyright (C) 2016 Daniel F Gray DanielFGray@gmail.com, 2021 Joe Bloggs vapniks@yahoo.com
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.