最近閉じたファイル
silog - memo/xyzzy/file #最後に閉じたファイルを開く にインスパイヤされました。
今回の改造にあたって加えられた新たなオリジナリティは以下。
- add-history でヒストリに登録するようにしました。
- ダイアログを追加しました。
以下の環境で動作確認しました。
- Windows XP Home Edition SP2
- xyzzy 0.2.2.235
recent-closed-file-open-last-one で最後に閉じたファイルを開きます。
recent-closed-file-open-dialog で最近閉じたファイルをダイアログ表示します。ファイルを選択して『OK』を押すと、選択したファイルを開きます。
開いたファイルはヒストリから消されます。
ヒストリの最大個数は *minibuffer-maximum-history-count* です。
コード
;; 最近閉じたファイル ; * silog - memo/xyzzy/file #最後に閉じたファイルを開く ; <http://white.s151.xrea.com/wiki/index.php?memo%2Fxyzzy%2Ffile#k96261fd> ; から朴りました。 (defvar *recent-closed-file-history* nil) ; ヒストリ変数をファイルに保存する ; 削除するときは ; > (unregister-history-variable '*recent-closed-file-history*) ; するのを忘れるな ;(define-history-variable *recent-closed-file-history* nil) (defun recent-closed-file-add-history () (let ((file (get-buffer-file-name))) (if file (if (file-exist-p file) (add-history file '*recent-closed-file-history*) (or (delete file *recent-closed-file-history* :test #'path-equal) (setq *recent-closed-file-history* nil))))) t) #| ; 保存するヒストリの個数を別に設定する ; 負の値を指定すると無制限 (defvar *recent-closed-file-maximum-history-count* *minibuffer-maximum-history-count*) (defun recent-closed-file-add-history () (let ((file (get-buffer-file-name))) (when file (or (delete file *recent-closed-file-history* :test #'path-equal) (setq *recent-closed-file-history* nil)) (if (file-exist-p file) (push file *recent-closed-file-history*)))) (let (n) (and (<= 0 *recent-closed-file-maximum-history-count*) (setq n (- (list-length *recent-closed-file-history*) *recent-closed-file-maximum-history-count*)) (> n 0) (or (nbutlast *recent-closed-file-history* n) (setq *recent-closed-file-history* nil)))) t) |# (add-hook '*query-kill-buffer-hook* 'recent-closed-file-add-history) ; 最後に閉じたファイルを開く (defun recent-closed-file-open-last-one () (interactive) (unless *recent-closed-file-history* (plain-error "ヒストリは空です")) (let ((file (pop *recent-closed-file-history*))) (unless (file-exist-p file) (plain-error "~A: そんなファイルはありません" file)) (find-file file))) ; ダイアログ (defvar *recent-closed-file-open-dialog-template* `(dialog 0 0 298 117 (:caption "最近閉じたファイル") (:font 9 "MS UI Gothic") (:control (:listbox IDC_LIST nil #x50b10119 5 6 288 84) (:button IDOK "&OK" #x50010001 6 96 50 14) (:button IDCANCEL "&Cancel" #x50010000 60 96 50 14)))) (defun recent-closed-file-open-dialog () (interactive) (let ((hlist (mapcar #'(lambda (x) (list (abbreviate-display-string x 96 t) x)) *recent-closed-file-history*))) (multiple-value-bind (result data) (let ((omode (get-ime-mode))) (toggle-ime nil) (unwind-protect (dialog-box *recent-closed-file-open-dialog-template* `((IDC_LIST . ,hlist)) `((IDC_LIST :column (1) :must-match t :enable (IDOK)))) (toggle-ime omode))) (if result (let ((lst (cdr (assoc 'IDC_LIST data))) dlst) (dolist (var lst t) (let ((filename (nth 1 var))) (or (delete filename *recent-closed-file-history*) (setq *recent-closed-file-history* nil)) (if (file-exist-p filename) (progn (find-file filename) (add-history filename '*minibuffer-file-name-history*)) (push filename dlst)))) (if dlst (let ((lstlen (list-length lst)) (dlstlen (list-length dlst))) (if (= lstlen dlstlen 1) (message "~A: そんなファイルはありません" (car dlst)) (msgbox (format nil "~D 個中 ~D 個のファイルが見つかりませんでした~%~{~%~A~}" lstlen dlstlen dlst))) nil) t)))))) ; 『ファイル』メニューに追加 (add-hook '*post-startup-hook* #'(lambda () (let* ((file (get-menu *app-menu* 'ed::file)) (pos (get-menu-position file :above-kill-xyzzy))) (insert-menu-item file pos nil "最近閉じたファイル(&L)..." 'recent-closed-file-open-dialog #'(lambda () (or *recent-closed-file-history* :disable))))))