2

I'm working on some code that is spread across several files.

I keep finding myself doing whitespace-cleanup and indent-region (on the whole file), and having to do it on each of the six files.

Any way to say: 'do tidying up on all .c and .h files currently open',

or maybe use emacs in batch mode from the bash shell?

  • You can mapc a function across a sequence, so e.g. write a cleanup function that does a find-file on a filename and then applies whitespace-cleanup and whatever else you want. Then create a list of the files that you want to apply it to: (setq my-file list '("file1" "file2" ....)) and then apply the cleanup ffunction on each file with (mapc '#my-cleanup-function my-filelist). – NickD Jun 23 '17 at 18:20
4

One option would be to use ibuffer. You can mark the buffers you want to modify, then use ibuffer-do-eval (bound to E) to evaluate a command on all of them.

If you always run the same sequence of steps, you can define a command such as:

(defun  my-clean-buffer ()
    (interactive)
    (whitespace-cleanup)
    (indent-region (point-min) (point-max)))

Then use E (my-clean-buffer) as described above. Note that this leaves the buffers modified and not saved, so either include a save in your command or use ibuffer-do-save (bound to S) after the updates to save the marked buffers.

2

You mention files, not buffers. And you say nothing about whether you care whether you visit the files in buffers or whether you are already visiting the files that you want to act on.

There are many ways to do such things. If you just want to act on a set of files, without caring whether you keep them visited in buffers, then yes, you can use Emacs in batch mode or just pass the file names to a shell script.

And you say nothing about how the set of files is chosen, e.g., whether the file names exist already as a list or you pick them interactively.

The question is really underspecified (too broad).


That said, here are a couple of possibilities that uses Dired, where you can choose the files by marking them in various ways (e.g., by extension, regexp, date, name).

Assuming that you have marked the files you want to act on:

  • You can use ! to apply a shell script or system command to each of them.

  • If you use Dired+ then you can use @ to apply a Lisp function to each of them. (E.g., apply the function posted by @glucas.)

C-h f diredp-do-apply-function:

@ runs the command diredp-do-apply-function, which is an interactive Lisp function in dired+.el.

It is bound to @, menu-bar operate diredp-do-apply-function.

(diredp-do-apply-function FUNCTION &optional ARG)

Apply FUNCTION to the marked files.

With a plain prefix ARG (C-u), visit each file and invoke FUNCTION with no arguments.

Otherwise, apply FUNCTION to each file name.

Any other prefix arg behaves according to the ARG argument of dired-get-marked-files. In particular, C-u C-u operates on all files in the Dired buffer.

You can also use M-+ @ (diredp-do-apply-function-recursive) to act on all marked files in a Dired buffer plus all marked files in any marked subdirs of that buffer that have their own Dired buffers, etc., recursively. (No need to insert the subdirs.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.