XeFM is customized through a Python configuration file. On first run XeFM creates it
from a template; edit it to change appearance, behavior, key bindings, and
external-program integration. Every option below is a real attribute of the
config class — see xefm/_config.py for the authoritative, fully-commented
template.
XeFM stores its configuration in:
~/.xefm/config.py
On first run, XeFM creates this file with default settings. You can edit it with any text editor.
# View it
cat ~/.xefm/config.py
# Edit it
vim ~/.xefm/config.py # or: nano / code / your editor of choice
Changes take effect the next time you start XeFM.
You can also edit and apply your config without leaving XeFM. Both actions live under the Tools menu (neither is bound to a key by default):
~/.xefm/config.py in your configured
TEXT_EDITOR, creating it from the template first if needed. With a terminal
editor (e.g. vim) XeFM reloads automatically when you save and quit; with a
GUI editor (e.g. VS Code) XeFM can’t tell when you’re done, so save and then run
Reload Configuration.~/.xefm/config.py from disk and applies it
without opening an editor — handy when you edit the file in a separate window.To bind either action, add it to KEY_BINDINGS:
KEY_BINDINGS = {
'edit_config': ['Y'],
'reload_config': ['Ctrl-R'],
}
Reloading applies live to key bindings, file associations, external programs, favorite directories, confirmation prompts, and the text-editor / diff-tool settings. Themes and post-effects, fonts (desktop mode), the pane-split and log-height ratios, and file-monitoring intervals are read once at startup and only fully apply on the next launch. XeFM logs a reminder after each reload.
If your edited config has a Python error, XeFM logs it and falls back to built-in
defaults rather than crashing; out-of-range values are still applied but logged
as a Config warning:.
These apply in desktop mode (the native macOS / Windows backend); the terminal backend uses your terminal’s font and ignores them.
UI_FONT_NAME = None # proportional face for names/labels (None = bundled/OS default)
MONO_FONT_NAME = None # monospaced face for the aligned grid (None = bundled default)
FONT_SIZE = 12 # point size applied to BOTH faces (8-72)
MONO_FONT_NAME must be a monospaced font; the on-screen grid is derived from its
glyph box. In desktop mode you can also change FONT_SIZE live with Cmd-+ /
Cmd--.
XeFM ships with built-in themes (Dark+, Monokai, Dracula, Nord, Solarized, Gruvbox
Dark, Light+, Solarized Light). Switch at runtime via View → Theme or the T
key; XeFM starts on Dark+ and remembers the last theme across restarts. There is no
COLOR_SCHEME string setting — instead you register your own named themes:
THEMES = {
'Ocean': { # builds on Dark+ by default
'accent': (0, 120, 160),
'background': (18, 26, 32),
},
}
See Color Schemes for the full theme key reference
(including the optional GUI post_effect CRT/phosphor look).
SHOW_HIDDEN_FILES = False # show dotfiles (toggle at runtime with '.')
DEFAULT_LEFT_PANE_RATIO = 0.5 # left pane width as a ratio (0.1 - 0.9)
DEFAULT_LOG_HEIGHT_RATIO = 0.25 # log pane height as a ratio (0.1 - 0.5)
DATE_FORMAT = 'short' # 'short' (YY-MM-DD HH:mm) or 'full' (YYYY-MM-DD HH:mm:ss)
SEPARATE_EXTENSIONS = True # show extensions in their own column
MAX_EXTENSION_LENGTH = 5 # longer extensions stay with the filename
Adjust the pane split at runtime with [ / ], and the log-pane height with
{ / }.
DATE_FORMAT chooses how modification times are shown in the file panes:
'short' gives YY-MM-DD HH:mm (compact, no seconds) and 'full' gives
YYYY-MM-DD HH:mm:ss (four-digit year plus seconds). Both use ISO-8601 ordering,
and the date column widens automatically for the longer form. You can also cycle
the format live from the View Options menu (z) without editing the config.
DEFAULT_SORT_MODE = 'name' # 'name', 'size', or 'date'
DEFAULT_SORT_REVERSE = False
Change sorting at runtime via the sort menu (s) or the quick-sort keys.
Name sorting is natural (alphanumeric): embedded numbers are compared as
numbers, so file2 sorts before file10, and leading zeros (Report001,
Report010) order as expected. It is case-insensitive, always applies to the
'name' sort mode, and can’t be turned off; the 'size' and 'date' modes are
unaffected. Directories are always listed before files regardless of sort mode.
CONFIRM_DELETE = True # before deleting files/directories
CONFIRM_QUIT = True # before quitting XeFM
CONFIRM_COPY = True # before copying
CONFIRM_MOVE = True # before moving
CONFIRM_EXTRACT_ARCHIVE = True # before extracting an archive
CONFIRM_ARCHIVE_CREATE = True # before creating an archive
KEY_BINDINGS = {
'quit': ['Q'],
'help': ['?'],
'toggle_hidden': ['.'],
# ... many more actions
}
Each action maps to a list of keys. Keys can be single characters ('a', 'Q')
or special names ('HOME', 'END', 'F1'…'F12', 'UP', 'DELETE', …). Letter
keys are case-insensitive: a bare 'q' and a bare 'Q' bind the same
physical key (the default template simply happens to spell them uppercase, e.g.
'Q', 'C', 'M', 'K'). To bind the shifted/uppercase variant on its own, use
Shift-<letter> (e.g. 'Shift-F'). Non-alphabet characters such as '?' and
'/' stay case-sensitive.
Some actions use the extended, selection-aware form:
KEY_BINDINGS = {
'copy_files': {'keys': ['C'], 'selection': 'required'},
'create_directory': {'keys': ['M'], 'selection': 'none'},
}
Selection modes: 'any' (default), 'required' (only with a selection), 'none'
(only without one). See Key Bindings for the full
action list.
FAVORITE_DIRECTORIES = [
{'name': 'Home', 'path': '~'},
{'name': 'Documents', 'path': '~/Documents'},
{'name': 'Projects', 'path': '~/Projects'},
]
Access favorites with the J key. See Navigation Dialogs.
MAX_HISTORY_ENTRIES = 100 # directory-history entries kept
MAX_LOG_MESSAGES = 1000 # messages retained in the log pane
See Logging.
PROGRESS_ANIMATION_PATTERN = 'spinner' # spinner, dots, progress, bounce, pulse, wave, clock, arrow
PROGRESS_ANIMATION_SPEED = 0.2 # frame interval in seconds
# Editor launched by edit_file. String ('vim') or list (['code', '--wait']).
# Defaults are chosen per backend: 'vim' in the terminal, 'code' in desktop mode.
TEXT_EDITOR = 'code' if is_desktop_mode() else 'vim'
# Diff tool launched from the diff viewers. Same string/list forms.
TEXT_DIFF = ['code', '--diff'] if is_desktop_mode() else 'vimdiff'
PROGRAMS = [
{'name': 'Git Status', 'command': ['git', 'status']},
{'name': 'Disk Usage', 'command': ['du', '-sh', '*']},
]
Each entry has a name, a command (list or string), and optional options
(e.g. {'terminal': True} for full-screen programs like vim or less).
Access programs with x. See
External Programs.
FILE_ASSOCIATIONS = [
{'pattern': '*.pdf', 'open|view': ['open', '-a', 'Preview']},
{'pattern': ['*.jpg', '*.jpeg', '*.png', '*.gif'], 'open|view': ['open', '-a', 'Preview']},
]
Each entry has a pattern (single fnmatch string or list) and one or more of
open / view / edit (or the combined open|view). Commands are lists or
strings. See File Associations.
S3_CACHE_TTL = 60 # S3 directory-listing cache TTL (seconds)
SSH_CACHE_TTL = 30 # SSH/SFTP cache TTL for successful results (seconds)
SSH_CACHE_ERROR_TTL = 300 # SSH/SFTP cache TTL for cached errors (seconds)
ARCHIVE_CACHE_MAX_OPEN = 5 # max archives kept open at once
ARCHIVE_CACHE_TTL = 300 # archive cache TTL (seconds)
Automatic reloading of a pane when its directory changes on disk:
FILE_MONITORING_ENABLED = True # enable/disable auto-reload
FILE_MONITORING_COALESCE_DELAY_MS = 200 # event coalescing window (ms)
FILE_MONITORING_MAX_RELOADS_PER_SECOND = 5 # rate limit
FILE_MONITORING_FALLBACK_POLL_INTERVAL_S = 5 # polling interval when native events are unavailable (s)
See File Monitoring.
The rendering backend is not a config option — it is chosen only by the
--backend command-line flag (tui/curses, the default, or gui/macos). In
desktop mode the window’s size and position are remembered automatically across
runs; there are no window-geometry config keys. See
Desktop Mode Guide.
SHOW_HIDDEN_FILES = False
CONFIRM_COPY = False
CONFIRM_MOVE = False
MAX_LOG_MESSAGES = 500
DATE_FORMAT = 'full'
SHOW_HIDDEN_FILES = True
DEFAULT_LEFT_PANE_RATIO = 0.5
DEFAULT_LOG_HEIGHT_RATIO = 0.3
MAX_LOG_MESSAGES = 2000
PROGRESS_ANIMATION_PATTERN = 'wave'
MONO_FONT_NAME = 'Menlo'
UI_FONT_NAME = 'Helvetica Neue'
FONT_SIZE = 14
TEXT_EDITOR = 'code'
~/.xefm/config.pyLikely a syntax error (missing quote/comma/bracket). Restore defaults:
rm ~/.xefm/config.py # XeFM recreates it from the template on next run
Check xefm/_config.py — it is the authoritative, fully-commented list of every
available setting.