Difference between revisions of "Ranger"

From ArchWiki
Jump to: navigation, search
(link to mailing list)
m (See also: official website is linked at the top)
 
(92 intermediate revisions by 31 users not shown)
Line 1: Line 1:
 +
{{DISPLAYTITLE:ranger}}
 
[[Category:File managers]]
 
[[Category:File managers]]
[[Category:File systems]]
+
[[ar:Ranger]]
 
[[fr:ranger]]
 
[[fr:ranger]]
{{Article summary start|Summary}}
+
[[ja:Ranger]]
{{Article summary text|A guide to installing and configuring ranger}}
+
[[zh-CN:Ranger]]
{{Article summary heading|Related}}
+
{{Related articles start}}
{{Article summary wiki|atool}}
+
{{Related|Midnight Commander}}
{{Article summary end}}
+
{{Related|vifm}}
{{DISPLAYTITLE:ranger}}
+
{{Related articles end}}
'''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.
+
[http://ranger.nongnu.org/ 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.  The closest competitor is [[Vifm]], which has two panes and vi-style key bindings, but fewer features overall.
 +
 
 +
== Installation ==
 +
 
 +
{{Pkg|ranger}} can be [[install]]ed from the [[official repositories]]. Use {{AUR|ranger-git}} in the [[AUR]] for the development version.
 +
 
 +
== Usage ==
 +
 
 +
To start ranger, launch a [[List of applications#Terminal emulators|terminal]] and run {{ic|ranger}}.
 +
 
 +
{| class="wikitable"
 +
|+
 +
! Key !! Command
 +
|-
 +
| {{ic|?}} || Open the manual or list keybindings, commands and settings
 +
|-
 +
| {{ic|l}}, {{ic|Enter}} || Launch files
 +
|}
 +
 
 +
== Configuration ==
  
==Installing==
+
After startup, ''ranger'' creates a directory {{ic|~/.config/ranger}}. To copy the default configuration to this directory issue the following command:
{{Pkg|ranger}} can be installed from the [[Official Repositories|official repositories]] with [[pacman]]:
+
# pacman -S ranger
+
There is also [https://aur.archlinux.org/packages.php?ID=35421 ranger-git] in [[AUR]].
+
  
Optional, for file previews with "scope.sh":
+
  ranger --copy-config=all
* {{Pkg|libcaca}} (img2txt) for previewing images
+
* {{Pkg|highlight}} for syntax highlighting of code
+
* {{Pkg|atool}} for previews of archives
+
* {{Pkg|lynx}}, {{Pkg|w3m}} or {{Pkg|elinks}} for previews of html pages
+
* {{Pkg|itext}} (pdftotext) for pdf previews
+
* {{Pkg|transmission-show}} for viewing bit-torrent information
+
* {{Pkg|mediainfo}} or  {{Pkg|exiftool}} for viewing information about media files
+
  
==Running==
+
* {{ic|rc.conf}} - startup commands and key bindings
To start ranger, launch a terminal such as xterm, and type the command {{ic|ranger}}. Or, you can use the command
+
* {{ic|commands.py}} - commands which are launched with {{ic|:}}
xterm -e ranger
+
* {{ic|rifle.conf}} - applications used when a given type of file is launched.
  
==Comparison with other File Managers==
+
{{ic|rc.conf}} only needs to include changes from the default file as both are loaded. For {{ic|commands.py}}, if you do not include the whole file, put this line at the top:
Compared to graphical mouse-based file managers, ranger is much more efficient, but still visually appealing. 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.
+
  
==Documentation==
+
from ranger.api.commands import *
ranger's man page can be opened by typing {{ic|?}}. You can also press {{ic|1?}} for a list of key bindings, {{ic|2?}} for a list of commands and {{ic|3?}} for a list of settings.
+
  
==Customization==
+
To add a keybind that moves files to a created directory {{ic|~/.Trash/}} with {{ic|DD}}, add to {{ic|~/.config/ranger/rc.conf}}:
After startup, ranger creates a directory {{ic|~/.config/ranger/}}.  You can copy the default configuration files to this directory with the following command:
+
<pre>ranger --copy-config=all</pre>
+
They can then be customized. Some basic knowledge of python is useful.
+
  
*{{ic|rc.conf}} controls startup commands and key bindings
+
map DD shell mv -t /home/${USER}/.Trash %s
*{{ic|commands.py}} controls the commands which are launched with the ":" key
+
*{{ic|rifle.conf}} controls the applications used when a given type of file is launched.
+
  
You can launch files with "l" (ell) or "<Enter>". For {{ic|rc.conf}}, you need only include changes from the default file, since both are loaded. For {{ic|commands.py}}, if you do not include the whole file, put this line at the top:
+
See [http://ranger.nongnu.org/ranger.1.html man ranger] for general configuration.
<pre>
+
from ranger.api.commands import *
+
</pre>
+
  
===Binding keys===
+
=== Defining commands ===
Use the file {{ic|~/.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 {{ic|~/.Trash/}}.  Put this code in {{ic|~/.config/ranger/rc.conf}}
+
Continuing the above example, add the following entry to {{ic|~/.config/ranger/commands.py}} to empty the trash directory {{ic|~/.Trash}}.
<pre>
+
# move to trash
+
map DD shell mv -t /home/myname/.config/ranger/Trash %s
+
</pre>
+
  
===Defining commands===
+
{{bc|<nowiki>
Continuing the above example, adding the following entry to {{ic|~/.config/ranger/commands.py}} would define a command to empty the trash directory {{ic|~/.Trash}}.
+
<pre>
+
 
class empty(Command):
 
class empty(Command):
 
     """:empty
 
     """:empty
Line 68: Line 63:
 
     def execute(self):
 
     def execute(self):
 
         self.fm.run("rm -rf /home/myname/.Trash/{*,.[^.]*}")
 
         self.fm.run("rm -rf /home/myname/.Trash/{*,.[^.]*}")
</pre>
+
</nowiki>}}
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.}}
+
To use it, type {{ic|:empty}} and {{ic|Enter}} with tab completion as desired.
  
===Opening files with a given application===
+
{{Warning|{{ic|[^.]}} is an essential part of the above command.  Without it, all files and directories of the form {{ic|..*}} will be deleted, wiping out everything in your home directory.}}
  
Modify {{ic|~/.config/ranger/rifle.conf}}.  Since the beginning lines are executed first, you should put your modifications at the beginning of the file.  For example, the following entry will open a tex file with kile.
+
=== Colorscheme ===
<pre>
+
ext tex = kile "$@"
+
</pre>
+
  
==Useful commands==
+
Create the {{ic|colorschemes}} subfolder in {{ic|~/.config/ranger}}:
===External Drives===
+
External drives can be automatically mounted with an [[Udev]] rule or with the help of an automounting Udev wrapper. Drives mounted under {{ic|/media}} can be easily accessed by pressing {{keypress|gm}} (go, media).
+
  
===Network Drives===
+
mkdir ~/.config/ranger/colorschemes
 +
 
 +
then copy your new {{ic|''newscheme''.py}} into that folder. Alter the default color scheme in the {{ic|~/.config/ranger/rc.conf}} file:
 +
 
 +
set colorscheme ''newscheme''
 +
 
 +
=== File association ===
 +
 
 +
Modify {{ic|~/.config/ranger/rifle.conf}}. As the beginning lines are executed first, you should put modifications at the top of the file. For example, the following entry will open a tex file with {{Pkg|kile}}:
 +
 
 +
ext tex = kile "$@"
 +
 
 +
To open all files with {{Pkg|xdg-utils}}:
 +
 
 +
has xdg-open, flag f = xdg-open "$1"
 +
 
 +
== Tips and tricks ==
 +
 
 +
{{Template:Poor writing|}}
 +
 
 +
=== Archives ===
  
===Archive Related===
 
 
These commands use {{Pkg|atool}} to perform archive operations.
 
These commands use {{Pkg|atool}} to perform archive operations.
  
====Extraction====
+
==== Archive extraction ====
The following command implements archive extraction by copying (yy) one or more archive files and then executing ":extracthere" on the desired directory.
+
 
 +
The following command implements archive extraction by copying (yy) one or more archive files and then executing {{ic|:extracthere}} on the desired directory.
  
<pre>
+
{{bc|<nowiki>
 
import os
 
import os
 
from ranger.core.loader import CommandLoader
 
from ranger.core.loader import CommandLoader
Line 99: Line 108:
 
     def execute(self):
 
     def execute(self):
 
         """ Extract copied files to current directory """
 
         """ Extract copied files to current directory """
         copied_files = tuple(self.fm.env.copy)
+
         copied_files = tuple(self.fm.copy_buffer)
  
 
         if not copied_files:
 
         if not copied_files:
Line 105: Line 114:
  
 
         def refresh(_):
 
         def refresh(_):
             cwd = self.fm.env.get_directory(original_path)
+
             cwd = self.fm.get_directory(original_path)
 
             cwd.load_content()
 
             cwd.load_content()
  
 
         one_file = copied_files[0]
 
         one_file = copied_files[0]
         cwd = self.fm.env.cwd
+
         cwd = self.fm.thisdir
 
         original_path = cwd.path
 
         original_path = cwd.path
 
         au_flags = ['-X', cwd.path]
 
         au_flags = ['-X', cwd.path]
Line 115: Line 124:
 
         au_flags += ['-e']
 
         au_flags += ['-e']
  
         self.fm.env.copy.clear()
+
         self.fm.copy_buffer.clear()
         self.fm.env.cut = False
+
         self.fm.cut_buffer = False
 
         if len(copied_files) == 1:
 
         if len(copied_files) == 1:
 
             descr = "extracting: " + os.path.basename(one_file.path)
 
             descr = "extracting: " + os.path.basename(one_file.path)
Line 126: Line 135:
 
         obj.signal_bind('after', refresh)
 
         obj.signal_bind('after', refresh)
 
         self.fm.loader.add(obj)
 
         self.fm.loader.add(obj)
</pre>
+
</nowiki>}}
  
====Compression====
+
==== Compression ====
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.
+
  
<pre>
+
The following command allows the user to compress several files on the current directory by marking them and then calling {{ic|: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 {{pkg|atool}} installed. Otherwise you will see an error message when you create the archive.
 +
 
 +
{{bc|<nowiki>
 
import os
 
import os
 
from ranger.core.loader import CommandLoader
 
from ranger.core.loader import CommandLoader
Line 138: Line 148:
 
     def execute(self):
 
     def execute(self):
 
         """ Compress marked files to current directory """
 
         """ Compress marked files to current directory """
         cwd = self.fm.env.cwd
+
         cwd = self.fm.thisdir
 
         marked_files = cwd.get_selection()
 
         marked_files = cwd.get_selection()
  
Line 145: Line 155:
  
 
         def refresh(_):
 
         def refresh(_):
             cwd = self.fm.env.get_directory(original_path)
+
             cwd = self.fm.get_directory(original_path)
 
             cwd.load_content()
 
             cwd.load_content()
  
Line 163: Line 173:
  
 
         extension = ['.zip', '.tar.gz', '.rar', '.7z']
 
         extension = ['.zip', '.tar.gz', '.rar', '.7z']
         return ['compress ' + os.path.basename(self.fm.env.cwd.path) + ext for ext in extension]
+
         return ['compress ' + os.path.basename(self.fm.thisdir.path) + ext for ext in extension]
</pre>
+
</nowiki>}}
  
===Image Mounting===
+
=== External drives ===
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'''.
+
 
 +
