4

I'm working in a codebase with an extensive use of function macros and I'm having some difficulty finding the correct way to set indentations with them. Specifically, we pass a lot of statement lists { //body } into these macros, and the nicest way to read them is when they sit flush with the calling macro start column.

What happens right now is

if (cond)
{
  SomeMacro(i, j, k,
            {
              // Do stuff
            });
}

But what I would like to be able to do is

if (cond)
{
  SomeMacro(i, j, k,
  {
    // Do stuff
  });
}

I've tried doing C-c C-o and running c-show-syntactic-information but it doesn't seem like it even recognizes that these are macro calls. Which is fine, but it doesn't seem to recognize them as anything, it just tells me the first thing above it (in this example it says statement-block-intro and highlights the opening if bracket)

EDIT So I was able to set the arglist-cont-nonempty symbol to 0 indent and that works, but the new problem is that it no longer indents argument lists that go into the next line even if they aren't a statement body. e.g.

SomeMacro(i, j, k, 
          a, b, c);

will now indent as

SomeMacro(i, j, k,
a, b, c);

Is there a way to differentiate between a continued arglist of regular variables and one that is a statement body?

EDIT2: So here's where I've gotten to:

(defun c-lineup-macro-body (langelem)
  (save-excursion
    (if (and (eq (car langelem) 'arglist-cont-nonempty)
             (progn (back-to-indentation)
                    (= (following-char) ?{)))
        (let* ((relpos (cdr langelem))
               (curcol (progn (goto-char relpos)
                              (current-column))))
          (- (current-column) curcol))
      (c-lineup-argcont langelem))))

(c-set-offset 'arglist-cont-nonempty 'c-lineup-macro-body)

This will line up the macro body argument { //body } correctly, but I still have the problem where all other argument lists (including operators being fed into array indices that break lines) will line up with the previous starting line column as well.

My hope was with (c-lineup-argcont langelem) as the else condition would trigger the default behavior, but it does not. Is there some way to insert this function as a conditional hook so that it performs the default indent behavior unless the specific condition is met?

  • You'll probably need a (ccmode) Custom Line-Up function for this. By the way, the relevant place to call C-c C-s is on the brace inside the macro (that's the line you want to change the indent of), not the macro call itself. – npostavs Jun 15 at 11:23
  • Edited the post with new info – Koala Bear Jun 18 at 15:52
2

I was able to get this figured out by checking the default function argument with C-c C-o

(defun c-lineup-macro-body (langelem)
  "Line up {} body arguments in macros with the starting column of the macro call/definition"
  (save-excursion
    (if (and (eq (car langelem) 'arglist-cont-nonempty)
             (progn (back-to-indentation)
                    (= (following-char) ?{)))
        0 ;; No indent
      (c-lineup-arglist langelem)))) ;; Default behavior

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.