Inheriting from variadic types messes up template member function indentation in Emacs

50 views Asked by At

Unpacking Ts in inheritance adds extra indentation to template member function void bar(). How can I get rid of that extra indentation?

template <typename ...Ts>
struct Foo: public Ts...
{
    Foo()
    {
    }

    template <typename U>
        void bar()
    {
    }
};

Non-unpacked inheritance works well:

template <typename T, typename U>
struct Foo: public T, public U
{
    Foo()
    {
    }

    template <typename S>
    void bar()
    {
    }
};

My .emacs:

; Replace highlighted text
(delete-selection-mode 1)


(defun bb-cpp-style()
  (c-set-style "linux")
  (setq indent-tabs-mode nil)
  (setq tab-width 4)
  (setq c-basic-offset 4)

  (c-set-offset 'case-label '+)
  (c-set-offset 'statement-case-intro '+)
  (c-set-offset 'statement-case-open '0)

  (c-set-offset 'inlambda 'c-lineup-inexpr-block) ;
  (c-set-offset 'inline-open '0) ;

)

(add-hook 'c++-mode-hook 'bb-cpp-style)

; treat .h as c++
(add-to-list 'auto-mode-alist '("\\.h\\'" . c++-mode))

Expected:

template <typename ...Ts>
struct Foo: public Ts...
{
    Foo()
    {
    }

    template <typename U>
    void bar()
    {
    }
};
1

There are 1 answers

3
Rorschach On

The cc-mode syntactic element associated with the offending line is statement-cont. You can see the syntactic info with the functions c-show-syntactic-information and c-syntactic-information-on-region. Maybe there is some issue with how those elements are parsed since that line is given different syntactic designations in your two versions of the code - I dont know.

You could try adding a custom indentation rule for statement-cont that says to add no indentation to a statement-cont when it isn't an assignment (note: c-lineup-assignments doesn't add indentation to continuations following a line with = at the end of the line). This is simple:

(defun my-lineup-statement (langelem)
  (or (c-lineup-assignments langelem) 0))

And call (c-set-offset 'statement-cont #'my-lineup-statement) in the buffer to test it out (or add it to your mode hook). That should fix the indent in the case you've shown.

I tested it briefly on a couple files and the only other side-effect of this change I noticed was that it removed the indentation of the continued statement following a naked =, as in

int x =
1;  // before adding 'my-lineup-assignments this usually indented (depending on chosen c style)

There might be other cases where you want statement-cont elements to get indented.