Sometimes I got itchy finger and kill some buffer that I meant to bury instead. The problem is, I use tramp to edit files from multiple machines, and those file names get long and nasty and just in general I'm not that good at finding where my files are anyways. So I would like to have emacs keep track of the files I just closed so that I can re-open them easily (via, ideally, an ido prompt).
Here is what I have so far, which is not working:
(defvar closed-files '())
(defun track-closed-file ()
(message buffer-file-name)
(and buffer-file-name
(cons buffer-file-name closed-files)))
(defun last-closed-files ()
(interactive)
(find-file (ido-completing-read "Last closed: " closed-files)))
(add-hook 'kill-buffer-hook 'track-closed-file)
I'm really not great at elisp and probably mess up somewhere in defining the variable and adding cell to it...
[I do know about recentf
, but that keeps track of opened files, instead of closed files.]
I have just tested this and it works with the use of a list and add-to-list
This also eliminates duplicate entries. Does this meet your needs?
(defvar closed-files (list))
(defun track-closed-file ()
(message buffer-file-name)
(and buffer-file-name
(add-to-list 'closed-files buffer-file-name)))
(defun last-closed-files ()
(interactive)
(find-file (ido-completing-read "Last closed: " closed-files)))
(add-hook 'kill-buffer-hook 'track-closed-file)
I quite like this functionality and have placed it in my emacs configuration. You may as well benefit from changes I have made.
This addition will push most recently closed files to the head of the list even if they have previously been closed (and are already in the closed-files
list).
(defun track-closed-file ()
(and buffer-file-name
(message buffer-file-name)
(or (delete buffer-file-name closed-files) t)
(add-to-list 'closed-files buffer-file-name)))
Your original problem was that cons
will return you the new list, not manipulate the input list:
(setq mylist '(2 3))
=> (2 3)
(cons 1 mylist)
=> (1 2 3)
mylist
=> (2 3)
in this case you would need to do:
(setq mylist (cons 1 mylist))
=> (1 2 3)
mylist
=> (1 2 3)
Have you tried using recentf? It should be provided with Emacs.
I originally saw it via XSteve's Emacs power-user tips where he suggests binding it to F12, and provides an interactive interface:
;;recentf
(require 'recentf)
(recentf-mode 1)
(setq recentf-max-saved-items 500)
(setq recentf-max-menu-items 60)
(global-set-key [(meta f12)] 'recentf-open-files)
(defun xsteve-ido-choose-from-recentf ()
"Use ido to select a recently opened file from the `recentf-list'"
(interactive)
(let ((home (expand-file-name (getenv "HOME"))))
(find-file
(ido-completing-read "Recentf open: "
(mapcar (lambda (path)
(replace-regexp-in-string home "~" path))
recentf-list)
nil t))))
[update]: whups, just saw your note about recentf awareness. True, it is for all opened files, so it included those currently in open buffers, too. Since I've only ever accessed it when I'm trying to track down a recently closed file, I never thought about that. Still, maybe filtering open files from that output might be easier than reinventing the entire wheel?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With