tags:

views:

138

answers:

3

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.]

+8  A: 

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)

Update

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)
kjfletch
It works. A new year resolution to learn lisp for the very basics is certain due!
polyglot
This is really handy. I've added it to my .emacs as well. Thanks.
seth
Fantastic! Thanks!
ThePower
A: 

Have you thought about rebinding "C-x k" to bury-buffer instead of kill-buffer? (You can then periodically clean up your buffer list with something like 'midnight.el' if necessary.)

sanityinc
oh, lord. As it is, I usually have about 50 buffers open.... But there's always another way.
Michael Paulukonis
Well I rebinded bury-buffer to shift-F4 and kill-buffer to ctrl-F4, and I do sometimes get confused :) But I'm quite a clean freak with respect to my open buffers that I cringe with horror not to kill all the gazillion logs file that I temporarily opened for inspection.
polyglot
I personally just let the buffers close, and I use exactly the ido/recentf integration that OtherMichael mentioned in order to reopen them if necessary.If you're opening and then closing files rapidly, as you suggest is the case with those logfiles, then there's not much difference between recently opened files and recently closed ones.
sanityinc
A: 

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?

Michael Paulukonis