Idoを用いてrecentf的にファイルおよびディレクトリを開く

はじめに

過去に開いたことのあるファイルやディレクトリをすばやく開くためのツールとしてrecentfが知られている。 またhelmというパッケージの中でもhelm-recentfなどの関数が用意されているなど、このような機能の便利さは皆の共通認識になっていると思われる。

今回はそれをEmacsビルトインのIdoインターフェイスを用いて行ってみよう、ということである。

コード

以下にコードを示す。

(defun recentf-ido-find-files-and-dirs (arg)
  "Find a recent file and a directory using Ido."
  (interactive "P")
  (let* ((show-full-path-p (cond (arg t) (t nil)))
         (file-assoc-list
          (mapcar (lambda (x)
                    (cond ((equal (substring x (- (length x) 1) (length x)) "/")
                           (cons (file-name-directory x) x))
                          (t
                           (cond (show-full-path-p
                                  (cons x x))
                                 (t
                                  (cons (file-name-nondirectory x) x))))))
                  recentf-list))
         (filename-list
          (remove-duplicates (mapcar #'car file-assoc-list)
                             :test #'string=))
         (filename (ido-completing-read "Choose recent file or directory: "
                                        filename-list nil t)))
    (when filename
      (find-file (cdr (assoc filename file-assoc-list))))))

上記のコードはEmacsWikiを参考にした。 そのまま呼び出すと、ファイルの場合はそのbasenameのみで候補が表示される。

異なるディレクトリに同じファイル名があると選択に困る場合もあるので、C-uつきで呼び出すことで、 ファイルの候補名がフルパス表示される。それならば最初からフルパスで表示したらどうかと思われるかもしれないが、 その場合はレスポンスが重くなるのでデフォルトでは避けているわけである。

このとき、候補名が横に長くなり見づらく感じる場合には、ido-vertical-modeの導入をおすすめする。 helmのように候補が縦方向に列挙され、大変見やすくなる。

おわりに

ファイルを開いたりするのはhelmを使わなくともEmacsビルトインの機能を用いて十分便利にできる。