いっつも開くファイルなんてたかだか 5〜6 個だけど、探すのがめんどくさい。
とくに今はカスタマイズ中なので、.xyzzy は頻繁に開くし、自前のライブラリとかもしょっちゅう開く。
じゃあ、登録しとけばってことで、こんなのを作ってみた。
;;; ;;; @@@ find-file-frequently ;;; (defvar *find-file-frequently-list* '((merge-pathnames ".xyzzy" (user-homedir-pathname)) (append-trail-slash (path-delim-to-slash (get-special-folder-location :desktop))) (default-directory))) (defvar *find-file-frequently-count* 0) (add-hook '*enter-minibuffer-hook* #'(lambda (buf his) (setq *find-file-frequently-count* 0))) (defun find-file-frequently-sort-function (x y) (cond ((and (not (file-directory-p x)) (file-directory-p y)) t) ((and (file-directory-p x) (not (file-directory-p y))) nil) (t (string-length-lessp x y)))) (defun find-file-frequently () (interactive) (let ((old (buffer-substring (point-min) (point-max))) (lst (mapcar #'truename-mod (mapcar #'eval *find-file-frequently-list*)))) (let ((s (nth (mod *find-file-frequently-count* (length lst)) (sort lst #'find-file-frequently-sort-function)))) (if (or (string= s old) (find s (mapcar #'get-buffer-file-name (buffer-list)) :test 'string=)) (progn (incf *find-file-frequently-count*) (find-file-frequently)) (progn (delete-region (point-min) (point-max)) (insert s) (incf *find-file-frequently-count*)))))) (define-key ed::minibuffer-local-completion-map #\C-\f #'(lambda () (interactive) (if (= (point) (point-max)) (find-file-frequently) (forward-char 1)))) ; (setq *find-file-frequently-list* (append *find-file-frequently-list* ; '("~/lisp/discrete.l" "~/lisp/lib.l" "~/lisp/")))
使い方
C-x C-f でミニバッファに入ったら、C-f する。
すると登録している候補が出てくる。C-f するごとに順に次の候補が出てくる。
C-f は末尾のときだけ機能するような変態キーバインドにしてみた。
キーバインドは ed::minibuffer-local-completion-map をいじる。
候補のリストは *find-file-frequently-list* をカスタマイズする(最下行を参考)。
候補の順が気に入らなければ、find-file-frequently-sort-function を差し替えるとよろしい。
そうそう、こんなの↓が要る。
;;; @@@ string<, string-lessp (defun string-length< (x y) (cond ((< (length x) (length y)) t) ((> (length x) (length y)) nil) ((string< x y) t) (t nil))) (defun string-length-lessp (x y) (cond ((< (length x) (length y)) t) ((> (length x) (length y)) nil) ((string-lessp x y) t) (t nil))) ;;; @@@ truename ;;; mod: fixed removing trailing slash (defun truename-mod (path) (let ((endc (char path (1- (length path))))) (if (or (eq endc #\/) (eq endc #\\)) (append-trail-slash (truename path)) (truename path))))