2

i'm trying to indent a couple of C++-files (and untabify them; and remove trailing whitespace), so i thought about using emacs in batch mode.

Since I'm pretty much a noob when it comes to elpa (or lisp in general), i searched the web and came up with something like this:

$ cat myscript.el
(defun myindent ()
   "Format the whole buffer."
   (c-set-style "stroustrup")
   (indent-region (point-min) (point-max) nil)
   (untabify (point-min) (point-max))
   (delete-trailing-whitespace)
   (save-buffer)
)
$ emacs -batch "somefile.cpp" -l $(pwd)/myscript.el -f myindent

This kind of works.

However, all of my header files contain a boilerplate in a C-style multiline comment, which is nicely formatted. Something like:

/*-----------------------------------------------------------------
LOG
    Foo Bar - the Pizza man

    Copyright (c) 1997-2017 Me, You and others
    For information on usage and redistribution, and for a DISCLAIMER OF ALL
    WARRANTIES, see the file "LICENSE.txt".

    CLASS
        Onion
        smells and bits like an onion

    KEYWORDS
        ingredients, vegetable

    DESCRIPTION
        hum, hmm...later

-----------------------------------------------------------------*/

now when i run my scrip on that file, all the pre-formatting is lost, and it ends up as:

/*-----------------------------------------------------------------
  LOG
  Foo Bar - the Pizza man

  Copyright (c) 1997-2017 Me, You and others
  For information on usage and redistribution, and for a DISCLAIMER OF ALL
  WARRANTIES, see the file "LICENSE.txt".

  CLASS
  Onion
  smells and bits like an onion

  KEYWORDS
  ingredients, vegetable

  DESCRIPTION
  hum, hmm...later

  -----------------------------------------------------------------*/

So the question is: Is there a way to indent my files in batch mode and preserve the formatting within multiline comments (and strings)?

I've tried using (indent-code-rigidly (point-min) (point-max) 0) instead of indent-region which leaves the comments intact, but I preservers too much of the original indentation of the code. So I guess I'd like something inbetween indent-region and indent-code-rigidly)

3
  • Not solving your problem, just info: indent-code-rigidly simply inserts a TAB or equivalent amount of SPC before the column where code originally started). What if in your original attempt you replace indent-region with c-indent-region?
    – wvxvw
    Commented Dec 6, 2017 at 16:06
  • unfortunately this left-aligns the comments as well (btw, the problem also exists in an interactive buffer; so it's not related to batch processing)
    – umläute
    Commented Dec 6, 2017 at 17:02
  • It seems like indent-region basically calls c-indent-line on each line (with a minor improvement in that it aligns backslashes in macro definitions). Perhaps, it would be possible to write an alternative indent-region-like function which skips lines in comments. (I'm not very familiar with c-mode, so, maybe this was already done somewhere).
    – wvxvw
    Commented Dec 7, 2017 at 9:02

2 Answers 2

1

Should just be a matter of setting the comment offset to always choose the current indentation:

(defun myindent ()
   "Format the whole buffer."
   (c-set-style "stroustrup")
   ;; `c' is for comment.
   (c-set-offset 'c (lambda (_syntax) (current-indentation)))
   (setq indent-tabs-mode nil) ; No new tabs.
   (indent-region (point-min) (point-max) nil)
   (untabify (point-min) (point-max)) ; Remove any remaining old tabs.
   (delete-trailing-whitespace)
   (save-buffer))
0

While I haven't found a solution (yet) to do-what-i-want withing emacs, I ended up by doing the indentation with astyle instead.

This was acceptable, as for now I'm really interested into a one-time conversion to enforce a common indentation across all files.

I'm still interested in a real emacs solution though.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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