ranger

Related articles
File manager functionality
lf
Midnight Commander
nnn
Vifm
ranger
is a text-based file manager written in
Python
. Directories are displayed in one pane with three columns. Moving between them is accomplished with keystrokes, bookmarks, the mouse or the command history. File previews and directory contents show automatically for the current selection.
Features include:
vi
-style key bindings, bookmarks, selections, tagging, tabs, command history, the ability to make symbolic links, several console modes, and a task view.
ranger
has customizable commands and key bindings, including bindings to external scripts. Ranger also comes with its own
file opener
,
rifle(1)
.
The closest competitors are
lf
and
Vifm
.
Installation
Install
the
ranger
package.
Usage
To start ranger, launch a
terminal
and run
ranger
.
Key
Command
?
Open the manual or list keybindings, commands and settings
l
,
Enter
Launch files
j
,
k
Select file in the current directory
h
,
l
Travel up and down in the directory tree
Configuration
After startup, ranger creates a directory
~/.config/ranger
. To copy the default configuration to this directory issue the following command:
$ ranger --copy-config=all
Afterwards, set
RANGER_LOAD_DEFAULT_RC=false
as an
environment variable
to avoid loading the global configuration in addition to the local.
rc.conf
- startup commands and key bindings
commands.py
- commands which are launched with
:
rifle.conf
- applications used when a given type of file is launched.
rc.conf
only needs to include changes from the default file as both are loaded. For
commands.py
, if you do not include the whole file, put this line at the top:
from ranger.api.commands import *
See
ranger(1)
for general configuration.
Move to trash
To add a keybind that moves files to your trash directory
~/.local/share/Trash/files/
with
DD
, amend the configuration file as follows:
~/.config/ranger/rc.conf
...
map DD shell mv %s /home/${USER}/.local/share/Trash/files/
...
Alternatively, use GIO commandline tool provided by
glib2
package:
map DD shell gio trash %s
Inspecting and emptying the "trash" is normally supported by graphical file managers such as
nautilus
, but you can also see the trash with the command
gio list trash://
, and empty it with:
gio trash --empty
.
Defining commands
Continuing the above example, add the following entry to empty the trash directory
~/.Trash
.
~/.config/ranger/commands.py
...

class empty(Command):
    """:empty

    Empties the trash directory ~/.Trash
    """

    def execute(self):
        self.fm.run("rm -rf /home/myname/.Trash/")
To use it, type
:empty
and
Enter
with tab completion as desired.
Color schemes
Ranger comes with four color schemes:
default
,
jungle
,
snow
and
solarized
.
You can change your color scheme using:
set colorscheme
scheme
Custom color schemes can be placed in
~/.config/ranger/colorschemes
.
Color highlight in file previews
Install the
python-pygments
package, then copy
/usr/share/doc/ranger/config/scope.sh
to
~/.config/ranger/scope.sh
and edit the variable
PYGMENTIZE_STYLE
in the configuration file of ranger to your liking. The complete list of supported themes can be obtained via
pygmentize -L style
.
File association
Ranger uses its own file opener called
rifle
.
It is configured in
~/.config/ranger/rifle.conf
. Run
ranger --copy-config=rifle
if it does not exist. For example, the following line makes
kile
the default program for tex files:
ext tex = kile "$@"
To open all files with
xdg-utils
, make sure your
$EDITOR
and
$PAGER
are set and add:
else = xdg-open "$1"
label editor = "$EDITOR" -- "$@"
label pager  = "$PAGER" -- "$@"
Tips and tricks
This article or section needs language, wiki syntax or style improvements. See
Help:Style
for reference.
Reason:
bad style (Discuss in
Talk:Ranger
)
Archives
These commands use
atool
to perform archive operations.
Archive extraction
The following command implements archive extraction of the selected items to the current directory.
import os
from ranger.core.loader import CommandLoader

class extract_here(Command):
    def execute(self):
        """ extract selected files to current directory."""
        cwd = self.fm.thisdir
        marked_files = tuple(cwd.get_selection())

        def refresh(_):
            cwd = self.fm.get_directory(original_path)
            cwd.load_content()

        one_file = marked_files[0]
        cwd = self.fm.thisdir
        original_path = cwd.path
        au_flags = ['-x', cwd.path]
        au_flags += self.line.split()[1:]
        au_flags += ['-e']

        self.fm.copy_buffer.clear()
        self.fm.cut_buffer = False
        if len(marked_files) == 1:
            descr = "extracting: " + os.path.basename(one_file.path)
        else:
            descr = "extracting files from: " + os.path.basename(
                one_file.dirname)
        obj = CommandLoader(args=['aunpack'] + au_flags
                            + [f.path for f in marked_files], descr=descr,
                            read=True)

        obj.signal_bind('after', refresh)
        self.fm.loader.add(obj)
Compression
The following command allows users to compress several files on the current directory by marking them and then calling
:compress
package name
. It supports name suggestions by getting the basename of the current directory and appending several possibilities for the extension. You need to have
atool
installed, otherwise you will see an error message when you create the archive.
import os
from ranger.core.loader import CommandLoader

