hotkeys.ini and the Hotkey Configurator bind commands to keys. keymap.ini
works one layer below: it substitutes one key for another as the keystroke
arrives, before anything in f4 has looked at it. Two problems need that layer.
Before reaching for either file: Ctrl+Shift+P opens the command palette,
which finds any command by name and shows the key it currently sits on. On a
legacy terminal that cannot distinguish Ctrl+Shift+letter from Ctrl+letter,
use the built-in Ctrl+Alt+P fallback — and in an X11 session the real
Ctrl+Shift+P is taken from the X server instead, so it works there even on a
terminal that cannot encode it (see TTY|Xi). When a multiplexer has eaten one
chord, or a laptop has no F5, running the command from the palette is usually
faster than writing a rule, and it is the only thing needed when the key was
never the point.
A terminal multiplexer takes the chord first. tmux, zellij, GNU screen and
dvtm own their prefixes upstream of f4, so those keys never reach the
application at all: Ctrl+B (tmux), Ctrl+A (screen), Ctrl+P, Ctrl+T,
Ctrl+N, Ctrl+O, Ctrl+G, Ctrl+Q (zellij). Several of them are f4
defaults — Ctrl+B toggles the key bar, Ctrl+O the panels, Ctrl+P the
passive panel.
The keyboard has no F-row. Many laptops and compact boards reach F1-F12
only through a Fn layer, and hotkeys.ini would need one binding per key per
modifier row per area to work around that.
A rule solves both in one line, and it also covers keys hotkeys.ini cannot
reach at all: framework shortcuts such as Ctrl+Tab, dialog and menu keys,
and the editor's own bindings.
Far Manager's standard Ctrl+Numpad + and Ctrl+Numpad - commands select and
deselect files with the same extension as the file under the cursor (see the
official panel-command help).
f4 also binds Ctrl+= and Ctrl+- on the main keyboard so this operation is
available on laptops and compact keyboards without a numeric keypad.
Extension matching ignores case and uses the last extension; virtual entries
marked NoExtension join extensionless files. With a folder under the cursor,
the command marks or unmarks folders instead. The parent entry is never marked,
and autofilter-hidden rows are left alone. Ctrl+M restores the previous marks.
Ctrl+Shift+= and Ctrl+Shift+- open the selection and deselection mask dialogs;
Alt+= inverts selection. Numpad 5 opens the viewer with Num Lock on or off,
while F3 remains the primary viewer shortcut. All of these are configurable
panel actions. OEM keys use names such as CtrlVK_BB and CtrlVK_BD in
hotkeys.ini, and the UI displays them as Ctrl+= and Ctrl+-.
Ctrl+Enter (Panel.InsertFileName) inserts the current filename into the
command line followed by a space, ready for the next argument. Shell quoting
is applied to the filename only; the trailing space stays outside the quotes.
No leading space is inserted, so an already typed path prefix stays attached
to the filename. While Fast Find is active, Ctrl+Enter still finds the next
match instead of inserting a filename.
keymap.ini lives in the profile directory next to hotkeys.ini
(~/.config/f4, %APPDATA%\f4, or the portable profile). f4 writes a
commented sample on first start; every line in it is inert until you remove a
semicolon.
[Common]
CtrlAltO=CtrlOThe left side is the key you press, the right side is the key f4 sees instead.
Spell both the way the Hotkey Configurator (Options > Hotkey Configuration)
shows them: Ctrl, Alt, Shift and RCtrl prefixes, then the key (A,
5, F7, Enter, Ins, PgDn, VK_DC). Neither case nor the order of the
prefixes matters, so ShiftAlt1, AltShift1 and altshift1 are one rule.
Everything after a ; or a # is a note rather than part of the rule, on
either side of the =. A marker only starts a note at the beginning of a
field or after whitespace, so Alt;=F1 still binds the semicolon key.
A rule must sit under a section header. The sample file ships with a live
[Common] line at the top for that reason — uncommenting a rule under a still
commented-out ;[Common] would leave it in no section, and it would be
ignored. Section names are the areas of hotkeys.ini — Shell, Terminal,
Editor, Viewer, Dialog, Menu, Disks — and Common applies to all of
them. An area rule wins over a Common one.
A trailing * on both sides rewrites the leading modifiers of every key at
once, which is the compact way to move f4 off a prefix the multiplexer wants:
[Common]
CtrlAlt*=Ctrl*Now Ctrl+Alt+O reaches f4 as Ctrl+O, Ctrl+Alt+F5 as Ctrl+F5, and so on,
while the plain Ctrl chords keep working for whatever the multiplexer leaves
alone. Longer source prefixes are matched first, so CtrlAltShift* wins over
CtrlAlt*. Exact rules always win over wildcard ones.
A * on one side only is ignored: Ctrl*=F1 would collapse every Ctrl
chord onto a single key, and CtrlB=Ctrl* names no key at all.
[Common]
Alt1=F1
Alt2=F2
Alt0=F10
Alt-=F11
AltShift-=F12
AltShift1=ShiftF1The key bar follows: its modifier row is re-derived from the substituted key,
so Alt+1 shows and runs the plain F1 command rather than the Alt+F1 one.
= cannot be named on the left-hand side: the first = of a line separates
the two sides of the rule, so that one key has to stay as it is.
A terminal that speaks neither the kitty keyboard protocol nor win32 input
mode cannot report Shift separately for a printable key. Shift+1 arrives as
a bare !, Alt+Shift+1 as Alt!; under the kitty protocol the same chords
come back as Shift! and AltShift!, and a backend that reports virtual keys
calls them Shift1 and AltShift1. Since multiplexers routinely strip the
protocol negotiation, the spelling can change underneath a file that used to
work.
f4 folds a shifted character back onto the key that produced it, so all of
those name the same rule. Write the Shift1 ... Shift0 form: it says which
key you meant, and it does not collide with the wildcard *.
Ctrl does nothing to a digit in a plain terminal — Ctrl+1, Alt+1 and
Ctrl+Alt+1 produce the same bytes. A CtrlAlt0=F11 rule therefore cannot be
told apart from Alt0=F10, and whichever of the two f4 sees first wins; the
symptom is a key that appears to do the other rule's job. The kitty keyboard
protocol and win32 input mode do distinguish them, but a multiplexer in
between usually removes that. Give such a rule a letter or a punctuation key
instead, or run the command from the palette.
- Substitution happens once. The result is never fed back through the
table, so
AltO=CtrlOplusCtrlO=F9makesAlt+OaCtrl+O, not anF9. Rules cannot chain or loop. - A foreign program keeps its keys. While the panels are hidden and a
full-screen or busy child owns the terminal (vim, htop, a running command),
remapping is suspended and every key is forwarded verbatim — the same
handover the
NoAltScreenAppandNoTerminalApphotkey conditions make. - Right Ctrl follows Ctrl. As in Far, a rule written for
Ctrlalso answers Right Ctrl unless anRCtrlrule says otherwise. - Bare modifiers are untouched. Pressing Ctrl alone is not a chord.
macOS needs the same layer for a different reason: Cmd and Opt carry the
editing chords there, and Far gives several of those keys other meanings. That
one is built in and does not have to be written out by hand — see
Mac keyboard mode. A rule here still wins over it, so a key you
have remapped yourself keeps what you gave it.
keymap.ini swaps keys, not commands, so giving f4 a layout that matches
muscle memory from Total Commander, an older Far build, or anything else is
the same recipe regardless of where the habit comes from: for every command
whose old key differs from f4's, find the key f4 already has it on and add
one line teaching the old key to reach it too.
Ctrl+Shift+P is the fastest way to find that key: it looks commands up by
name and shows the chord currently bound to each one. Say your fingers
expect a chord for some command — open the palette, find that command by
name, note the key it already answers to in f4, and add a line teaching your
old chord to reach it too:
[Shell]
<your old chord>=<the key the palette showed>For "Swap Panels", for instance, f4's own default already happens to be
Ctrl+U, so nothing would be needed there — but the same one-line recipe
covers whichever commands your particular habit does expect somewhere else.
Repeat for every other command your muscle memory expects on a different
key. There is no separate "Total Commander preset" to keep in sync here:
each command keeps working under its own key exactly as before, and this
file only teaches the old chord to reach it too — the same mechanism as the
multiplexer and F-row workarounds earlier in this document, just aimed at a
different habit. See also Options > Hotkey Configuration in the next
section if what you actually want is to give a command a new key rather
than have an old one reach its current one.
Rebinding a command is still the better tool when a command is what you want
to move: Options > Hotkey Configuration lists every command with its key,
and its Assign button waits for you to press the new chord and writes
hotkeys.ini for you. Menus and help then show the shortcut you chose.
Reach for keymap.ini when the key itself has to change — one modifier for
everything, an F-row that does not exist, or a key that belongs to a dialog
rather than to a command.
And reach for neither when you only need the command once: Ctrl+Shift+P
runs it by name.