Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Execute a particular command on multiple emacs buffers

Tags:

emacs

Is there a way to execute emacs command on multiple buffers without having to selecting them individually and executing it on each individual buffer.

I usually open multiple files matching a particular regex, e.g. ~/*.py and wish to enable a particular mode, say hs-minor-mode or glasses-mode on each, or say execute C-c @ C-M-h on each. Currently I have to select each one of them and do it individually. So is there a hack or a loop to automate the task.

Lets say I mark the buffers from the buffer-list and then run the command for all those marked.

I tried this but after executing the commands in eval-expression I completely lost access to my minibuffer, meaning whenever I typed M-x the minibuffer returned this

unable to access the minibuffer emacs error "Process Menu Mode doesn't support Hideshow Minor Mode"

and I was forced to actually kill the entire emacs process because the C-x C-s wasn't working neither was the End Task.

PS: I have no experience in elisp

like image 406
Bleeding Fingers Avatar asked Jan 12 '13 12:01

Bleeding Fingers


2 Answers

You can use ibuffer mode for this (It is part of the default Emacs distribution).

(global-set-key "\C-x\C-b" 'ibuffer) ;; make ibuffer the default

In *Ibuffer* you can mark the required buffers with m and then execute a form in each with E.

Generally, ibuffer is a lot more flexible then the usual buffer list and I think ibuffer should really be the default buffer-list in Emacs.

If you do this often, you might want to switch those particular modes on every time you enter python mode by attaching them to the mode-hook:

(add-hook 'python-mode-hook 'hs-minor-mode)
(add-hook 'python-mode-hook 'glasses-mode)
like image 64
pmr Avatar answered Nov 15 '22 09:11

pmr


I didn't know ibuffer had that feature! Anyway, for those who are more familiar with dired, here is a command that do the same. Select the files in dired with m or any other more powerful method. Then do, M-xdired-do-command and write a form or a command just as in M-x.

(defun dired-do-command (command)
  "Run COMMAND on marked files. Any files not already open will be opened.
After this command has been run, any buffers it's modified will remain
open and unsaved."
  (interactive
   (list
    (let ((print-level nil)
          (minibuffer-history-position 0)
          (minibuffer-history-sexp-flag (1+ (minibuffer-depth))))
      (unwind-protect
          (read-from-minibuffer
           "Command: " (prin1-to-string (nth 0 command-history))
           read-expression-map t
           (cons 'command-history 0))

        ;; If command was added to command-history as a
        ;; string, get rid of that.  We want only
        ;; evaluable expressions there.
        (if (stringp (car command-history))
            (setq command-history (cdr command-history)))))))
  (dolist (filename (dired-get-marked-files))
    (with-current-buffer (find-file-noselect filename)
      (if (symbolp command)
          (call-interactively command)
        (eval command)))))
like image 43
thisirs Avatar answered Nov 15 '22 08:11

thisirs