Wednesday, April 15, 2009

Running an elisp function on each marked file in a dired buffer


Chain Tool by Florian 

If you have some function, say some custom refactoring operation, you can call it from a dired buffer, and have it run on each marked file, using the code below. 

Go into a dired buffer, mark some files, and then do M-x and run your command. In this case it would be test-for-each-dired-marked-file


;;; iterating over files in dired

;;; usage example - for-each-dired-marked-file returns a filename and path
;;; for each marked file, so this is what a function using it looks like
(defun view-stuff(filename)
"opens up the file and gets the length of it, then messages the result"
(let (fpath fname mybuffer len)
(setq fpath filename)
(setq fname (file-name-nondirectory fpath))
(setq mybuffer (find-file fpath))
(setq len (buffer-size))
(kill-buffer mybuffer)
(message "Buffer length %d %s" len (buffer-file-name mybuffer))))

; Usage example
(defun test-for-each-dired-marked-file()
(interactive)
(for-each-dired-marked-file 'view-stuff))

(defun for-each-dired-marked-file(fn)
"Do stuff for each marked file, only works in dired window"
(interactive)
(if (eq major-mode 'dired-mode)
(let ((filenames (dired-get-marked-files)))
(mapcar fn filenames))
(error (format "Not a Dired buffer \(%s\)" major-mode))))

2 comments:

Christoph said...

It's easy to rewrite that for ibuffer, and to supply an argument when using the function interactive.

(defun for-each-ibuffer-marked-file(fn)
"Do stuff for each marked file, only works in dired window"
(interactive "aFunction: ")
;; (if (eq major-mode 'dired-mode)
(if (eq major-mode 'ibuffer-mode)
;; dired-get-marked-files
(let ((filenames (ibuffer-get-marked-buffers)))
(mapcar fn filenames))
(error (format "Not a Dired buffer \(%s\)" major-mode))))

Justin said...

Thanks, I don't use ibuffer so I'll investigate.