class compress(Command):
    def execute(self):
        """ Compress marked files to current directory """
        cwd = self.fm.thisdir
        marked_files = cwd.get_selection()

        if not marked_files:
            return

        def refresh(_):
            cwd = self.fm.get_directory(original_path)
            cwd.load_content()

        original_path = cwd.path
        parts = self.line.split()
        au_flags = parts[1:]

        descr = "compressing files in: " + os.path.basename(parts[1])
        obj = CommandLoader(args=['apack'] + au_flags + \
                [os.path.relpath(f.path, cwd.path) for f in marked_files], descr=descr, read=True)

        obj.signal_bind('after', refresh)
        self.fm.loader.add(obj)

    def tab(self, tabnum):
        """ Complete with current folder name """

        extension = ['.zip', '.tar.gz', '.rar', '.7z']
        return ['compress ' + os.path.basename(self.fm.thisdir.path) + ext for ext in extension]
External drives
External drives can be automatically mounted with
udev
or
udisks
. The default key mappings to go to common mount points
/media
and
/run/media/$USER
are
gm
and
gi
respectively.
Hidden files
You can toggle the visibility of hidden files with the following command:
:set show_hidden!
, or use
:set show_hidden true
to make hidden files visible.
To make this permanent, add the setting to your configuration file:
rc.conf
set show_hidden true
Alternatively, hidden files can be toggled by pressing
zh
.
Image mounting
The following command assumes you are using
CDemu
as your image mounter and some kind of system like
autofs
which mounts the virtual drive to a specified location ('/media/virtualrom' in this case).
Do not forget to change mountpath to reflect your system settings
.
To mount an image (or images) to a cdemud virtual drive from ranger you select the image files and then type ':mount' on the console. The mounting may actually take some time depending on your setup (in mine it may take as long as one minute) so the command uses a custom loader that waits until the mount directory is mounted and then opens it on the background in tab 9.
import os, time
from ranger.core.loader import Loadable
from ranger.ext.signals import SignalDispatcher
from ranger.ext.shell_escape import *

class MountLoader(Loadable, SignalDispatcher):
    """
    Wait until a directory is mounted
    """
    def __init__(self, path):
        SignalDispatcher.__init__(self)
        descr = "Waiting for dir '" + path + "' to be mounted"
        Loadable.__init__(self, self.generate(), descr)
        self.path = path

    def generate(self):
        available = False
        while not available:
            try:
                if os.path.ismount(self.path):
                    available = True
            except:
                pass
            yield
            time.sleep(0.03)
        self.signal_emit('after')

class mount(Command):
    def execute(self):
        selected_files = self.fm.thisdir.get_selection()

        if not selected_files:
            return

        space = ' '
        self.fm.execute_command("cdemu -b system unload 0")
        self.fm.execute_command("cdemu -b system load 0 " + \
                space.join([shell_escape(f.path) for f in selected_files]))

        mountpath = "/media/virtualrom/"

        def mount_finished(path):
            currenttab = self.fm.current_tab
            self.fm.tab_open(9, mountpath)
            self.fm.tab_open(currenttab)

        obj = MountLoader(mountpath)
        obj.signal_bind('after', mount_finished)
        self.fm.loader.add(obj)
New tab in current folder
You may have noticed there are two shortcuts for opening a new tab in home (
g
n
and
Ctrl+n
). Let us rebind
Ctrl+n
:
rc.conf
map <c-n>  eval fm.tab_new('%d')
PDF file preview
PDF text preview
By default, ranger will preview PDF files as text with no additional configuration needed.
PDF image preview
You can preview PDF files as an image in ranger by first converting the PDF file to an image. For this feature to work, you need to install
pdftoppm(1)
, which is part of
poppler
package.
Ranger stores the image previews in
~/.cache/ranger/
. You either need to create this directory manually or set
preview_images
to
true
in
~/.config/ranger/rc.conf
to tell
ranger
to create it automatically at the next start.  However, note that
preview_images
does not need to be set to
true
the whole time to preview PDF file as images, only
~/.cache/ranger
directory is needed.
To enable this feature, uncomment the appropriate lines in
/usr/share/doc/ranger/config/scope.sh
, or add/uncomment these lines in your local file
~/.config/ranger/scope.sh
.
Shell tips
Synchronize path
Ranger provides a shell
function
/usr/share/doc/ranger/examples/shell_automatic_cd.sh
. Running
ranger_cd
instead of
ranger
will automatically
cd
to the last browsed folder.
If you launch ranger from a graphical launcher (such as
$TERMCMD -e ranger
, where TERMCMD is an X terminal), you cannot use
ranger_cd
. Instead, create an executable script:
ranger-launcher.sh
#!/bin/sh
export RANGERCD=true
$TERMCMD
And add the following at the end of your shell configuration:
.
shell
rc
$RANGERCD && unset RANGERCD && ranger_cd
This will launch
ranger_cd
only if the
RANGERCD
variable is set. It is important to unset this variable again, otherwise launching a subshell from this terminal will automatically relaunch
ranger
.
Preventing nested ranger instances
You can start a shell in the current directory with
S
, when you exit the shell you get back to your ranger instance.
When you however forget that you already are in a ranger shell and start ranger again you end up with ranger running a shell running ranger.
To prevent this you can create the following function in your
shell's startup file
:
ranger() {
    if [ -z "$RANGER_LEVEL" ]; then
        /usr/bin/ranger "$@"
    else
        exit
    fi
}
Image preview on Wayland
Ueberzugpp serves as a drop in replacement for ueberzug, adding Wayland support. It does not support all Wayland compositors, please check if your compositor is supported. See
[1]
.
~/.config/ranger/rc.conf
set preview_images_method ueberzug
If low quality pixel image is previewed,
change the layer output to kitty
even if kitty is not installed.
~/.config/ueberzugpp/config.json
{ "layer": { "output": "kitty"  } }
See also
BBS thread
GitHub
Official User Guide
Installing and using ranger
Mailing list
Ranger tutorial