External drives can be automatically mounted with [[udev]] or [[udisks]]. Drives mounted under {{ic|/media}} can be easily accessed by pressing {{ic|gm}} (go, media).
 +
 
 +
=== 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.
 
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.
  
<pre>
+
{{bc|<nowiki>
 
import os, time
 
import os, time
 
from ranger.core.loader import Loadable
 
from ranger.core.loader import Loadable
Line 201: Line 216:
 
class mount(Command):
 
class mount(Command):
 
     def execute(self):
 
     def execute(self):
         selected_files = self.fm.env.cwd.get_selection()
+
         selected_files = self.fm.thisdir.get_selection()
  
 
         if not selected_files:
 
         if not selected_files:
Line 221: Line 236:
 
         obj.signal_bind('after', mount_finished)
 
         obj.signal_bind('after', mount_finished)
 
         self.fm.loader.add(obj)
 
         self.fm.loader.add(obj)
</pre>
+
</nowiki>}}
 +
 
 +
=== New tab in current folder ===
 +
 
 +
You may have noticed there are two shortcuts for opening a new tab in home ({{ic|g}}{{ic|n}} and {{ic|Ctrl+n}}). Let us rebind {{ic|Ctrl+n}}:
 +
{{hc|rc.conf|<nowiki>
 +
map <c-n>  eval fm.tab_new('%d')
 +
</nowiki>}}
 +
 
 +
