tags:

views:

168

answers:

3

I am looking for an equivalent of the ":bufdo" Vim command in Emacs. ":bufdo" takes an argument - another command - and executes the command on all open buffers. I have not yet found a similar feature in Emacs - any suggestions?

Thanks.

+7  A: 

Depending on what your command is, you can do:

M-: (mapc (lambda (b) (set-buffer b) (*command*)) (buffer-list))

But, I have a feeling you want something not so lispy. Take a look at keyboard macros. Namely, decide what you want to do:

C-x ( <do-your-command> C-x )
M-: (mapc (lambda (b) (set-buffer b) (kmacro-end-and-call-macro)) (buffer-list))

You'd probably want to define that last part as a function if you use it much:

(defun bufdo ()
   "execute last macro on all buffers, ala bufdo from vi"
   (interactive)
   (mapc (lambda (b) 
            (with-current-buffer b
              (kmacro-end-and-call-macro)))
         (buffer-list)))

Note: code is untested

Trey Jackson
Probably best to use "with-current-buffer", like (loop for buf in (buffer-list) do (with-current-buffer buf <forms>)).
jrockway
"with-current-buffer" is definitely a win, thanks.
Trey Jackson
+2  A: 

Take a look at buffer-list (function). It returns a list of all the open buffers (BUFFER objects). See the manual for a simple example of using it with mapcar (which operates on every element of the list, and accumulates the results). You would probably also find set-buffer, which programatically sets the current buffer from Emacs Lisp, useful.

Matthew Flaschen
+6  A: 

You can also checkout ibuffer, it allows you to mark buffers you like to operate on with m and then you can execute something on it with E. Other common operations are also available, e.g. query-replace on Q. Just check out the menu or the mode description (C-h m).

BTW, similar things are also possible from dired, although it doesn't seem to give you an eval command.

danielpoe