Skip to content

Advanced

leo-arch edited this page Oct 2, 2024 · 243 revisions

Advanced tricks

The img_viewer plugin in action

Table of contents


Plugins

A. Description

Plugins are shell scripts or programs (written in any language) able to add, extend or improve clifm functionalities. Plugins are found in DATADIR/clifm/plugins (usually /usr/local/share/clifm/plugins or /usr/share/clifm/plugins).

You can copy these plugins to the local plugins directory ($XDG_CONFIG_HOME/clifm/plugins) and modify them to fit your needs. The local plugins directory takes precedence over the system-wide one. Of course, you can also write new plugins, in which case you can create a pull request to share your cool creations. See below the writing plugins section.

Plugins are linked to action names via a configuration file: you only need to enter the action name to execute the plugin (see the table below).

NOTE: When running in stealth mode, since no configuration file is read, plugins are disabled.

Plugin Default action name Brief description Dependencies
batch_copy.sh bcp Copy multiple files and/or directories into multiple files and/or directories at once
batch_create.sh bn Create multiple files and/or directories at once
bm_import.sh bmi Import bookmarks from either Ranger or Midnight Commander
clip.sh clip Send/get files from the primary clipboard xclip or xsel (X: Linux - BSD), wl-copy/wl-paste (Wayland: Linux - BSD), clipboard (Haiku), clip (Cygwin), pbcopy/pbget (MacOS), termux-clipboard-set/termux-clipboard-get (Termux), clipboard (cross-platform)
colors.sh Check your terminal color capabilities
cprm.sh1 cr Copy a file or directory to a remote location fzf, and one of these: scp(1), ffsend, or croc
disk_analyzer.sh da Navigate the file system with FZF and print (sub)directories size via du(1) du, fzf
dragondrop.sh dragon Drag and drop files dragon or dragon-drag-and-drop
fdups.sh fdups Find and remove duplicate files find, md5sum, sort, uniq, xargs, sed, stat
finder.sh + Fuzzy files finder fzf or rofi
git_status.sh Print current git repository status git
fzcd.sh _ Fuzzy directory changer fzf
fzfdesel.sh ** Deselect selected files fzf
fzfhist.sh h Fuzzy command history navigation fzf
fzfnav.sh - Navigate the filesystem (with files preview capability) fzf. For the list of dependencies of the files preview function see the files preview section
fzfsel.sh * Fuzzy select files (includes flat or branch view) fzf, find
ihelp.sh ih Interactive manpage navigation fzf or rofi
img_viewer.sh i View images as thumbnails sxiv, feh or lsix
jumper.sh ++ Fuzzy directory jumper fzf or rofi
kbgen2 kbgen Generate escape sequences for keyboard presses to customize clifm keybindings
decrypt.sh kd Decrypt a GnuPG encrypted file (usually encrypted via the encryption plugin (see below)) gpg, tar, sed, grep
encrypt.sh ke Encrypt files/dirs using GnuPG gpg, tar, sed, fzf, awk, xargs
mime_list.sh ml List files by MIME type
music_player.sh music Reproduce music playlists mplayer
pager.sh gg Pipe the current list of files through a pager (PAGER or less) less, column
pdf_viewer.sh ptot View PDF files as text pdftotext
rgfind.sh // Recursively search files by content fzf and ripgrep
update.sh update Check for clifm updates
vid_viewer.sh vid View video thumbnails ffmpegthumbnailer
virtualize.sh vt Create a virtual directory for a set of files More information
wallpapper_setter.sh wall Set image as wallpaper feh, xloadimage, hsetroot, or nitrogen (for X), swww or swaybg (Wayland)
xclip.sh kclip Copy the current line buffer to the clipboard via custom keybinding. See the plugin file itself for usage instructions. clipboard, wl-copy, xclip, xsel, pbcopy, termux-clipboard-set, clipboard, or clip

To run a plugin, say pager.sh, you only need to enter its corresponding action name, in this case, gg. To list available plugins and associated action names run the actions command.

NOTE: All plugins provide a -h,--help parameter for a brief usage description.

NOTE 2: Whereas some distributions have a packaged version of fzf, it could be a bit outdated. Since some options were renamed and/or modified in newer releases, this might cause some plugins not to work. It is recommended thereby to install the latest version directly from the Github repository by downloading the executable tarball, decompressing it, and copying the executable file somewhere in your PATH (e.g., /usr/local/bin).

1 Consult the Send files to Android device section for details.

2 The kbgen plugin is a C program, and as such needs to be compiled first. Go to the plugins directory and compile as follows:

gcc -o kbgen kbgen.c -lcurses

Depending on your system settings, you might need to replace -lcurses by -lncurses.

If running on Haiku, first install ncurses6_devel and then compile the program:

pkgman install ncurses6_devel
gcc -o kbgen kbgen.c -lncurses

