Hotkeys and “:” commands
Quick access to commands and views
TLDR: you can assign hotkeys to commands and views. Hotkeys are keys that
start with ctrl-, alt-, shift-, or function keys f1 to f12, or the
special key del. See the “AVAILABLE KEYS” section in the fzf man page for
more on this. You can also assign a colon-command short form for each
command.
Quick examples (details in the next 3 sections):
: key=alt-8 files modified in last 8 hours ; fd -H -tf --newer 8hours
You press the hotkey alt-8, and the magic happens :) alt-8 is recognised by fzf so it works directly. No need to hit ctrl-v, pick this line, and hit enter.
: key=:mr recursive, mtime descending, files only ; find -type f -printf '%TF.%TT\t%p\n' | sort -k1r | cut -f2
You type the colon-command :mr and hit enter.
But both hotkey and colon-command mechanisms first require that you know how to add a description to a command. So here goes…
Adding a description to a command
When you have too many commands that may look similar, it may be easier to select using a description. For example, take this command:
git log --name-only --format=%n | CDUP=(git rev-parse --show-cdup) perl -lne 'print if /./ and s(^)($ENV{CDUP}) and -f and not $seen{$_}++'
Offhand, it’s not obvious that this shows you the files in “most recently committed” order.
But add a description:
: git - files by most recent commit ; git log --name-only --format=%n | CDUP=(git rev-parse --show-cdup) perl -lne 'print if /./ and s(^)($ENV{CDUP}) and -f and not $seen{$_}++'
and now it’s not only easier to remember, it’s much easier to search using fzf (on my set of commands, “rec com” gets me this command straight away).
There’s no special trick here. All 3 major shells accept “:” as a kind of
no-op command that does nothing, even if it has arguments, so we just use
that. The “;” at the end of the description leads to the command that
actually gets executed. (You can’t use a “#” instead of the :; that would
make the entire line a comment).
Here’s another one: take each tar file and extract its contents into its own
directory. This examples also shows multiple commands chained, including
setting local variables. The %c ensures that it runs once per tar file
selected.
: unpack tar file into its own directory; set -l b (path basename -E %c); mkdir $b; tar -C $b -xvf %c
Adding a hotkey
So now you can see how we specify the hotkey:
: key=alt-8 files modified in last 8 hours ; fd -H -tf --newer 8hours
To the (fish) shell executing the command, the key=alt-8 is just part of our
“description”. But fzfm parses it as an instruction to assign that hotkey
to that command.
You can add hotkeys to either of the two history files, but you can’t add the same hotkey to both files.
Other examples from the defaults that come with fzfm:
# run (ctrl-r) examples
: key=del delete files ; ls -ald %f; pause "remove these files?" && rm -rf %f
: key=alt-up cd up ; cd ..
: key=alt-left cd prev dir ; prevd
: key=alt-right cd next dir ; nextd
Notice how you get a chance to eyeball the files/dirs being deleted before you hit enter. (Or hit n and enter to abort the rm).
And I particularly like how the alt-left and alt-right mimic the fish shell’s own shortcuts (and using the same keys too!)
The next section is about adding colon-commands, but you should also see hotkeys vs colon-commands for when to use which.
Adding a “colon-command” shortcut
Hotkeys are fine, and there’s no shortage of them; the fzf documentation indicates there are over a hundred key-combinations available, even if you don’t count common navigation keys and ctrl-c and so on.
But if you add more than a dozen hotkeys, you may find it difficult to remember them.
So, time to borrow something from vim and create our own :foo commands!
# view (ctrl-v) example
: key=:s size descending ; fd -d 1 -0 | xargs -0 du -sk | sort -rn | cut -f2
It is hard to say if this is faster than hitting ctrl-r/ctrl-v and picking the correct command to run. That would depend on how many similar commands existed, and how often you used them. For me, this is more deterministic, but YMMV, as they say.
WARNING: The one thing you must remember is
that in this mode, if the command expects a file (i.e., has %c or %f in
it), you have to use TAB to select the file even if you’re just selecting
one file. (If you know how fzf works, you know why this is).
Hotkeys vs colon-commands
When to assign a hotkey, and when to make do with a “colon-command”?
First, reread the warning at the end of the previous section: if the command expects arguments, you need to TAB-select if using a colon-command.
So the general guideline is: if it’s a frequently used command, or the
command expects arguments (i.e., contains %c or %f), give it a hotkey. If
it’s not frequently used, or the command does not expect arguments, give
it a colon command. Example:
# Works like vim's "yy" or "dd", then "p", but note the uppercase.
# You have to hit alt-shift-y/d not just alt-y/d.
: key=alt-Y ; set -U -- fzfm_yyddbuf cp -ai -- (path resolve -- %f)
: key=alt-D ; set -U -- fzfm_yyddbuf mv -i -- (path resolve -- %f)
: key=:p ; test -n "$fzfm_yyddbuf" && ls -ald -- $fzfm_yyddbuf[4..] && pause "$fzfm_yyddbuf[1..2] these files to PWD ?" && $fzfm_yyddbuf .
They’re modelled after vim’s yy/dd/p normal mode commands. The first two (copy/cut) need arguments, so they get hotkeys. The third one (paste) does not, so it gets a colon command, albeit a very short one.
But it’s not a hard and fast rule, and it’s entirely up to you. For example,
I deem chmod to be rare enough that even though it uses arguments, I didn’t
give it a hotkey. But cd .. is frequent enough to get one (and there are
many more such expections if you look in the sample files that get installed
when you first run fzfm).
And finally, commands that are even rarer, don’t get either; you have to hit ctrl-r or ctrl-v and pick them from the list.
Default Commands that come with fzfm
Several commands come with the code, as examples of how to use them. You’ve
seen some of them earlier, with explanations. You can see all of them in the
files cmd_hist and view_hist in the source repo, or, with your own
customisations and modifications, in the same files in ~/.config/fzfm.