fimrc(5)

๐Ÿ“ฆ
version 0.7.1 ยท 3 versions
, in debian trixie, ubuntu stonking

fimrc โ€” the fim config file & language ref ๐Ÿ’–

okay bestie, welcome to fimrc(5) from the File Formats Manual โœจ this is the whole vibe of how fim gets told what to do, and honestly? it's giving main character energy.


๐ŸŒธ NAME ๐ŸŒธ

fimrc โ€” the fim configuration file and language reference ๐ŸŽ€


โœจ SYNOPSIS โœจ

~/.fimrc
/usr/local/etc/fimrc
fim --script-from-stdin [ {options} ] < {scriptfile}
fim --execute-script {scriptfile} [ {options} ]
fim --execute-commands {commands} [ {options} ]
fim --final-commands {commands} [ {options} ]
fim --write-scriptout {scriptfile} [ {options} ]
fim --write-scriptout /dev/stdout [ {options} ]
fim --chars-press :{commands} [ {options} ]
fim --chars-press :{commands} --chars-press '' [ {options} ]
fim --keysym-press {keysym} [ {options} ]

๐Ÿฆ‹ DESCRIPTION ๐Ÿฆ‹

so this page is literally the whole lore of the fim scripting language โ€” the thing you use for fimrc config files, for {scriptfile}s, and for {commands} you hand over through command line {options} ๐Ÿ’…

you can use this language to fire off commands (or programs, no cap) from the internal program command line โ€” which, by default, you pop open interactively with the ":" key. (yes, and you can customise that key via the "_console_key" variable, iconic.)

wanna leave command line mode? two ways, bestie:

  • press Enter on an empty line โ€” if the line isn't empty, it gets submitted for execution instead ๐Ÿ™ˆ
  • press Esc โ€” but only in SDL mode

the general shape of a fim command/program is right there in the next section, keep scrolling ๐Ÿซถ


๐ŸŽ€ FIM LANGUAGE GRAMMAR ๐ŸŽ€

this section spells out the grammar of the fim language, fr fr.

language elements wrapped in a single quote ("'") are literals.

โš ๏ธ Warning: at the present state, this grammar has conflicts. A future release shall fix them. ๐Ÿ˜ญ
program: %empty
       | statement_list

statement_list: statement
              | statement ';' statement_list
              | non_atomic_statements_block statement_list
              | statements_block

non_atomic_statements_block: '{' statement_list '}'
                           | INTEGER '{' statement_list '}'
                           | conditional_statement

statements_block: atomic_statements_block
                | non_atomic_statements_block

conditional_statement: if_statement
                     | loop_statement

if_statement: 'if' '(' expression ')' statements_block
            | 'if' '(' expression ')' statements_block 'else'
statements_block

loop_statement: 'while' '(' expression ')' statements_block
              | 'do' statements_block 'while' '(' expression ')'

atomic_statements_block: statement ';'
                       | statement ';' ';'
                       | statement ';' ';' ';'

statement: '!' arguments
         | INTEGER ',' INTEGER IDENTIFIER
         | INTEGER ',' INTEGER IDENTIFIER arguments
         | INTEGER IDENTIFIER
         | SLASH_AND_REGEXP
         | '+' UNQUOTED_FLOAT '%'
         | '+' QUOTED_FLOAT '%'
         | '+' INTEGER '%'
         | '*' UNQUOTED_FLOAT
         | '*' QUOTED_FLOAT
         | '*' INTEGER
         | UNQUOTED_FLOAT '%'
         | QUOTED_FLOAT '%'
         | INTEGER '%'
         | '-' UNQUOTED_FLOAT '%'
         | '-' QUOTED_FLOAT '%'
         | '-' INTEGER '%'
         | INTEGER
         | '-' INTEGER
         | IDENTIFIER
         | IDENTIFIER FILE_PATH
         | IDENTIFIER arguments
         | INTEGER IDENTIFIER arguments
         | IDENTIFIER '=' expression

arguments: expression
         | expression arguments

expression: '(' expression ')'
          | expression '.' expression
          | '!' expression
          | expression '%' expression
          | expression '+' expression
          | expression '-' expression
          | expression '*' expression
          | expression '/' expression
          | expression '<' expression
          | expression '>' expression
          | expression '||' expression
          | expression BOR expression
          | expression '&&' expression
          | expression BAND expression
          | expression '>=' expression
          | expression '<=' expression
          | expression '!=' expression
          | expression '==' expression
          | expression '=~' expression
          | '-' expression
          | IDENTIFIER
          | INTEGER
          | QUOTED_FLOAT
          | UNQUOTED_FLOAT
          | STRING