This will produce the kbgen binary file necessary to run the plugin.

B. Keybindings for plugins

Clifm provides four customizable keybindings for custom plugins. The procedure for setting a keybinding for a plugin is the following:

1) Copy your plugin to the plugins directory (or use any of the plugins already in there)

2) Link pluginx (where x is the plugin number [1-4]) to your plugin using the actions edit command. For example:

plugin1=myplugin.sh
  1. Set a keybinding for pluginx using the kb edit command. For instance:
plugin1:\M-7

In this way, Alt-7 will now execute myplugin.sh.

C. Writing plugins

Though the above plugins are provided at installation time, you can write your owns as you like, with any language you like, and for whatever goal you want. Writing plugins is generally quite easy, but your mileage may vary depending on what you are trying to achieve. A good place to start is examining the provided plugins and reading the actions command description, just as the Environment and Files sections.

(Since 1.20.4) When running a plugin, and as a way to assist the plugins writer, clifm exports status information via environment variables. For example, CLIFM_LONG_VIEW is set to 1 if currently running in long view. For the complete list of exported values consult the Environment section. For a concrete usage example take a look at this discussion.

A convenient helper script is provided to get a consistent look across all plugins, specially those running FZF. Edit this file is you want to change the way FZF plugins look. This helper script is located in DATADIR/clifm/plugins/plugins-helper, but it will be overridden by XDG_CONFIG_HOME/clifm/plugins/plugins-helper if found. The location of this file is set by clifm itself in the CLIFM_PLUGINS_HELPER environment variable to be used by plugins. Source the file and use any of the functions and variables provided by it to write a new FZF plugin:

# Source our plugins helper
if [ -z "$CLIFM_PLUGINS_HELPER" ] || ! [ -f "$CLIFM_PLUGINS_HELPER" ]; then
	printf "clifm: Unable to find plugins-helper file\n" >&2
	exit 1
fi
# shellcheck source=/dev/null
. "$CLIFM_PLUGINS_HELPER"

NOTE: If you want to send a pull request with some of your plugins, make sure it is free of errors and warnings (running shellcheck) and 100% POSIX compliant. Portability matters.

D. General description of the plugins system

1) Plugins and clifm communicate via environment variables. Once the value of these variables is known, almost any other value could be obtained from here: almost everything in clifm is stored in the corresponding profile directory.

2) Plugins talk to clifm mainly via a pipe specifically created for this purpose. The path to this pipe can be found in the CLIFM_BUS environment variable.

A plugin can write to this pipe, which, after the plugin's execution, will be immediately read (and then deleted) by clifm. After reading this pipe, if not empty, clifm could take two possible actions:

a) If the content of the pipe is a directory, it will change to that directory (as if cd DIR were executed from within clifm itself).

b) Else, this content will be taken as a command (just as any command executed in clifm itself) and executed as such. For example: s * to select all non-hidden files in the current directory.

Example:

echo "/tmp" > "$CLIFM_BUS"

tells clifm to change the current directory to /tmp

echo "s *.png" > "$CLIFM_BUS"

instructs clifm to select all files in the current directory ending with ".png"

The pipe (CLIFM_BUS) is deleted immediately after the execution of its content and recreated before running any other plugin.

Plugins can also talk to clifm by editing or modifying clifm files. For example, to select some files, append those files to CLIFM_SELFILE (or delete this file to deselect all files):

printf "%s" "$files" > "$CLIFM_SELFILE"

or

rm "$CLIFM_SELFILE"

Files preview

Clifm provides two file preview methods:

1. Internally, via shotgun, a built-in files previewer

2. Externally, via the BFG script (as a plugin)

Shotgun

FZF TAB completion with file previews using the shotgun

a. Usage

Executed via the --preview command line switch, shotgun performs file preview for any file passed as argument. For example:

clifm --preview myfile.txt

Though it may be used as a standalone and general purpose file previewer (similar in this regard to pistol), it is mainly aimed to be used by clifm's TAB completion running in FZF mode: every time TAB completion is invoked for files, shotgun will be executed with the currently highlighted file as argument (as described above), generating a preview of the corresponding file using the application defined in the configuration file (see below). Set the FzfPreview option in the configuration file to false (or run with --no-fzfpreview) to disable this feature.

Shotgun is also used by the view command to preview files in the current directory in full screen.

b. Configuration file

Previewing applications (based on either MIME type or file name) are defined in a configuration file ($XDG_CONFIG_HOME/clifm/profiles/PROFILE/preview.clifm) using the same syntax used by Lira (the built-in resource opener). Run view edit (F7 is also available) to edit the configuration file.

If running as a standalone files previewer (i.e., outside clifm), you can set an alternative configuration file via the --shotgun-file command line option. Example:

clifm --shotgun-file=/path/to/shotgun/file --preview=/path/to/file

c. Customization

To customize the appearance of the preview window, use the --preview-window option (plus --color if you want to set the border color as well) in the FzfTabOptions line in the current color scheme file (cs edit or F8). For example, if you want bold red top and bottom borders for the preview window:

--preview-window=border-horizontal --color='border:1:bold'

c.1. Keybindings for the preview window

Key Action
Alt-p Toggle the preview window on/off
Ctrl-Up / Shift-Up Scroll the preview window up one line
Ctrl-Down / Shift-Down Scroll the preview window down one line
Alt-Up Scroll the preview window up one page
Alt-Down Scroll the preview window down one page

Keybindings can be customized using the --bind option in the FzfTabOptions field in the color scheme file.

Consult fzf(1) for more information.

d. Getting image previews with the shotgun

By default, shotgun performs only text based previews (including ASCII previews for image files). However, it is possible to make it display proper 24-bit images using the clifmimg plugin.

image_previews

BFG - Clifm's files previewer

The fzfnav plugin doing its previewing stuff

If we have a ranger, and a rifle, and a pistol (and now a shotgun as well), why not a BFG?

The fzfnav plugin uses FZF to navigate the filesystem and BFG (a script similar to Ranger's scope.sh located in the plugins directory) to show file previews. Bear in mind that, though as capable as shotgun, BFG is a shell script completely external to clifm, and thereby much slower than the shotgun.

A configuration file, located in the plugins directory itself, is available to customize BFG. This is the list of general options:

Option Default value Description
BFG_FILE ${XDG_CONFIG_HOME:-$HOME/.config}/clifm/plugins/BFG.sh Location of the BFG script
OPENER clifm Resource opener used to open files
PREVIEWDIR ${XDG_CACHE_HOME:-$HOME/.cache}/clifm/previews BFG caches images to speed up the previewing process. Specify here where to store these cached files
USE_SCOPE 0 Set to 1 to use Ranger's scope previewer
SCOPE_FILE ${XDG_CONFIG_HOME:-$HOME/.config}/ranger/scope.sh Location of the scope.sh script
USE_PISTOL 0 Set to 1 to use pistol
PREVIEW_IMAGES 0 Set to 1 to enable image previews
PLAY_MUSIC 0 Set to 1 to automatically play sound files
ANIMATE_GIFS 0 Set to 1 to animate GIF's instead of displaying an static image
FALLBACK_INFO 1 BFG will try to print file information if no previewing application is found. Set to 0 to disable this behavior

The BFG configuration file also allows you to specify applications to preview different kinds of files. It is highly recommended to set these values to prevent BFG from scanning the system looking for available applications. Setting these values will thus speed up the previewing process. Of course, you can also edit both fzfnav and BFG scripts to your liking, for example, adding custom previewing applications. If you decide to do this, bear in mind the logical structure of the previewing process:

1) The fzfnav script will first read the configuration file (BFG.cfg) looking for user defined values.
2) If no value was set for a given option, fzfnav will scan the system looking for an appropriate application.
3) Once the application was found (either via 1 or 2), an environment variable will be used to store the corresponding value.
4) BFG.sh will be executed: it will launch the previewing application as specified by the corresponding environment variable.

Files previewing dependencies

This is a list of applications needed to preview different file types.

File type Dependencies1
archives atool, bsdtar or tar
audio ffmpeg, mplayer or mpv
directories ls, tree, exa, or lsd
DjVu djvulibre or djvutxt
docs libreoffice, catdoc, odt2txt, pandoc
epub epub-thumbnailer
files info exiftool, mediainfo or file
fonts fontpreview or fontforge
highlight bat, highlight or pygmentize
images imagemagick, and either the Kitty terminal, ueberzug, or, to display images a text, viu, catimg, img2txt, or pixterm
json python or pq
markdown glow
PDF pdftoppm, pdftotext or mutool
Postscript ghostscript
torrent transmission-cli
videos ffmpegthumbnailer
web w3m, linx, elinks or pandoc

Unlike Ranger's scope, BFG does not need to check for available previewing applications for each highlighted/selected file, since previewing applications are checked only once when fzfnav is invoked; then, the list of applications is passed to BFG, so that it already knows what to use for each file type case.

It is highly recommended nonetheless to edit BFG configuration file and set your preferred/installed previewing applications, preventing thus fzfnav from performing these checks itself, and thereby, improving performance.

For those file types that need to be converted into images before being displayed (GIF's, PDF's, Videos, Postscript files, office documents, and so on), the corresponding images are cached (in ${XDG_CACHE_HOME:-$HOME/.cache}/clifm/previews) to avoid the process of converting files once and again. If possible, preview images will be loaded from the cache directory for better performance.

Cached images are stored using MD5 hashes instead of the original file names to uniquely identify files.

Replacing BFG