=== Shell tips ===
 +
 
 +
==== Synchronize path ====
 +
 
 +
''ranger'' provides a shell [[Bash/Functions|function]] {{ic|/usr/share/doc/ranger/examples/bash_automatic_cd.sh}}. Running {{ic|ranger-cd}} instead of {{ic|ranger}} will automatically ''cd'' to the last browsed folder.
 +
 
 +
If you launch ranger from a graphical launcher (such as {{ic|$TERMCMD -e ranger}}, where TERMCMD is an X terminal), you cannot use {{ic|ranger-cd}}. Create an executable script:
 +
 
 +
{{hc|ranger-launcher.sh|<nowiki>
 +
#!/bin/sh
 +
export RANGERCD=true
 +
$TERMCMD
 +
</nowiki>}}
 +
 
 +
and add at the ''very end'' of your shell configuration:
 +
 
 +
{{hc|.''shell''rc|<nowiki>
 +
$RANGERCD && unset RANGERCD && ranger-cd
 +
</nowiki>}}
 +
 
 +
This will launch {{ic|ranger-cd}} only if the {{ic|RANGERCD}} variable is set. It is important to unset this variable again, otherwise launching a subshell from this terminal will automatically relaunch {{ic|ranger}}.
 +
 
 +
==== Start a shell from ranger ====
 +
 
 +