okay so let's decode the types, because this matters ๐Ÿงš

  • a STRING can be either a single quoted string or a double quoted string.
  • a floating point number can be either unquoted (UNQUOTED_FLOAT) or quoted (QUOTED_FLOAT).
  • a QUOTED_FLOAT is a floating point number, either single ("'") or double (""") quoted.
  • an INTEGER shall be an unsigned integer number.
  • an IDENTIFIER shall be one of the valid fim commands (peep the COMMANDS REFERENCE ๐Ÿ‘€) or a valid alias.
  • a VARIABLE shall be an already declared or undeclared variable identifier (peep the VARIABLES REFERENCE ๐Ÿ‘€) or a valid alias, created using the alias command.

now the spicy bits ๐Ÿ”ฅ

the "=~" operator treats the right expression as a STRING, and uses it as a regular expression for matching purposes.

the SLASH_AND_REGEXP is a slash ("/") followed by a STRING, interpreted as a regular expression.

if 'INTEGER , INTEGER IDENTIFIER arguments' shows up, command IDENTIFIER will be repeated on each file in the interval between the two INTEGERs, and substituting the given file name to any '{}' found in the commands arguments (which must be quoted in order to be treated as strings).

see regex(1) for regular expression syntax, iykyk ๐Ÿ’…


๐Ÿ’ซ how some one-line statements get evaluated ๐Ÿ’ซ

  • : โ€” enter command line mode (here one can use readline bindings as C-r, C-s, M-b, M-f, ...)
  • :{number} โ€” jump to {number}^th image in the list
  • :^ โ€” jump to first image in the list
  • :$ โ€” jump to last image in the list
  • :*{factor} โ€” scale the image by {factor}
  • :{scale}% โ€” scale the image to the desired {scale}
  • :+{scale}% โ€” scale the image up to the desired percentage {scale} (relatively to the original)
  • :-{scale}% โ€” scale the image down to the desired percentage {scale} (relatively to the original)
  • /{regexp} โ€” entering the pattern {regexp} (with '/') makes fim jump to the next image whose filename matches {regexp}
  • /*.png$ โ€” entering this pattern (with '/') makes fim jump to the next image whose filename ends with 'png'
  • /png โ€” a shortcut for '/.*png.*'
  • 2,4 stdout '{}' โ€” print three filenames to standard output.
  • !{syscmd} โ€” executes the {syscmd} quoted string as an argument to the "system" fim command.

๐Ÿ‘‘ COMMANDS REFERENCE ๐Ÿ‘‘

๐Ÿ’– alias

alias
alias [{identifier} [{commands} [{description}]]]
  • no arguments โ†’ lists the current aliases.
  • one argument โ†’ shows an identifier's assigned command.
  • two โ†’ assigns to an identifier a user defined command or sequence of commands.
  • three โ†’ also assigns a help string.

๐Ÿ’– align

align ['bottom'|'top'|'left'|right']: if the image is larger than the drawing area, align one side of the image to the border.

align 'center': align equally far from all sides.

align 'info': print internal alignment information.

๐Ÿ’– autocmd

autocmd {event} {pattern} {commands}: manipulate autocommands (inspired from Vim autocmd's, periodt).

  • without arguments โ†’ list autocommands.
  • with arguments โ†’ specifies for which type of event and which current file open, which commands to execute.

see the default built-in configuration files for examples ๐Ÿ‘€

๐Ÿ’– autocmd_del

autocmd_del: specify autocommands to delete.

usage: autocmd_del {event} {pattern} {commands}.

๐Ÿ’– basename

basename {filename}: returns the basename of {filename} in the '_last_cmd_output' variable. โœจ

๐Ÿ’– bind

bind [{keysym} [{commands} [{description}]]]: bind a key {keysym} to {commands}.

  • optional {description} specifies a documentation string.
  • if {keysym} is at least two characters long and begins with 0 (zero), the integer number after the 0 will be treated as a raw keycode to bind the specified {keysym} to.
  • use the '_verbose_keys' variable to discover (display device dependent) raw keys.
  • key binding is dynamical, so you can bind keys even during program's execution ๐Ÿ”ฅ
  • you can get a list of valid symbols (keysyms) by invoking dump_key_codes or in the man page.

๐Ÿ’– cd

cd {path}: change the current directory to {path}.

if {path} is a file, use its base directory name.

cd '-' changes to the previous current directory (before the last ':cd {path}' command).

๐Ÿ’– clear

clear: clear the virtual console. ๐Ÿงผ

๐Ÿ’– commands

commands: display the existing commands.

๐Ÿ’– color

  • color ['desaturate']: desaturate the displayed image colors.
  • color ['negate']: negate the displayed image colors.
  • color ['colorblind'|'c'|'deuteranopia'|'d']: simulate a form of the deuteranopia color vision deficiency (cvd).
  • color ['protanopia'|'p']: simulate a form of the protanopia cvd.
  • color ['tritanopia'|'t']: simulate a form of the tritanopia cvd.
  • color ['daltonize'|'D']: if following a cvd specification, attempts correcting it.
  • color ['identity']: populate the image with 'RGB identity' pixels.
to get back the original, you have to reload the image. ๐Ÿ˜ญ

๐Ÿ’– crop

  • crop: crop image to a centered rectangle, half the width and half the height.
  • crop {p}: crop image to the middle {p} horizontal percent and {p} vertical percent of the image.
  • crop {w} {h}: crop image to the middle {w} horizontal percent and {h} vertical percent of the image.
  • crop {x1} {y1} {x2} {y2}: crop image to the area between the upper left ({x1},{y1}) and lower right ({x2},{y2}) corner.

units are intended as percentage (0 to 100).

Note: still experimental functionality. ๐Ÿ™ˆ

๐Ÿ’– desc

desc 'load' {filename} [{sepchar}]: load description file {filename}, using the optional {sepchar} character as separator.

desc 'reload': load once again description files specified at the command line with --load-image-descriptions-file, with respective separators.

desc ['-all'] ['-append'] ['-nooverw'] 'save' {filename} [{sepchar}]: save current list descriptions to file {filename}, using the optional {sepchar} character as separator, and if '-all' is present then save the variables, and if '-append' is present then only append, and if '-nooverw' is present then do not overwrite existing files.

see documentation of --load-image-descriptions-file for the format of {filename}.

display ๐Ÿ’…โœจ

display
display ['reinit' {string} | 'resize' {w} {h} | ['menuadd' {menuspec}|'menudel'|'v'|'V'] ]: display the current file contents or change display settings.

Okay so display is your main character command โ€” it shows the current file contents or tweaks display settings. ๐Ÿ’–

If you pass the 'reinit' switch, that {string} specifier reinitializes the display device parameters, like resolution and window system options. Pro tip: peep the --output-device command line switch for the allowed values. ๐Ÿ‘€

If 'resize' comes with no argument, it asks the window manager to resize the window like the image. If 'resize' has two arguments, those reset the width and height of the current window. ๐Ÿ“

In the 'menuadd' case, {menuspec} is used as a GTK window menu specification. You can repeat this specification string argument. Each argument has form M/S. M is a slash-separated submenu location, with an optional '_' (underscore) before a GTK accelerator character โ€” e.g. "File", "_File", "View/Scale", "_View/Scale". M cannot be empty and must be followed by a '/'. S can specify a simple entry, a toggle entry, or radio buttons. ๐ŸŽ›๏ธ

If it's a simple entry, it has one to three sections separated by " " (two spaces). If M begins with two non-alphanumeric symbols, those become the separators instead of the two spaces. First section = menu entry name (label), second = command specification, third = shortcut character. The following labels are special, and if followed by '/', they create custom menus: FimMenuLimit (pre-categorized "limit"-based commands based on actual "desc" command data), FimMenuCommands (with commands), FimMenuAliases (with aliases), FimMenuKeyBindings (with bindings), FimMenuVariables (with variables' values), FimMenuCommandsHelp (commands help), FimMenuAliasesHelp (aliases help), FimMenuKeyBindingsHelp (bindings help), FimMenuVariablesHelp (variables' help). โœจ

A toggle button specification can take the form 'toggle__'{identifier}'__'{value}'__'{value} and starts the toggle button with the second {value} (which has to be different). Actually, between 'toggle' and the second value, instead of '__' you can use any two same punctuation signs or Tab characters consistently. E.g. "menu/label toggle___v__1__2 " or "menu/label toggle::_v::1::2 " are ok, but "menu/label toggle___v__1__1 " or "menu/label toggle___v::1::2 " are not. ๐Ÿšซ

A radio buttons specification has as many sections as radio buttons, separated internally by double spaces, and each consists of a string, two spaces, an assignment {identifier}={value} (notice no quotes are necessary around {value}, and repetitions are illegal), two spaces, and an optional accelerator character. E.g. "m/first: v=1 a second: v=2 b third: v=3 c" is ok, but "m/first: v=1 a second: v=2 b third: v=2 c" is not. ๐Ÿ“ป

Option 'menudel' removes all menus. ๐Ÿ—‘๏ธ

Note: 'menuadd' and 'menudel' are only valid for the gtk mode and are experimental. In particular, currently there are limitations on which characters are allowed in menu command specifications; the recommended workaround is to use aliases. ๐Ÿ˜ญ

Experimental option 'v' increases internal verbosity for some graphical outputs; experimental option 'V' decreases it. ๐Ÿ“ข

See also the '_debug_commands' variable. ๐Ÿ”


dump_key_codes ๐ŸŽน

dump_key_codes: dump the active key codes (unescaped, for inspection purposes).

Basically it dumps the active key codes, unescaped, just for inspection purposes. No cap. ๐Ÿ‘€


echo ๐Ÿ“ฃ

echo {args}: print the {args} on console.

Prints the {args} on console. Simple as that, bestie. ๐Ÿ’ฌ


else ๐Ÿค”

if(expression){action;}['else'{action;}]: see if.

This is the else companion โ€” see if. ๐Ÿ”


eval ๐Ÿง 

eval {args}: evaluate {args} as commands, executing them.

Evaluates {args} as commands, executing them. It's giving "run this for me". โšก


exec ๐Ÿƒโ€โ™€๏ธ

exec {filename(s)}: execute script {filename(s)}.

Executes script {filename(s)}. Go off, script. ๐Ÿ“œ


font ๐Ÿ”ค

font 'scan' [{dirname}]: scan {dirname} or /usr/share/consolefonts looking for fonts in the internal fonts list.
font 'load' {filename}: load font {filename}.
font {'next'|'prev'}: load next or previous font from the internal fonts list.
font 'info': print current font filename.

Font time! โœจ

  • font 'scan' [{dirname}] โ€” scan {dirname} or /usr/share/consolefonts looking for fonts in the internal fonts list. ๐Ÿ”
  • font 'load' {filename} โ€” load font {filename}. ๐Ÿ“ฅ
  • font {'next'|'prev'} โ€” load next or previous font from the internal fonts list. โญ๏ธ
  • font 'info' โ€” print current font filename. โ„น๏ธ

getenv ๐ŸŒ

getenv {identifier}: create a variable with the same value as the '{identifier}' environment variable, but with an identifier prefixed by 'ENV_'. So e.g. getenv 'DISPLAY' creates 'ENV_DISPLAY'. Nothing is being printed; no variable is created if {identifier} is empty.

Creates a variable with the same value as the '{identifier}' environment variable, but with an identifier prefixed by 'ENV_'. So e.g. getenv 'DISPLAY' creates 'ENV_DISPLAY'. Nothing is printed; no variable is created if {identifier} is empty. ๐Ÿซฅ


goto ๐Ÿš€

goto {['+'|'-']{number}['%']['f'|'p'|'F'|'P']}+ | {/{regexp}/} | {?{filename}} | {'+//'} | {'+/'|'-/'}[C] | {{'+'|'-'}{identifier}['+']}: jump to an image.

Okay so goto jumps to an image. It's the navigation queen. ๐Ÿ‘‘

If {number} is given, and not surrounded by any specifier, go to image at index {number}. If followed by '%', the effective index is computed as a percentage to the current available images. If prepended by '-' or '+', the jump is relative to the current index. The 'f' specifier asks for the jump to occur within the files (same for 'F', but accelerates if keep pressing). The 'p' specifier asks for the jump to occur in terms of pages, within the current file (same for 'P', but accelerates if keep pressing). If there's only one file in the list and no 'f' specified, a 'p' will be implied, for a page jump. ๐Ÿ“„

The above form can be concatenated several times, but only the last occurrence of either file or page goto will be effective. โš ๏ธ

If /{regexp}/ is given, jump to the first image matching the given /{regexp}/ regular expression pattern. ๐Ÿ”Ž

If the argument starts with ?, jump to the filename following ?. ๐Ÿ“

If given '+//', jump to the first different image matching the last given regular expression pattern. ๐ŸŒ€

With '+/'C or '-/'C, jump to the next or the previous file according to C: if 's' if same directory, if 'd' if down the directory hierarchy, if 'u' if down the directory hierarchy, if 'b' if same basename, if upper case match is negative, if missing defaults to 'S' (jump to file in different dir). ๐Ÿ“‚

If {identifier|identifier2...}] is encountered after a '+' or '-' sign, jump to the next or the previous image having a different value for any corresponding i:{identifier} (a trailing '+' requires a non empty value). ๐Ÿท๏ธ

Matching can occur on both file name and description, possibly loaded via desc or --load-image-descriptions-file; see also '_lastgotodirection' and '_re_search_opts'. ๐Ÿง

You can specify multiple arguments to goto: those after the first one triggering a jump are ignored. ๐Ÿšซ

Executes autocommands for events PreGoto and PostGoto. Keeping pressed shall accelerate images browsing. โฉ


help ๐Ÿ†˜

help [{identifier}]: provide online help, assuming {identifier} is a variable, alias, or command identifier.

Provides online help, assuming {identifier} is a variable, alias, or command identifier. ๐Ÿซถ

If {identifier} begins with '/', search on the help contents, and show a list of matching items. ๐Ÿ”

A list of commands can be obtained simply invoking 'commands'; a list of aliases with 'alias'; a list of bindings with 'bind'; a list of variables with 'variables'. ๐Ÿ“‹


if ๐Ÿงฉ

if(expression){action;}['else'{action;}]: see 'else'.

This is the if โ€” see 'else'. ๐Ÿ”€


info โ„น๏ธ

info: display information about the current file.

Displays information about the current file. That's it, that's the tweet. ๐Ÿฆ


limit ๐ŸŽฏ

limit  {'-list'|'-listall'} 'variable'|['-further'|'-merge'|'-subtract'] [{expression} |{variable} {value}]: A browsable file list filtering function (like limiting in the 'mutt' program). Uses information loaded via --load-image-descriptions-file.

Limit is a browsable file list filtering function โ€” like limiting in the 'mutt' program. It uses information loaded via --load-image-descriptions-file. ๐ŸŽ›๏ธ

  • If invoked with '-list'/'-listall' only, will list the current description variable ids. ๐Ÿ“
  • If invoked with '-list'/'-listall' 'id', will list set values for the variable 'id'. ๐Ÿ”ข
  • If '-further' is present, will start with the current list; if not, with the full list. ๐Ÿ“š
  • If '-merge' is present, new matches will be merged in the existing list and sorted. ๐Ÿ”€
  • If '-subtract' is present, sort and filter out matches. โž–
  • If {variable} and {value} are provided, limit to files having property {variable} set to {value}. ๐Ÿท๏ธ
  • If {expression} is one exclamation point ('!'), will limit to the currently marked files only. โ—
  • If {expression} is '~!' will limit to files with unique basename. ๐Ÿงฌ
  • if '~=', to files with duplicate basename. ๐Ÿ‘ฏ
  • if '~^', to the first of the files with duplicate basename. ๐Ÿฅ‡
  • if '~$', to the last of the files with duplicate basename. ๐Ÿฅ‰
  • On '~i' [MINIDX][-][MAXIDX], (each a number possibly followed by a multiplier 'K') will limit on filenames in position MINIDX to MAXIDX. ๐Ÿ”ข
  • On '~z' will limit to files having the current file's size. ๐Ÿ“
  • on '~z' [MINSIZE][-][MAXSIZE], (each a number possibly followed by a multiplier among 'k','K','m','M') will limit on filesize within these limits. ๐Ÿ“
  • on '~d' will limit to files having the current file's date +- one day. ๐Ÿ“…
  • on '~d' [MINTIME][-][MAXTIME], (each the count of seconds since the Epoch (First of Jan. of 1970) or a date as DD/MM/YYYY) will limit on file time (struct stat's 'st_mtime', in seconds) within this interval. โณ
  • For other values of {expression}, limit to files whose description string matches {expression}. ๐Ÿ”

Invoked with no arguments, the original browsable files list is restored. ๐Ÿ”„

list ๐Ÿ“‹

bestie, list is literally the file-list manager and she has so many moods. here's the full menu, no skips:

  • list โ€” display the files list.
  • list 'random_shuffle' โ€” randomly shuffle the file list.
  • list 'reverse' โ€” reverse the file list.
  • list 'clear' โ€” clear the file list.
  • list 'sort' โ€” sort the file list.
  • list 'sort_basename' โ€” sort the file list according to base name.
  • list 'sort_comment' โ€” sort the file list according to the value of the _comment variable.
  • list 'sort_var' {var} โ€” sort the file list according to the value of the i:{var} variable.
  • list 'vars'|'variables' โ€” list variables in all i:* read from description file.
  • list 'sort_fsize' โ€” sort the file list according to file size.
  • list 'sort_mtime' โ€” sort the file list according to modification date.
  • list 'pop' โ€” remove the current file from the files list, and step back.
  • list 'remove' [{filename(s)}] โ€” remove the current file, or the {filename(s)}, if specified.
  • list 'push' {filename(s)} โ€” push {filename(s)} to the back of the files list.
  • list 'filesnum' โ€” display the number of files in the files list.
  • list 'mark' [{args}] โ€” mark image file names for stdout printing at exit; with {args}, mark the ones matching according to the rules of the 'limit' command, otherwise the current file.
  • list 'unmark' [{args}] โ€” unmark marked image file names; with {args}, unmark the ones matching according to the rules of the 'limit' command, otherwise the current file.
  • list 'marked' โ€” show which files have been marked so far.
  • list 'dumpmarked' โ€” dump to stdout the marked files (you usually want to 'unmarkall' afterwards).
  • list 'markall' โ€” mark all the current list files.
  • list 'unmarkall' โ€” unmark all the marked files.
  • list 'pushdir' {dirname} โ€” push all the files in {dirname}, when matching the regular expression in variable _pushdir_re or, if empty, from constant regular expression .(JPG|PNG|GIF|BMP|TIFF|TIF|JPEG|JFIF|PPM|PGM|PBM|PCX|QOI|AVIF|WEBP)$.
  • list 'pushdirr' {dirname} โ€” like pushdir, but also push encountered directory entries recursively.
  • list 'swap' โ€” move the current image filename to the first in the list (you'll have to invoke reload to see the effect).
๐Ÿšจ heads up: of the above commands, several are temporarily not available for the duration of a background load (enabled by --background-recursive), which lasts until _loading_in_background is 0.

load ๐Ÿซถ

  • load โ€” load the image, if not yet loaded (see also 'reload').

Executes autocommands for events PreLoad and PostLoad.

pan ๐Ÿ•น๏ธ

the little movement gremlin. here's every form:

pan {vsteps}% {hsteps}%: pan the image to {vsteps} percentage steps from the top and {hsteps} percentage steps from left.
pan {vsteps} {hsteps}: pan the image to {vsteps} pixels from the top and {hsteps} pixels from left.
pan {'down'|'up'|'left'|'right'|'ne'|'nw'|'se'|'sw'}[+-] [{steps}['%']]: pan the image {steps} pixels in the desired direction.
  • If the '%' specifier is present, {steps} is treated as a percentage of current screen dimensions.
  • If {steps} is not specified, the _steps variable is used.
  • If present, the _hsteps variable is considered for horizontal panning.
  • A '+' (or '-') sign at the end of the first argument jumps to next (or previous) if border is reached.
  • If present, the _vsteps variable is considered for vertical panning.
  • The variables may be terminated by the '%' specifier.

Executes autocommands for events PrePan and PostPan.

popen ๐Ÿš

  • popen {syscmd} โ€” pipe a command, invoking popen(): spawns a shell, invoking '{syscmd}' and executing as fim commands the output of '{syscmd}'. Can be disabled at configure time with --disable-system.

pread ๐Ÿ“–

  • pread {args} โ€” execute {args} as a shell command and read the output as an image file (using 'popen'). Can be disabled at configure time with --disable-system.

prefetch ๐Ÿ”ฎ

  • prefetch โ€” prefetch (read into the cache) the two nearby image files (next and previous), for a faster subsequent opening.

Executes autocommands for events PrePrefetch and PostPrefetch.

See also the _want_prefetch variable.

pwd ๐Ÿ“

  • pwd โ€” print the current directory name, and updates the _pwd variable.

quit ๐Ÿ‘‹

  • quit [{number}] โ€” terminate the program.
  • If {number} is specified, use it as the program return status.
๐Ÿ’€ note that autocommand 'PostInteractiveCommand' does not trigger after this command.

recording โบ๏ธ

  • recording 'start' โ€” start recording the executed commands.
  • recording 'stop' โ€” stop recording the executed commands.
  • recording 'dump' โ€” dump in the console the record buffer.
  • recording 'execute' โ€” execute the record buffer.
  • recording 'repeat_last' โ€” repeat the last performed action.

redisplay ๐Ÿ–ฅ๏ธ

  • redisplay โ€” re-display the current file contents.

reload ๐Ÿ”„

  • reload [{arg}] โ€” load the image into memory.
  • If {arg} is present, force reloading, bypassing the cache (see also 'load').

Executes autocommands for events PreReload and PostReload.

rotate ๐ŸŒ€

  • rotate {number} โ€” rotate the image the specified amount of degrees. If unspecified, by one. If you are interested in orthogonal rotations, see _orientation and related aliases.

Executes autocommands for events PreScale and PostScale.

scale ๐Ÿ“

scale
{['+'|'-']{value}['%']|'*'{value}|'w'|'h'|'a'|'b'|'+[+-*/]'|['<'|'>']|'shadow'}:

scale the image according to a scale {value} (e.g.: 0.5,40%,'w','h','a','b').

  • If given '*' and a value, multiply the current scale by that value.
  • If given 'w', scale according to the screen width.
  • If given 'h', scale to the screen height.
  • If given 'a', to the minimum of 'w' and 'h'.
  • If given 'b', like 'a', provided that the image width exceeds 'w' or 'h'.
  • If {value} is a number, scale relatively to the original image width.
  • If the number is followed by '%', the relative scale is treated as a percentage.
  • If given '++'('+-'), increment (decrement) the _magnify_factor, _reduce_factor variables by _scale_factor_delta.
  • If given '+*'('+/'), multiply (divide) the _magnify_factor, _reduce_factor variables by _scale_factor_multiplier.
  • If given '<' (or '>'), shrink (or magnify) image using nearest mipmap (cached pre-scaled version). If given 'shadow' as a parameter, search a same-named file in one of the directories specified to --load-shadow-dir.

Executes autocommands for events PreScale and PostScale.

scroll ๐ŸŽž๏ธ

  • scroll โ€” scroll down the image, going next when hitting the bottom.
  • scroll 'forward' โ€” scroll the image as we were reading left to right (see '_scroll_skip_page_fraction' variable).

Executes autocommands for events PrePan and PostPan.

set ๐ŸŽ›๏ธ

  • set โ€” returns a list of variables which are set.
  • set {identifier} โ€” returns the value of variable {identifier}.
  • set {identifier} {value} โ€” sets variable {identifier} to value {value}.

set_commandline_mode โŒจ๏ธ

  • set_commandline_mode โ€” set console mode. Note that the mode will change only after the current block of commands is evaluated.

set_interactive_mode ๐ŸŽฎ

  • set_interactive_mode โ€” set interactive mode. Note that the mode will change only after the current block of commands is evaluated.

sleep ๐Ÿ˜ด

  • sleep [{number}] โ€” sleep for the specified number of seconds (or 1, if unspecified).

status ๐Ÿ“Š

  • status โ€” set the status line to the collation of the given arguments.

stderr ๐Ÿšจ

  • stderr {args} โ€” writes to stderr its arguments {args}.

stdout ๐Ÿ“ค

  • stdout {args} โ€” writes to stdout its arguments {args}.

system ๐Ÿ’ป

  • system {syscmd} โ€” get the output of executing the {syscmd} system command. Uses the popen() system call. Usually popen invokes "/bin/sh -c {syscmd}". This might not handle a multi-word command; in that case you have to put it into a script. See 'man popen' for more. Can be disabled at configure time with --disable-system.

variables ๐Ÿ—‚๏ธ

  • variables โ€” display the existing variables.

unalias ๐Ÿงน

  • unalias {identifier} | '-a' โ€” delete the alias {identifier} or all aliases (use '-a', not -a).

unbind ๐Ÿ”“

  • unbind {keysym} โ€” unbind the action associated to a specified {keysym}.
  • If {keysym} is at least two characters long and begins with 0 (zero), the integer number after the 0 will be treated as a raw keycode to bind the specified {keysym} to.
  • Use the '_verbose_keys' variable to discover (display device dependent) raw keys.

while โ™พ๏ธ

  • while(expression){action;} โ€” A conditional cycle construct.
๐Ÿ˜ญ may be interrupted by hitting the 'Esc' or the ':' key.

window ๐ŸชŸ

  • window {args} โ€” this command is disabled.

โŒจ๏ธ KEYSYMS REFERENCE โŒจ๏ธ

the full roster of key names you can bind, every single one, no cap:

" "  "!"  '"'  "#"  "$"  "%"  "&"  "'"  "("  ")"  "*"  "+"  ","  "-"
"."  "/"  "0"  "1"  "2"  "3"  "4"  "5"  "6"  "7"  "8"  "9"  ":"  ";"
"<"  "="  ">"  "?"  "@"  "A"  "Any"  "B"  "Backspace"  "C"  "C-a"  "C-b"
"C-c"  "C-d"  "C-e"  "C-f"  "C-g"  "C-h"  "C-i"  "C-j"  "C-k"  "C-l"
"C-m"  "C-n"  "C-o"  "C-p"  "C-q"  "C-r"  "C-s"  "C-t"  "C-u"  "C-v"
"C-w"  "C-x"  "C-y"  "C-z"  "D"  "Del"  "Down"  "E"  "End"  "Enter"
"Esc"  "F"  "F1"  "F10"  "F11"  "F12"  "F2"  "F3"  "F4"  "F5"  "F6"
"F7"  "F8"  "F9"  "G"  "H"  "Home"  "I"  "Ins"  "J"  "K"  "L"  "Left"
"M"  "N"  "O"  "P"  "PageDown"  "PageUp"  "Q"  "R"  "Right"  "S"  "T"
"Tab"  "U"  "Up"  "V"  "W"  "X"  "Y"  "Z"  "["  "\"  "]"  "^"  "_"  "`"
"a"  "b"  "c"  "d"  "e"  "f"  "g"  "h"  "i"  "j"  "k"  "l"  "m"  "n"
"o"  "p"  "q"  "r"  "s"  "t"  "u"  "v"  "w"  "x"  "y"  "z"  "{"  "|"
"}"  "~"

โœจ AUTOCOMMANDS REFERENCE โœจ

the available autocommands are: PreScale, PostScale, PrePan, PostPan, PreRedisplay, PostRedisplay, PreDisplay, PostDisplay, PrePrefetch, PostPrefetch, PreReload, PostReload, PreLoad, PostLoad, PreGoto, PostGoto, PreConfigLoading, PostConfigLoading, PreHardcodedConfigLoading, PostHardcodedConfigLoading, PreUserConfigLoading, PostUserConfigLoading, PreGlobalConfigLoading, PostGlobalConfigLoading, PreInteractiveCommand, PostInteractiveCommand, PreExecutionCycle, PostExecutionCycle, PreExecutionCycleArgs, PreWindow, PostWindow, and they are triggered on actions as suggested by their name. ๐Ÿ’–

those associated to actual commands are mentioned in the associated commands reference. iykyk.


๐Ÿฆ‹ VARIABLES REFERENCE ๐Ÿฆ‹

๐Ÿ‘‘ if undeclared, a variable will evaluate to 0.

when assigning a variable to a string, use single or double quoting, otherwise it will be treated as a number. periodt.

the namespaces in which variables may exist are: current image, global. a namespace is specified by a prefix, which can be: 'i:', be prepended to the variable name. the global namespace is equivalent to the empty one: ''. the special variable i:* expands to the collation of all the name-value pairs for the current image.

in the following, the [internal] variables are the ones referenced in the source code (not including the hardcoded configuration, which may be inspected and/or invalidated by the user at runtime).

okay bestie we're still deep in the variables and they just keep coming ๐Ÿ’– stay with me, we're doing great, this is the main character part of the manpage fr fr.

  • _TERM [out,g:] โ€” the environment TERM variable. that's it, that's the whole thing โœจ
  • __exif_flipped [out,i:] โ€” flipping information, read from the EXIF tags of a given image ๐Ÿฆ‹
  • __exif_mirrored [out,i:] โ€” mirroring information, read from the EXIF tags of a given image ๐Ÿฆ‹
  • _all_file_loaders [out,g:] โ€” a space-separated list of hardcoded file loaders, and you can use them with _file_loader ๐Ÿ’…
  • _archive_files [in,g:] โ€” if it's non-empty, it's a regular expression matching the filenames to be treated as archives (multipage files). if it's empty, then ".(RAR|ZIP|TAR|TAR.GZ|TGZ|TAR.BZ2|TBZ|TBZ2|CBR|CBZ|LHA|7Z|XAR|ISO)$" gets used instead. and inside each archive? only the filenames matching the regular expression in the _pushdir_re variable are even considered for loading. periodt.
  • _autocmd_trace_stack [in,g:] โ€” dumps an autocommands (autocmd) stack trace to stdout while they execute. it's for debugging purposes, bestie ๐Ÿ›
  • _autodesaturate [in,g:] โ€” if 1, desaturate all images.
  • _autoflip [in,g:] โ€” if 1, flip all images.
  • _automirror [in,g:] โ€” if 1, mirror all images.
  • _autonegate [in,g:] โ€” if 1, negate all images.
  • _autotop [in,g:] โ€” if 1, align freshly loaded images to the top โœจ
  • _buffered_in_tmpfile [out,i:] โ€” if an image got temporarily converted and decoded from a temporary file, its name lives here.
  • _cache_control [in,g:] โ€” a string for cache control. if it starts with 'm', cache mipmaps; if it starts with 'M' then do not not cache them (yes, exactly like that, i don't make the rules ๐Ÿ’€). otherwise the defaults apply.
  • _cache_status [out,g:] โ€” a string with current information on cache status.
  • _cached_images [out,g:] โ€” the number of images currently cached.
  • _caption_over_image [in,g:] โ€” if you set it to a value different than 0, it displays a custom comment string specified according to the value of _caption_over_image_fmt; if it's larger than 1, you get a black background; if it's 3, it draws above the image, with no overlap. and it occupies at most half of the screen ๐ŸŽ€
  • _caption_over_image_fmt [in,g:] โ€” a custom info format string, displayed in a caption over the image; if it's unset you get i:_comment; otherwise it's a custom format string specified just as _info_fmt_str.
  • _command_expansion [in,g:] โ€” if 1, enable autocompletion (on execution) of alias and command strings โœจ
  • _comment [i:,out] โ€” the image comment, extracted from the image file (if there is any).
  • _console_buffer_free [out,g:] โ€” amount of unused memory in the output console buffer.
  • _console_buffer_total [out,g:] โ€” amount of memory allocated for the output console buffer.
  • _console_buffer_used [out,g:] โ€” amount of used memory in the output console buffer.
  • _console_key [in,g:] โ€” the key bound (an integer variable) to spawn the command line; it overrides any other binding. it's set to -1 if the command line is disabled.
  • _console_lines [out,g:] โ€” the number of buffered output console text lines.
  • _console_offset [in,out,g:] โ€” position of the text beginning in the output console, expressed in lines.
  • _debug_commands [in,g:] โ€” debugging option string for printing out stuff. here's the tea:
    • if it contains 'a' โ†’ print out autocmd info
    • if it contains 'c' โ†’ print out each command
    • if it contains 'k' โ†’ print out each pressed key in command line mode
    • if it contains 'i' โ†’ print interpreter internal steps
    • if it contains 'B' โ†’ clear screen and print background loading files
    • if it contains 'C' โ†’ print cache activity
    • if it contains 'm' โ†’ gtk mode menus tooltips will contain also specification strings
    • if it contains 'mm' โ†’ gtk mode menu building will also be very verbose ๐Ÿ˜ญ
  • _device_string [out,g:] โ€” the current display device string, in the form [fb|sdl|gtk|ca|aa|dumb][={gfxopts}]. see option --output-device for a description ๐Ÿฆ‹
  • _display_as_binary [in,g:] โ€” force loading files as pixelmaps (no image decoding is performed); if 1, using one bit per pixel; if 24, using 24 bits per pixel. if it's empty, load and decode the files as usual.
  • _display_as_rendered_text [in,g:] โ€” if 1, force loading the specified files as text files (no image decoding is performed); otherwise load and decode the files as usual.
  • _display_busy [in,g:] โ€” if 1, display a message on the status bar when processing.
  • _display_console [in,g:] โ€” if 1, display the output console.
  • _display_status [in,g:] โ€” if 1, display the status bar.
  • _display_status_bar [in,g:] โ€” if 1, display the status bar. (yes, its twin ๐Ÿ’…)
  • _display_status_fmt [in,g:] โ€” a custom info format string, displayed in the lower left corner of the status bar; if it's unset you get the full pathname; otherwise it's a custom format string specified just as _info_fmt_str.
  • _do_sanity_check [in,experimental,g:] โ€” if 1, execute a sanity check on startup ๐Ÿงš
  • _downscale_huge_at_load [in,g:] โ€” if 1, downscale at load time those huge images (aka the ones exceeding by 1.5 times the screen size).
  • _exif_orientation [out,i:] โ€” orientation information in the same format of _orientation, read from the orientation EXIF tags (i:EXIF_Orientation).
  • _exiftool_comment [out,g:] โ€” comment extracted via the exiftool interface; see _use_exiftool.
  • _external_decoder_program [out,i:] โ€” if an image has been decoded via an external program, its name is here.
  • _fbfont [out,g:] โ€” The current console font file string. if the internal hardcoded font has been used, then its value is "fim://".
  • _fbfont_as_screen_fraction [in,g:] โ€” Scale the rendered text to at least this (integer) fraction of the screen. disable font autoscaling with -1. (Only enabled if configured with --with-font-magnifying-factor=FACTOR, with FACTOR<1).
  • _fbfont_magnify_factor [in,g:] โ€” For the rendered text, use a font magnified by this (integer) factor. Maximal value is "16". (Only enabled if configured with --with-font-magnifying-factor=FACTOR, with FACTOR<1).
  • _fbfont_verbosity [in,g:] โ€” if > 0, verbose font loading
  • _file_load_time [out,i:] โ€” time taken to load the file and decode the image, in seconds โฑ๏ธ
  • _file_loader [in,i:,g:] โ€” specify a file loader to use (among the ones listed in the -V switch output); [out] i:_file_loader stores the loader of the current image.
  • _fileindex [out,g:] โ€” the current image numeric index.
  • _filelistlen [out,g:] โ€” current image list length (number of visible images).
  • _filename [out,i:] โ€” the current file name string.
  • _fim_bpp [out,g:] โ€” the bits per pixel count.
  • _fim_default_config_file_contents [out,g:] โ€” the contents of the default (hardcoded) configuration file (executed after the minimal hardcoded config).
  • _fim_default_grammar_file_contents [out,g:] โ€” the contents of the default (hardcoded) grammar file.
  • _fim_scriptout_file [in,g:] โ€” the name of the file to write to when recording sessions.
  • _fim_version [out,g:] โ€” fim version number; may be used for keeping compatibility of fim scripts across evolving versions.
  • _hide_gtk_menus [out,g:] โ€” internal ๐Ÿคซ
  • _hsteps [in,g:] โ€” the default steps, in pixels, when panning images horizontally (overrides steps).
  • _ignorecase [in,g:] โ€” if 1, allow for case-insensitive regexp-based match in autocommands (autocmd).
  • _info_fmt_str [in,g:] โ€” a custom info format string, displayed in the lower right corner of the status bar; it may contain ordinary text and special 'expando' sequences. These are:
    • %p for current scale, in percentage
    • %w for width
    • %h for height
    • %i for image index in list
    • %k for the value of i:_comment (comment description) variable in square brackets (if non empty)
    • %l for current image list length
    • %L for flip/mirror/orientation information
    • %P for page information
    • %F for file size
    • %M for screen image memory size
    • %m for memory used by mipmap
    • %C for memory used by cache
    • %T for total memory used (approximation)
    • %R for total max memory used (as detected by getrusage())
    • %n for the current file path name
    • %N for the current file path name basename; ;
    • %c for centering information
    • %v for the fim program/version identifier string
    • %% for an ordinary %

a sequence like %?VAR?EXP? expands to EXP if i:VAR is set (or, otherwise, if VAR); EXP is copied verbatim except for contained sequences of the form %:VAR:, which expand to the value of variable i:VAR (or, if unset, VAR); this is meant to be used like in e.g. '%?EXIF_DateTimeOriginal?[%:EXIF_DateTimeOriginal:]?', where the EXIF-set variable EXIF_DateTimeOriginal (make sure you have libexif for this) are used only if present. โœจ

  • _inhibit_display [internal,g:] โ€” if 1, inhibit display.
  • _last_cmd_output [out,experimental,g:] โ€” the last command output.
  • _last_file_loader [out,g:] โ€” set to the name of the last file loader used.
  • _last_system_output [out,experimental,g:] โ€” the standard output of the last call to the system command.
  • _lastfileindex [out,g:] โ€” the last visited image numeric index (different than _fileindex). super useful for jumping back and forth easily between two images with 'goto _lastfileindex' ๐Ÿฆ‹
  • _lastgotodirection [out,g:] โ€” the last file goto direction (either string '+1' or string '-1').
  • _lastpageindex [out,g:] โ€” the last visited file page index.
  • _load_default_etc_fimrc [in,g:] โ€” if 1 at startup, load the system wide initialization file.
  • _load_fim_history [in,g:] โ€” if 1 on startup, load the ~/.fim_history file on startup.
  • _load_hidden_dirs [in,g:] โ€” if it's not 1, when pushing directories/files, the ones with a name beginning with a dot (.) get skipped ๐Ÿ‘€
  • _loading_in_background [out,g:] โ€” 1 if the program has been invoked with --background-recursive and is still loading in background.
  • _loop_only_once [internal,g:] โ€” if 1 and doing a --slideshow, do it once.
  • _lwidth [in,g:] โ€” if>0, force the output console text width.
  • _magnify_factor [in,g:] โ€” the image scale multiplier used when magnifying images size.
  • _max_cached_images [in,g:] โ€” the maximum number of images after which forcing evictions. setting this to 0 (no limits) is ok provided _max_cached_memory is set meaningfully ๐Ÿ‘‘
  • _max_cached_memory [in,g:] โ€” the maximum amount of memory (in KiB) at which images continue being added to the cache.
bestie. listen. setting this to 0 (no limit) leads to a crash (there is no protection currently). do not do the thing ๐Ÿ’€
  • _max_iterated_commands [g:] โ€” the iteration limit for N in "N[commandname]" iterated command invocations.
  • _min_cached_images [in,g:] โ€” the minimum number of images to keep from eviction; if it's less than four it can lead to inefficiencies: e.g. when jumping between two images, each time an erase and a prefetch of neighboring images would trigger. default value is 4.
  • _no_default_configuration [in,g:] โ€” if 0, a default, hardcoded configuration is loaded at startup, after the minimal hardcoded one.
  • _no_external_loader_programs [in,g:] โ€” if 1, do not attempt using external programs to decode a file of an unknown format.
  • _no_rc_file [in,g:] โ€” if 1, do not load the ~/.fimrc configuration file at startup.
  • _open_offset [in,optional,g:,i:] โ€” offset (specified in bytes) used when opening a file; [out] i:_open_offset is assigned to images opened at a nonzero offset.
  • _open_offset_retry [in,optional,g:] โ€” number of adjacent bytes to probe in opening the file.
  • _orientation [internal,i:] โ€” Orthogonal clockwise rotation (orientation) is controlled by: 'i:_orientation', 'g:_orientation' and applied on a per-image basis. In particular, the values of the three variables are summed up and the sum is interpreted as the image orientation. If the

sum is 0, no rotation applies; if it is 1, a single (90ยฐ) rotation applies; if it is 2, a double (180ยฐ) rotation applies; if it is 3, a triple (270ยฐ) rotation applies. If the sum is not one of 0,1,2,3, the value of the sum modulo 4 is considered. Therefore, :i:_orientation=1 and :i:_orientation=5 are equivalent: they rotate the image one time by 90ยฐ. math is math bestie ๐Ÿ’…

  • _pread_cmd [in,g:] โ€” a user-specified shell command that emits an image on stdout, in a format readable by the convert utility. If the current filename matches "^[/A-Za-z0-9_.][/A-Za-z0-9_.-]*$", substitute it to any occurrence of '{}'.
  • _preferred_rendering_dpi [in,optional,g:] โ€” if >0, rendering of pdf, ps, djvu use this value for a default document dpi; if unset, use an internal default value.
  • _preferred_rendering_width [in,optional,g:] โ€” if >0, bit-based (see _display_as_binary) rendering uses this value for a default document width (instead of a default value).
  • _push_checks [in,experimental,g:] โ€” if 1 (default), check with stat() the existence of input files before push'ing them (set this to 0 to speed up loading very long file lists; in these cases a trailing slash (/) must be used to tell fim a pathname is a directory). This only works after initialization (thus, after command line files have been push'ed); use --no-stat-push if you wish to set this to 0 at command line files specification.
  • _push_pushes_dirs [in,g:] โ€” if 1, the push command also accepts and pushes directories (using pushdir). if 2, also push hidden files/directories, that is, ones whose names begin with a dot (.).
  • _pushdir_re [in] โ€” regular expression to match against when pushing files from a directory or an archive. By default this is ".(JPG|PNG|GIF|BMP|TIFF|TIF|JPEG|JFIF|PPM|PGM|PBM|PCX|QOI|AVIF|WEBP)$".
  • _pwd [out,g:] โ€” the current working directory; variable updated at startup and whenever the working directory changes.
  • _re_search_opts [in,g:] โ€” affects regexp-based searches; if an empty string, defaults apply; if it contains 'i' ('I'), case insensitive (sensitive) searches occur; if it contains 'b', match on basename, if contains 'f' on full pathname; if it contains 'D', match on description.
  • _reduce_factor [in,g:] โ€” the image scale multiplier used when reducing images size.
  • _retry_loader_probe [in,g:] โ€” if set to 1 and a user-specified file loader fails, probe for a different loader.
  • _rows [in,g:] โ€” if >0, set the number of text lines in the console to be displayed .
  • _save_fim_history [in,g:] โ€” if 1 on exit, save the ~/.fim_history file on exit.
  • _scale_factor_delta [in,g:] โ€” value used for incrementing/decrementing the scaling factors.
  • _scale_factor_multiplier [in,g:] โ€” value used for scaling up/down the scaling factors.
  • _scale_style [in,g:] โ€” if non empty, pass it to the scale command; see its documentation for possible values.
  • _screen_height [out] โ€” the screen height.
  • _screen_width [out,g:] โ€” the screen width.
  • _scroll_skip_page_fraction [int,g:] โ€” if >1, fraction of page to skip when scrolling (e.g. 'scrollforward'); if 1, auto chosen; if <1, disabled.
  • _seek_magic [optional,g:] โ€” seek a 'magic' signature in the file after opening it, and try decoding it starting within the range of that signature (use like this: fim -C '_seek_magic=MAGIC_STRING;push filename').
  • _slideshow_sleep_time [in,g:] โ€” number of seconds of sleep during slideshow mode.
  • _status_line [in,g:] โ€” if 1, display the status bar.
  • _steps [in,g:] โ€” the default steps, in pixels, when panning images.
  • _stop_slideshow [internal,g:] โ€” if it becomes 1 during a slideshow, stop it; gets unset before each 'while'.
  • _sys_rc_file [in,g:] โ€” string with the global configuration file name.
  • _use_exiftool [in,g:] โ€” if >0 and supported, use exiftool to get additional information. If 1, append this information to _comment; if 2, to _exiftool_comment.
  • _use_mipmaps [in,g:] โ€” if >0, use mipmaps to speed up downscaling of images (this has a memory overhead equivalent to one image copy); mipmaps are not cached. If 2, use every fourth source pixel instead of averaging (good for photos, not for graphs).
  • _verbose_errors [in,g:] โ€” if 1, display on stdout internal errors, while parsing commands.
  • _verbose_keys [in,g:] โ€” if 1, display on the console the raw keycode of each key hit interactively.
  • _verbosity [in,experimental,g:] โ€” program verbosity.
  • _vsteps [in,g:] โ€” the default steps, in pixels, when panning images vertically (overrides steps).
  • _want_autocenter [in,g:] โ€” if 1, center the image when displayed.
  • _want_exif_orientation [in,g:] โ€” if 1, reorient images using information from EXIF metadata (and stored in in _exif_orientation, __exif_mirrored, __exif_flipped ).
  • _want_prefetch [in,g:] โ€” if 1, prefetch further files just after displaying the first file; if 2 (and configured with --enable-cxx11) load in the background.
  • _want_wm_caption_status [in,g:] โ€” this works only if supported by the display device. If set to a number that is not 0, show the status (or command) line in the window manager caption; if set to a non-empty string, interpret it just as a file info format string (see _info_fmt_str); if empty, show the program version.
  • _want_wm_mouse_ctrl [in,g:] โ€” if at least 9 chars long, enable mouse click/movement behaviour when in GTK, SDL or libcaca mode; the 9 chars correspond to a 3x3 screen clickable grid and the equivalent command keys; clicking middle or right button toggle on-screen usage info.
  • angle [in,out,i:] โ€” a floating point number specifying the rotation angle, in degrees.
  • ascale [in,out,i:] โ€” the asymmetric scaling of the current image.
  • desaturated [out,i:] โ€” 1, if the image is desaturated.
  • flipped [out,i:] โ€” 1, if the image is flipped.
  • fresh [in,out,i:,experimental] โ€” 1 if the image was loaded, before all autocommands (autocmd) execution.
  • height [out,i:] โ€” the current image original height.
  • mirrored [out,i:] โ€” 1, if the image is mirrored.
  • negated [out,i:] โ€” 1, if the image is negated.
  • page [out,experimental,g:] โ€” the current page.
  • pages [out,experimental,i:] โ€” the current number of pages of an image.
  • random [out] โ€” a pseudorandom number.
  • scale [in,i:] โ€” the scale of the current image.
  • sheight [out,i:] โ€” the current image scaled height.
  • swidth [out,i:] โ€” the current image scaled width.
  • width [out,i:] โ€” the current image original width.

๐ŸŽ€ DEFAULT ALIASES REFERENCE ๐ŸŽ€

Hardcoded aliases are:

alias "A" "_autotop=1-_autotop;"
alias "magnify" "scale '+'" # magnify the displayed image by the
_magnify_factor variable or {args}
alias "next" "goto '+1'" # go to the next page or file
alias "next_file" "goto '+1f'" # go to the next file in the list
alias "next_page" "goto '+1p'" # go to the next page in the file
alias "prev" "goto '-1'" # go to the previous page or file
alias "prev_file" "goto '-1f'" # go to the previous file in the list
alias "prev_page" "goto '-1p'" # go to the previous page in the file
alias "reduce" "scale '-'" # reduce the displayed image by
_reduce_factor or {args}
alias "scale_factor_decrease" "scale '+-'" # subtract
_scale_factor_delta to the scale factors _reduce_factor and
_magnify_factor
alias "scale_factor_grow" "scale '+*'" # multiply the scale factors
_reduce_factor and _magnify_factor by _scale_factor_multiplier
alias "scale_factor_increase" "scale '++'" # add _scale_factor_delta to
the scale factors _reduce_factor and _magnify_factor
alias "scale_factor_shrink" "scale '+/'" # divide the scale factors
_reduce_factor and _magnify_factor by _scale_factor_multiplier

They can be redefined with alias or deleted with the unalias command. Further default aliases are usually loaded at startup -- see the CONFIGURATION FILE EXAMPLE section below.

okay so these are like, the factory settings bestie. your starter pack. you can rewrite them, but honestly they ate ๐Ÿ’…


๐Ÿ”ฅ COMMAND LINE USAGE EXAMPLES ๐Ÿ”ฅ

# jump to the third image:
3;
# jump to first image:
^;
# jump to last image:
$;
# magnify the image two times:
*2;
# scale the image to the 30% of the original:
30%;
# scale the image up by 30%:
+30%;
# scale the image down by 30%:
-30%;
# jump to the next image whose filename matches the ".*jpg" regular expression:
/.*jpg;
# execute the "date" system command
!"date";

โœจ CONFIGURATION FILE EXAMPLE โœจ

Part of the default configuration comes from the _fim_default_config_file_contents variable, shown here. One can skip its loading by using the _no_default_configuration variable.

and yes that's literally where all your default aliases come from, we love a self-aware config ๐Ÿซถ

okay so now we get to the good part โ€” the actual default fimrc that's literally baked into the fim executable. like, it's not a file you download, it's in there, and the manual is just showing you the whole thing so you can copy the vibe. it's giving starter pack but make it iconic ๐Ÿ’…


๐ŸŽ€ the header notes, bestie ๐ŸŽ€

# $LastChangedDate: 2024-05-15 01:34:42 +0200 (Wed, 15 May 2024) $
# Contents of the default 'fimrc' file, hardcoded in the fim executable.
# Read the documentation (man fimrc) to discover how to change this default hardcoded file and how to make your own.
# Note that usually a ~/.fimrc file is read after these options take effect, so you could reset all of this with ease.
# Lines beginning with a pound (#) are ignored by fim (they are treated as comments).

so the tea is: your own ~/.fimrc gets read after these defaults kick in, which means you can undo literally all of it if you want. freedom, fr fr ๐Ÿฆ‹


๐Ÿง  internal variables (the girlies that run the show) ๐Ÿง 

#
# Internal variables.
# Some of these variables influence fim's behaviour (input variables), some are set by fim (output variables).
# It is wise the input variables are set at the beginning of the file, so the bottom may issue commands correctly affected by them.
if(_cache_control==''){_cache_control='m';}
if(_debug_commands==''){_debug_commands='';}
if(_command_expansion==''){_command_expansion=1;}
if(_display_status==''){_display_status=0;}
if(_max_cached_images==''){_max_cached_images=5;}
if(_min_cached_images==''){_min_cached_images=4;}
if(_max_cached_memory==''){_max_cached_memory=81920;}
if(_max_iterated_commands==''){_max_iterated_commands=100;}
if(_want_prefetch==''){_want_prefetch=1;}
if(_no_external_loader_programs==''){_no_external_loader_programs=0;}
if(_scale_style==''){_scale_style='b';}
if(_save_fim_history==''){_save_fim_history=1;}
if(_load_fim_history==''){_load_fim_history=1;}
if(_verbose_keys==''){_verbose_keys=0;}
if(_display_busy==''){_display_busy=1;}
if(_ignorecase==''){_ignorecase=1;}
if(_re_search_opts==''){_re_search_opts='biD';}
if(_console_offset==''){_console_offset=0;}
if(_console_key==''){_console_key=58;}
if(_display_as_binary==''){_display_as_binary=0;}
if(_push_checks==''){_push_checks=1;}
#if(_want_wm_caption_status==''){_want_wm_caption_status=0;}
if(_want_exif_orientation==''){_want_exif_orientation=1;}
if(ascale==''){ascale="1.0";}
if(_use_mipmaps==''){_use_mipmaps=1;}
if(_downscale_huge_at_load==''){_downscale_huge_at_load=1;}
if(_scroll_skip_page_fraction==''){_scroll_skip_page_fraction=0;}
if(_want_wm_mouse_ctrl==''){_want_wm_mouse_ctrl="'pP+a-=nN";}
if(_slideshow_sleep_time==''){_slideshow_sleep_time=1;}

the way every single one of these is wrapped in if(...=='') is genuinely so smart โ€” it means only set it if it's not already set. don't touch what's already been touched. boundaries, periodt โœจ

ngl the comment right there is the whole strategy: put your input variables at the top of the file so everything below them behaves correctly. order matters, bestie, it's giving lineup at a concert ๐Ÿ™ˆ

๐ŸŒธ external variables (not used internally, just chilling) ๐ŸŒธ

#
# External variables (not used internally).
if(allow_round_scroll==''){allow_round_scroll=0;}
if(console_scroll_n==''){console_scroll_n=3;}

these ones are literally labeled as not used internally โ€” they're for you, the user, to poke at. iconic honesty honestly ๐ŸŒˆ


๐Ÿ’– the flip/mirror/limit aliases ๐Ÿ’–

alias "toggleautoflip" "_autoflip=1-_autoflip" "";
alias "toggleautonegate" "_autonegate=1-_autonegate" "";
alias "toggleflip" "i:flipped=1-i:flipped" "toggles flipped property on the current image";
alias "flip" "toggleflip;redisplay"        "flip the current image along the horizontal axis";
alias "fliponce" "flip;toggleflip"         "flip, but just for one display";
alias "toggleautomirror" "_automirror=1-_automirror" "";
alias "togglemirror" "i:mirrored=1-i:mirrored" "toggles mirrored property on the current image";
alias "mirror" "togglemirror;redisplay"         "mirror the image along the vertical axis" "";
alias "mirroronce" "mirror;togglemirror"        "mirror, but just for one display";
alias 'toggleLimitMarked' '__pre_limit_fileindex=_fileindex;_limit_mode=1-_limit_mode; if(_limit_mode==1){limit "!";} else { limit; } if(_filelistlen<1){_limit_mode=0;limit;goto __pre_limit_fileindex;} i:fresh=1;redisplay; ' "toggle between limiting file list to the marked files and the full list";
alias "unlimit" "limit;i:fresh=1;reload;redisplay" "calling limit with no arguments restores the original list";

the 1- trick everywhere is so clean โ€” that's how you flip a boolean from 0 to 1 and back, no cap. fliponce being just flip;toggleflip is lowkey genius, it's giving "do the thing, then undo the thing" ๐Ÿฆ‹


๐Ÿ“ the marked-file aliases (temporary, allegedly) ๐Ÿ“

#alias 'mark_current_file' '_markedfile=i:_filename';
#alias 'goto_marked_file' 'goto "?"._markedfile';
alias 'mark_current_file' '_markedfile=_fileindex'; # Note: temporary; _markedfile undocumented.
alias 'goto_marked_file'  'goto _markedfile'; # Note: temporary.
okay so these two are explicitly marked as temporary, and _markedfile is straight-up documented as undocumented. so like, use it but know it's not a promise, bestie ๐Ÿ’€

โš ๏ธ the console key warning (read this one, fr) โš ๏ธ

# Warning : binding to C-s, C-z and C-c won't make effect, as these
# codes are get caught by the console driver and will have no effect in fim.
# Moreover, C-z will crash fim and C-c will terminate it.
# Some other combinations (e.g.:C-l) may have similar problems in your console.
bestie. do not bind to C-s, C-z or C-c. the console driver grabs those before fim even gets a look, so your binding does literally nothing. worse: C-z will crash fim and C-c will terminate it. and some other combos like C-l might act up in your console too. no notes, just don't ๐Ÿ™ˆ

๐Ÿ’… the binds (the whole keymap, every last one) ๐Ÿ’…

bind 'f' "flip";
bind 'F' "fliponce";
bind 'm' "mirror";
bind 'M' "mirroronce";
bind 'q'   "quit";
bind 'Esc' "quit";
#bind 'n' "next_file";
#bind 'n' "next";
bind 'C-h' "help";
#bind '?' "help"; # assigned to back-search
#bind '/' "help"; # assigned to forward-search
bind '=' "scale '100%'";
#bind 'p' "prev_file";
#alias 'list_remove_and_reload' "list 'remove';reload"; # once menus commands can support ;, remove this
bind 'Del' "list 'remove';reload"; # no quit on last file
#bind 'Del' "list_remove_and_reload"; # no quit on last file
#bind 'Del' "if(_filelistlen<2)quit;list 'remove';reload;"; # quit if no files left
#bind 's' "list 'sort'";
bind ' ' "scroll 'forward'";
bind 'S' "toggleDisplayStatus";
bind 'I' "toggleautonegate";
bind 'i' "color 'negate';redisplay";
bind 'g' "color 'desaturate';redisplay";
bind '[' 'font_reduce;redisplay';
bind ']' 'font_magnify;redisplay';
bind '|' 'toggle_font_auto_scale;redisplay';
bind '{' 'font "prev";redisplay';
bind '}' 'font "next";redisplay';
bind 'G' "toggleDesaturate";
bind 'r' "rotate90";
bind 'R' "rotate270";
bind '+' "magnify";
bind 'a' "scale 'a'";
bind 'H' "scale 'H'";
bind 'Tab'  "toggleVerbosity";
bind 'Menu' "toggleVerbosity";
bind 'v' "toggleDisplayStatus";
bind 'A' "A";
#bind 'C-m' "list 'mark'";
bind 'C-m' "mark_current_file";
bind 'C-j' "goto_marked_file";
bind 'u'   "list 'unmark'";
bind 'Enter' "list 'mark';goto _lastgotodirection";
bind '-' "reduce";
bind "Up" "pan_up";
bind 'k' "pan_up";
bind "Right" "pan_right";
bind 'l' "pan_right";
bind "Down" "pan_down";
bind 'j' "pan_down";
bind "Left" "pan_left";
bind 'h' "pan_left";
bind 't' "align 'top'";
bind 'C-g' "system 'fbgrab' 'fim_'._device_string.'.png'"; # grab a screenshot
#bind 'C-r' "recording 'start'";
bind 'C-r' "reload ''";
bind 'Q' "recording 'stop'";
bind 'D' "recording 'dump'";
bind 'E' "recording 'execute'";
bind 'C-e' "recording 'execute'";
bind 'C-x' "recording 'execute'";
bind '.' "recording 'repeat_last'";
bind '`' "toggleLimitMarked";

the h j k l pan situation is giving vim energy and i'm obsessed โ€” arrows and letters both work, choose your fighter ๐ŸŽ€

also C-g literally shells out to fbgrab to grab a screenshot named fim_ + _device_string + .png. cute. and the commented-out #bind 'C-r' "recording 'start'" got swapped for bind 'C-r' "reload ''" โ€” history, bestie ๐Ÿ“ธ


๐Ÿงš the toggle aliases + the idempotent one ๐Ÿงš

alias "toggleVerbosity" "_display_console=1-_display_console;i:fresh=1;redisplay" "";
alias "toggleKeyVerbosity" "_verbose_keys=1-_verbose_keys;redisplay" "";
alias "toggleDesaturate" "_autodesaturate=1-_autodesaturate;redisplay" "";
alias "idempotent_cmd" "goto ''";

idempotent_cmd is literally just goto '' and it exists for a reason, hold that thought ๐Ÿ‘€


โœจ autocommands examples (all commented out, study them tho) โœจ

#
# Autocommands examples:
#autocmd "PostInteractiveCommand" "fim.png" "echo '\nmatched an interactive command on fim.png\n'";
#autocmd "PostDisplay" ".*png" "echo 'this is a png file'";
#autocmd "PostDisplay" ".*jpg" "echo 'this is a jpg file'";
#autocmd "PostDisplay" "" "echo '\nthis is a file\n'";
#autocmd "PostGoto"   "" "set_interactive_mode";
autocmd "PostGoto"      "" "reload";
autocmd "PostWindow" ""   "i:fresh=1;redisplay;";
autocmd "PreRedisplay"  "" "i:_will_display=1";
autocmd "PreRedisplay"  "" "if(_scale_style!='' && i:fresh){i:fresh=0;scale _scale_style ;i:fresh=0;}";
autocmd "PostRedisplay" ""   "i:_will_display=0";

see how the examples are all #-ed out? they're not active, they're tutorials. then the real ones below are live. the _will_display flag gets set PreRedisplay and cleared PostRedisplay โ€” that's how fim knows if it's mid-display or not, and it's giving main character bookkeeping ๐Ÿ’œ


๐ŸŒˆ display-device-specific config (the aalib + libcaca situation) ๐ŸŒˆ

# Display device specific config
alias "aalib_fix_do" "{if(aascale==''){ascale='2.0';}else{ascale=aascale;} i:fresh=1;display;if(_TERM=~'screen'){echo 'Detected screen+aalib: key bindings may not work as intended.'}}" "See aalib_fix.";
alias "aalib_fix" "if(_device_string=~'^aa'){aalib_fix_do;scale 'a';}" "When using the aalib (ASCII art) library we face a problem: glyph proportions are seldom square (as pixels are), and are tricky to detect; for this reason, we need to reshape the image with respect to the font ratio, but we have to make a guess in the scaling factor to compensate. If at runtime a better value is known for the terminal font height/with ratio, it may be fed in the 'aascale' variable for an accurate scaling.";
alias "cacalib_fix_do" "{if(cacascale==''){ascale='1.18';}else{scale=cacascale;} i:fresh=1;display;if(_TERM=~'screen'){echo 'Detected screen+cacalib: key bindings may not work as intended.'}}" "See cacalib_fix.";
alias "cacalib_fix" "getenv 'DISPLAY';if(_device_string=~'^ca' && ENV_DISPLAY==''){cacalib_fix_do;scale 'a';}" "When using the libcaca (Coloured ASCII art) library we face a problem: glyph proportions are seldom square (as pixels are), and are tricky to detect; for this reason, we need to reshape the image with respect to the font ratio, but we have to make a guess in the scaling factor to compensate. If at runtime a better value is known for the terminal font height/with ratio, it may be fed in the 'cacascale' variable for an accurate scaling.";
autocmd "PostReload"  "" "aalib_fix";
autocmd "PostLoad"    "" "aalib_fix";
autocmd "PostReload"  "" "cacalib_fix";
autocmd "PostLoad"    "" "cacalib_fix";
alias "refresh" "desc 'reload';redisplay;" "reloads and displays image description";
bind "F5" "refresh";
alias "toggle_fullscreen" "if( (_device_string=~'^sdl' || _device_string=~'^gtk' ) && !_fullscreen){_old_sw=_screen_width;_old_sh=_screen_height;display 'reinit' 'mW0:0';_fullscreen=1;}else if( (_device_string=~'^sdl' || _device_string=~'^gtk' ) && _old_sw*_old_sh*_fullscreen){display 'reinit' 'rwm'._old_sw.':'._old_sh;_fullscreen=0;}_gtk_fullscreen=_fullscreen;" "Toggles full screen. Will show mouse cursor in full screen.";
alias "_gtk_check_for_toggle_fullscreen" "if( _device_string=~'^gtk' && _gtk_fullscreen != _fullscreen){toggle_fullscreen;}";
alias "_gtk_check_for_toggle_gtk_menus" "if(_device_string=~'^gtk'){if(_hide_gtk_menus){display 'reinit' 'b';}else{display 'reinit' 'B';}}";
bind "F11" "toggle_fullscreen";

the whole ASCII-art thing here is so real โ€” glyphs in a terminal are seldom square like pixels are, and detecting that is tricky, so fim reshapes the image relative to the font ratio but has to guess a scaling factor to compensate. if you happen to know your terminal font's height/width ratio at runtime, feed it into the aascale (or cacascale) variable for accurate scaling. that's it, that's the whole flex ๐Ÿ’…

also note toggle_fullscreen only fires for sdl/gtk devices, saves _old_sw and _old_sh, and โ€” iconically โ€” will show the mouse cursor in full screen. and F11 is the bind for it, F5 is refresh, periodt ๐Ÿ‘‘


๐Ÿ’œ the final autocmd block (where the workaround lives) ๐Ÿ’œ

autocmd "PostReload"  "" "i:fresh=1" ;
autocmd "PostScale"   "" "if(0==i:_will_display){i:fresh=1;display;}" ;
autocmd "PostPan"     "" "{i:fresh=1;display;}" ;
#autocmd "PostReload"   "pdf|ps|djvu|dvi" "scale 'w';align 'top'";
autocmd "PostReload"   "" "if(i:fresh){redisplay;}";
autocmd "PostInteractiveCommand"   "" "if(i:fresh){display;i:fresh=0;}";
autocmd "PostInteractiveCommand"   "" "if(_want_prefetch>0){prefetch;}";
autocmd "PostInteractiveCommand"   "" "if(_display_console==0 && i:fresh){redisplay;i:fresh=0;}";
autocmd "PostInteractiveCommand"   "" "idempotent_cmd"; # Bug workaround: without it console scroll is broken.
autocmd "PostInteractiveCommand"   "" "_gtk_check_for_toggle_gtk_menus;_gtk_check_for_toggle_fullscreen";

there it is โ€” the idempotent_cmd call right there is a bug workaround, and the comment says it out loud: without it, console scroll is broken. so it's not decorative, it's load-bearing, no cap ๐Ÿซถ

and the very last line runs the gtk menu check and the fullscreen check after every interactive command, so if you toggled either one, fim notices on the next beat. that's the whole default file bestie โ€” and there's more where that came from, so don't go anywhere ๐Ÿ’–

okay bestie, the config file example is still serving looks โœจ here's the next chunk of that fimrc magic โ€” all the binds and aliases doing their thing ๐Ÿ’…

#alias "next10" "i=0;while(i<10){i=i+1;next;display;sleep '1';}" "goes forward 10 images";
#alias "prev10" "i=0;while(i<10){i=i+1;prev;display;sleep '1';}" "goes backward 10 images";
bind 'N' "goto '+1p' '+museum|series|city|category|artist+' '+/S' '+10';" "goto by jump or category or directory or just ahead";
bind 'P' "goto '-1p' '-museum|series|city|category|artist+' '-/S' '-10';" "goto by jump or category or directory or just back ";
bind 'C-n' "goto '+//'";
bind 'C-p' "goto '-//'";
bind 'C-b' "goto '-//'"; # Warning: many configurations cannot detect C-b.
bind 'W' "display 'resize'" "if supported, resizes the window to match the current image pixels size";
#bind 'C-w' "scale '100%';display 'resize'" "if supported, scales the image to 100% and resizes the window to match its size (if fits)";
bind 'C-w' "if(_scale_style!='w'){_scale_style='w';scale 'w';}else{_scale_style='';scale '100%';}" "scale to width";
alias "endless_slideshow" "while(1){display;sleep _slideshow_sleep_time;next;}" "performs an automated slideshow, endlessly";
alias "bookview"          "while(1){display;sleep '2';scroll 'down';}" "";
alias "comicview"         "while(1){display;sleep '2';scroll 'down';}" "";
alias "read"              "while(1){display;sleep '2';scroll 'forward';}" "";
alias "slowread"          "while(_fileindex<=_filelistlen-1){display;sleep '2';scroll 'forward';}" "loop once slowly";
alias "fastread"          "while(_fileindex<=_filelistlen-1){display;sleep '0.1';scroll 'forward';}" "proceeds like in a book but very fast, once";
alias "pornview"          "echo 'press any key repeatedly to terminate' ;endless_slideshow" "enters an endless slideshow (alias name from an actual image viewer)";
autocmd "PreExecutionCycle" "/fbps-" "_display_busy=0;_display_status=0" ;
autocmd "PreExecutionCycle" "" "i:fresh=1;reload";
autocmd "PreExecutionCycle" "/fbps-.*ps001.png" "i:fresh=1;redisplay";
## Example in imposing a file loader to an extension:
#autocmd "PreReload"    ".*mtx.gz" "_file_loader='MatrixMarket'";
#autocmd "PostReload"   ".*mtx.gz" "_file_loader=''";
bind '*' "_display_console=0;toggleVerbosity;echo i:*";
bind 'w' "scale 'w'";
bind '<' "rotate10_ccw;display";
bind '>' "rotate10;display";
bind '_' "_scale_style='';scale '100%'";
bind ',' "_display_console=1;echo _last_system_output";
bind 'C-a' "if(_scale_style!='a'){_scale_style='a';scale 'a';}else{_scale_style='';scale '100%';}" "scale to height";
#
alias "pan_nw" "pan 'nw'" "pans the image to the upper left";
alias "pan_ne" "pan 'ne'" "pans the image to the upper right";
alias "pan_se" "pan 'se'" "pans the image to the lower left";
alias "pan_sw" "pan 'sw'" "pans the image to the lower right";
alias "pan_down" "if(_display_console==0){pan 'down';}else{scd;}" "pans the image down / scrolls console down";
alias "pan_up"   "if(_display_console==0){pan 'up'  ;}else{scu;}"   "pans the image up / scrolls console up";
alias "pan_left" "pan 'left'" "pans the image left";
alias "pan_right" "pan 'right'" "pans the image right";
alias "diagonal_nw" "pan_nw" "pans the image to the upper left";
alias "diagonal_ne" "pan_ne" "pans the image to the upper right";
alias "diagonal_se" "pan_se" "pans the image to the lower left";
alias "diagonal_sw" "pan_sw" "pans the image to the lower right";
bind 'd' "diagonal_nw";
bind 'D' "diagonal_se";
bind 'x' "diagonal_ne";
bind 'X' "diagonal_sw";
alias "toggleDisplayStatus" "_display_status=1-_display_status;redisplay" "";
alias "toggleDisplayBusy"   "_display_busy=1-_display_busy" "";
alias "sort" "list 'sort'"  "sorts the files list ordered";
bind 'o' "sort";
bind 'b' "prev";
bind 'B' "toggleDisplayBusy";
alias "random_slideshow" "while(1){display;sleep _slideshow_sleep_time; eval 'r=random';goto r;}" "performs a shuffled slideshow, endlessly";
alias "rotate90_ccw" "i:_orientation=i:_orientation+3;i:fresh=1;redisplay" "rotate 90 degrees counter clockwise";
alias "rotate90_cw"  "i:_orientation=i:_orientation+1;i:fresh=1;redisplay" "rotate 90 degrees clockwise";
alias "rotate180"  "i:_orientation=i:_orientation+2;i:fresh=1;redisplay" "rotate 180 degrees";
alias "rotate90" "rotate90_cw;display" "rotate 90 degrees clockwise";
alias "rotate270" "rotate90_ccw;display" "rotate 90 degrees counter clockwise";
alias "rotate10"     "rotate  '10';display" "rotate 10 degrees counter clockwise";
alias "rotate10_ccw" "rotate -10  ;display" "rotate 10 degrees clockwise";

bind 'K' 'if(_display_console==0){echo i:_filename.": ".i:_comment;toggleVerbosity}else{toggleVerbosity;}';
bind 'C-k' 'crop' # still experimental

and there's more config deliciousness coming, so don't touch that dial ๐Ÿ‘‘


๐ŸŽ€ the rest of the config file, bestie, keep scrolling ๐ŸŽ€

okay so we're back in the config example and it's still serving looks. next up, the cute little one-liners:

       alias 'cache' 'echo _cache_status' "displays cached images status";
       bind 'c' 'align "center"';
       alias 'widen'  'i:ascale=i:ascale*"1.1";*1.0' "widen the current image";
       alias 'narrow' 'i:ascale=i:ascale/"1.1";*1.0' "narrow the current image";
       bind  'y' "widen" "widen horizontally the image";
       bind  'Y' "narrow" "shrink horizontally the image";

like โ€” cache literally just echoes _cache_status and tells you the cached images status. and c centers, y widens horizontally, Y (capital, mind you ๐Ÿ’…) shrinks horizontally. the way that y/Y pair ate fr fr.


๐Ÿ–ฅ๏ธ virtual console scrolling, no cap

these bad boys move you around the virtual console:

       alias 'console_scroll_up' 'if(_console_offset<_console_lines+console_scroll_n-_rows){_console_offset=_console_offset+console_scroll_n;}' "scrolls up the virtual console";
       alias 'console_scroll_down' 'if(allow_round_scroll || (_console_offset>=console_scroll_n)){_console_offset=_console_offset-console_scroll_n;}' "scrolls down the virtual console";
       alias 'console_scroll_reset' '{_console_offset=0;}';
       alias 'scu'    'console_scroll_up'   "";
       alias 'scd'    'console_scroll_down' "";
       alias 'scz'    'console_scroll_reset' "";

console_scroll_up scrolls up the virtual console, console_scroll_down scrolls down the virtual console, and console_scroll_reset just yeets _console_offset back to 0. then the shorties: scu, scd, scz โ€” iconic abbreviations, obsessed.


โœจ alignment era โœจ

       alias 'center' 'align "center"';
       alias 'left'   'align "left"';
       alias 'right'  'align "right"';
       alias 'top'    'align "top"';
       alias 'bottom' 'align "bottom"';

five aliases, five vibes: center, left, right, top, bottom, each one a lil align wrapper. main character alignment energy ๐ŸŒˆ


๐Ÿ”ค font stuff (magnify + reduce) ๐Ÿ”ค

okay this chunk is where the font magic lives:

       alias "font_magnify_auto" "if(_fbfont_as_screen_fraction>1){_fbfont_as_screen_fraction=_fbfont_as_screen_fraction-1;}else{_fbfont_as_screen_fraction=_screen_width/100+_screen_height/100;}" "";
       alias "font_magnify_manual"      "_fbfont_magnify_factor=_fbfont_magnify_factor+1" "";
       alias "font_reduce_auto"  "if(_fbfont_as_screen_fraction>1){_fbfont_as_screen_fraction=_fbfont_as_screen_fraction+1;}" "";
       alias "font_reduce_manual"       "_fbfont_magnify_factor=_fbfont_magnify_factor-1" "";
       alias "toggle_font_auto_scale" "if(_fbfont_as_screen_fraction<0){_fbfont_as_screen_fraction=0;echo 'Auto font scaling on.';}else{_fbfont_as_screen_fraction=-1;echo 'Auto font scaling off.';}" "toggles between manual and auto font scaling control";

font_magnify_auto, font_magnify_manual, font_reduce_auto, font_reduce_manual โ€” and toggle_font_auto_scale, which toggles between manual and auto font scaling control and literally echos 'Auto font scaling on.' or 'Auto font scaling off.' so you're never confused. thoughtful queen ๐Ÿ’–


๐Ÿ—‚๏ธ next / prev file navigations ๐Ÿ—‚๏ธ

these are the "where do I go next" girlies:

       alias 'next_file_same_search'      "goto '+//';" "go to next file with same search criteria";
       alias 'next_file_dir_same'      "goto '+/s';" "go to next file in same dir";
       alias 'next_file_dir_other'     "goto '+/S';" "go to next file in other dir";
       alias 'next_file_dir_up'        "goto '+/u';" "go to next file up the dir hierarchy";
       alias 'next_file_dir_down'      "goto '+/d';" "go to next file down the dir hierarchy";
       alias 'next_file_same_basename' "goto '+/b';" "go to next file with same basename";
       alias 'prev_file_dir_same'      "goto '-/s';" "go to prev file in same dir";
       alias 'prev_file_dir_other'     "goto '-/S';" "go to prev file in other dir";
       alias 'prev_file_dir_up'        "goto '-/u';" "go to prev file up the dir hierarchy";
       alias 'prev_file_dir_down'      "goto '-/d';" "go to prev file down the dir hierarchy";
       alias 'prev_file_same_basename' "goto '-/b';" "go to prev file with same basename";

the pattern is so clean โ€” + for next, - for prev, then s same dir, S other dir, u up the hierarchy, d down the hierarchy, b same basename, and // for same search criteria. periodt.

then these two are commented out โ€” not active, bestie, do not come for me:

       #alias "font_magnify" "if(_fbfont_as_screen_fraction<0) {font_magnify_manual;}else{font_magnify_auto;}" "increase font size (either relative or absolute)";
       #alias "font_reduce"  "if(_fbfont_as_screen_fraction<0) {font_reduce_manual;} else{font_reduce_auto;}"  "increase font size (either relative or absolute)";

and here's what they got replaced with โ€” the live versions:

       alias "font_magnify" "_fbfont_as_screen_fraction=-1;font_magnify_manual" "increase absolute font size and set manual font control";
       alias "font_reduce"  "_fbfont_as_screen_fraction=-1;font_reduce_manual"  "decrease absolute font size and set manual font control";

so font_magnify increases absolute font size and sets manual font control, font_reduce decreases absolute font size and sets manual font control. we love a glow-up ๐Ÿ”ฅ


โŒจ๏ธ the keybinds โŒจ๏ธ

okay these are the bindings, and the PageUp/PageDown ones are so smart โ€” they check _display_console first:

       bind "PageUp" "if(_display_console==0){prev;}else{scu;}";
       bind "PageDown" "if(_display_console==0){next;}else{scd;}";
       bind "Home" "0;";
       bind "End" "$;";
       bind "^" "0;";
       bind "$" "$;";
       #bind "Backspace" "prev"; # console code for C-h and Backspace is the same :-)
       bind "'" "goto _lastfileindex.'f'.(_lastpageindex+1).'p'";
       bind '"' "scale 'shadow';i:fresh=1;redisplay;";
       bind '(' "goto '^p'";
       bind ')' "goto '$p'";
       bind 'Z' "sleep 1";

so PageUp goes prev when the console is hidden, else scu. PageDown goes next, else scd. Home and ^ jump to 0;, End and $ jump to $;. the Backspace one is commented out (with the note that the console code for C-h and Backspace is the same, plus a lil :-)), ' does that goto _lastfileindex.'f'.(_lastpageindex+1).'p' thing, " does scale 'shadow';i:fresh=1;redisplay;, ( goes goto '^p', ) goes goto '$p', and Z is literally sleep 1. a whole mood ๐Ÿ™ˆ


๐Ÿฉท status line + caption vars ๐Ÿฉท

       _display_status=1; # lower status line
       _want_wm_caption_status="fim:%N@%p%%%L[%i/%l]";
       _caption_over_image_fmt="%?_comment?%:_comment:?";
       _info_fmt_str="%p%% %wx%h%L %i/%l%P %F %T %c"; # lower right line part
       #_display_status_fmt="%N:%k"; #
       _display_status_fmt="%N%?EXIF_DateTimeOriginal?[%:EXIF_DateTimeOriginal:]?%?EXIF_ExposureTime?[%:EXIF_ExposureTime:]?%?EXIF_FNumber?[%:EXIF_FNumber:]?%?EXIF_ApertureValue?[%:EXIF_ApertureValue:]?%?EXIF_ISOSpeedRatings?[ISO%:EXIF_ISOSpeedRatings:]?%?_markedfile?[mark on %:_markedfile:]?:%k"; # lower left line part

so _display_status=1 turns on the lower status line, _want_wm_caption_status is set to "fim:%N@%p%%%L[%i/%l]", _caption_over_image_fmt is "%?_comment?%:_comment:?", and _info_fmt_str handles the lower right line part. the commented #_display_status_fmt="%N:%k"; is just chilling there, and then the real _display_status_fmt (lower left line part) is that big long EXIF-and-markedfile masterpiece. it's giving โœจ thorough โœจ


๐Ÿ˜ญ the funny aliases ๐Ÿ˜ญ

the section header literally says it:

       # funny aliases:
       alias "webcam" "pread 'vgrabbj -d /dev/video0';$" "say cheese";
       alias 'espeak' 'system \'espeak\' i:_filename." ".i:_comment' 'say something';
       #_fbfont_as_screen_fraction=-1; # disable auto font scaling

webcam runs pread 'vgrabbj -d /dev/video0';$ and its description is "say cheese" โ€” I'm crying ๐Ÿ˜ญ. espeak runs system 'espeak' i:_filename." ".i:_comment and says 'say something'. and the commented-out #_fbfont_as_screen_fraction=-1; disables auto font scaling if you ever want it.


๐Ÿ–ผ๏ธ the GTK block (yes, it's guarded by an if) ๐Ÿ–ผ๏ธ

okay so all of this only happens when _device_string=~'^gtk[^e]*$' โ€” i.e. inside that if(...) { ... }:

       if( _device_string=~'^gtk[^e]*$' ) {
            alias "man_fim"   "system 'man' 'fim';  _display_console=0;toggleVerbosity;";
            alias "man_fimrc" "system 'man' 'fimrc';_display_console=0;toggleVerbosity;";
            alias '_rebuild_menus' 'display "reinit" "f";';
            alias '_rebuild_quieter_menus' '_debug_commands=_debug_commands-"m";display "reinit" "fV";'; # remove "m" occurrences from _debug_commands and rebuild
            alias '_rebuild_verboser_menus' '_debug_commands=_debug_commands."m";_rebuild_menus;';
            alias '_rebuild_verbosest_menus' '_debug_commands=_debug_commands."mm";_rebuild_menus;';
            alias 'toggle_gtk_menus' 'if(!_hide_gtk_menus){_hide_gtk_menus=1;}else{_hide_gtk_menus=0;}';
            autocmd "PreInteractiveCommand"  "" "if(__internal_state_changed){_rebuild_menus;__internal_state_changed=0;}";
            autocmd "PostInteractiveCommand" "" "if(__internal_state_changed){_rebuild_menus;__internal_state_changed=0;}";
            autocmd "PreExecutionCycle"      "" "if(__internal_state_changed){_rebuild_menus;__internal_state_changed=0;}";

man_fim and man_fimrc open the man pages (and reset _display_console + toggleVerbosity). then there's the rebuild squad โ€” _rebuild_menus, _rebuild_quieter_menus (removes "m" occurrences from _debug_commands and rebuilds), _rebuild_verboser_menus (appends "m"), _rebuild_verbosest_menus (appends "mm"). plus toggle_gtk_menus which flips _hide_gtk_menus. and three autocmds on PreInteractiveCommand, PostInteractiveCommand and PreExecutionCycle that all rebuild the menus whenever __internal_state_changed is truthy. the consistency, the dedication ๐Ÿ‘‘

now the big one โ€” the actual menu definition. display "menuadd" with a whole tree of entries:

            display "menuadd"
                 "_File/"
                 "_File/_Open file  open  C-o"
                 "_File/Open _directory  open_dir  "
                 "_File/_Next file or page  next  "
                 "_File/_Next file  next_file  "
                 "_File/_Next in other directory  next_file_dir_other"
                 "_File/_Next in this directory  next_file_dir_same"
       #         "_File/_Next as last search  goto +  " # Note that slashes are not supported currently.
                 "_File/_Next as last search  next_file_same_search  "
                 "_File/_Go back to last file  goto _lastfileindex  "
                 "_File/_Previous in list  prev  p"
       #         "_File/Remove from list  list 'pop'"
       #         "_File/Remove from list  list_remove_and_reload  "
                 "_File/Remove from list  list 'remove';reload  "
                 "_File/Mark  list 'mark'"
                 "_File/Unmark  list 'unmark'"
                 "_File/_Quit  quit  q"
                 "_List/Show  list"
                 "_List/_Limit  FimMenuLimit/"
                 "_List/Limit to.../files sized as current one  limit '~z'" #
                 "_List/Limit to.../files dated as current one  limit '~d'"
                 "_List/Limit to.../files with duplicate basename  limit '~='"
                 "_List/_Unlimit list (reset)  unlimit  u"
                 "_List/Reverse  list 'reverse'  "
                 "_List/Sort by name  list 'sort'  "
                 "_List/Sort by size  list 'sort_fsize'  "
                 "_List/Sort by time  list 'sort_mtime'  "
                 "_List/Shuffle randomly  list 'random_shuffle'  "
                 "_List/Mark all  list 'markall'  "
                 "_List/Slideshow/Random  random_slideshow  "
                 "_List/Slideshow/Endless  endless_slideshow  "
                 "_List/Slideshow/Slideshow time: 0 s  _slideshow_sleep_time=0    0.5 s  _slideshow_sleep_time=0.5    1 s  _slideshow_sleep_time=1    2 s  _slideshow_sleep_time=2    3 s  _slideshow_sleep_time=3    "
                 "_List/Slideshow/Stop  _stop_slideshow=1  "
                 "_List/Slideshow/Slow read  slowread  "
                 "_List/Slideshow/Fast read  fastread  "
                 "_View/  Automirror  toggle||_automirror||1||0  " # '  ' as external separator, || as internal separator
                 "_View/||Autoflip||toggle.._autoflip..1..0||" # || as external separator, .. as internal separator
       #         "_View/Scale: _auto  _scale_style=a  a  Scale: by _hand (manual)  _scale_style=m  m  Scale: by _width  _scale_style=w  w  Scale: by _height  _scale_style=h  h"
                 "_View/**Scale: 1x**_scale_style= ** **Scale: _auto**_scale_style=a**a**Scale: _auto (till 100%)**_scale_style=b**b**Scale: by _hand (manual)**_scale_style=m**m**Scale: by window _width**_scale_style=w**w**Scale: by window _height**_scale_style=h**h"
                 "_View/Orientation: normal  _orientation=0    Orientation: 90'right  _orientation=1    Orientation: upside down  _orientation=2    Orientation: 90' left  _orientation=3  "
                 "_View/Desaturate  toggle___autodesaturate__1__0  "
                 "_View/Autonegate  toggle___autonegate__1__0  "
                 "_View/Vertical scroll/** Default steps: auto**_vsteps=****10%**_vsteps=10%****20%**_vsteps=20%****50%**_vsteps=50%****100%**_vsteps=100%**"
                 "_View/Vertical scroll/** Skip page fraction if smaller than ...auto**_scroll_skip_page_fraction=****disabled**_scroll_skip_page_fraction=-1****1/8**_scroll_skip_page_fraction=8****1/16**_scroll_skip_page_fraction=16**"
                 "_View/Refresh description & co  refresh  "
                 "_View/||Apply EXIF Orientation||toggle.._want_exif_orientation..1..0||"
                 "_Image/_Mirror  toggle__i:mirrored__1__0  m"
                 "_Image/_Flip  toggle&&i:flipped&&1&&0  f" # && as internal separator
       #         "_Image Extras/_Let's Flip again  toggle&&i:flipped&&1&&0  f" # && as internal separator
                 "_Image/Orientation: normal  i:_orientation=0    Orientation: 90'right  i:_orientation=1    Orientation: upside down  i:_orientation=2    Orientation: 90' left  i:_orientation=3  "
                 "_Image/EXIF Orientation: normal  i:_exif_orientation=0    EXIF Orientation: 90'right  i:_exif_orientation=1    EXIF Orientation: upside down  i:_exif_orientation=2    EXIF Orientation: 90' left  i:_exif_orientation=3  " # previously __exif_orientation but renamed for the double-symbol-separator convention
                 "_Window/_Fullscreen  toggle**_gtk_fullscreen**1**0  F11"
                 "_Window/Hide the menu bar (press mouse button to restore)  toggle_gtk_menus"
       #         "_Window/Hide menu bar (press mouse button to restore)  toggle||_hide_gtk_menus||0||1" # not yet ready to replace toggle_gtk_menus
                 "_Window/Resize window to image size  display 'resize'"
                 "_Window/Text size reduce  font_reduce"
                 "_Window/Text size magnify  font_magnify"
                 "_Window/Text font: next  font 'next'"
                 "_Window/Text font: prev  font 'prev'"
                 "_Window/Show status line  toggle||_display_status||1||0  "
                 "_Window/Caption over image: None  _caption_over_image=0    Caption over image: No background  _caption_over_image=1    Caption over image: Black background  _caption_over_image=2    Caption over image: Above image, no overlap  _caption_over_image=3  "
                 "_Window/Window caption: minimal  _want_wm_caption_status=FIM    Window caption: reasonable  _want_wm_caption_status=fim:[%i/%l]    Window caption: rich  _want_wm_caption_status=fim:%N@%p%%%L[%i/%l]%?EXIF_DateTimeOriginal?[%:EXIF_DateTimeOriginal:]?  "
                 "_Window/Mouse click help grid: default  _want_wm_mouse_ctrl='pP+a-=nN    Mouse click help grid: simplified  _want_wm_mouse_ctrl=ppp+a-nnn  "

okay so first of all, the separator lore is RIGHT THERE in the comments โ€” ' ' as external separator and || as internal separator on the _View/ Automirror line, then || as external separator and .. as internal separator on the _View/||Autoflip||... line, and && as internal separator on the _Image/_Flip line. iykyk ๐Ÿงš

and the commented-out bits โ€” the goto + one (with the note that slashes are not supported currently), the two old Remove from list variants, the old _View/Scale line, the _Image Extras/_Let's Flip again line, and the toggle||_hide_gtk_menus||0||1 one (with the note it's not yet ready to replace toggle_gtk_menus) โ€” all still here, untouched, iconic. and the _Image/EXIF Orientation line has its lil note that it was previously __exif_orientation but got renamed for the double-symbol-separator convention. the lore!! ๐Ÿ’€

the _File/ tree, the _List/ tree (with FimMenuLimit/ nested inside the _Limit entry, and the whole Slideshow submenu with 0 s / 0.5 s / 1 s / 2 s / 3 s sleep times), the _View/ tree with all those scale and scroll options, the _Image/ tree, the _Window/ tree โ€” it's a whole app's worth of menus and it's all right here in your rc file. slay ๐Ÿ’…

โ€ฆand the config file keeps going, because of course it does ๐Ÿ’… here's the rest of that menu spec, verbatim, no cap:

                 "_Advanced/Show output console (then hide with Tab)  toggleVerbosity  v"
                 "_Advanced/Verbose keys  toggle___verbose_keys__1__0  "
                 "_Advanced/Low execution verbosity  _debug_commands=0    Intermediate execution verbosity  _debug_commands=ackCm    High execution verbosity  _debug_commands=ackCmmi  "
                 "_Advanced/Rebuild menus with no verbosity  _rebuild_quieter_menus"
                 "_Advanced/Rebuild menus with tooltips  _rebuild_verboser_menus"
                 "_Advanced/Rebuild menus very verbosely  _rebuild_verbosest_menus"
                 "_Advanced/Verbose menu  toggle||_display_busy||1||0"
                 "_Advanced/Downscale huge images on load  toggle||_downscale_huge_at_load||1||0"
                 "_Advanced/Background prefetch  _want_prefetch=2    Foreground prefetch  _want_prefetch=1    No prefetch  _want_prefetch=0    "
                 "_Custom actions/_Mark current file  mark_current_file"
                 "_Custom actions/_Go to marked file  goto_marked_file"
                 "_Custom actions/Webcam shot (needs vgrabbj)  webcam"
                 "_Custom actions/Say something (needs espeak)  espeak"
                 "_Custom actions/Max cached memory: 256MiB  _max_cached_memory=262144    unlimited  _max_cached_memory=0    very little  _max_cached_memory=1    80MiB  _max_cached_memory=81920  "
                 "_Custom actions/Max cached images: unlimited  _max_cached_images=0    5  _max_cached_images=5    10  _max_cached_images=10    100  _max_cached_images=100  "
                 "_All actions/_Commands  FimMenuCommands/"
                 "_All actions/_Aliases  FimMenuAliases/"
                 "_All actions/_Key Bindings  FimMenuKeyBindings/"
                 "_All actions/_Variables  FimMenuVariables/"
                 "_Help/_Commands  FimMenuCommandsHelp/"
                 "_Help/_Aliases  FimMenuAliasesHelp/"
                 "_Help/_Key Bindings  FimMenuKeyBindingsHelp/"
                 "_Help/_Variables  FimMenuVariablesHelp/"
                 "_Help/_man FIM  man_fim"
                 "_Help/_man fimrc  man_fimrc";
                 #"_Custom actions/scaling: _auto  _scale_style=a  a  scaling: _auto to original  _scale_style=b  b  scaling: manual  _scale_style=m  m  scaling: by _width  _scale_style=w  w" # copy for demo purposes
                 #"_Custom actions/_Toggle flipped flag  toggle__i:flipped__1__0  f"
                 #"_Custom actions/_Submenu/_Frobnicate  unmapped_cmd  /"
                 #"_Custom actions/_Submenu/_Defrobnicate  unmapped_cmd  u"
                 #"_Custom actions/_Submenu/FimMenuLimit  FimMenuLimit/"
                 #"_Custom actions/_Submenu/_Do-frobnicate  unmapped_cmd *" # bad specification
                 #"_Custom actions/_Submenu/_Fribnikate  frobnicate  unmapped_cmd *" # bad specification
                 #"_Custom actions/_Submenu/_Next  next *" # bad specification
                 #"_Custom actions/_Add menu...  menu_dialog"
                 #"_Custom actions/_Toggle full screen view  toggle          _gtk_fullscreen          1         0"
                 if (_last_cmd_output!="") quit -1;
       }
       help ''; # WELCOME...
       # More examples:
       #alias "plisten" 'popen "nc -l -p 9999 "' "executes fim commands coming from port 9999 on this computer";
       #alias "wlisten" "while(1){sleep;plisten;}" "listen to a pipe, endlessly";
       #alias "musicplay"  "system 'mpc' 'play'" "";
       #alias "musicpause" "system 'mpc' 'pause'" "";
       #alias "rdjpgcom" 'system "rdjpgcom" i:_filename';
       # offsetscan usage : need a mechanism for popping all images before.
       #alias "offsetscan" "while(i:width<1){list 'push' 'blob.jpg';stdout _open_offset ;_open_offset=_open_offset+1;reload;}";
       #alias "webcam_cycle" "while(1){webcam;reload;sleep 1;}";
       # This is a FIM initialization file.
       # Without it FIM cannot work like it should.
       # Feel free to modify it, but with caution!

Okay so notice how many of those lines are commented out with # โ€” they're examples and demo copy, not live config, bestie. And that last little block? A whole mood: it literally says feel free to modify it, but with caution! ๐ŸŽ€


๐ŸŒธ NOTES ๐ŸŒธ

This manual page could be improved. Certain side effects of commands are not documented. Neither a formal description of the various commands. Interaction of commands and variables is also not completely documented.

ngl bestie, they're being so real here ๐Ÿ˜ญ โ€” the page itself is admitting it's a work in progress. No formal spec for the commands, side effects not written down, and command/variable interactions not fully documented either. Lowkey iconic honesty, fr fr.

๐Ÿ’€ BUGS ๐Ÿ’€

The fim language shall be more liberal with quoting.

Translation: the quoting rules are stricter than anyone would like, and the fix is "be more chill about quotes." Noted. ๐Ÿ’…

๐Ÿฆ‹ SEE ALSO ๐Ÿฆ‹


๐Ÿ‘‘ AUTHOR ๐Ÿ‘‘

Michele Martone <dezperado _CUT_ autistici _CUT_ org>


See copyright notice in fim(1).


And that's a wrap on the whole fimrc(5) page, bestie ๐Ÿ’– The source is fimrc(5) from the FIM project, the copyright line belongs to (c) 2011-2024 Michele Martone, and the date on the page is the same 2011-2024 era. Go forth and configure your ~/.fimrc with main character energy โœจ๐Ÿซถ

๐Ÿ“ฆ where this page comes from