ranger

出自 Arch Linux 中文维基

ranger 是一個基於文本的文件管理器,以 Python 編寫。不同層級的目錄分別在一個面板的三列中進行展示. 可以通過快捷鍵, 書籤, 滑鼠以及歷史命令在它們之間移動. 當選中文件或目錄時, 會自動顯示文件或目錄的內容.

主要特性有: vi 風格的快捷鍵, 書籤, 選擇, 標籤, 選項卡, 命令歷史, 創建符號連結的能力, 多種終端模式, 以及任務視圖. ranger 可以定製命令和快捷鍵,包括綁定到外部腳本。最接近的競爭者是 Vifm, 它有 2 個面板以及 vi 風格的快捷鍵,但是總體特性相對較少。

安裝[編輯 | 編輯原始碼]

安裝 ranger 包,或其開發版 ranger-gitAUR

用法[編輯 | 編輯原始碼]

終端裡執行 ranger 來啟動 ranger。

快捷鍵 命令
? 打開幫助手冊或列出快捷鍵、命令以及設置項
l, Enter 打開文件
j, k 選擇當前目錄中的文件
h, l 在目錄樹中上移和下移
q 退出

定製[編輯 | 編輯原始碼]

第一次啟動 ranger 會創建一個目錄 ~/.config/ranger/。可以使用以下命令複製默認配置文件到這個目錄:

$ ranger --copy-config=all

了解一些基本的 python 知識可能對定製 ranger 會有幫助。

  • rc.conf - 選項設置和快捷鍵
  • commands.py - 能通過 : 執行的命令
  • rifle.conf - 指定不同類型的文件的默認打開程序。
  • scope.sh - 文件預覽相關配置

rc.conf 只需要包含與默認配置文件不同的部分,因為它們都會被加載。對於 commands.py,如果你沒有包含整個文件,把下面這一行加入到文件起始處:

from ranger.api.commands import *

更多配置選項請參考 ranger(1)

移動到回收站[編輯 | 編輯原始碼]

如果想添加一個把文件移動到目錄 ~/.local/share/Trash/files/ 的快捷鍵 DD,把以下這一行添加到 ~/.config/ranger/rc.conf

map DD shell mv %s /home/${USER}/.local/share/Trash/files/

或使用 glib2 軟體包提供的 GIO 命令:

map DD shell gio trash %s

一般的圖形文件管理器都支持查看或清空回收站,此外還可以使用 gio list trash:// 命令查看,用 gio trash --empty 命令清空回收站。

命令定義[編輯 | 編輯原始碼]

繼續上面的例子,在 ~/.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/{*,.[^.]*}")

輸入 :emptyEnter 來執行命令, 如果希望的話,也可以使用 tab 補全。

警告: 注意 [^.] 是上面命令的必要部分。否則,它會刪除所有 ..* 形式的文件和目錄,即刪除你家目錄的所有數據。
提示: 你可以在官方 wiki 中找到很多有用的命令。

配色方案[編輯 | 編輯原始碼]

Ranger 配備了四個配色方案:默認 (default)叢林 (jungle)積雪 (snow)烈日 (solarized)。 下列命令可自定義配色:

 set colorscheme scheme

自定義配色方案放在 ~/.config/ranger/colorschemes

文件關聯[編輯 | 編輯原始碼]

Ranger 使用自己的文件打開程序,名為rifle,它的配置文件為 ~/.config/ranger/rifle.conf。如果該文件不存在,可運行 ranger --copy-config=rifle 生成。例如,如下的代碼指定 kile 為打開 tex 文件的默認程序。

ext tex = kile "$@"

使用 xdg-utils 來打開所有文件,設置 $EDITOR$PAGER:

else = xdg-open "$1"
label editor = "$EDITOR" -- "$@"
label pager  = "$PAGER" -- "$@"

提示與技巧[編輯 | 編輯原始碼]

本文或本章節的語言、語法或風格需要改進。參考:幫助:風格

原因:(在Talk:Ranger討論)

存檔相關[編輯 | 編輯原始碼]

可以使用 atoolp7zip 來進行存檔操作。

解壓縮[編輯 | 編輯原始碼]

下面的命令實現了複製(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.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)

對於使用 7z 的用戶, 可以在添加以下命令後, 選中壓縮包然後執行 ":extract" 或通過綁定的快捷鍵來解壓