With the previous method you can switch to a shell in last browsed path simply by leaving ranger. However you may not want to quit ranger for several reasons (numerous opened tabs, copy in progress, etc.).
 +
You can start a shell from ranger ({{ic|S}} by default) without losing your ranger session. Unfortunately, the shell will not switch to the current folder automatically. Again, this can be solved with an executable script:
 +
 
 +
{{hc|shellcd|<nowiki>
 +
#!/bin/sh
 +
export AUTOCD="$(realpath "$1")"
 +
 
 +
$SHELL
 +
</nowiki>}}
 +
 
 +
and - as before - add this to at the very end of your shell configuration:
 +
 
 +
{{hc|shellrc|<nowiki>
 +
cd "$AUTOCD"
 +
</nowiki>}}
 +
 
 +
Now you can change your shell binding for ranger:
 +
 
 +
{{hc|rc.conf|
 +
map S shell shellcd %d
 +
}}
 +
 
 +
Alternatively, you can make use of your shell history file if it has any. For instance, you could do this for [[zsh#Dirstack|zsh]]:
 +
 
 +
{{hc|shellcd|<nowiki>
 +
## Prepend argument to zsh dirstack.
 +
BUF="$(realpath "$1")
 +
$(grep -v "$(realpath "$1")" "$ZDIRS")"
 +
echo "$BUF" > "$ZDIRS"
 +
 
 +
zsh
 +
</nowiki>}}
 +
 
 +
Change ZDIRS for your dirstack.
 +
 
 +
===== A simpler solution =====
 +
 
 +
{{hc|rc.conf|<nowiki>
 +
map S shell bash -c "cd %d; bash"
 +
</nowiki>}}
 +
This could probably be adapted to other shells as well.
 +
Instead of just running a shell (like the default config), this will run {{ic|cd}} in a shell, then execute a interactive shell which will not immediately exit so that you can continue with what you wanted.
 +
 
 +
==== Start new ranger instance only if it is not running in current shell ====
 +
 
 +
Put this in your [[Autostarting#Shells|shell's startup file]]:
 +
 
 +
rg() {
 +
    if [ -z "$RANGER_LEVEL" ]
 +
    then
 +
        ranger
 +
    else
 +
        exit
 +
    fi
 +
}
 +
 
 +
Execute {{ic|rg}} to start or restore ranger.
 +
 
 +
== Troubleshooting ==
 +
 
 +
=== Artifacts in image preview ===
 +
 
 +
Borderless columns may cause stripes in image previews. [https://bbs.linuxdistrocommunity.com/showthread.php?tid=1051] In {{ic|~/.config/ranger/rc.conf}} set:
 +
 
 +
set draw_borders true
 +
 
 +
== See also ==
  
==Web Resources==
+
* [https://bbs.archlinux.org/viewtopic.php?id=93025 BBS thread]
* [http://nongnu.org/ranger ranger] web page.
+
* [http://dotshare.it/category/fms/ranger/ DotShare.it configurations]
* [https://lists.nongnu.org/mailman/listinfo/ranger-users ranger mailing list]
+
* [http://github.com/hut/ranger GitHub]
* Arch Linux [https://bbs.archlinux.org/viewtopic.php?id=93025 forum thread].
+
* [https://www.digitalocean.com/community/tutorials/installing-and-using-ranger-a-terminal-file-manager-on-a-ubuntu-vps Installing and using ranger]
* [http://github.com/hut/ranger GitHub-page]
+
* [https://lists.nongnu.org/mailman/listinfo/ranger-users Mailing list]
* [http://dotshare.it/category/fms/ranger/ DotShare.it] configurations.
+
* [http://bloerg.net/2012/10/17/ranger-file-manager.html Ranger tutorial]

Latest revision as of 09:17, 14 June 2016

Related articles

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. The closest competitor is Vifm, which has two panes and vi-style key bindings, but fewer features overall.

Installation

ranger can be installed from the official repositories. Use ranger-gitAUR in the AUR for the development version.

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

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
  • 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 *

To add a keybind that moves files to a created directory ~/.Trash/ with DD, add to ~/.config/ranger/rc.conf:

map DD shell mv -t /home/${USER}/.Trash %s

See man ranger for general configuration.

Defining commands

Continuing the above example, add the following entry to ~/.config/ranger/commands.py to empty the trash directory ~/.Trash.

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.

Warning: [^.] is an essential part of the above command. Without it, all files and directories of the form ..* will be deleted, wiping out everything in your home directory.

Colorscheme

Create the colorschemes subfolder in ~/.config/ranger:

mkdir ~/.config/ranger/colorschemes

then copy your new newscheme.py into that folder. Alter the default color scheme in the ~/.config/ranger/rc.conf file:

set colorscheme newscheme

File association

Modify ~/.config/ranger/rifle.conf. As the beginning lines are executed first, you should put modifications at the top of the file. For example, the following entry will open a tex file with kile:

ext tex = kile "$@"

To open all files with xdg-utils:

has xdg-open, flag f = xdg-open "$1"

Tips and tricks

Tango-edit-clear.pngThis article or section needs language, wiki syntax or style improvements.Tango-edit-clear.png

Reason: (Discuss in Talk:Ranger#)

Archives

These commands use atool to perform archive operations.

Archive extraction

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.copy_buffer)

        if not copied_files:
            return

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

        one_file = copied_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(copied_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 copied_files], descr=descr)

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

Compression

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. 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)

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

    def tab(self):
        """ 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. Drives mounted under /media can be easily accessed by pressing gm (go, media).

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 (gn and Ctrl+n). Let us rebind Ctrl+n:

rc.conf
map <c-n>  eval fm.tab_new('%d')

Shell tips

Synchronize path

ranger provides a shell function /usr/share/doc/ranger/examples/bash_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. Create an executable script:

ranger-launcher.sh
#!/bin/sh
export RANGERCD=true
$TERMCMD

and add at the very end of your shell configuration:

.shellrc
$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.

Start a shell from ranger

With the previous method you can switch to a shell in last browsed path simply by leaving ranger. However you may not want to quit ranger for several reasons (numerous opened tabs, copy in progress, etc.). You can start a shell from ranger (S by default) without losing your ranger session. Unfortunately, the shell will not switch to the current folder automatically. Again, this can be solved with an executable script:

shellcd
#!/bin/sh
export AUTOCD="$(realpath "$1")"

$SHELL

and - as before - add this to at the very end of your shell configuration:

shellrc
cd "$AUTOCD"

Now you can change your shell binding for ranger:

rc.conf
map S shell shellcd %d

Alternatively, you can make use of your shell history file if it has any. For instance, you could do this for zsh:

shellcd
## Prepend argument to zsh dirstack.
BUF="$(realpath "$1")
$(grep -v "$(realpath "$1")" "$ZDIRS")"
echo "$BUF" > "$ZDIRS"

zsh

Change ZDIRS for your dirstack.

A simpler solution
rc.conf
map S shell bash -c "cd %d; bash"

This could probably be adapted to other shells as well. Instead of just running a shell (like the default config), this will run cd in a shell, then execute a interactive shell which will not immediately exit so that you can continue with what you wanted.

Start new ranger instance only if it is not running in current shell

Put this in your shell's startup file:

rg() {
    if [ -z "$RANGER_LEVEL" ]
    then
        ranger
    else
        exit
    fi
}

Execute rg to start or restore ranger.

Troubleshooting

Artifacts in image preview

Borderless columns may cause stripes in image previews. [1] In ~/.config/ranger/rc.conf set:

set draw_borders true

See also