Difference between revisions of "Ranger"

From ArchWiki
Jump to navigation Jump to search
(→‎Defining commands: highlight a potentially destructive operation)
Line 1: Line 1:
[[Category: File managers (English)]]
[[Category:File managers]]
[[Category: File systems (English)]]
[[Category: File systems (English)]]

Revision as of 14:43, 23 April 2012

This template has only maintenance purposes. For linking to local translations please use interlanguage links, see Help:i18n#Interlanguage links.

Local languages: Català – Dansk – English – Español – Esperanto – Hrvatski – Indonesia – Italiano – Lietuviškai – Magyar – Nederlands – Norsk Bokmål – Polski – Português – Slovenský – Česky – Ελληνικά – Български – Русский – Српски – Українська – עברית – العربية – ไทย – 日本語 – 正體中文 – 简体中文 – 한국어

External languages (all articles in these languages should be moved to the external wiki): Deutsch – Français – Română – Suomi – Svenska – Tiếng Việt – Türkçe – فارسی

Tango-view-fullscreen.pngThis article or section needs expansion.Tango-view-fullscreen.png

Reason: please use the first argument of the template to provide a brief explanation. (Discuss in Talk:Ranger#)

Ranger is a text-based file manager written in Python with vi-style key bindings. It has an extensive set of features , and you can accomplish file management tasks with a few keystrokes with no need for the mouse.

Web Resources


Ranger is included in the Community repository. Or, use the ranger-git PKGBUILD in AUR.

Comparison with other File Managers

Compared to graphical mouse-based file managers, Ranger is much more efficient, but still visually beautiful. Ranger has one pane with multiple columns for different directories in the path, and file previews on the right. Compared to double-pane file managers, Ranger shows more directory and file information. You can quickly move between directories using keystrokes, bookmarks or the command history. Previews of files and directory contents automatically show up for the current selection. Ranger's 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. The closest competitor is Vifm, which has two panes and vi-style key bindings, but has fewer features overall.


Ranger's man page can be opened by typing "?". You can also press "1?" for a list of key bindings, "2?" for a list of commands and "3?" for a list of settings.


After startup, Ranger creates a directory ~/.config/ranger/. You can copy the default configuration files to this directory with the command

ranger --copy-config=all

and edit them as you like. Some basic knowledge of python is useful here. options.py controls general options, rc.conf controls startup commands and key bindings, commands.py controls the commands which are launched with the ":" key, and apps.py controls the applications used when a given type of file is launched. You can launch files with "l" (ell) or "<Enter>". You need only include changes from the default files, but be sure to include any necessary headers. Also, if you change part of a function, be sure to include the whole thing, since you're redefining that function.

Binding keys

Use the file ~/.config/ranger/rc.conf to modify key bindings. There are many keybindings already defined, and you can learn the syntax by reading the file.

The following example shows how to use "DD" to move selected files to a directory ~/.Trash/. Put this code in ~/.config/ranger/rc.conf

# move to trash
map DD shell mv -t /home/carl/.config/ranger/Trash %s

Defining commands

Continuing the above example, adding the following entry to ~/.config/ranger/commands.py would define a command to empty the trash directory ~/.Trash.

class empty(Command):

	Empties the trash directory ~/.Trash

 	def execute(self):
		self.fm.run("rm -rf /home/myname/.Trash/{*,.[^.]*}")

To use it, you would type ":empty<Enter>", using tab completion if desired.

Warning: Note that [^.] is an essential part of the above command. Otherwise, it will remove all files and directories of the form ..*, thereby wiping out everything in your home directory.

Starting programs in the background

In many cases, launching a file will make Ranger unusable until the program you used to launch the file is closed. The following example shows how to change this for html files. In ~/.config/ranger/apps.py, change

if f.extension in ('html', 'htm', 'xhtml', 'swf'):
	return self.either(c, 'firefox', 'opera', 'elinks')


if f.extension in ('html', 'htm', 'xhtml', 'swf'):
	c.flags += 'd'
	return self.either(c, 'firefox', 'opera')

The option "d" stands for "detached". We removed "elinks" because it's a text-mode browser, and cannot be detached

Useful commands

Archive Related

These commands use atool to perform archive operations.


The following command implements archive extraction by copying (yy) one or more archive files and then executing ":extracthere" on the desired directory.

import os
from ranger.core.loader import CommandLoader

class extracthere(Command):
    def execute(self):
        """ Extract copied files to current directory """
        copied_files = tuple(self.fm.env.copy)

        if not copied_files:

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

        one_file = copied_files[0]
        cwd = self.fm.env.cwd
        original_path = cwd.path
        au_flags = ['-X', cwd.path]
        au_flags += self.line.split()[1:]
        au_flags += ['-e']

        self.fm.env.cut = False
        if len(copied_files) == 1:
            descr = "extracting: " + os.path.basename(one_file.path)
            descr = "extracting files from: " + os.path.basename(one_file.dirname)
        obj = CommandLoader(args=['aunpack'] + au_flags \
                + [f.path for f in copied_files], descr=descr)

        obj.signal_bind('after', refresh)


The following command allows the user 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.

import os
from ranger.core.loader import CommandLoader

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

        if not marked_files:

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

        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)

        obj.signal_bind('after', refresh)

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

        extension = ['.zip', '.tar.gz', '.rar', '.7z']
        return ['compress ' + os.path.basename(self.fm.env.cwd.path) + ext for ext in extension]

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). Don't 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):
        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:
                if os.path.ismount(self.path):
                    available = True

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

        if not selected_files:

        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)

        obj = MountLoader(mountpath)
        obj.signal_bind('after', mount_finished)