LF(1)
π NAME π
okay so bestie, welcome to the LF(1) page of the DOCUMENTATION β this is lf, and it is a terminal file manager. that's it, that's the whole name section, but we're not done, obviously, buckle up π
πΈ SYNOPSIS πΈ
the vibe check, in code form:
lf [-command command] [-config path] [-cpuprofile path] [-doc] [-help]
[-last-dir-path path] [-log path] [-memprofile path] [-print-last-dir]
[-print-selection] [-remote command] [-selection-path path] [-server]
[-single] [-version] [cd-or-select-path]
π¦ DESCRIPTION π¦
lf is a terminal file manager. literally its whole job description, no notes π
the source code lives in the repository at https://github.com/gokcehan/lf
you can read this documentation three (3) ways and honestly? pick your fighter:
- from the terminal, using
lf -doc - online at https://github.com/gokcehan/lf/blob/master/doc.md
- or use the
helpcommand (default f-1) insidelfitself to view the docs in a pager π
a man page with the same content is also hanging out in the repo at https://github.com/gokcehan/lf/blob/master/lf.1
β¨ OPTIONS β¨
π POSITIONAL ARGUMENTS
cd-or-select-pathβ sets where you're starting. if path is a directory, you start up in there πͺ. if it's a file, you start in that file's parent directory and the file gets selected for you, like a little spotlight moment. if you don't pass any path at all,lfjust uses the current directory. and heads up: it only takes one argument, so don't try to be greedy π
π« META OPTIONS
-docβ showslf's documentation (same content as this very file) and then dips. π-helpβ shows the command-line usage and exits.-versionβ shows version info and exits.
π STARTUP & CONFIGURATION
-command commandβ runs command during client initialization (aka after the config is read, but beforeon-init). wanna run more than one? either stack the-commandflag multiple times, or pass a bunch of commands at once by chaining them with";"βοΈ-config pathβ use the config file at path instead of the normal search locations. important: this only affects whichlfrcgets read at startup, that's it, no other side quests π«Ά
π SHELL INTEGRATION
-print-last-dirβ prints the last directory tostdoutwhenlfexits. use this to letlfchange your shell's working directory. see CHANGING DIRECTORY for more deets β¨-last-dir-path pathβ same as-print-last-dir, except it writes the directory to path instead ofstdout.-print-selectionβ prints selected files tostdoutwhen you open a file inlf. this is how you uselfas an "open file" dialog π first you select the files you wanna hand off to another program. then you confirm the selection by opening a file. that makeslfquit and print out the selection. and quittinglfprematurely discards the selection β the selection does not survive a rage-quit, bestie π-selection-path pathβ same as-print-selection, but writes the newline-separated list to path instead ofstdout.
π SERVER
-remote commandβ sends command to the running server (so likesend,query,list,quit, orquit!). see REMOTE COMMANDS for the details π‘-serverβ starts the (headless) server process explicitly. it runs in the foreground and writes server logs tostderr(or to the file you set with-log). clients auto-start a server if none is running, unless you're using-single.-singleβ starts a stand-alone client with no server. disables remote control. you're on your own, main character energy, no one can reach you π«
π§ DIAGNOSTICS
-log pathβ appends runtime log messages to path.-cpuprofile pathβ writes a CPU profile to path. that profile can be used bygo tool pprof.-memprofile pathβ writes a memory profile to path. that profile can also be used bygo tool pprof.
π EXAMPLES
use lf to select files (while hiding certain file types):
lf -command 'set nohidden' -command 'set hiddenfiles "*mp4:*pdf:*txt"' -print-selection
another sophisticated "open file" dialog, this one focusing on design:
lf -command 'set nopreview; set ratios 1; set drawbox; set promptfmt "Select files [%w] %S q: cancel, l: confirm"' -print-selection
open Downloads and set sortby and info to creation date:
lf -command 'set sortby btime; set info btime' ~/Downloads
temporarily stop lf from messing with your command history:
lf -command 'set nohistory'
use default settings and log the current session:
lf -config /dev/null -log /tmp/lf.log
force-quit the server:
lf -remote 'quit!'
inherit lf's working directory in your shell:
cd "$(lf -print-last-dir)"
β QUICK REFERENCE β
the cheat sheet section, aka the part you'll actually screenshot and post, iykyk πΈ
the following commands are provided by lf:
quitβ default'q'upβ default'k'and'<up>'half-upβ default'<c-u>'page-upβ default'<c-b>'and'<pgup>'scroll-upβ default'<c-y>'downβ default'j'and'<down>'half-downβ default'<c-d>'page-downβ default'<c-f>'and'<pgdn>'scroll-downβ default'<c-e>'updirβ default'h'and'<left>'openβ default'l'and'<right>'jump-nextβ default']'jump-prevβ default'['topβ default'gg'and'<home>'bottomβ default'G'and'<end>'highβ default'H'middleβ default'M'lowβ default'L'toggleinvertβ default'v'unselectβ default'u'glob-selectglob-unselectcopyβ default'y'cutβ default'd'pasteβ default'p'clearβ default'c'syncdrawredrawβ default'<c-l>'loadreloadβ default'<c-r>'deleteβ (modal)renameβ (modal) (default'r')readβ (modal) (default':')shellβ (modal) (default'$')shell-pipeβ (modal) (default'%')shell-waitβ (modal) (default'!')shell-asyncβ (modal) (default'&')findβ (modal) (default'f')find-backβ (modal) (default'F')find-nextβ default';'find-prevβ default','searchβ (modal) (default'/')search-backβ (modal) (default'?')search-nextβ default'n'search-prevβ default'N'filterβ (modal)setfiltermark-saveβ (modal) (default'm')mark-loadβ (modal) (default"'")mark-removeβ (modal) (default'"')tagtag-toggleβ default't'echoechomsgechoerrcdselectsourcepushaddcustominfocalcdirsizeclearmapstty-writevisualβ default'V'
the following Visual mode commands are provided by lf:
visual-acceptβ default'V'visual-unselectvisual-discardβ default'<esc>'visual-changeβ default'o'
the following Command-line mode commands are provided by lf:
cmd-insertcmd-escapeβ default'<esc>'cmd-completeβ default'<tab>'cmd-menu-completecmd-menu-complete-backcmd-menu-acceptcmd-menu-discardcmd-enterβ default'<c-j>'and'<enter>'cmd-interruptβ default'<c-c>'cmd-history-nextβ default'<c-n>'and'<down>'cmd-history-prevβ default'<c-p>'and'<up>'cmd-leftβ default'<c-b>'and'<left>'cmd-rightβ default'<c-f>'and'<right>'cmd-homeβ default'<c-a>'and'<home>'cmd-endβ default'<c-e>'and'<end>'cmd-deleteβ default'<c-d>'and'<delete>'cmd-delete-backβ default'<backspace>'cmd-delete-homeβ default'<c-u>'cmd-delete-endβ default'<c-k>'cmd-delete-unix-wordβ default'<c-w>'cmd-yankβ default'<c-y>'cmd-transposeβ default'<c-t>'cmd-transpose-wordβ default'<a-t>'cmd-wordβ default'<a-f>'cmd-word-backβ default'<a-b>'cmd-delete-wordβ default'<a-d>'cmd-delete-word-backβ default'<a-backspace>'cmd-capitalize-wordβ default'<a-c>'cmd-uppercase-wordβ default'<a-u>'cmd-lowercase-wordβ default'<a-l>'
the following options can be used to customize the behavior of lf:
anchorfindβbool(defaulttrue)autoquitβbool(defaulttrue)borderfmtβstring(default"\033[0m")borderstyleβstring(default'box')cleanerβstring(default'')copyfmtβstring(default"\033[7;33m")cursoractivefmtβstring(default"\033[7m")cursorparentfmtβstring(default"\033[7m")cursorpreviewfmtβstring(default"\033[4m")cutfmtβstring(default"\033[7;31m")dircountsβbool(defaultfalse)dirfirstβbool(defaulttrue)dironlyβbool(defaultfalse)dirpreviewsβbool(defaultfalse)drawboxβbool(defaultfalse)dupfilefmtβstring(default'%f.~%n~')errorfmtβstring(default"\033[7;31;47m")filesepβstring(default"\n")filtermethodβstring(default'text')findlenβint(default1)hiddenβbool(defaultfalse)hiddenfilesβ[]string(default'.*'for Unix and''for Windows)historyβbool(defaulttrue)iconsβbool(defaultfalse)ifsβstring(default'')ignorecaseβbool(defaulttrue)ignorediaβbool(defaulttrue)incfilterβbool(defaultfalse)incsearchβbool(defaultfalse)infoβ[]string(default'')infotimefmtnewβstring(default'Jan _2 15:04')infotimefmtoldβstring(default'Jan _2 2006')menufmtβstring(default"\033[0m")menuheaderfmtβstring(default"\033[1m")menuselectfmtβstring(default"\033[7m")mergeindicatorsβbool(defaultfalse)mouseβbool(defaultfalse)numberβbool(defaultfalse)numbercursorfmtβstring(default'')numberfmtβstring(default"\033[33m")periodβint(default0)preloadβbool(defaultfalse)preserveβ[]string(default"mode")previewβbool(defaulttrue)previewerβstring(default'')promptfmtβstring(default"\033[32;1m%u@%h\033[0m:\033[34;1m%d\033[0m\033[1m%f\033[0m")ratiosβ[]int(default'1:2:3')relativenumberβbool(defaultfalse)reverseβbool(defaultfalse)rulerfileβstring(default"")rulerfmtβstring(default"")scrolloffβint(default0)searchmethodβstring(default'text')selectfmtβstring(default"\033[7;35m")selmodeβstring(default'all')shellβstring(default'sh'for Unix and'cmd'for Windows)shellflagβstring(default'-c'for Unix and'/c'for Windows)shelloptsβ[]string(default'')showbindsβbool(defaulttrue)sizeunitsβstring(default'binary')smartcaseβbool(defaulttrue)smartdiaβbool(defaultfalse)sortbyβstring(default'natural')sortignorecaseβbool(defaulttrue)sortignorediaβbool(defaulttrue)statfmtβstring(default"\033[36m%p\033[0m| %c| %u| %g| %S| %t| -> %l")tabstopβint(default8)tagfmtβstring(default"\033[31m")tempmarksβstring(default'')terminalcursorβstring(default'default')timefmtβstring(default'Mon Jan _2 15:04:05 2006')truncatecharβstring(default'~')truncatepctβint(default100)visualfmtβstring(default"\033[7;36m")waitmsgβstring(default'Press any key to continue')watchβbool(defaultfalse)wrapscanβbool(defaulttrue)wrapscrollβbool(defaultfalse)user_{option}βstring(default none)
okay pausing the list for a sec because these next bits are the actual glue that makes your shell commands and your config talk to each other π«Ά
π Environment variables that get exported for shell commands
When lf runs your shell commands, it hands these over so your scripts aren't just out here guessing:
ffsfvfxidPWDOLDPWDLF_LEVELOPENERVISUALEDITORPAGERSHELLlflf_{option}lf_user_{option}lf_flag_{flag}lf_widthlf_heightlf_countlf_mode
π Special shell commands
These are not like⦠regular commands you type. They're hooks. If you define them, lf uses them to customize how it behaves. The full roster:
openpasterenamedeletepre-cdon-cdon-loadon-focus-gainedon-focus-loston-initon-selecton-redrawon-quit
π Commands and keybindings you get for free
Bestie these ship already set up, no config required. Here's the whole default set.
Unix:
cmd open &$OPENER "$f"
map e $$EDITOR "$f"
map i $$PAGER "$f"
map w $$SHELL
cmd help $$lf -doc | $PAGER
map <f-1> help
cmd maps $lf -remote "query $id maps" | $PAGER
cmd nmaps $lf -remote "query $id nmaps" | $PAGER
cmd vmaps $lf -remote "query $id vmaps" | $PAGER
cmd cmaps $lf -remote "query $id cmaps" | $PAGER
cmd cmds $lf -remote "query $id cmds" | $PAGER
Windows:
cmd open &%OPENER% %f%
map e $%EDITOR% %f%
map i !%PAGER% %f%
map w $%SHELL%
cmd help !%lf% -doc | %PAGER%
map <f-1> help
cmd maps !%lf% -remote "query %id% maps" | %PAGER%
cmd nmaps !%lf% -remote "query %id% nmaps" | %PAGER%
cmd vmaps !%lf% -remote "query %id% vmaps" | %PAGER%
cmd cmaps !%lf% -remote "query %id% cmaps" | %PAGER%
cmd cmds !%lf% -remote "query %id% cmds" | %PAGER%
Heads up: the defaults for Windows are usingcmdsyntax. If you're on PowerShell and want something that actually matches your vibe, there's a PowerShell compatible configuration file athttps://github.com/gokcehan/lf/blob/master/etc/lfrc.ps1.example
β¨ Extra keybindings that also come by default
map zh set hidden!
map zr set reverse!
map zn set info
map zs set info size
map zt set info time
map za set info size:time
map sn :set sortby natural; set info
map ss :set sortby size; set info size
map st :set sortby time; set info time
map sa :set sortby atime; set info atime
map sb :set sortby btime; set info btime
map sc :set sortby ctime; set info ctime
map se :set sortby ext; set info
map gh cd ~
nmap <space> :toggle; down
π±οΈ If you turn mouse on
Once the mouse option is enabled, your mouse buttons do these things by default:
- Left mouse button β Click on a file or directory to select it.
- Right mouse button β Enter a directory or open a file. Also works on the preview pane.
- Scroll wheel β Move up or down. If Ctrl is pressed, scroll up or down.
π CONFIGURATION
This is where you make lf yours. Your config files live here:
- Configuration files β should be located at:
- Unix β system-wide:
/etc/lf/lfrc, user-specific:~/.config/lf/lfrc - Windows β system-wide:
C:\ProgramData\lf\lfrc, user-specific:C:\Users\<user>\AppData\Roaming\lf\lfrc
- Unix β system-wide:
- The colors file β should be located at:
- Unix β system-wide:
/etc/lf/colors, user-specific:~/.config/lf/colors - Windows β system-wide:
C:\ProgramData\lf\colors, user-specific:C:\Users\<user>\AppData\Roaming\lf\colors
- Unix β system-wide:
- The icons file β should be located at:
- Unix β system-wide:
/etc/lf/icons, user-specific:~/.config/lf/icons - Windows β system-wide:
C:\ProgramData\lf\icons, user-specific:C:\Users\<user>\AppData\Roaming\lf\icons
- Unix β system-wide:
- The selection file β should be located at:
- Unix:
~/.local/share/lf/files - Windows:
C:\Users\<user>\AppData\Local\lf\files
- Unix:
- The marks file β should be located at:
- Unix:
~/.local/share/lf/marks - Windows:
C:\Users\<user>\AppData\Local\lf\marks
- Unix:
- The tags file β should be located at:
- Unix:
~/.local/share/lf/tags - Windows:
C:\Users\<user>\AppData\Local\lf\tags
- Unix:
- The history file β should be located at:
- Unix:
~/.local/share/lf/history - Windows:
C:\Users\<user>\AppData\Local\lf\history
- Unix:
You can configure these locations with the following variables, given with their order of precedences and their default values:
- Unix
$LF_CONFIG_HOME$XDG_CONFIG_HOME~/.config$LF_DATA_HOME$XDG_DATA_HOME~/.local/share
- Windows
%LF_CONFIG_HOME%%XDG_CONFIG_HOME%%APPDATA%%LF_DATA_HOME%%XDG_DATA_HOME%%LOCALAPPDATA%
And if you want something to copy-paste instead of building from scratch, a sample configuration file can be found at https://github.com/gokcehan/lf/blob/master/etc/lfrc.example π
β¨οΈ COMMANDS β¨οΈ
okay bestie this is the big one. this section is all about the built-in commands and there are so many of them, but like, don't panic, they're all pretty intuitive once you see them. β¨
heads up on one thing though: modal commands do not take any arguments. instead of taking args, they flip lf into a whole different mode so you can type your input all comfy-like. which means you're meant to bind them to keybindings. it's giving "special little guy" energy and honestly? iconic. π
quit β default q
Quit lf and get you back to your shell. bye bestie, love u, u ate π«Ά
up β default k and <up> Β· half-up β default <c-u> Β· page-up β default <c-b> and <pgup> Β· scroll-up β default <c-y> Β· down β default j and <down> Β· half-down β default <c-d> Β· page-down β default <c-f> and <pgdn> Β· scroll-down β default <c-e>
Move or scroll the current file selection upwards/downwards by one line, half a page, or a whole entire page. pick your fighter. π
updir β default h and <left>
Change the current working directory to the parent directory. we're going UP, girlies π¦
open β default l and <right>
If the current file is a directory, then it changes the current directory to it. otherwise it executes the open command. there's a default open command provided that calls the default system opener asynchronously with the current file as the argument. and yes, you can define a custom open command to override that default. main character of the file-manager verbs fr. π
jump-next β default ] Β· jump-prev β default [
Change the current working directory to the next/previous jumplist item. hop hop hop π
top β default gg and <home> Β· bottom β default G and <end>
Move the current file selection to the top/bottom of the directory. and here's a cute little trick: a count can be specified to move to a specific line β for example, use 3G to move to the third line. β¨
high β default H Β· middle β default M Β· low β default L
Move the current file selection to the high/middle/low of the screen. screen placement is a vibe β¨
toggle
Toggle the selection of the current file, or of the files given as arguments.
invert β default v
Reverse the selection of all files in the current directory (i.e. toggle all files). Selections in other directories are not affected by this command, just so you know. π
and ooh, fun fact, you can define a new command to select all files in the directory by combining invert with unselect (i.e. cmd select-all :unselect; invert) β though bestie, be aware, this will also remove selections in other directories. so it's a lil chaotic, but in a fun way. π
unselect β default u
Remove the selection of all files in all directories. full reset, we're starting over π
glob-select, glob-unselect
Select/unselect files that match the given glob. π
copy β default y
Save the paths of selected files to the clipboard as files to be copied. If there are no selected files, the path of the current file is used instead. no selection? no problem π
cut β default d
Save the paths of selected files to the clipboard as files to be moved. If there are no selected files, the path of the current file is used instead.
paste β default p
Copy/move files in the clipboard to the current working directory. and yep, a custom paste command can be defined to override this default. π«Ά
clear β default c
Clear file paths in the clipboard. clipboard said "and i oop" and emptied π§
sync
Synchronize copied/cut files with the server. this command is automatically called when required β you don't gotta babysit it.
draw
Draw the screen. also automatically called when required. β¨
redraw β default <c-l>
Synchronize the terminal and redraw the screen. when everything looks cursed, hit this π
load
Load modified files and directories. automatically called when required, again. lf is very much a "i got it" type of program.
reload β default <c-r>
Flush the cache and reload all files and directories. nuke the cache, live your truth π₯
delete β modal
Remove the current file or selected file(s). A custom delete command can be defined to override this default.
π bestie. this one removes files. like, for real, actually. maybe peek at what you selected before you hit it, okay? i'm not being annoying, i'm being a good friend.
rename β modal β default r
Rename the current file using the built-in method. A custom rename command can be defined to override this default. glow-up arc for your filenames β¨
read β modal β default :
Read a command to evaluate. this is the : of it all, iykyk π
shell β modal β default $
Read a shell command to execute. live ur unix fantasy π
shell-pipe β modal β default %
Read a shell command to execute, piping its standard I/O to the bottom statline. cute lil output bar moment πΈ
shell-wait β modal β default !
Read a shell command to execute and wait for a key press at the end. it literally waits for you to be done looking before it moves on. so polite π₯Ή
shell-async β modal β default &
Read a shell command to execute asynchronously without standard I/O. fire and forget, no chat, no notes π₯
find β modal β default f Β· find-back β modal β default F Β· find-next β default ; Β· find-prev β default ,
Read key(s) to find the appropriate filename match in the forward/backward direction, and jump to the next/previous match. π¦
search β default / Β· search-back β default ? Β· search-next β default n Β· search-prev β default N
Read a pattern to search for a filename match in the forward/backward direction, and jump to the next/previous match. the search girlies know π
filter β modal Β· setfilter
Command filter reads a pattern to filter out and only view files matching the pattern. Command setfilter does the same thing, but it uses an argument to set the filter immediately. also, you can supply an argument to filter to use as the starting prompt. β¨
mark-save β modal β default m
Save the current directory as a bookmark assigned to the given key. π
mark-load β modal β default '
Change the current directory to the bookmark assigned to the given key. and psst β there's a special bookmark ' that holds the previous directory after a mark-load, cd, or select command. so handy, obsessed π
mark-remove β modal β default "
Remove a bookmark assigned to the given key. rip bookmark πͺ¦
tag
Tag a file with * or a single-width character given in the argument. and you can define a new tag-clearing command by combining tag with tag-toggle (i.e. cmd tag-clear :tag; tag-toggle). π
tag-toggle β default t
Tag a file with * or a single-width character given in the argument if the file is untagged, otherwise remove the tag. it's a toggle, bestie, that's literally the gig π
echo
Print the given arguments to the message line at the bottom. π£
echomsg
Print the given arguments to the message line at the bottom and also to the log file. double the exposure, double the slay β¨
echoerr
Print given arguments to the message line at the bottom as errorfmt and also to the log file. it's the error-flavored cousin π₯
cd
Change the working directory to the given argument. classic. timeless. iconic. π
select
Change the current file selection to the given argument. π«Ά
source
Read the configuration file given in the argument.
push
Simulate key pushes given in the argument. yes, it literally pretends you pressed keys π
addcustominfo
Update the custom info and .Stat.CustomInfo field of the given file with the given string. The info string may contain ANSI escape codes to further customize its appearance. And if no info is provided, it clears the file's info instead. β¨
calcdirsize
Calculate the total size for each of the selected directories. For this size to actually show up, option info should include size and option dircounts should be disabled. and if the total size of a directory is not calculated, it will be shown as -. πΈ
clearmaps
Remove all keybindings associated with the map, nmap and vmap command. This command can be used in the config file to remove the default keybindings. but for safety purposes: : is left mapped to the read command, and cmap keybindings are retained so that it is still possible to exit lf using :quit. so like, you can go feral but you can never fully trap yourself in there. thank u for the guardrails π«Ά
tty-write
Write the given string to the tty. This is useful for sending escape sequences to the terminal to control its behavior (e.g. OSC 0 to set the window title).
and here's the important part bestie: using tty-write is preferred over directly writing to /dev/tty, because the latter is not synchronized and can interfere with drawing the UI. so like, be a good citizen and use tty-write. π
visual β default V
Switch to Visual mode. If you're already in Visual mode, discard the visual selection and stay in Visual mode. it's giving "we're so back either way" π
π¦ VISUAL MODE COMMANDS π¦
a whole separate little command set just for when you're in Visual mode. so cozy.
visual-accept β default V
Add the visual selection to the selection list, quit Visual mode and return to Normal mode. you did it, you committed, slay β¨
visual-unselect
Remove the visual selection from the selection list, quit Visual mode and return to Normal mode. plot twist, we're undoing it π
visual-discard β default <esc>
Discard the visual selection, quit Visual mode and return to Normal mode. no take-backs, it's just gone π«Ά
visual-change β default o
Go to the other end of the current Visual mode selection. flip it, reverse it, o it π
π¬ COMMAND-LINE MODE COMMANDS π¬
The prompt character is literally your lil mode indicator bestie β it tells you which of the several Command-line modes you're currently living in. For example, read command? Boom, you're in : mode. Periodt.
When the cursor is at the first character in : mode, pressing one of the keys !, $, %, or & teleports you to the corresponding mode. Wanna go back? That's what cmd-delete-back (<backspace> by default) is for, babe. π«Ά
The command line commands should be mostly compatible with readline keybindings. A character refers to a Unicode code point, a word consists of letters and digits, and a Unix word consists of any non-blank characters. iykyk πΈ
cmd-insert
Insert the character given in the argument. This command is automatically called when required. no thoughts, it just happens β¨
cmd-escape (default <esc>)
Quit Command-line mode and go back to Normal mode. escapΓ© π
cmd-complete (default <tab>)
Autocomplete the current word. β¨
cmd-menu-complete, cmd-menu-complete-back
Autocomplete the current word with the menu selection. You need to assign keys to these commands yourself (e.g. cmap <tab> cmd-menu-complete; cmap <backtab> cmd-menu-complete-back). Then you can use the assigned keys to display the menu and then cycle through completion options. lil menu moment π
cmd-menu-accept
Accept the currently selected match in menu completion and close the menu. yes queen, commit π
cmd-menu-discard
Discard the currently selected match in menu completion and close the menu. not it, bye π
cmd-enter (default <c-j> and <enter>)
Execute the current line. go go go π₯
cmd-interrupt (default <c-c>)
Interrupt the current shell-pipe command and return to the Normal mode. emergency stop bestie π
cmd-history-next (default <c-n> and <down>), cmd-history-prev (default <c-p> and <up>)
Go to the next/previous entry in the command history. If part of the command is already typed, then only matching entries will be considered, and consecutive duplicate entries are skipped. lowkey smart π§
cmd-left (default <c-b> and <left>), cmd-right (default <c-f> and <right>)
Move the cursor to the left/right.
cmd-home (default <c-a> and <home>), cmd-end (default <c-e> and <end>)
Move the cursor to the beginning/end of the line.
cmd-delete (default <c-d> and <delete>)
Delete the next character.
cmd-delete-back (default <backspace>)
Delete the previous character. When at the beginning of a prompt, returns either to Normal mode or to : mode.
cmd-delete-home (default <c-u>), cmd-delete-end (default <c-k>)
Delete everything up to the beginning/end of the line. yeet π¨
cmd-delete-unix-word (default <c-w>)
Delete the previous Unix word.
cmd-yank (default <c-y>)
Paste the buffer content containing the last deleted item. the comeback is real π«Ά
cmd-transpose (default <c-t>)
Swap the characters before and after the cursor, then move the cursor forward. If there is no character after the cursor, swap the previous two characters instead.
cmd-transpose-word (default <a-t>)
Swap the words before and after the cursor, then move the cursor forward. If there is no word after the cursor, swap the previous two words instead.
cmd-word (default <a-f>), cmd-word-back (default <a-b>)
Move the cursor by one word in the forward/backward direction.
cmd-delete-word (default <a-d>)
Delete the next word in the forward direction.
cmd-delete-word-back (default <a-backspace>)
Delete the previous word in the backward direction.
cmd-capitalize-word (default <a-c>), cmd-uppercase-word (default <a-u>), cmd-lowercase-word (default <a-l>)
Capitalize/uppercase/lowercase the current word and jump to the next word. she's doing the MOST and we love her π
βοΈ SETTINGS βοΈ
This section shows information about options to customize the behavior. Character : is used as the separator for list options []int and []string. ok so that's the whole vibe, let's get into the options π¦
anchorfind (bool) (default true)
When this option is enabled, the find command starts matching patterns from the beginning of filenames, otherwise, it can match at an arbitrary position.
autoquit (bool) (default true)
Automatically quit the server when there are no clients left connected. ghost town rules π»
borderfmt (string) (default \033[0m)
Format string of border characters.
borderstyle (string) (default box)
Border style used by drawbox.
The following styles are supported:
boxβ outline around all panes and separators between themroundboxβ likebox, but with rounded outer cornersoutlineβ outline around all panesroundoutlineβ likeoutline, but with rounded outer cornersseparatorsβ separators between panes
aesthetic choices fr fr β¨
cleaner (string) (default ``) (not called if empty)
Set the path of a cleaner file. The file should be executable. This file is called if previewing is enabled, the previewer is set, and the previously selected file has its preview cache disabled. The following arguments are passed to the file, (1) current filename, (2) width, (3) height, (4) horizontal position, (5) vertical position of preview pane and (6) next filename to be previewed respectively. Preview cleaning is disabled when the value of this option is left empty.
copyfmt (string) (default \033[7;33m)
Format string of the indicator for files to be copied.
cursoractivefmt (string) (default \033[7m), cursorparentfmt (string) (default \033[7m), cursorpreviewfmt (string) (default \033[4m)
Format strings for highlighting the cursor. cursoractivefmt applies in the current directory pane, cursorparentfmt applies in panes that show parents of the current directory, and cursorpreviewfmt applies in panes that preview directories.
The default is to make the active cursor and the parent directory cursor inverted. The preview cursor is underlined.
Some other possibilities to consider for the preview or parent cursors: an empty string for no cursor, \033[7;2m for dimmed inverted text (visibility varies by terminal), \033[7;90m for inverted text with grey (aka "brightblack") background.
If the format string contains the characters %s, it is interpreted as a format string for fmt.Sprintf. Such a string should end with the terminal reset sequence. For example, \033[4m%s\033[0m has the same effect as \033[4m.
main character cursor energy π
cutfmt (string) (default \033[7;31m)
Format string of the indicator for files to be cut.
dircounts (bool) (default false)
When this option is enabled, directory sizes show the number of items inside instead of the total size of the directory, which needs to be calculated for each directory using calcdirsize. This information needs to be calculated by reading the directory and counting the items inside. Therefore, this option is disabled by default for performance reasons. This option only has an effect when info has a size field and the pane is wide enough to show the information. 9999 items are counted per directory at most, and bigger directories are shown as 9999+.
lowkey a CPU eater bestie, that's why it's off by default π
dirfirst (bool) (default true)
Show directories first above regular files. With dircounts enabled, sorting by size always separates directories and files, regardless of dirfirst.
dironly (bool) (default false)
Show only directories. directories only, we don't see files π
dirpreviews (bool) (default false)
If enabled, directories will also be passed to the previewer script. This allows custom previews for directories.
drawbox (bool) (default false)
Draw borders around panes using box drawing characters. β¨
dupfilefmt (string) (default %f.~%n~)
Format string of filename when creating duplicate files. With the default format, copying a file abc.txt to the same directory will result in a duplicate file called abc.txt.~1~. Special expansions are provided, %f as the file name, %b for the base name (file name without extension), %e as the extension (including the dot) and %n as the number of duplicates.
errorfmt (string) (default \033[7;31;47m)
Format string of error messages shown in the bottom message line.
If the format string contains the characters %s, it is interpreted as a format string for fmt.Sprintf. Such a string should end with the terminal reset sequence. For example, \033[4m%s\033[0m has the same effect as \033[4m.
filesep (string) (default \n)
File separator used in environment variables fs, fv and fx.
filtermethod (string) (default text)
How filter command patterns are treated. Currently supported methods are text (i.e. string literals), glob (i.e. shell globs) and regex (i.e. regular expressions). See SEARCHING FILES for more details.
findlen (int) (default 1)
Number of characters prompted for the find command. When this value is set to 0, find command prompts until there is only a single match left. so dramatic, I love it π
hidden (bool) (default false)
Show hidden files. On Unix systems, hidden files are determined by the value of hiddenfiles. On Windows, files with hidden attributes are also considered hidden files.
hiddenfiles ([]string) (default .* for Unix and `` for Windows)
List of hidden file glob patterns. Patterns can be given as relative or absolute paths. Globbing supports the usual special characters, * to match any sequence, ? to match any character, and [...] or [^...] to match character sets or ranges. In addition, if a pattern starts with !, then its matches are excluded from hidden files. To add multiple patterns, use : as a separator. Example: .*:lost+found:*.bak
history (bool) (default true)
Save command history. for the girlies who forget things π
icons (bool) (default false)
Show icons before each item in the list. π¦β¨
ifs (string) (default ``)
Sets IFS variable in shell commands. It works by adding the assignment to the beginning of the command string as IFS=...; .... The reason is that IFS variable is not inherited by the shell for security reasons. This method assumes a POSIX shell syntax so it can fail for non-POSIX shells. This option has no effect when the value is left empty. This option does not have any effect on Windows.
ignorecase (bool) (default true)
Ignore case in search patterns. See also sortignorecase.
ignoredia (bool) (default true)
Ignore diacritics in search patterns. See also sortignoredia.
incfilter (bool) (default false)
Apply filter pattern after each keystroke during filtering. every keystroke, no cap β¨οΈ
incsearch (bool) (default false)
Jump to the first match after each keystroke during searching.
info ([]string) (default ``)
A list of information that is shown for directory items at the right side of the pane.
The following information types are supported:
permβ file permissionuserβ user namegroupβ group namesizeβ file sizetimeβ time of last data modificationatimeβ time of last accessbtimeβ time of file birthctimeβ time of last status (inode) changecustomβ property defined viaaddcustominfo(empty by default)
Information is only shown when the pane width is more than twice the width of information.
infotimefmtnew (string) (default Jan _2 15:04)
Format string of the file time shown in the info column when it matches this year.
infotimefmtold(string) (defaultJan _2 2006) β the format string for the file time in the info column when it's not from this year. bestie it's the throwback timestamp format, the one for when the file's a little old πmenufmt(string) (default\033[0m) β format string of the menu itself. the menu's whole lewk πmenuheaderfmt(string) (default\033[1m) β format string of the header row in the menu. the header ate, respectfully πmenuselectfmt(string) (default\033[7m) β format string of the currently selected item in the menu. where the cursor is sitting, that's what this styles β¨mergeindicators(bool) (default false) β when this is on, the tag indicators and the selection indicators both get drawn in a single column, which shrinks the gap before the filenames. if a file is both tagged and selected, the tag uses the selection format (likecopyfmt) instead oftagfmt. no cap, it's just tidier πΈmouse(bool) (default false) β send mouse events as input. do you want the mouse to actually do stuff? here's your switch π±οΈnumber(bool) (default false) β show the position number for directory items on the left side of the pane. whenrelativenumberis also enabled, only the current line shows the absolute position and relative positions are shown for everything else. iykyk π’numberfmt(string) (default\033[33m),numbercursorfmt(string) (default ``) β format strings for highlighting line numbers.numberfmtapplies to all lines.numbercursorfmtapplies to the cursor line, and it falls back tonumberfmtwhen it's left empty. so it's the main slay and then the special cursor slay πperiod(int) (default 0) β sets the interval in seconds for periodic checks of directory updates. how does it work? it periodically calls theloadcommand. heads up: directories are already updated automatically in many cases, so this isn't usually necessary. it can be useful when there's an external process changing the displayed directory and you're not doing anything in lf at all. periodic checks are disabled when this option's value is set to zero. zero = off, periodt π¦preload(bool) (default false) β allow previews to be generated in advance using the previewer script, as the user navigates through the filesystem. future-proofing the vibes β¨preserve([]string) (defaultmode) β the list of attributes that get preserved when copying files. the currently supported attributes aremode(i.e. access mode) andtimestamps(i.e. modification time and access time). ngl preserving other attributes like ownership or change/birth timestamps is a nice dream, but it's not portably supported in Go. so. yeah. πpreview(bool) (default true) β show previews of files and directories at the rightmost pane. if the file has more lines than the preview pane, the rest of the lines are just not read. files are considered binary and displayed as binary if the read portion contains a control character other than bell, backspace, tab, newline, vertical tab, form feed, carriage return, escape or delete. the read portion, bestie, that's the key part πpreviewer(string) (default ``) (not filtered if empty) β set the path of a previewer file to filter the content of regular files for previewing. the file should be executable. the following arguments are passed to the file: (1) current filename, (2) width, (3) height, (4) horizontal position, (5) vertical position, and (6) mode ("preview"or"preload").SIGPIPEsignal is sent when enough lines are read. if the previewer returns a non-zero exit code, then the preview cache for the given file is disabled β which means if the file is selected in the future, the previewer is called once again. preview filtering is disabled and files are displayed as they are when this option is left empty. if thepreloadoption is enabled, then this will be called withpreloadas the mode when preloading file previews. refer to the PREVIEWING FILES section for more info on configuring custom previews π«Άpromptfmt(string) (default\033[32;1m%u@%h\033[0m:\033[34;1m%d\033[0m\033[1m%f\033[0m) β format string of the prompt shown in the top line. here's the special expansions, bestie:%fβ file name%hβ host name%uβ user name%wβ working directory%dβ working directory (with trailing path separator)%Fβ current filter%Sβ spacer to right-align the following parts (can be used once)
the home folder is shown as ~ in the working directory expansion. directory names get automatically shortened to a single character starting from the leftmost parent when the prompt doesn't fit the screen. it's giving adaptive π
ratios([]int) (default 1:2:3) β list of ratios of pane widths. the number of items in the list determines the number of panes in the UI. when thepreviewoption is enabled, the rightmost number is used for the width of the preview pane. so the last one is doing double duty πrelativenumber(bool) (default false) β show the position number relative to the current line. whennumberis enabled, the current line shows the absolute position, otherwise nothing is shown. it's a lil collab between the two options π€reverse(bool) (default false) β reverse the direction of sort. flip it πrulerfile(string) (default ``) β set the path of the ruler file. if it's not set, then a default template will be used for the ruler. refer to the RULER section for more info about how the ruler file works πrulerfmt(string) (default ``) β format string of the ruler shown in the bottom right corner. when set, it will be used along withstatfmtto draw the ruler, andrulerfilewill be ignored. however, usingrulerfileis preferred and this option is provided for backwards compatibility. the special expansions:%aβ pressed keys%pβ progress of file operations%mβ number of files to be cut (moved)%cβ number of files to be copied%sβ number of selected files%vβ number of visually selected files%tβ number of shown files in the current directory%hβ number of hidden files in the current directory%fβ current filter%iβ cursor position%Pβ scroll percentage%dβ amount of free disk space
additional expansions are provided for environment variables exported by lf, in the form %{lf_<name>} (e.g. %{lf_selmode}). this is useful for displaying the current settings. expansions are also provided for user-defined options, in the form %{lf_user_<name>} (e.g. %{lf_user_foo}). the | character splits the format string into sections. any section containing a failed expansion (result is a blank string) is discarded and not shown. gone, deleted, not invited π
scrolloff(int) (default 0) β minimum number of offset lines shown at all times at the top and bottom of the screen when scrolling. the current line is kept in the middle when this option is set to a large value that's bigger than half the number of lines. a smaller offset can be used when the current file is close to the beginning or end of the list, so you still get the maximum number of items shown πsearchmethod(string) (default text) β howsearchcommand patterns are treated. the currently supported methods aretext(i.e. string literals),glob(i.e. shell globs) andregex(i.e. regular expressions). see SEARCHING FILES for more details πselectfmt(string) (default\033[7;35m) β format string of the indicator for files that are selected. the selected girlies get their own lewk πselmode(string) (default all) β selection mode for commands. when set toallit will use the selected files from all directories. when set todirit will only use the selected files in the current directory. choose your scope bestie π―shell(string) (defaultshfor Unix andcmdfor Windows) β shell executable to use for shell commands. shell commands are executed asshell shellopts shellflag command -- arguments. that's the exact recipe, don't mess with it π§shellflag(string) (default-cfor Unix and/cfor Windows) β the command line flag used to pass shell commands π©shellopts([]string) (default ``) β list of shell options to pass to the shell executable. extra seasoning for your shell πΆοΈshowbinds(bool) (default true) β show bindings associated with pressed keys. helpful lil cheat sheet while you panic-mash β¨οΈsizeunits(string) (default binary) β determines whether file sizes are displayed using binary units (1K is 1024 bytes) or decimal units (1K is 1000 bytes). pick your math β¨smartcase(bool) (default true) β override theignorecaseoption for searching when the pattern contains an uppercase character. this option has no effect whenignorecaseis disabled. they work as a duo, fr fr πsmartdia(bool) (default false) β override theignorediaoption when the pattern contains a character with a diacritic. this option has no effect whenignorediais disabled πΈsortby(string) (default natural) β sort type for directories. the supported sort types:naturalβ file name (track_2.flaccomes beforetrack_10.flac)nameβ file name (track_10.flaccomes beforetrack_2.flac)extβ file extensionsizeβ file sizetimeβ time of last data modificationatimeβ time of last accessbtimeβ time of file birthctimeβ time of last status (inode) changecustomβ property defined viaaddcustominfo(empty by default)
natural vs name, that's the whole debate, periodt π
sortignorecase(bool) (default true) β ignore case when sorting. see alsoignorecaseπ€sortignoredia(bool) (default true) β ignore diacritics when sorting. see alsoignorediaπΌstatfmt(string) (default\033[36m%p\033[0m| %c| %u| %g| %S| %t| -> %l) β format string of the file info shown in the bottom left corner. this option has no effect unlessrulerfmtis also set. usingrulerfileis preferred and this option is provided for backwards compatibility. the special expansions:%pβ file permission%cβ link count%uβ user name%gβ group name%sβ file size%Sβ file size (left-padded with spaces to a fixed width of 5 characters)%tβ time of last data modification%lβ link target%mβ current mode%Mβ current mode (displayingNORMALinstead of a blank string in Normal mode)
the | character splits the format string into sections. any section containing a failed expansion (result is a blank string) is discarded and not shown π
tabstop(int) (default 8) β number of space characters to show for the horizontal tabulation (U+0009) character. how wide should a tab look, that's the question πtagfmt(string) (default\033[31m) β format string of the tags. if the format string contains the characters%s, it's interpreted as a format string forfmt.Sprintf. such a string should end with the terminal reset sequence. for example,\033[4m%s\033[0mhas the same effect as\033[4m. don't forget the reset bestie, that's the whole trick π₯tempmarks(string) (default ``) β marks to be considered temporary (e.g.abcrefers to marksa,b, andc). these marks are not synced to other clients and they're not saved in the bookmarks file. note that the special bookmark'is always treated as temporary and it does not need to be specified. it's automatically in the temp club πterminalcursor(string) (defaultdefault) β set the appearance of the terminal cursor for prompts shown in the bottom line. the currently supported values aredefault,block,underline,bar,blinkblock,blinkunderlineandblinkbar. pick your cursor era πtimefmt(string) (defaultMon Jan _2 15:04:05 2006) β the format string for the file modification time that shows up in the bottom line. bestie it's a Go time layout, not strftime, don't come for me πtruncatechar(string) (default~) β the lil char that gets slapped on the end when a filename refuses to fit in the pane β¨truncatepct(int) (default100) β okay so when a filename is too long to show fully, the available space gets split into two parts.truncatepctis a percentage between0and100that decides how big the first part is β and that first part gets shown at the beginning of the filename. The second part takes whatever space is left and goes at the end of the filename. The two parts get separated by the truncation character (truncatechar). And no, truncation is not applied to the file extension, she's protected π
So like, with the filename very_long_filename.txt:
- set
truncatepct100->very_long_filena~.txt(default) - set
truncatepct50->very_lon~filename.txt - set
truncatepct0->~ry_long_filename.txt
visualfmt(string) (default\033[7;36m) β the format string for the indicator that marks files as visually selected. iconic little glow-up β¨waitmsg(string) (defaultPress any key to continue) β the string shown after commands of theshell-waittype. it's literally just asking you to press a key bestie π«Άwatch(bool) (defaultfalse) β watch the filesystem for changes usingfsnotify, so file info auto-refreshes. plot twist: FUSE is currently not supported becausefsnotifyhas limitations πwrapscan(bool) (defaulttrue) β searching is allowed to wrap around the file list πwrappscroll... no bestie, it'swrapscroll(bool) (defaultfalse) β scrolling is allowed to wrap around the file listuser_{option}(string) (default none) β any option prefixed withuser_is a user-defined option and you can set it to literally any string you want. Inside a user-defined command, that value gets handed to you in thelf_user_{option}environment variable. Heads up though: these options are not used bylfitself and they are not persisted. so don't go expecting them to survive a restart π
π ENVIRONMENT VARIABLES π
These following variables get exported for shell commands. Also!! the syntax changes depending on your shell, iykyk: on POSIX shells you refer to them with a $ prefix (like $f), on Windows cmd you wrap them in % characters (like %f%), and on Windows PowerShell you use the $env: prefix (like $env:f). slay, cross-platform π
f
Current file selection, as a full path.
fs
Selected file(s), separated with the value of the filesep option, as full path(s).
fv
Visually selected file(s), separated with the value of the filesep option, as full path(s).
fx
Selected file(s) (that means fs, never fv) if there are any selected files β otherwise it falls back to the current file selection (that's f). she's flexible like that π
id
Id of the running client.
PWD
Present working directory.
OLDPWD
Initial working directory.
LF_LEVEL
The value of this variable is set to the current nesting level when you run lf from a shell that was spawned inside lf. You can add its value to your shell prompt to make it clear that your shell is running inside lf β main character transparency β¨. For example, with POSIX shells you can put this in your shell configuration file (e.g. ~/.bashrc):
[ -n "$LF_LEVEL" ] && PS1="$PS1""(lf level: $LF_LEVEL) "
OPENER
If this variable is set in the environment, use that same value. Otherwise it gets set to start in Windows, open in macOS, and xdg-open everywhere else.
EDITOR
If VISUAL is set in the environment, use its value. Otherwise use the value of the environment variable EDITOR. And if neither variable is set, this gets set to vi on Unix and notepad in Windows.
PAGER
If this variable is set in the environment, use that same value. Otherwise this gets set to less on Unix and more in Windows.
SHELL
If this variable is set in the environment, use that same value. Otherwise this gets set to sh on Unix and cmd in Windows.
lf
Absolute path to the currently running lf binary, if it can be found. Otherwise this gets set to the string lf.
lf_{option}
Value of the {option}.
lf_user_{option}
Value of the user_{option}.
lf_flag_{flag}
Value of the command line {flag}.
lf_width, lf_height
Width/Height of the terminal. know your limits bestie π
lf_count
Value of the count associated with the current command.
lf_mode
The current mode that lf is operating in. This one is so useful for customizing keybindings depending on what mode you're currently in β obsessed π. Possible values are compmenu, delete, rename, filter, find, mark, search, command, shell, pipe (when running a shell-pipe command), normal, visual and unknown.
πΈ SPECIAL COMMANDS πΈ
This section is all about the special shell commands, bestie. read carefully π
open
This shell command can be defined to override the default open command when the current file is not a directory.
paste
This shell command can be defined to override the default paste command.
rename
This shell command can be defined to override the default rename command.
delete
This shell command can be defined to override the default delete command.
pre-cd
This shell command can be defined to be executed before changing a directory.
on-cd
This shell command can be defined to be executed after changing a directory.
on-load
This shell command can be defined to be executed after loading a directory. It provides the files inside the directory as arguments π
on-focus-gained
This shell command can be defined to be executed when the terminal gains focus.
on-focus-lost
This shell command can be defined to be executed when the terminal loses focus.
on-init
This shell command can be defined to be executed after initializing and connecting to the server.
on-select
This shell command can be defined to be executed after the selection changes.
on-redraw
This shell command can be defined to be executed after the screen is redrawn or if the terminal is resized.
on-quit
This shell command can be defined to be executed before quitting.
β¨ PREFIXES β¨
These are the command prefixes that lf uses, bestie, memorize them π§ :
:β read (default), for built-in/custom commands$β shell, for a shell command%β shell-pipe, a shell command running with the UI!β shell-wait, a shell command that waits for a key press&β shell-async, a shell command running asynchronously
The same evaluator gets used for the command line and the configuration file when reading shell commands. The difference? Prefixes aren't necessary in the command line. Instead, different modes are provided to read the corresponding commands, and those modes are mapped to the prefix keys above by default. And Visual mode mappings are defined the exact same way Normal mode mappings are. no cap π―
π¦ SYNTAX π¦
Characters from # to newline are comments, and they get ignored:
# comments start with `#`
The following commands (set, setlocal, map, nmap, vmap, cmap, and cmd) are used for configuration.
Command set is used to set an option, which can be a boolean, an integer, or a string:
set hidden # boolean enable
set hidden true # boolean enable
set nohidden # boolean disable
set hidden false # boolean disable
set hidden! # boolean toggle
set scrolloff 10 # integer value
set sortby time # string value without quotes
set sortby 'time' # string value with single quotes (whitespace)
set sortby "time" # string value with double quotes (backslash escapes)
Command setlocal is used to set a local option for a directory, which can be a boolean or a string. Currently supported local options are dircounts, dirfirst, dironly, hidden, info, reverse, sortby, sortignorecase and sortignoredia.
setlocal /foo/bar hidden # boolean enable
setlocal /foo/bar hidden true # boolean enable
setlocal /foo/bar nohidden # boolean disable
setlocal /foo/bar hidden false # boolean disable
setlocal /foo/bar hidden! # boolean toggle
setlocal /foo/bar sortby time # string value without quotes
setlocal /foo/bar sortby 'time' # string value with single quotes (whitespace)
setlocal /foo/bar sortby "time" # string value with double quotes (backslash escapes)
Command map is used to bind a key in Normal and Visual mode to a command, which can be a built-in command, a custom command, or a shell command:
map gh cd ~ # built-in command
map D trash # custom command
map i $less $f # shell command
map U !du -csh * # waiting shell command
Command nmap does the same, but for Normal mode only.
Command vmap does the same, but for Visual mode only.
Overview of which map command works in which mode π:
mapβ Normal, Visualnmapβ Normalvmapβ Visualcmapβ Command-line
Command cmap is used to bind a key on the command line to a command line command or any other command:
cmap <c-g> cmd-escape
cmap <a-i> set incsearch!
You can delete an existing binding by leaving the expression empty:
map gh # deletes 'gh' mapping in Normal and Visual mode
nmap v # deletes 'v' mapping in Normal mode
vmap o # deletes 'o' mapping in Visual mode
cmap <c-g> # deletes '<c-g>' mapping
Command cmd is used to define a custom command:
cmd usage $du -h -d1 | less
You can delete an existing command by leaving the expression empty:
cmd trash # deletes 'trash' command
If there's no prefix, then : is assumed:
map zt set info time
An explicit : can be provided to group statements until a newline, which is especially useful for map and cmd commands:
map st :set sortby time; set info time
And if you need multiline, bestie, you can wrap statements in {{ and }} after the proper prefix:
map st :{{
set sortby time
set info time
}}
β¨ KEY MAPPINGS β¨
okay so bestie, mapping regular keys? super chill, you just use the normal syntax π
map a down
wanna do a capital letter? that's literally just the Shift combo, so type the uppercase letter:
map A down
special keys live between < and > and they always use lowercase letters, no exceptions:
map <enter> down
and yes you can grab angle brackets themselves by their special names π:
map <lt> down
map <gt> down
function keys get an f in front:
map <f-1> down
keys chillin' with the Ctrl key get a c in front:
map <c-a> down
now Alt keys? it's giving "it depends" energy because there are two different ways depending on how your terminal behaves π
Older terminals (think xterm) may set the 8th bit of a character when the Alt key is pressed. On those terminals, you use the corresponding byte for the mapping:
map Γ‘ down
Newer terminals (think gnome-terminal) may prefix the key with an escape character when Alt is pressed. lf uses the escape delaying mechanism to recognize Alt keys in these terminals β the delay is 100ms β and on these terminals, keys combined with Alt get an a in front:
map <a-a> down
you can also mix special keys with modifiers, obsessed π:
map <a-enter> down
combining multiple modifiers (e.g. Ctrl+Shift+Space) is not supported π
ngl, lf's key mapping syntax is similar to Vim's but not identical, fr fr. Some special keys and modifiers use different names and separators, and key names are matched literally β so no case-folding, no aliases β which means some forms you're used to will just not work:
map <enter> down # not <Enter>, <Return> or <CR>
map <f-1> down # not <F1>
map <a-j> down # not <A-j> or <M-j> (Meta)
map <m-2> down # not <RightMouse>
map <m-up> down # not <ScrollWheelUp>
WARNING: some key combinations will likely be intercepted by your OS, your window manager, or your terminal π and other key combinations may not be distinguishable bylf, depending on how the terminal reports them (e.g. Ctrl+h may be reported as backspace instead). The easiest way to find out the name of a key combination and whether it will work on your system is to press the key whilelfis running and read the name from the unknown mapping error. detective era πβ¨
mouse buttons get an m in front of them π:
map <m-1> down # primary
map <m-2> down # secondary
map <m-3> down # middle
map <m-4> down # thumb next
map <m-5> down # thumb prev
map <m-6> down
map <m-7> down
map <m-8> down
and mouse wheel events? also m-prefixed, iconic:
map <m-up> down
map <m-down> down
map <m-left> down
map <m-right> down
π«Ά PUSH MAPPINGS π«Ά
so the usual way to map a key sequence is to assign it to a named or unnamed command. That gives you a clean way to remap built-in keys as well as other commands, but lowkey it can be limiting at times. That's exactly why lf provides the push command π This command is used to simulate key pushes given as its arguments. So you can map a key to a push command with an argument and create all kinds of keybindings β¨
it's mainly useful for two purposes. First, it can map a command with a command count:
map <c-j> push 10j
Second, it saves you from typing the name when a command takes arguments:
map r push :rename<space>
one thing to be careful of though β since the push command works with keys instead of commands, it's possible to accidentally create recursive bindings π:
map j push 2j
these types of bindings create a deadlock when executed. not the slay we're going for bestie, please don't π
πΈ SHELL COMMANDS πΈ
regular shell commands are the most basic command type and they're useful for so many things. For example, we can write a shell command to move the selected file(s) to trash. A first attempt to write such a command may look like this:
cmd trash ${{
mkdir -p ~/.trash
if [ -z "$fs" ]; then
mv "$f" ~/.trash
else
IFS="$(printf '\n\t')"; mv $fs ~/.trash
fi
}}
we check $fs to see if there are any selected files. Otherwise, we just delete the current file. Since this is such a common pattern, a separate $fx variable is provided π
We can use this variable to get rid of the conditional entirely:
cmd trash ${{
mkdir -p ~/.trash
IFS="$(printf '\n\t')"; mv $fx ~/.trash
}}
the trash directory is checked each time the command is executed. We can move it outside of the command so it would only run once at startup:
${{ mkdir -p ~/.trash }}
cmd trash ${{ IFS="$(printf '\n\t')"; mv $fx ~/.trash }}
and since these are one-liners, we can drop the {{ and }} β¨:
$mkdir -p ~/.trash
cmd trash $IFS="$(printf '\n\t')"; mv $fx ~/.trash
finally, note that we set the IFS variable manually in these commands. Instead, we could use the ifs option to set it for all shell commands (i.e. set ifs "\n"). This can be especially useful for interactive use (e.g. $rm $f or $rm $fs would simply work π). This option is not set by default as it can behave unexpectedly for new users. However, use of this option is highly recommended and it is assumed in the rest of the documentation. periodt π
π PIPING SHELL COMMANDS π
regular shell commands have some limitations in some cases, ngl. When an output or error message is given and the command exits afterwards, the UI is immediately resumed, and there is no way to see the message without dropping to shell again π Also, even when there is no output or error, the UI still needs to be paused while the command is running. This can cause flickering on the screen for short commands and similar distractions for longer commands π
instead of pausing the UI, piping shell commands connect stdin, stdout, and stderr of the command to the statline at the bottom of the UI. This can be useful for programs following the Unix philosophy to give no output in the success case, and brief error messages or prompts in other cases β¨
for example, the following rename command prompts for overwrite in the statline if there is an existing file with the given name:
cmd rename %mv -i $f $1
you can also output error messages in the command and they will show up in the statline. For example, an alternative rename command may look like this:
cmd rename %[ -e $1 ] && printf "file exists" || mv $f $1
note that input is line buffered and output and error are byte buffered π«Ά
π¦ WAITING SHELL COMMANDS π¦
waiting shell commands are similar to regular shell commands except that they wait for a key press when the command is finished. These can be useful to see the output of a program before the UI is resumed π Waiting shell commands are more appropriate than piping shell commands when the command is verbose and the output is best displayed as multiline.
π ASYNCHRONOUS SHELL COMMANDS π
asynchronous shell commands are used to start a command in the background and then resume operation without waiting for the command to finish β¨ stdin, stdout, and stderr of the command are neither connected to the terminal nor the UI. main character energy, honestly π
π« REMOTE COMMANDS π«
okay bestie this is one of the more advanced lil features in lf, but it's so fun once it clicks. here's the tea: every client connects to a server when it starts up. and because they all share that common server, you can yeet commands to all of them, or just any one of them. internally, lf literally uses this to tell other clients "hey, the file selection changed π
".
to use it yourself, you need a client that knows how to talk to a Unix domain socket. the OpenBSD implementation of netcat (nc) is one such example. you can use it to fire a command at the socket file:
echo 'send echo hello world' | nc -U ${XDG_RUNTIME_DIR:-/tmp/lf-$(id -u)}/lf.sock
but since such a client might not be installed everywhere, lf comes bundled with a command line flag you can use instead. and the best part β when you're using lf, you don't have to specify the address of the socket file. this is the recommended way to do remote commands, because it's shorter and it's immune to the socket file address changing:
lf -remote 'send echo hello world'
in that command, send is what sends the rest of the string as a command to all connected clients. and you can optionally hand it an ID number to send to just one single client:
lf -remote 'send 1234 echo hello world'
π the $id situation
every client has a unique ID number, but like... you probably don't know the ID number when you're writing a command, right? π for that reason, an $id variable gets exported to the environment for shell commands. its value is set to the process ID of the client. so you can send a remote command from a client to the server, which then sends a command right back to itself. meaning you can display a message in the current client by calling this in a shell command:
lf -remote "send $id echo hello world"
since lf doesn't have control flow syntax, remote commands are how you get that kind of stuff done. for example, you can configure the number of columns in the UI based on the terminal width like this:
cmd recol %{{
if [ $lf_width -le 80 ]; then
lf -remote "send $id set ratios 1:2"
elif [ $lf_width -le 160 ]; then
lf -remote "send $id set ratios 1:2:3"
else
lf -remote "send $id set ratios 1:2:3:5"
fi
}}
π querying
also, the query command can give you info about a specific lf instance if you give it that instance's ID:
lf -remote "query $id maps"
these are the types of information it supports:
mapsβ list of mappings created by the'map','nmap'and'vmap'commandnmapsβ list of mappings created by the'nmap'and'map'commandvmapsβ list of mappings created by the'vmap'and'map'commandcmapsβ list of mappings created by the'cmap'commandcmdsβ list of commands created by the'cmd'commandjumpsβ contents of the jump list, showing previously visited locationshistoryβ list of previously executed commands on the command linefilesβ list of files in the currently open directory as displayed bylf, empty if dir is still loading
and when you're listing mappings, the characters in the first column mean:
nβ Normalvβ Visualcβ Command-line
this is so useful for scripting actions based on the internal state of lf. like, say you wanna pick a previous command with fzf and run it:
map <a-h> ${{
clear
cmd=$(
lf -remote "query $id history" |
awk -F'\t' 'NR > 1 { print $NF}' |
sort -u |
fzf --reverse --prompt='Execute command: '
)
lf -remote "send $id $cmd"
}}
π― the rest of the remote commands
the list command prints the IDs of all currently connected clients:
lf -remote 'list'
there's also a quit command to quit the server once there are no connected clients left, and a quit! command to force quit the server by closing client connections first:
lf -remote 'quit'
lf -remote 'quit!'
and lastly, the commands conn and drop connect or disconnect an ID to/from the server:
lf -remote 'conn $id'
lf -remote 'drop $id'
ngl these last ones are internal and generally not needed by users π«Ά
π FILE OPERATIONS π
lf uses its own built-in copy and move operations by default. they're implemented as asynchronous operations, and the progress shows up in the bottom ruler (obsessed tbh). here's the important bit: these commands do not overwrite existing files or directories that have the same name. instead, a suffix gets added to the new files or directories that's compatible with the --backup=numbered option in GNU cp. only file modes and (some) timestamps can be preserved β that's the preserve option, go peep it β and all other attributes are ignored, including ownership, context, and xattr. special files like character and block devices, named pipes, and sockets get skipped, and links are not followed. moving is done using the rename operation of the underlying OS. for cross-device moving, lf falls back to copying and then deletes the original files if there are no errors. operation errors show up in the message line as well as the log file, and they do not prematurely terminate the corresponding file operation.
file operations can be performed on the currently selected file, or on multiple files if you select them first. and here's a fun fact: when you copy a file, lf doesn't actually copy the file on the disk β it only records its name to a file. the actual file copying happens when you paste. similarly, paste after a cut operation moves the file. π
you can customize copy and move operations by defining a paste command. this is a special command that gets called when it's defined instead of the built-in implementation. use this example as a starting point:
cmd paste %{{
load=$(cat ~/.local/share/lf/files)
mode=$(echo "$load" | sed -n '1p')
list=$(echo "$load" | sed '1d')
if [ $mode = 'copy' ]; then
cp -R $list .
elif [ $mode = 'move' ]; then
mv $list .
rm ~/.local/share/lf/files
lf -remote 'send clear'
fi
}}
some useful things to think about: use the backup (--backup) and/or preserve attributes (-a) options with the cp and mv commands if they support it (i.e. the GNU implementation), change the command type to asynchronous, or use the rsync command with the progress bar option for copying and feed the progress to the client periodically with remote echo calls. β¨
by default, lf does not assign a delete command to a key, and that's on purpose β it's to protect new users π. you can customize file deletion by defining a delete command. you can also assign a key to this command if you like. there's an example command in the example configuration file that moves selected files to a trash folder and removes files completely after a prompt.
π SEARCHING FILES π
there are two mechanisms implemented in lf to search a file in the current directory. searching is the traditional method to move the selection to a file matching a given pattern. finding is an alternative way to search for a pattern, possibly using fewer keystrokes. it's giving efficiency.
searching
the searching mechanism is implemented with the commands search (default /), search-back (default ?), search-next (default n), and search-prev (default N). you can set searchmethod to glob to match using a glob pattern. globbing supports * to match any sequence, ? to match any character, and [...] or [^...] to match character sets or ranges. you can set searchmethod to regex to match using a regex pattern. for a full overview of Go's RE2 syntax, see https://pkg.go.dev/regexp/syntax. you can enable the incsearch option to jump to the current match at each keystroke while you're typing. in this mode, you can either use cmd-enter to accept the search or cmd-escape to cancel the search. you can also map some other commands with cmap to accept the search and execute the command immediately afterwards. for example, you can use the right arrow key to finish the search and open the selected file with this mapping:
cmap <right> :cmd-enter; open
finding
the finding mechanism is implemented with the commands find (default f), find-back (default F), find-next (default ;), find-prev (default ,). you can disable the anchorfind option to match a pattern at an arbitrary position in the filename instead of at the beginning. you can set the number of keys to match using the findlen option. if you set this value to zero, then the keys are read until there's only a single match. the default values of these two options are set to jump to the first file with the given initial.
both at once π
some options affect both searching and finding. you can disable the wrapscan option to prevent searches from being wrapped around at the end of the file list. you can disable the ignorecase option to match cases in the pattern and the filename β though heads up, this option is already automatically overridden if the pattern contains uppercase characters. you can disable the smartcase option to disable this behavior. and there are two similar options, ignoredia and smartdia, provided to control matching diacritics in Latin letters. πΈ
β¨ OPENING FILES β¨
OMG bestie, so you can totally define an open command β the default is l and <right> β to configure how files open. This command only gets called when the current file is not a directory; otherwise, you just enter the directory instead. You define it just like any other command:
cmd open $vi $fx
You can also use different command types:
cmd open &xdg-open $f
Maybe you wanna use either file extensions or MIME types from the file command:
cmd open ${{
case $(file --mime-type -Lb $f) in
text/*) vi $fx;;
*) for f in $fx; do xdg-open $f > /dev/null 2> /dev/null & done;;
esac
}}
Pro tip: you might wanna use setsid before your opener command so your processes stay persistent and keep running after lf quits. π
Regular shell commands (i.e. $) drop you to the terminal, which makes a flicker for commands that finish instantly (like xdg-open up there). But if you want asynchronous shell commands (i.e. &) while still using the terminal when necessary (like vi in that example), you can use a remote command:
cmd open &{{
case $(file --mime-type -Lb $f) in
text/*) lf -remote "send $id \$vi \$fx";;
*) for f in $fx; do xdg-open $f > /dev/null 2> /dev/null & done;;
esac
}}
Note: asynchronous shell commands run in their own process group by default, so they do not require the manual use of setsid. No cap. β¨
The following command is provided by default:
cmd open &$OPENER $f
You may also use any other existing file openers as you like. Possible options are libfile-mimeinfo-perl (executable name is mimeopen), rifle (ranger's default file opener), or mimeo β just to name a few. Slay. π
β¨ PREVIEWING FILES β¨
lf previews files in the preview pane by printing the file until the end or until the preview pane is filled. This output can be enhanced by providing a custom preview script for filtering. That can be used to highlight source code, list contents of archive files, or view PDF or image files β just to name a few. For coloring, lf recognizes ANSI escape codes. π
To use this feature, you need to set the value of the previewer option to the path of an executable file. The following arguments are passed to the file: (1) current filename, (2) width, (3) height, (4) horizontal position, (5) vertical position, and (6) mode ("preview" or "preload"). The output of the execution is printed in the preview pane.
Different types of files can be handled by matching by extension (or MIME type from the file command):
#!/bin/sh
case "$1" in
*.tar*) tar tf "$1";;
*.zip) unzip -l "$1";;
*.rar) unrar l "$1";;
*.7z) 7z l "$1";;
*.pdf) pdftotext "$1" -;;
*) highlight -O ansi "$1";;
esac
Because files can be large, lf automatically closes the previewer script output pipe with a SIGPIPE when enough lines are read. Heads up: some programs may not respond well to SIGPIPE and will exit with a non-zero return code, which avoids caching. You may add a trailing || true command to avoid such errors:
highlight -O ansi "$1" || true
You may also want to use the same script in your pager mapping as well:
set previewer ~/.config/lf/pv.sh
map i $~/.config/lf/pv.sh $f | less -R
For less pager, you may instead utilize the LESSOPEN mechanism so that useful information about the file β such as the full path of the file β can still be displayed in the statusline below:
set previewer ~/.config/lf/pv.sh
map i $LESSOPEN='| ~/.config/lf/pv.sh %s' less -R $f
Since the preview script is called for each file selection change, it may not generate previews fast enough if the user scrolls through files quickly. To deal with this, the preload option can be set to enable file previews to be preloaded in advance. If enabled, the preview script will be run on files in advance as the user navigates through them. In this case, if the exit code of the preview script is zero, then the output will be cached in memory and displayed by lf (useful for text or sixel previews). Otherwise, it will fall back to calling the preview script again when the file is actually selected (useful for previews managed by an external program).
β¨ CHANGING DIRECTORY β¨
lf changes the working directory of the process to the current directory so that shell commands always work in the displayed directory. After quitting, it returns to the original directory where it is first launched β like all shell programs. If you want to stay in the current directory after quitting, you can use one of the example lfcd wrapper shell scripts provided in the repository at https://github.com/gokcehan/lf/tree/master/etc
There is a special command on-cd that runs a shell command when it is defined and the directory is changed. You can define it just as you would define any other command:
cmd on-cd &{{
bash -c '
# display git repository status in your prompt
source /usr/share/git/completion/git-prompt.sh
GIT_PS1_SHOWDIRTYSTATE=auto
GIT_PS1_SHOWSTASHSTATE=auto
GIT_PS1_SHOWUNTRACKEDFILES=auto
GIT_PS1_SHOWUPSTREAM=auto
git=$(__git_ps1 " (%s)")
fmt="\033[32;1m%u@%h\033[0m:\033[34;1m%d\033[0m\033[1m%f$git\033[0m"
lf -remote "send $id set promptfmt \"$fmt\""
'
}}
If you want to send escape sequences to the terminal, you can use the tty-write command to do so. The following xterm-specific escape sequence sets the terminal title to the working directory:
cmd on-cd &{{
lf -remote "send $id tty-write \"\033]0;$PWD\007\""
}}
This command runs whenever you change the directory but not on startup. You can add an extra call to make it run on startup as well:
cmd on-cd &{{ ... }}
on-cd
Note: all shell command types can be used, but%and&are usually more appropriate, as$and!cause flickering and pauses respectively. π
There is also a pre-cd command that works like on-cd, but is run before the directory is actually changed. Another related command is on-load which gets executed when loading a directory.
β¨ LOADING DIRECTORY β¨
Similar to on-cd there also is on-load that when defined runs a shell command after loading a directory. It works well when combined with addcustominfo.
The following example can be used to display git indicators in the info column:
cmd on-load &{{
cd "$(dirname "$1")" || exit 1
[ "$(git rev-parse --is-inside-git-dir 2>/dev/null)" = false ] || exit 0
cmds=""
for file in "$@"; do
case "$file" in
*/.git|*/.git/*) continue;;
esac
status=$(git status --porcelain --ignored -- "$file" | cut -c1-2 | head -n1)
if [ -n "$status" ]; then
cmds="${cmds}addcustominfo \"${file}\" \"$status\"; "
else
cmds="${cmds}addcustominfo \"${file}\" ''; "
fi
done
if [ -n "$cmds" ]; then
lf -remote "send $id :$cmds"
fi
}}
Another use case could be showing the dimensions of images and videos:
cmd on-load &{{
cmds=""
for file in "$@"; do
mime=$(file --mime-type -Lb -- "$file")
case "$mime" in
# vector images cause problems
image/svg+xml)
;;
image/*|video/*)
dimensions=$(exiftool -s3 -imagesize -- "$file")
cmds="${cmds}addcustominfo \"${file}\" \"$dimensions\"; "
;;
esac
done
if [ -n "$cmds" ]; then
lf -remote "send $id :$cmds"
fi
}}
π COLORS π
okay bestie listen up because this is the part where lf gets pretty π
lf literally tries to automatically adapt its colors to your environment, no cap. It starts with a default color scheme and then updates those colors using values of existing environment variables β possibly overwriting its previous values along the way. So the colors get set in this exact order:
- default
LSCOLORS(macOS/BSDls)LS_COLORS(GNUls)LF_COLORS(lf specific)- colors file (lf specific)
pls go read the corresponding man pages if you want the tea on LSCOLORS and LS_COLORS. LF_COLORS is provided with the same syntax as LS_COLORS in case you wanna configure colors only for lf but not for ls. That's lowkey useful since there are some differences between ls and lf, though you should expect the same behavior for common cases. The colors file (refer to the CONFIGURATION section π«Ά) is there for easier configuration without environment variables. That file should consist of whitespace-separated pairs with a # character to start comments until the end of the line.
You can configure lf colors in two different ways, and yes you can have both, icon behavior:
First way β you only configure the 8 basic colors used by your terminal, and lf should pick those colors up automatically. Depending on your terminal, you should be able to select your colors from a 24-bit palette. This is the recommended approach because colors used by other programs will also match each other. β¨
Second way β you set the values of environment variables or the colors file mentioned above for fine-grained customization. Note that LS_COLORS/LF_COLORS are more powerful than LSCOLORS and they can be used even when GNU programs are not installed on the system. You can combine this second method with the first method for the best results. periodt.
Lastly, you may also want to configure the colors of the prompt line to match the rest of the colors. Colors of the prompt line can be configured using the promptfmt option, which can include hardcoded colors as ANSI escapes. Go peek at the default value of this option to get an idea about how to color this line. π
It's worth noting that lf uses as many colors as advertised by your terminal's entry in terminfo or infocmp databases on your system. If an entry is not present, it falls back to an internal database. If your terminal supports 24-bit colors but either does not have a database entry or does not advertise all capabilities, you can enable support by setting the $COLORTERM variable to truecolor or ensuring $TERM is set to a value that ends with -truecolor. π¦
Default lf colors are mostly taken from GNU dircolors defaults. These defaults use 8 basic colors and the bold attribute. Default dircolors entries with background colors are simplified to avoid confusion with the current file selection in lf. Similarly, there are only file type matchings and extension matchings are left out for simplicity. Default values are as follows, given with their matching order in lf:
ln 01;36
or 31;01
tw 01;34
ow 01;34
st 01;34
di 01;34
pi 33
so 01;35
bd 33;01
cd 33;01
su 01;32
sg 01;32
ex 01;32
fi 00
Note that lf first tries matching file names and then falls back to file types. The full order of matchings from most specific to least is as follows:
- Full Path (e.g.
~/.config/lf/lfrc) - Dir Name (e.g.
.git/) (only matches dirs with a trailing slash at the end) - File Type (e.g.
ln) (exceptfi) - File Name (e.g.
README*) - File Name (e.g.
*README) - Base Name (e.g.
README.*) - Extension (e.g.
*.txt) - Default (i.e.
fi)
For example, given a regular text file /path/to/README.txt, the following entries are checked in the configuration and the first one to match is used:
/path/to/README.txt- (skipped since the file is not a directory)
- (skipped since the file is of type
fi) README.txt**README.txtREADME.**.txtfi
Given a regular directory /path/to/example.d, the following entries are checked in the configuration and the first one to match is used:
/path/to/example.dexample.d/diexample.d**example.dexample.**.dfi
heads up bestie: glob-like patterns do not perform glob matching, for performance reasons. so like, don't come for lf about it, it's literally doing its best π
For example, you can set a variable as follows:
export LF_COLORS="~/Documents=01;31:~/Downloads=01;31:~/.local/share=01;31:~/.config/lf/lfrc=31:.git/=01;32:.git*=32:*.gitignore=32:*Makefile=32:README.*=33:*.txt=34:*.md=34:ln=01;36:di=01;34:ex=01;32:"
Having all entries on a single line can make it hard to read, and honestly, same. You may instead divide it into multiple lines in between double quotes by escaping newlines with backslashes as follows:
export LF_COLORS="\
~/Documents=01;31:\
~/Downloads=01;31:\
~/.local/share=01;31:\
~/.config/lf/lfrc=31:\
.git/=01;32:\
.git*=32:\
*.gitignore=32:\
*Makefile=32:\
README.*=33:\
*.txt=34:\
*.md=34:\
ln=01;36:\
di=01;34:\
ex=01;32:\
"
The ln entry supports the special value target, which will use the link target to select a style. Filename rules will still apply based on the link's name β this mirrors GNU's ls and dircolors behavior. π
Having such a long variable definition in a shell configuration file might be undesirable. You may instead use the colors file (refer to the CONFIGURATION section) for configuration. A sample colors file can be found at https://github.com/gokcehan/lf/blob/master/etc/colors.example. You may also see the wiki page for ANSI escape codes at https://en.wikipedia.org/wiki/ANSI_escape_code. π
β¨ ICONS β¨
Icons are configured using the LF_ICONS environment variable or an icons file (refer to the CONFIGURATION section, iykyk). The variable uses the same syntax as LS_COLORS/LF_COLORS. Instead of colors, you should use single characters or symbols as values β that's the whole vibe. πΈ
The ln entry supports the special value target, which will use the link target to select an icon. Filename rules will still apply based on the link's name β this mirrors GNU's ls and dircolors behavior. π«Ά
The icons file (refer to the CONFIGURATION section) should consist of whitespace-separated arrays with a # character to start comments until the end of the line. Each line should contain 1-3 columns: a file type or file name pattern, the icon, and an optional icon color. Using only one column disables all rules for that type or name. And do not forget to add set icons true to your lfrc to actually see the icons, bestie, otherwise you'll be staring at nothing wondering why. π
Default values are listed below in the order lf matches them:
ln l
or l
tw t
ow d
st t
di d
pi p
so s
bd b
cd c
su u
sg g
ex x
fi -
A sample icons file can be found at https://github.com/gokcehan/lf/blob/master/etc/icons.example
A sample colored icons file can be found at https://github.com/gokcehan/lf/blob/master/etc/icons_colored.example
you're so close to being a full lf icon-configuring legend it's unreal π
π RULER π
okay bestie, this is the part where you get to build your own ruler β the little strip that shows off your percentages and your file tea. You set it up with the rulerfile option (go peek at the CONFIGURATION section for that, iykyk). The contents of the ruler file should be a Go template, and that template gets rendered to create the actual output β more deets on the syntax over at https://pkg.go.dev/text/template.
It's literally giving custom status bar, and honestly? Iconic.
The following data fields are exported β these are your ingredients, bestie, sprinkle them in πΈ:
.Messageβ string β includes internal messages, errors, and messages generated by theecho/echomsg/echoerrcommands.Keysβ string β keys pressed by the user.Progressβ []string β progress indicators for copied, moved and deleted files.Copyβ []string β list of files in the clipboard to be copied.Cutβ []string β list of files in the clipboard to be moved.Selectβ []string β selection list.Visualβ []string β visual selection.Indexβ int β index of the cursor.Totalβ int β number of visible files in the current working directory.Hiddenβ int β number of hidden files in the current working directory.Allβ int β number of all files in the current working directory.LinePercentageβ string β line percentage (analogous to%pfor thestatuslineoption in Vim).ScrollPercentageβ string β scroll percentage (analogous to%Pfor thestatuslineoption in Vim).Filterβ []string β filter currently being applied.Modeβ string β current mode ("NORMAL"for Normal mode, and"VISUAL"for Visual mode).Optionsβ map[string]string β the value of options (e.g.{{.Options.hidden}}).UserOptionsβ map[string]string β the value of user-defined options (e.g.{{.UserOptions.foo}}).Stat.Pathβ string β path of the current file.Stat.Nameβ string β name of the current file.Stat.Extensionβ string β extension of the current file.Stat.Sizeβ int64 β size of the current file.Stat.DirSizeβ int64 β total size of the current directory if calculated viacalcdirsize(-1if not calculated).Stat.DirCountβ int β number of items in the current directory if thedircountsoption is enabled (-1if the directory cannot be read).Stat.Permissionsβ string β permissions of the current file.Stat.ModTimeβ string β last modified time of the current file (formatted based on thetimefmtoption).Stat.AccessTimeβ string β last access time of the current file (formatted based on thetimefmtoption).Stat.BirthTimeβ string β birth time of the current file (formatted based on thetimefmtoption).Stat.ChangeTimeβ string β last status (inode) change time of the current file (formatted based on thetimefmtoption).Stat.LinkCountβ string β number of hard links for the current file.Stat.Userβ string β user of the current file.Stat.Groupβ string β group of the current file.Stat.Targetβ string β target if the current file is a symbolic link, otherwise a blank string.Stat.CustomInfoβ string β custom property if defined viaaddcustominfo, otherwise a blank string
And the following functions are exported β yes ma'am, you can call functions in there too π:
dfβfunc() stringβ get an indicator representing the amount of free disk space availableenvβfunc(string) stringβ get the value of an environment variablehumanizeβfunc(int64) stringβ express a file size in a human-readable formatjoinβfunc([]string, string) stringβ join a string array by a separatorlowerβfunc(string) stringβ convert a string to lowercasesubstrβfunc(string, int, int) stringβ get a substring based on starting index and lengthupperβfunc(string) stringβ convert a string to uppercase
and then there's the special identifier {{.SPACER}} β¨ β you drop that in to divide the ruler into sections that are spaced evenly from each other. the way it just evens everything out?? chef's kiss, no notes.
If you wanna see what the default looks like before you start remixing it, the default ruler file lives at https://github.com/gokcehan/lf/blob/master/etc/ruler.default. go look, get inspired, then go absolutely feral with your own. π
and that's the whole manual, bestie β you made it to the end π«Ά this page is from r42, dated 2026-07-31, so that's your version and your date right there. screenshot it, frame it, put it on your wall. you're officially a certified lf girlie now. slay, periodt. πβ¨π
π¦ where this page comes from
- arch rolling: lf 42-1 Β· MIT
- nixpkgs unstable: lf 42
- ubuntu stonking: lf 42+ds-1 Β· MIT
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms