やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

rangerの設定 scope.shの書き方

 rangerはTUIファイラ。

rifle.conf

 scope.shはranger内のプレビュー機能を実装するシェルスクリプト

  • ソースコードをハイライト表示する
  • ranger内に画像表示する(rifleとは違い、外部アプリで起動するのではない)

起動条件

~/.config/ranger/rc.conf

set use_preview_script true

終了コード

 終了コードはexit 6のように実行することで示す。

code 意味 rangerの行動
0 成功 プレビューとして標準出力を表示する
1 プレビューなし プレビューをまったく表示しない
2 プレーンテキスト ファイルのプレーンコンテンツを表示する
3 固定幅 幅が変わってもリロードしない
4 高さを固定 高さが変わってもリロードしない
5 両方とも直す リロードしない
6 画像 画像のプレビューとして$IMAGE_CACHE_PATHが指す画像を表示する
7 画像 ファイルを画像として直接表示する

起動引数

 scope.shの引数は以下5つ。

FILE_PATH="${1}"         # Full path of the highlighted file
PV_WIDTH="${2}"          # Width of the preview pane (number of fitting characters)
PV_HEIGHT="${3}"         # Height of the preview pane (number of fitting characters)
IMAGE_CACHE_PATH="${4}"  # Full path that should be used to cache image preview
PV_IMAGE_ENABLED="${5}"  # 'True' if image previews are enabled, 'False' otherwise.

 4つの関数が定義されている。プレビュー表示処理を「何を基準に処理分けするか」で関数分けしている模様。

関数

関数 処理分け基準
handle_extension ファイルの拡張子
handle_image rc.confでset preview_images trueなら実行する
handle_mime MIME
handle_fallback 上記のいずれにも該当しない場合

実行

 実行箇所は以下。

MIMETYPE="$( file --dereference --brief --mime-type -- "${FILE_PATH}" )"
if [[ "${PV_IMAGE_ENABLED}" == 'True' ]]; then
    handle_image "${MIMETYPE}"
fi
handle_extension
handle_mime "${MIMETYPE}"
handle_fallback

exit 1

 関数を実行する条件や優先順位がわかる。

 fileコマンドにてMIMEタイプを取得している。

読んでみる

シンタックス・ハイライト

 rangerがシンタックス・ハイライトを表示する処理をみてみる。

# Settings
HIGHLIGHT_SIZE_MAX=262143  # 256KiB
HIGHLIGHT_TABWIDTH=8
HIGHLIGHT_STYLE='pablo'
PYGMENTIZE_STYLE='autumn'
...
handle_mime() {
    local mimetype="${1}"
    case "${mimetype}" in
        # Text
        text/* | */xml)
            # Syntax highlight
            if [[ "$( stat --printf='%s' -- "${FILE_PATH}" )" -gt "${HIGHLIGHT_SIZE_MAX}" ]]; then
                exit 2
            fi
            if [[ "$( tput colors )" -ge 256 ]]; then
                local pygmentize_format='terminal256'
                local highlight_format='xterm256'
            else
                local pygmentize_format='terminal'
                local highlight_format='ansi'
            fi
            highlight --replace-tabs="${HIGHLIGHT_TABWIDTH}" --out-format="${highlight_format}" \
                --style="${HIGHLIGHT_STYLE}" --force -- "${FILE_PATH}" && exit 5
            #pygmentize -f "${pygmentize_format}" -O "style=${PYGMENTIZE_STYLE}" -- "${FILE_PATH}" && exit 5
            exit 2;;
  • MIMEタイプがtext/*, */xmlのときに処理を行っている
  • ハイライタはhighlightを使っている(pygmentizeコメントアウト
  • exit 2によりrangerへ「プレーンテキストを表示せよ」としている
    • rangerはscope.shにて標準出力された結果を終了コードに応じた形式で表示する

 あとはコマンドとその引数の使い方を把握すればOK。

画像プレビュー

 rc.confでset preview_images trueなら以下を実行する。

handle_image() {
    local mimetype="${1}"
    case "${mimetype}" in
        # SVG
        # image/svg+xml)
        #     convert "${FILE_PATH}" "${IMAGE_CACHE_PATH}" && exit 6
        #     exit 1;;

        # Image
        image/*)
            local orientation
            orientation="$( identify -format '%[EXIF:Orientation]\n' -- "${FILE_PATH}" )"
            # If orientation data is present and the image actually
            # needs rotating ("1" means no rotation)...
            if [[ -n "$orientation" && "$orientation" != 1 ]]; then
                # ...auto-rotate the image according to the EXIF data.
                convert -- "${FILE_PATH}" -auto-orient "${IMAGE_CACHE_PATH}" && exit 6
            fi

            # `w3mimgdisplay` will be called for all images (unless overriden as above),
            # but might fail for unsupported types.
            exit 7;;
        ...
    esac
}
  • ImageMagickconvertコマンドを使っている
    • rangerの表示領域に合うよう縮小されている
  • exit 6にて$IMAGE_CACHE_PATHが指す画像をプレビューする

 rc.confでpreview_imagesfalseなら以下を実行する。

handle_mime() {
    local mimetype="${1}"
    case "${mimetype}" in
        ...
        # Image
        image/*)
            # Preview as text conversion
            # img2txt --gamma=0.6 --width="${PV_WIDTH}" -- "${FILE_PATH}" && exit 4
            exiftool "${FILE_PATH}" && exit 5
            exit 1;;
        ...
    esac
}
  • exiftoolコマンドにてExif情報をテキスト表示する
    • exit 4にて高さが変わってもリロードしない

 img2txtがあるならコメントアウトを外すことで画像をASCIIアート表示できる。以下、外してみてそれぞれの状態で比較してみた。

tool ラスタ(png) ベクタ(svg)
scope convert
f:id:ytyaru:20190326170736p:plain
exiftool
f:id:ytyaru:20190326171114p:plain
rifle sxiv
f:id:ytyaru:20190326171130p:plain
inkview
f:id:ytyaru:20190326171146p:plain

 img2txtSVGを変換できないらしい。次のexiftoolの処理が実行された。

 なお、img2txtは解像度が高いものは苦手。イラストは表現しやすいが写真は苦手。たとえば壁紙につかう写真は以下のようになる。

img2txt sxiv
f:id:ytyaru:20190326171901p:plain f:id:ytyaru:20190326171913p:plain

 もちろん画像表示できるターミナルならconvertコマンドで縮小した画像をきれいに表示できる。たとえばtarminologyなら以下のように。

f:id:ytyaru:20190326174002p:plain f:id:ytyaru:20190326174011p:plain

 しかしキーボードが日本語でなく英語になってしまうなどの問題により使い勝手が悪い。詳細は以下。

 結局、LxTerminal + img2txt(+exiftool) + sxiv(+inkview) が最もマシ。

対象環境

  • Raspbierry pi 3 Model B+
  • Raspbian stretch 9.0 2018-11-13
  • bash 4.4.12
  • python 2.7.13, pip 9.0.1
  • python3 3.5.3, pip3 9.0.1
  • ranger 1.9.2
$ uname -a
Linux raspberrypi 4.14.98-v7+ #1200 SMP Tue Feb 12 20:27:48 GMT 2019 armv7l GNU/Linux