help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: C++ Indentation and access-labels


From: Marc Dürner
Subject: Re: C++ Indentation and access-labels
Date: Mon, 28 Sep 2009 18:39:42 +0200

Hello,

Thank you, Alan. This works much better now. Can you help me out with a few remaining problems?

1) The inline-methods in a class or struct are not indented to the same level as topmost-intro

Here is an example how it looks like:

class c
{
    friend class y;

    public:
        c()
        : _n(8)
    { } <=== here

        void meth()
    {} <=== here

    private:
        int _n;
};

2) when I type 'void meth()' after typing ')' eight spaces (two levels of indentation) are added to the next line with the cursor positioned at the beginning of the line:

class c
{
    public:
        void method()
X.......

where X is the cursor position and . are trailing whitespace. The same happens when I close a inline-defun with '}'. When I continue it disappears, but it is a bit uncomfortable if I would just add a method to a class. Also, the trailing whitespace stays when I reindent a block with the tab key

3) Another problem is caused by macros before class names. This is something which is very common:

class MY_API MyClass
{};

MY_API is some macro which expands to compiler specific attributes like declspec (VC) or __attribute__ (GCC). Many libraries have macros like this. Somehow it confuses the parser and indentation of access-labels is only two spaces (half of what it should be, c-basic-offset is 4).Example:

class MY_API c
{
    friend class y;

  public:
    c()
        : _n(8)
    { }

    void meth()
    {}

  private:
    int _n;
};

Maybe there is another way to tell the parser to simply ignore "MY_API".

regards,
Marc

2009/9/25 Alan Mackenzie <acm@muc.de>
Hi, Marc!

On Mon, Sep 21, 2009 at 04:08:30PM +0200, Marc Dürner wrote:

> > # File ~/duerner.el:
> > #########################################################################
> > (defsubst md-at-inclass/topmost-intro (sintax)
> >  (and
> >   (eq (caar sintax) 'inclass)
> >   (eq (car (cadr sintax)) 'topmost-intro)))

> > (defun md-ind-prot-class ()
> >  "Give an extra level of indentation to class thingies under an access
> > specifier, e.g.:

> >    public
> >        A();        <========== extra level of indentation.

> > This should really be properly implemented in CC Mode, but it's not."
> >  (and
> >   (md-at-inclass/topmost-intro c-syntactic-context)
> >   (let (m-type)
> >     (when
> >         (save-excursion
> >           (back-to-indentation)
> >           ;; Go back one "statement" at a time till we reach a label or
> > something
> >           ;; which isn't an inclass/topmost-intro
> >           (while
> >               (and (eq (setq m-type (c-beginning-of-statement-1))
> > 'previous)
> >                    (md-at-inclass/topmost-intro (c-guess-basic-syntax))))
> >           ;; Have we found "private:", "public": or "protected"?
> >           (and (eq m-type 'label)
> >                (looking-at
> >                 (eval-when-compile
> >                  (c-make-keywords-re nil (c-lang-const c-protection-kwds
> > c++))))))
> >       (save-excursion
> >        (back-to-indentation)
> >        (c-shift-line-indentation c-basic-offset))))))

> > (defun md-add-hook ()
> >  (add-hook 'c-special-indent-hook 'md-ind-prot-class))
> > (add-hook 'c++-mode-hook 'md-add-hook)
> > #########################################################################

> > The above is a fairly rough and ready hack.  If it does something silly,
> > please get back to me with a description of the failure.


> Thank you for you help!

> The script you wrote seems to have no effect (yet):

Sorry.  I hadn't tested things enough.  Here's what the problem is:

> Here is what I added to my .emacs:

> (require 'cc-mode)
> (setq c-basic-offset 4)
> (setq-default c-tab-always-indent nil)

Just an aside: (setq c-basic-offset 4) will set the global value, but
this will get overridden by the style system.  Either create your own
style. or set this to c++-mode-hook (see below).  Yes, it's
overcomplicated.  ;-(

> (add-hook 'c++-mode-hook
>           '(lambda ()
>              (c-set-style "ellemtel")
>              (c-set-offset 'access-label '0)))

The form (c-set-style "ellemtel") in c++-mode-hook wipes clean the
value of c-special-indent-hook.  :-(  So we need to arrange to do
"ellemtel" before doing "special-indent".

> (eval-after-load "cc-mode" '(load-file "~/duerner.el"))

So, please change the following:
(i) in ~/duerner.el, REMOVE the last line, "(add-hook 'c++-mode-hook
 'md-add-hook)".

(ii) in ~/duerner.el, insert at the top the line "(require 'cc-langs)",
 to make sure it compiles properly.

(ii) Change your .emacs bit to this:

 (require 'cc-mode)
 ;; (setq c-basic-offset 4)  ; <===== commented out
 (setq-default c-tab-always-indent nil)

 (add-hook 'c++-mode-hook
           '(lambda ()
              (c-set-style "ellemtel")
              (add-hook 'c-special-indent-hook 'md-ind-prot-class) ; <======
              (c-set-offset 'access-label '0)
              (setq c-basic-offset 4)))

 (eval-after-load "cc-mode" '(load-file "~/duerner.el"))

Hope it works now!

> regards,
> Marc

--
Alan Mackenzie (Nürnberg).


reply via email to

[Prev in Thread] Current Thread [Next in Thread]