class extract(Command):
    """:extract <paths>
    
    Extract archives using 7z
    """
    def execute(self):
        import os
        fail=[]
        for i in self.fm.thistab.get_selection():
            ExtractProg='7z x'
            if i.path.endswith('.zip'):
                # zip encoding issue
                ExtractProg='unzip -O gbk'
            elif i.path.endswith('.tar.gz'):
                ExtractProg='tar xvf'
            elif i.path.endswith('.tar.xz'):
                ExtractProg='tar xJvf'
            elif i.path.endswith('.tar.bz2'):
                ExtractProg='tar xjvf'
            if os.system('{0} "{1}"'.format(ExtractProg, i.path)):
                fail.append(i.path)
        if len(fail) > 0:
            self.fm.notify("Fail to extract: {0}".format(' '.join(fail)), duration=10, bad=True)
        self.fm.redraw_window()

PS: 如果需要解壓 ZIP 壓縮包還需要安裝 unzip-iconvAUR[損壞的連結:package not found](為了解決中文亂碼問題)

壓縮[編輯 | 編輯原始碼]

以下命令允許用戶將當前目錄下選中的文件通過":compress <package name>"命令壓縮。它還支持通過當前目錄名和為擴展名追加幾種可能性來建議名稱。

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]

外部驅動[編輯 | 編輯原始碼]

外部驅動可以通過 udev 或 [udisks] 自動掛載。掛載在 /media 下的驅動可以通過快捷鍵 gm (go, media) 訪問。

鏡像掛載[編輯 | 編輯原始碼]

以下命令假設你正在使用 CDemu 作為你的鏡像掛載器和一些掛載虛擬驅動器到指定位置 (如 '/media/virtualrom') ,類似於 autofs的系統。不要忘記根據你的系統設置修改掛載路徑.

為了從 ranger 裡把鏡像掛載到 cdemud 虛擬驅動器, 需要選中鏡像文件然後在終端輸入 ':mount'。根據你的設置,掛載可能會需要一些時間(我的需要長達一分鐘的時間). 以下命令使用自定義的 loader 會等待加載過程結束然後通過後台在第 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)

PDF文件預覽[編輯 | 編輯原始碼]

在默認情況下,ranger將會以文本的形式預覽PDF文件。然後,你可以通過先將PDF文件轉換為圖片,再以圖片的方式預覽PDF文件。ranger將圖片預覽保存在 ~/.cache/ranger/目錄下。你需要手動創建這個目錄,或者在~/.config/ranger/rc.confpreview_images設置為true來讓ranger在下一次啟動時自動創建這個目錄。然而,請注意你並不需要將preview_images一直設置為true來以圖片的方式預覽PDF文件,只要有 ~/.cache/ranger就可以了。

為了啟用這個功能,你可以在/usr/share/doc/ranger/config/scope.sh去掉相應行的注釋,或者在你本地文件~/.config/ranger/scope.sh中增加/取消注釋這些行。

在當前目錄打開新標籤[編輯 | 編輯原始碼]

你可能已經注意到有兩個快捷鍵能夠以家目錄為默認目錄創建新的標籤 (gnCtrl+n). 不妨重新綁定 Ctrl+n:

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

Shell tips[編輯 | 編輯原始碼]

目錄同步[編輯 | 編輯原始碼]

ranger 提供了一個 shell function /usr/share/doc/ranger/examples/shell_automatic_cd.sh. 執行 ranger-cd 會自動切換到最後一次瀏覽的目錄.

如果你的ranger是從一個終端模擬器啟動的(比如$TERMCMD -e ranger, 其中 TERMCMD 是某個X終端), 你將無法使用 ranger-cd. 請創建以下可執行腳本:

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

並在你的shell配置文件追加以下內容:

.shellrc
$RANGERCD && unset RANGERCD && ranger-cd

只在設置了RANGERCD變量的情況下才會啟動ranger-cd. 其中unset RANGERCD是必要的, 否則在終端中啟動一個subshell將會重新啟動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.

避免在 ranger 啟動的 shell 內創建新的 ranger[編輯 | 編輯原始碼]

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.

疑難解答[編輯 | 編輯原始碼]

Artifacts in image preview[編輯 | 編輯原始碼]

無邊框邊欄可能在圖片預覽中產生條紋。[1]~/.config/ranger/rc.conf 設置:

set draw_borders true

可以解決這個問題

參見[編輯 | 編輯原始碼]