Monthly Archives: 3月 2016

2016-03-01

Diredで一部の詳細(属性、ユーザ名、グループ名)を隠す(ファイルサイズと日時は残す)

Emacs24.4 から dired-hide-details-mode が使えるようになりましたが、ファイル名以外全部隠すんですね。極端だってば。いや、それが良いときもありますけど。

普段欲しい情報はファイルサイズと日付くらいでしょうか。属性(パーミッション等)、ユーザ名、グループ名は日頃の作業(一人用PCの非root作業)では意識する必要がないでしょう。しかし、これだけを隠すのは一筋縄ではいかないようです。

diredはいろんな動作がバッファ上のテキストに依存しています。例えばディレクトリかどうかはバッファにdという文字があるかどうかで判断していますし、マーク自体もバッファに*が付いているかで記録しているくらいです。なので、不用意に文字を消すと動作に支障を来してしまいます。

lsコマンドの引数を指定する dired-listing-switches という変数がありますが -l オプションを省くことは出来ません。gを指定すればグループ名くらいは消せます(全てのアクションが正しく動作するかは不明)。

それでは dired-hide-details-mode はどうやって情報を消しているかというと、文字列を存在させたまま非表示にすることで実現しています。実装を見ると dired-insert-set-properties関数 でバッファ上のテキストに invisibleプロパティ を設定しています。そしてそのdired-insert-set-properties関数は、diredバッファ上のテキストに次の三種類のシンボルをinvisibleプロパティとして設定します。

  • dired-hide-details-information (バッファ先頭の残り容量などの行)
  • dired-hide-details-detail (ファイルの詳細情報の部分)
  • dired-hide-details-link (シンボリック情報の部分)

それらのシンボルに対して dired-hide-details-update-invisibility-spec関数add-to-invisibility-specやremove-from-invisibility-spec を使うことでinvisible状態を変化させています。(GNU Emacs Lisp Reference Manual: Invisible Text)

さて、どうしましょうか。

理想的には dired-hide-details-detail を細分化すべきでしょう。

  • dired-hide-details-detail-perms
  • dired-hide-details-detail-links
  • dired-hide-details-detail-user
  • dired-hide-details-detail-group
  • dired-hide-details-detail-size
  • dired-hide-details-detail-time

といった具合に。

(setq dired-hide-details-parts '(perms links user group size time))

というリストを作っておけば、次のコードでこれらのシンボルが得られます。

(mapcar
 #'(lambda (part) (intern (concat "dired-hide-details-detail-" (symbol-name part))))
 dired-hide-details-parts)

表示する部分を指定するリストを次のように定義します。

(setq dired-hide-details-visible-parts '(size time)) ;;sizeとtimeのみ表示

実際にこれらを使ってinvisibleプロパティを操作するには次のようにします。

(mapc
 #'(lambda (part)
     (funcall
      (if (memq part dired-hide-details-visible-parts) 'remove-from-invisibility-spec 'add-to-invisibility-spec)
      (intern (concat "dired-details-s-" (symbol-name part)))))
  dired-hide-details-parts)

と、このような理屈で詳細をさらに詳細に非表示に出来るようにする dired-details-s.el を作成しました。

2016-03-01-dired-details-s-1.png

うまくパーミッション等だけを消せたのですが、うーん、どうにも見た目がダサいような。バッファの左端にいきなり右寄せの数字が現れるせいでしょうか。日時、サイズの順に並べればもう少し良くなると思います。順番を入れ替えるにはinvisibleプロパティだけでは実現できないので大変なのですが、それが出来たとしても根本的な解決にはならない無い気もします。ファイル名は左端、詳細情報はその右に表示するのが普通ではないでしょうか。エクスプローラにせよ、昔ながらのファイラーにせよ、少なくともデフォルトはそうなっているような気がします。

というわけで、頑張って詳細情報をファイル名の右に表示させてみたのが dired-details-r.el です。

2016-03-01-dired-details-r-1.png

うん、こんなもんでしょう。

もはやinvisibleプロパティだけでは対処できないので、ファイル名にオーバーレイを適用してafter-stringプロパティで文字列を表示しています。

その弊害がいくつか。

  • Font Lockで色づけできない(代わりの手段を提供)
  • カーソルの移動に不自然な所あり(左右移動でオーバーレイの右に出ると左に戻れないことがある。Dired側でもカーソルの動きを多少制限しているので、その兼ね合いか?)
  • オーバーレイの削除のタイミングが難しい(沢山のファイルがあると効率的に心配)
  • たまにレイアウトが崩れるかも?(元々?)

文字列は自分で組み立てているので自由な順番にカスタマイズできます。 わざわざ最大文字幅を計算してレイアウトし直しているので。 あらかじめ設定した組み合わせを'('キーでローテート出来ます。

あまりに長いファイル名が数個あるために全体が空白だらけになってしまうのを防ぐため、レイアウト上の最大幅を設定できるようにしました。レイアウトは崩れますが、見やすさを確保することが出来ます。

参考: