3

This is my configuration in init.el for C/C++ code which is default value in linux kernel:

(setq indent-tabs-mode t)

I'm using this style and won't change it to nil.

And indentation and alignment work perfectly when I'm writing C/C++ code.

But I found that when I try to manually align multiple lines of comments (comment at the end of a line) or macro, the M-x align or M-x align-regexp command will align them with tabs, sometimes tab+space, this is really annoying, since when I tried to view the file in other tools such as vim, less or in git diff, the alignment will be messed up, and I work with other people, so I cannot change all the tool.

The easiest thing to do is to change Emacs align and align-regexp. So how can I make M-x align and M-x align-regexp align all the multiple macros and comments with pure space instead tab (or tab+space)?

Original:

enter image description here

Current align or align-regexp, I enable whitespace-mode to show the tab/space, you can see that all the blanks of the alignment of macros and comments are tabs instead spaces.(If the original block contains multiple spaces, it will be space+tab): enter image description here

Desired align or align-regexp: enter image description here

How can I modify align/align-regexp or define a new function for both macros and comments of multiple lines?


UPDATE:

I already come up a solution, it is not smart, but it is enough. If anyone got any better idea, welcome.

https://gist.github.com/c02y/53f3dc97f2c985e89b86095d6a27a1c3

1

2 Answers 2

2

Without really knowing anything about this, can't you just define your own my-align or my-align-regexp command that invokes the standard command after binding indent-tabs-mode to nil?

If, in that context, you want spaces only, then just turn the mode off in that context (and turn it back on again when the command is done).

E.g., something like this (untested):

(defun my-align (beg end &optional separate rules exclude-rules)
  "`align', but with `indent-tabs-mode' bound to nil."
  (interactive "r")
  (let ((indent-tabs-mode  nil))
    (align beg end separate rules exclude-rules)))

(defun my-align-regexp (beg end regexp &optional group spacing repeat)
  "`align-regexp', but with `indent-tabs-mode' bound to nil."
  (interactive "r")
  (let ((indent-tabs-mode  nil))
    (align-regexp beg end regexp group spacing repeat)))

Well, looking quickly at align.el I'm guessing that might not work (but you might try it). align-to-tab-stop has indent-tabs-mode as its default value, suggesting that maybe the align code depends on indent-tabs-mode (dunno).

If align.el relies on indent-tabs-mode being non-nil then you might just write commands that first call align or align-regexp and then, over the region affected, call untabify. IOW, let it insert TAB chars, but then convert them to SPC chars.

Instead of defining your own commands (and binding those to keys, e.g., the keys that might normally be bound to align and align-regexp), you could advise those commands. But that's typically overkill, and it can have nasty unexpected effects if some other code invokes those functions.

In general, if it's just for your own interactive use then you are better off defining and using your own commands, not advising standard commands/functions.

Luckily, Emacs supports dynamic binding, in addition to lexical binding, so you often need only bind a variable around the standard command/function whose behavior you want to modify.

0

In your "current" example, which we must presume has indentation the way you want it, we can see that you're actually indenting your code with spaces, despite setting (setq indent-tabs-mode t).

So your claim that "I'm using this style and won't change [indent-tabs-mode] to nil" seems flawed to me -- even if it's set to t, you are apparently clobbering that behaviour somehow -- except where it's being used for alignment, which you don't want.

So despite your insistence, I can only say: (setq indent-tabs-mode nil) in your c-mode and c++-mode hooks -- because that is what you want, so far as I can tell.

If you really won't do that, then see https://stackoverflow.com/a/8129994 for a way to ensure that alignments are always done with spaces.

2
  • "If you really won't do that, then see stackoverflow.com/a/8129994 for a way to ensure that alignments are always done with spaces." I already did this, but it stills align with tabs. And my solution is not smart, it is just a workaround.
    – CodyChan
    Jul 6, 2018 at 10:00
  • Well I can't replicate your problem. Running emacs -Q in c-mode with indent-tabs-mode set to t and using the advice I linked to, indentation is done with tabs and alignment is done with spaces, exactly as I would expect. I presume that something in your configuration is overriding this. Assuming you get the same result as me under emacs -Q then use recursive bisection on your config to isolate the cause of your problem.
    – phils
    Jul 6, 2018 at 10:09

Your Answer

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

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