gonypage diary

トップ > 2023/06 > 11 > 20:57

2023/06/11

20:57 pager-modeを作ってEmacsのバッファ内でログを読んだりできるようにした

最近は業務でもプライベートでも端末内で生活している時間が長く、特に業務ではsshなのでセッション数を増やすのも面倒で可能な限りなんでもEmacs上で済ませたいと思っている。なので、eshellを導入してEmacs内でコンパイルもバージョン管理も済ませるようにしたのだが、これが端末としての互換性はかなりきびしくてlessがまともに動かなく、しょうがないので環境変数PAGERにcatを設定して逃げていた。

それにしてもあまり快適ではないのでもっとよい方法がないのかと思っていたが、Emacs上でテキストファイル内のエスケープシーケンスを色付け表示する方法があるということで、それを使えばよいのではないかと思って実験してみた。

まずは.emacsに以下のように追加してpager-modeを作る:

(define-derived-mode pager-mode fundamental-mode
  "Pager"
  "Pager mode to view texts with ANSI colors."
  (ansi-color-apply-on-region (point-min) (point-max))
  (set-buffer-modified-p nil)
  (define-key pager-mode-map (kbd "SPC") 'scroll-up-command)
  (define-key pager-mode-map "b" 'scroll-down-command)
  (define-key pager-mode-map "q" 'kill-this-buffer))
(add-to-list 'auto-mode-alist '("\\.pager\\'" . pager-mode))

拡張子.pagerで起動するように、ANSIカラーを適用するように、バッファ削除時に確認されないようにする。キーバインドはスペース、B、Qくらいあればよいだろう。

続いてページャコマンドを作る。ここではPythonで書いてemacspagerという名前でパスが通っている場所に置いた:

#! /usr/bin/python3

import os
import sys
import tempfile

if __name__ == "__main__":
    text = ""
    if len(sys.argv) == 1:
        done = False
        while not done:
            try:
                text += input() + "\n"
            except EOFError:
                done = True
    else:
        with open(sys.argv[1]) as file:
            text = file.read()

    fd, file_name = tempfile.mkstemp(".pager", "")
    with os.fdopen(fd, "w") as file:
        file.write(text)
        file.close()

    os.system("emacsclient " + file_name)

やっていることは引数がなければ標準入力を、引数があればそのファイルの内容を一時ファイルに出力し、emacsclientを起動するだけ。

最後に.emacsに環境変数PAGERを設定し、ページャとして使用されるようにする。emacsclientを使用するのでEmacsサーバも起動する必要がある:

(server-start)
(setenv "PAGER" "emacspager")

その後ページャを使用するコマンドを実行すると、その内容がEmacsのバッファ内に開かれるようになる。非常に便利だが、まだエラーハンドリングや大きい文書表示時のパフォーマンスという課題はあるので、追ってそのへんもなんとかしたい。

Generated by Rui 0.4.3