However, fzfnav supports the use of both Ranger's scope.sh script and pistol instead of BFG definitions for files previews. To use scope, edit the BFG.sh script and set USE_SCOPE to 1 and SCOPE_FILE to the correct path to the scope.sh file (normally $HOME/.config/ranger/scope.sh). To use pistol instead, set USE_PISTOL to 1.

Of course, you can always replace the BFG by the shotgun.


Git integration

The git_status.sh plugin is not intended to be used as a normal plugin, that is, executed via an action name, but rather to be executed as a prompt command. Call the script as a prompt command as follows:

promptcmd /usr/share/clifm/plugins/git_status.sh

After doing this you should see the current git status immediately before each new prompt:

git

Whereas this plugin provides basic Git integration, it could be easily modified (it is just a few lines long) to include whatever git function you might need.


Icons 😏

Clifm with icons-in-terminal

Though clifm natively supports the use of icons, it is not enabled by default. However, enabling icons is just a few steps away. Both icons-in-terminal and Nerdfonts, just as emoji-icons (Unicode characters as icons) are supported.

1) Get your icons set

1.a) emoji-icons:

  • If using some major desktop environment you are more likely ready to go, since desktop environments usually provide emoji fonts by default. If not, install the appropriate package: noto-fonts-emoji for Arch-based distributions, fonts-noto-color-emoji for Debian-based distros, and google-noto-emoji-fontsfor those based on RedHat.
  • By default, clifm is compiled with support for emoji-icons, so that no further action is required: it should work out of the box.

1.b) icons-in-terminal:

export CPPFLAGS="$CPPFLAGS -D_ICONS_IN_TERMINAL"
make

1 Consult the compilation page for more information.

1.c) Nerdfonts:

  • Download some patched Nerdfont
  • Install it, normally copying the font file to ~/.fonts, and then running fc-cache -f ~/.fonts. Restart your terminal emulator.
  • Change your terminal emulator's font to the patched Nerdfont. Some GUI menu should do the trick. If no GUI is available, you need to rely on the .Xresources file.
  • Clone this repository and recompile clifm passing the -D_NERD option directly to the compiler (say gcc or clang),1 or run make as follows:
export CPPFLAGS="$CPPFLAGS -D_NERD"
make

1 Consult the compilation page for more information.

2) Once the icons are set, using any of the methods described above, run clifm with the --icons command line option, or, once in the program itself, enter icons on.
That's it.

Customizing icons

For the time being there is no option to customize icons. However, if you feel adventurous, you can edit the source code and recompile the program. Icons are defined in the icons.h header file in the form of constants taken from icons-in-terminal.h (provided by the icons-in-terminal project), icons-nerdfont.h, and icons-emoji.h.

Changing icons is done by replacing the appropriate value for each icon you want to change (codepoints for nerdonts and icons-in-terminal, for example, \u1234, or the actual emoji if using rather emoji-icons). For example, the icons.h file specifies that (when using icons-in-terminal icons) the icon for files ending with .pdf is ICON_PDF, whose value is set to FA_FILE_PDF_O, defined as \ue27a in icons-in-terminal.h. So, to change the icon for file names ending with .pdf you only need to edit the value of ICON_PDF in icons.h. You can choose one of the following procedures:

  1. change the value of ICON_PDF to the Unicode code point you want, say \u1234:
ICON_PDF = "\u1234";

or,

  1. directly assign this value to file extension itself:
{"pdf", "\u1234", RED},

As you can see, the icons color could be easily customized in this same file, using macros (here RED) for ANSI escape codes, or these escape codes themselves. So, to make PDF icons bold blue, replace RED by the appropriate color code:

{"pdf", "\u1234", "\x1b[1;34m"},

Note: emoji-icons use their own color, so that there is no need to manually specify any color.
Note 2: The icons check precedence is performed from greater to lesser specificity:

  1. Filename or filename.extension (try to match exact file names)
  2. Extension
  3. File type

Bear in mind that, if running in light mode, only the file type check (3) is performed.

Issues with icons

If experiencing some issue when trying to enable icons, consider the following suggestions:

1) Make sure a proper font is installed. Consult the icons section.
2) Check whether your terminal supports Unicode:

  • Issue this command on it: echo -e '\xe2\x82\xac'. It should print an euro sign. If not, it most likely does not support Unicode.

3) If using a patched Nerdfont, your terminal must be set to use this font, either via the GUI, if available, or the .Xresources file. If the latter:

  • List font names: fc-list | cut -d: -f2 | sort -u
  • Now, edit ~/.Xresources and use the chosen font (name) for your terminal (say, urxvt):
URxvt*font: xft:NAME:size=12

Files filters

Clifm provides multiple ways to filter files in the current directory.

1. Dot filter

Used to permanently exclude/include hidden files (more specifically dotfiles) from the files list.

