# Ranger (简体中文)

翻译状态： 本文是英文页面 Ranger 的翻译，最后翻译时间：2013-05-24，点击这里可以查看翻译后英文页面的改动。

ranger 是一个 Python 编写，vi 操作风格，基于文本的文件管理器。它具有良好的扩展性能，你可以在不需要鼠标的情况下，通过一些按键完成文件管理任务。

## 安装

ranger 可以使用 pacman 从 official repositories 安装. 在 AUR 还包含 ranger-git。

Optional, for file previews with "scope.sh":

- libcaca (img2txt) 用于图片预览
- highlight 用于高亮代码
- atool 用于存档预览
- lynx, w3m 或 elinks 用于 html 页面预览
- poppler (pdftotext) 用于 pdf 预览
- transmission-show 用于浏览 bit-torrent 信息
- mediainfo 或 perl-image-exiftool 用于浏览媒体文件信息

## 运行

启动一个终端，例如 xterm，以运行 ranger，输入命令 `ranger`。或者，你也可以使用如下命令

    xterm -e ranger

## 与其他文件管理器的比较

较之于图形化基于鼠标的文件管理器，ranger 效率更高，but still visually appealing。ranger 有一个面板，包含多个列，可以在右边进行文件预览。相对于双面板的文件管理器, ranger 显示了更多的目录和文件信息。你可以使用按键，书签，命令历史在目录中快速移动。自动显示当前选择的文件和目录预览。ranger 的特性包括： vi 风格的键绑定，书签，选择，标签，选项卡，命令历史，创建符号链接，多种终端模式，以及任务视图。ranger 可以定制命令和键绑定，包括绑定到外部脚本。最接近的竞争者是 Vifm， 它有 2 个面板以及 vi 风格的键绑定，但是总体特性相对较少。

## 文档

输入 `?` 可以打开 ranger 的手册页面。 也可以输入 `1?` 得到一个键绑定的列表，`2?` 得到一个命令的列表，`3?` 得到设置的列表.

## 定制

启动之后 ranger 会创建一个目录 `~/.config/ranger/`。可以使用以下命令复制默认配置文件到这个目录:

    ranger --copy-config=all

然后可以对它们进行定制。了解一些基本的 python 知识可能会有帮助。

- `rc.conf` 控制启动命令和键绑定
- `commands.py` controls the commands which are launched with the ":" key
- `rifle.conf` 控制当给定文件类型启动时，使用的应用程序。

你可以使用 "l"(ell) 或 "<enter>" 启动文件。For `rc.conf`, you need only include changes from the default file, since both are loaded。对于 `commands.py`，如果你没有包含整个文件，把下面这一行加入到文件起始处：

    from ranger.api.commands import *

### 键绑定

使用 `~/.config/ranger/rc.conf` 修改键绑定。已经定义了许多键绑定，你可以通过阅读这个文件学习相关语法。

以下示例显示如何使用 "DD" 移动指定文件到一个目录 `~/.Trash/`。把代码放在 `~/.config/ranger/rc.conf`

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

### 命令定义

继续上面的例子，在 `~/.config/ranger/commands.py` 增加如下代码将会定义一个清空垃圾箱 `~/.Trash` 的命令。

    class empty(Command):
        """:empty

        Empties the trash directory ~/.Trash
        """

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

输入 ":empty<Enter>" 以使用命令， 如果希望的话，也可以使用 tab 补全。

Warning: 注意 [^.] 是上面命令的必要部分。否则，它会删除所有 ..* 形式的文件和目录，即删除你家目录的所有数据。

### 使用指定的程序打开文件

修改 `~/.config/ranger/rifle.conf`。因为开头的行先被执行，你应该把你的修改放在文件的开始处。 例如，如下的代码会使用 kile 打开一个 tex 文件。

    ext tex = kile "$@"

#### Using sxiv to browse through images

In order to browse through images in sxiv after launching the viewer from ranger by opening an image file, use the rifle_sxiv.sh script and follow the instructions in its comments.

## 有用的命令

### 外部驱动

外部驱动可以被 Udev 规则或在一个自动挂载的 Udev wrapper 帮助下自动挂载。挂载在 `/media` 下的驱动可以通过输入 `gm` (go, media) 被访问。

### 网络驱动

### 存档相关

可以使用 atool 来进行存档操作。

#### 解压缩

下面的命令实现了复制(yy)一个或多个存档文件，然后执行 ":extracthere" 解压到需要的目录。

    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:
                return

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

            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.copy.clear()
            self.fm.env.cut = 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)

#### 压缩

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:
                return

            def refresh(_):
                cwd = self.fm.env.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.env.cwd.path) + ext for ext in extension]

### 镜像挂载

如下命令假设你正在使用 cdemu 作为你的镜像挂载器和一些挂载虚拟驱动器到指定位置 ('/media/virtualrom' in this case) 的，类似于 autofs的系统。不要忘记根据你的系统设置修改挂载路径.

To mount an image (or images) to a cdemud 虚拟驱动器 from ranger you select the image files and 然后在终端输入 ':mount'。根据你的设置，挂载可能会需要一些时间(我的需要长达一分钟的时间) 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.env.cwd.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)

## 网络资源

- ranger web page.
- ranger mailing list
- Arch Linux forum thread.
- GitHub-page
- DotShare.it configurations.

Category:

- File managers (简体中文)