Use -a, --show-hidden to enable hidden files, and -A, --no-hidden to disable them.

Use the hh command (or Alt-.) to toggle hidden files on/off on the fly.

1.b .hidden files

The usual way to hide files in Unix environments is via the use of dotfiles. But renaming files (just to make them hidden) is not always possible or desirable: renaming ~/Downloads to ~/.Downloads without affecting the rest of the system is just not possible.

Files listed in a special file named .hidden in the current directory will be hidden as well (even if they do not start with a dot) whenever hidden files are not shown.

Lines in a .hidden file are of two types: plain file names and wildcards. Note that, when specifying plain file names, only base names (that is, names of files in the current directory) are allowed: lines containing a slash character are ignored.

For example, to hide all .pdf files, plus the directory Secret and all files starting with test in the ~/Downloads directory, create a file named .hidden in ~/Downloads and add the following lines:

/These files will be hidden:
Secret
test*

/And these too
*.pdf

Note: Empty lines are ignored, and lines starting with a slash (/) are comments (and thereby ignored as well).

This feature is disabled by default. To enable it, set ReadDotHidden to true in the configuration file.

2. Directories filter

Use the Alt-, keybinding to toggle list-directories-only on/off. The --only-dirs command line flag can be used as well.

3. Files filter (either by name or file type)

Used to filter files by name (via a regular expression) or by file type (via a file type character). Use the exclamation mark (!) at the beginning of a query to invert the meaning of the query.

Supposing you want to exclude backup files (ending with ~), the three possible procedures would be:

a. Via the CLIFM_FILTER environment variable:

export CLIFM_FILTER='!.*~$'
# or
CLIFM_FILTER='!.*~$' clifm

Note: If using double quotes, escape the exclamation mark to prevent the shell from expanding the expression: CLIFM_FILTER="\!.*~$"

b. Via the Filter option in the configuration file:

Filter=!.*~$

c. Via the ft command (do not quote the expression):

ft !.*~$

Note: Only the second procedure provides a permanent files filter.

To filter by file type, instead of file name, use the = keyword (see below). For example, to list only symbolic links in the current directory

ft =l

or, to exclude socket files:

ft !=s

Once you are done, unset the filter:

ft unset

See below for the list of available file type characters.

4. The quick search function

Use the quick search function (supporting both regular expressions, wildcards, and invert matching) to temporarily filter the current list of files. See the search section for more information.

Note: There is a fourth files filter that searches for files not by names, but by content. The rgfind.sh plugin, bound by default to the // action, uses ripgrep and fzf to interactively search for files by inspecting their content. For example, to get the list of C files in the current directory calling strncmp(3):

// strncmp

5. Filter expressions

When working with large lists of files, it is often useful to be able to quickly filter files, either by file name, MIME type, or file type.

1. To filter files by file name, use the appropriate glob expression and then hit TAB:1

p *.PDF<TAB>

or as a quick search:

/*.PDF<TAB>

2. Filter files by MIME type using the @ keyword. For example:

@<TAB>

to list all MIME types found in the current directory.

You can also use a query string (which could be any of the MIME types found before or a custom string). For instance:

@image<TAB>

will print all files in the current directory whose MIME type includes the given query string, in this case, image.

To directly operate on all files matching the given query, use the @QUERY construct. For example, to get file properties for all image files:

p @image

3. Filter files by file type using the = keyword

=<TAB>

This lists all file types available in the current directory.

Use a file type character1 to get the list of files matching that specific file type. For example:

=d<TAB>

to get the list of all directories in the current directory.2

Or, if you need rather the list of executable files:

=x<TAB>

To directly operate on all files of a given file type, use the =FILE-TYPE-CHAR construct. For example, to get file properties for all executable files and symlinks in the current directory:

p =x =l

The =x and =l expressions will be automatically expanded to executable files and symlinks respectively after pressing Enter.

1 Multi-selection is available if using the FZF TAB completion mode.
2 Alt-, can also be used to toggle list-directories-only on/off.

Available file type characters

Char Description
b Block devices
c Character devices
C Files with capabilities1 2
d Directories
D Empty directories2
f Regular files
F Empty regular files2
g SGID files2
h Multi-hardlink files (directories excluded)2
l Symbolic links
L Broken symbolic links2
O Doors (Solaris only)
o Other-writable files2
p FIFO/pipes
P Ports (Solaris only)
s Sockets
t File with the sticky bit set2
u SUID files2
x Executable files2

1 Only for TAB completion
2 Not available in light mode

Grouping files (via automatic expansion)

Using the above mentioned features, clifm allows you to easily group and operate on groups of files. For example:

vt :b @image =l =x *.txt t:work sel

opens a virtual directory (via the vt plugin) automatically expanding the above expressions as follows:

Expression Description
:b All you bookmarks
@image All image files (filtered by MIME type) in the CWD1
=x All executable files (CWD)
=l All symbolic links (CWD)
*.txt All .txt files (CWD)
t:work All files tagged as work
sel All selected files

1 Technically, all files whose MIME type contains the string image

If you need rather to operate only on some files of a given group, hit TAB immediately after the corresponding expression:

p sel<TAB>

to list and choose from selected files.

Or

p =d<TAB>

to list and choose from all directories in the current directory.

Or

p *.pdf<TAB>

to list and choose from all PDF files in the current directory.

Note that these automatic expansions can be used as well with any shell command, say ls(1):

ls =x @pdf

Virtual directories

Clifm is able to read and list files from the standard input stream (STDIN). Each file in the list should be an absolute path, terminated with a new line character (\n) and stripped from extra characters not belonging to the path itself. The size of the input stream buffer is 262MiB (65536 paths, provided each path takes PATH_MAX bytes (4096 by default)).

Each file passed via standard input is stored as a symbolic link pointing to the original file in a temporary directory (called here virtual directory) with read-only (0500) permissions. By default, the system temporary directory (usually /tmp/clifm/USER/vdir.XXXXXX, where XXXXXX is a random six digits string) is used. To specify a custom virtual directory use the --virtual-dir command line flag. This directory, and all its contents, will be deleted at program exit.

The user can operate on these files as if they were any other regular file, since all operations performed on these symbolic links (provided the current working directory is the virtual directory where all these files are stored) are performed on the target files and NOT on the symbolic links themselves.

Once in the virtual directory, files are listed by default using only the base name of the target file. For example, if the target file is /home/user/Downloads/myfile.tar.gz, this file will be listed as myfile.tar.gz. If this file already exists in the virtual directory (because there is another target file with the same base name, say, /home/user/Documents/tars/myfile.tar.gz), a random six digits suffix will be appended to the file (for instance, myfile.tar.gz.12Rgj6).

Since this listing mode does not allow the user to get a clear idea of the actual location of each listed file, a keybinding (by default Alt-w) is available to toggle short (base names only) and long file names: in this latter case, file names are listed using the full path to the target file, replacing slashes by colons (:). For example, if the target file is /home/user/Downloads/myfile.tar.gz, it will be listed in the virtual directory as home:user:Downloads:myfile.tar.gz.

If you prefer the long names approach, you can use the --virtual-dir-full-paths command line flag.

Tip: If file names are too long, specially if using the long name mode, you can toggle max name length on/off pressing Ctrl-Alt-l.

Note: Since the virtual directory is deleted at program exit, the restore last path function is disabled when listing in this way.

Clifm provides to ways of using virtual directories:

  1. Reading files from the standard input
  2. Listing sets of files via the virtualize.sh plugin (which is in fact a special use case of point 1)

1. Standard input

Examples:

ls -Ad /var/* | clifm

This command will pass all files in /var to clifm

If you need to perform more specific queries, you can use find(1) as follows:

find -maxdepth 1 -size +500k -print0 | tr '\0' '\n' | sed 's/\.\///g' | clifm --no-restore-last-path

The above command will pass all files in the current directory bigger than 500KiB to clifm.

Note: If restore-last-path is enabled in the configuration file, and you pass to clifm relative paths, and clifm's last path is not the current directory, then it has no way to locate those files in the file system. To avoid this scenario, always run with --no-restore-last-path.

You can also use stream redirection:

ls -Ad $PWD/* > list.txt
clifm < list.txt

2. The virtualization plugin

The virtualize.sh plugin, bound by default to the vt action name, is intended to provide an easy way of listing sets or collections of files, such as selected, tagged, or bookmarked files. For example, to send all selected files to a virtual directory, you can issue this command:

vt sel

and, if you want rather files tagged as PDF:

vt t:PDF

Of course, individual files can also be used:

vt file1 file2 file3

Once executed, the vt plugin will launch a new instance of clifm (on a new terminal emulator window)1 where you can operate on the specified files as if they were just normal files. Once done, quit this new instance (via the q command) to return to the primary instance of clifm.

1 By default, the terminal emulator used is xterm, but can easily be customized by editing the plugin script (virtualize.sh).

If navigating the file system, you can quickly go back to the virtual directory using the -d option:

vt -d

The navigation keys (see the Navigation section) and the CLIFM_VIRTUAL_DIR environment variable are also available: Shift-Left/Shift-Right or cd $CLIFM_VIRTUAL_DIR.

Tip: Write an alias to make this even easier:

alias vtd='cd $CLIFM_VIRTUAL_DIR'

Wildcards and REGEX

Wildcards and regular expressions are understood by all clifm internal commands, though they are mostly useful for searching and selecting files.

You can certainly do something like this:

cd Do*

to access a directory called Documents.

NOTE: If more than one file matches your glob expression, the first one will be used. A better (more secure) alternative in this case would be to use TAB completion

However, the true power of glob and regular expressions is manifested by the search and selection functions. For example:

/*.png

or (using now a regular expression)

/.*png$

to list all files in the current directory ending with .png. Another example:

s .*\.[ch]

to select all C source (.c) and header (.h) files in the current directory.

For more information consult the search and selection sections.


Multiple instances

Sometimes it is useful to have several open windows each running a terminal, and, in our case, clifm. Indeed, you can browse files in one instance of the program, pick or select a few files, and then operate on these files using a second (or third) instance, for example, to copy or move selected files into a new directory, or whatever you like.

Using multiple terminal windows is not the only way though: you can also use some terminal multiplexer like Tmux, GNU Screen or dvtm.

A better, because native, alternative to this procedure is the use of clifm's workspaces: do not change windows, no even terminals; just switch workspaces with a single keybinding (Alt-[1-4])!


CD on quit

This shell function allows your shell to cd into the last directory visited by clifm to keep directories in sync. The general procedure is as follows: run clifm and, after exit, read the .last file and cd into the path specified there.

  1. Customize the below function (you can find it in /usr/share/clifm/functions/cd_on_quit.sh) as you need:
c() {
	clifm "--cd-on-quit" "$@"
	dir="$(grep "^\*" "${XDG_CONFIG_HOME:=${HOME}/.config}/clifm/.last" 2>/dev/null | cut -d':' -f2)";
	if [ -d "$dir" ]; then
		cd -- "$dir" || return 1
	fi
}
  1. Add this line to your shell configuration file (e.g., .bashrc, .zshrc, etc):
source /usr/share/clifm/functions/cd_on_quit.sh

Note: If you're using the Fish shell, use cd_on_quit.fish instead.

  1. Restart your shell for changes to take effect.
  2. Run clifm using the name of the function above instead of the usual clifm:
c [OPTIONS] [PATH]

Once you quit clifm, your shell will automatically change to the last visited directory.


File picker

The file picker plugin allows you to use clifm as a file selector/picker for another shell command or program.

Usage:

file_picker.sh [FILE]

Clifm will be executed as usual. Select the files you need and exit. If FILE is specified, selected files are written to FILE, or to stdout otherwise.

Usage example:

ls -ld $(file_picker.sh)

Note that by default xterm is used as terminal emulator. Edit the plugin file and set the CLIFM_TERM variable to your preferred terminal application (you can also set CLIFM_TERM as an environment variable). For example:

export CLIFM_TERM="alacritty"
ls -ld $(file_picker.sh)

Files lister (ls-mode)

Clifm can be used as a simple (ls(1)-like) files lister via the --list-and-quit command line option. For example:

# Emulate ls(1)
clifm --list-and-quit --no-clear-screen --no-eln --no-classify --no-files-counter /bin
# or (a bit shorter version)
clifm --ls --no-clear-screen -e --no-classify --no-files-counter /bin

To simplify this long command, write an alias in the corresponding shell configuration file (say ~/.bashrc):

alias lsc='clifm --ls --no-clear-screen -e --no-classify --no-files-counter'

Now run your alias as any other command (adding some extra options if needed):

lsc --icons /bin

or, to list files properties (long view) and hidden files:

lsc -al /bin

To customize information displayed in long view, use the --prop-fields switch. For example, to display exactly the same fields displayed by ls(1) by default (permissions, links, user/group ID names, size in bytes, and modification time):

lsc -al --prop-fields="plISm" /bin

Consult the File details section for more information.

Note: Bear in mind that clifm's command line switches are not the same as those used by ls(1) nor any other files lister. Run clifm --help for more information.


stat(1) replacement

Via the --stat and --stat-full command line switches, clifm works like the old stat(1) command: print information about the specified file and exit. Example:

clifm --stat ~/Downloads

or, if you prefer the full stat mode (symlinks are always dereferenced and directories size is computed recursively):

clifm --stat-full ~/Downloads

Note: While --stat runs internally the p command, --stat-full runs rather the pp command.

You might want to create a shell alias for these commands. For instance

alias p="clifm --stat"
alias pp="clifm --stat-full"

Afterwards you can use any of these aliases instead of stat:

p ~/Downloads

or

pp ~/Downloads

Subshell notification

Since clifm can spawn a subshell from within itself (via the ; or : command), it is useful to add a prompt notice to let the user know that this shell has been spawned from clifm.

To achieve this source this file, /usr/share/clifm/functions/subshell_notice.sh from your shell configuration file (say ~/.bashrc, ~/.zshrc, etc) and then restart your shell:

source /usr/share/clifm/functions/subshell_notice.sh

Of course, you can also copy the following line to your shell configuration file (after the PS1 assignment line):

[ -n "$CLIFM" ] && PS1="$PS1"'(clifm) '

Bulk operations

1. Rename files in bulk

Let's suppose you have a bunch of files named like this:

abc1
abc2
abc3
...

It is clear that renaming the files one by one with the shell mv command is not a great solution. This is where a bulk rename function comes in handy. To invoke this function in clifm use the br command followed by the names of those files to be renamed. Wildcards and regular expressions are allowed. For example:

br abc*

Each file name to be renamed will copied into a text file and opened via the default associated application for text files. Here you can modify each file name as you please. Once the file is saved and the editor is closed, clifm will ask for confirmation: if you accept, all files will be renamed at once.

2. Remove files in bulk

See the rr command

Note: Note that both things, bulk remove/rename, can be achieved at once using the vidir(1) shell command. If vidir(1) is preferred over br and rr, you can make use of an alias:

br="vidir"

3. Create files in bulk

See the bn plugin.

4. Create symbolic links in bulk

See the bl command.


Archives

By invoking some external tools, clifm provides archiving and compression support. This is the list of dependencies:

Dependencies Functions
zstd Everything related to Zstandard
mkisofs (provided by cdrtools) Create an ISO 9660 file
7z (provided by p7zip) and mount 1 Operate on ISO 9660 files
archivemount Mount archives
atool Extraction/decompression, listing, and repacking archives

1 Mounting ISO files is restricted to Linux only

The commands used to manage archives are ac and ad, the former for compression/archiving and the latter for decompression/dearchiving.

1. Archiving

Archiving files, via the ac command, involves only two steps:

  1. Select files to be archived. This can be done either via the selection function (s) or directly telling ac what files are to be archived:
s FILES(s)

and then

ac sel

or

ac FILE(s)
  1. The user will be asked for the archiving/compression type, which must be indicated via the file extension. For example: filename.xz. If not extension is provided .tar.gz is used instead.

2. Dearchiving

For dearchiving/decompressing files use the ad command as follows:

ad FILE(s)

The user will be presented with the following menu:

[e]xtract [E]xtract-to-dir [l]ist [m]ount [r]epack [q]uit

Now select the desired operation. That's it.


Send files to Android device

There are three steps involved in this procedure (1 and 2 need to be done only once):

1. Set up a SSH server on your Android device

a. Install SSH Server from Google Play.

b. Run the app, set up your server, and start it. Write down your user name, password, and home directory; you'll need them later to set up the client. You'll also need the device's IP address.

2. Set up the client

a. Install openssh; it provides scp, used by this plugin to remotely copy files.

b. In clifm, run cr --edit1 to set up the details of our remote location (the Android device). It should be something like this:

[Android phone]
Options="-P 2222 -o HostKeyAlgorithms=+ssh-dss" # These options will be passed as parameters to scp(1)
Target="android@192.168.0.165:/storage/emulated/0/Download"
  • [Android phone] is the name used to identify this connection. You can set up as many connections as you want, so that a descriptive name is a good idea.
  • 2222 is the default port used by SSH Server.
  • HostKeyAlgorithms=+ssh-dss instructs scp to use the DSA algorithm to connect to the SSH server (though insecure and deprecated, this is the algorithm used by SSH Server).
  • android@192.168.0.165: is the user name (the one used while setting up the SSH server) and the IP address of the Android device.
  • /storage/emulated/0/Download is the home directory set in SSH Server. Files will be copied here.

1 cr is an action name linked to the cprm.sh plugin.

3. Copy files

Run cr FILE/DIR, where FILE/DIR is the regular file or directory you want to copy.1 You'll be asked for the remote location by name (using FZF). Finally, you'll be asked for the SSH server password and the file will be copied into Target (as specified in step 2).

1 To copy multiple files at once you can either archive them (see the ac command) and then use this archive as FILE, or copy them into an empty directory and then pass this directory as DIR.


cp/mv With a Progress Bar

By default, c and m commands invoke cp(1) and mv(1) commands. However, none of them includes a progress bar: just wait patiently until they finish their work. There are nonetheless a few alternative implementations able to do precisely this: inform the user about the command progress. clifm offers built-in support for three of these implementations, namely, advcpmv, wcp, and rsync(1).

Via clifm's configuration file you can choose which implementation to invoke when using the c and m commands:

  • cpCmd: Available options are: 0 = regular cp, 1 = advcp, 2 = wcp. Parameters passed to advcp are -giRp SOURCE DEST. wcp takes no option, so that we can only pass SOURCE DEST. Parameters passed to rsync are -avP.

  • mvCmd: Only two options are available: 0 = regular mv, and 1 = advmv. Parameters passed to advmv are -gi SOURCE DEST.

NOTE: If you prefer a different implementation, or just a different command/parameters to copy or move files, you can make use of aliases. For example, if you want to use rsync instead of cp to copy big files, set an alias like this:

alias bcp='rsync -avP'
Clone this wiki locally