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

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

bug#5091: indentation in c++-mode


From: Vivien Oddou
Subject: bug#5091: indentation in c++-mode
Date: Mon, 14 Dec 2009 12:33:44 +0100

Hello :)

On Thu, 2009-12-10 at 14:37 +0000, Alan Mackenzie wrote:
> Hi, Vivien!
> 
> On Tue, Dec 01, 2009 at 03:35:38PM +0100, Vivien Oddou wrote:
> > in this code:
> 
> > namespace n
> > {
> >     int a = func<int,
> >                  float>();  // C-c C-s gives ((template-args-cont))
> > }
> 
> > void f()
> > {
> >     int a = func<int,
> >         float>();  // C-C Cs : ((defun-block-intro))
> 
> >     int b = func<
> >     int,   // here too, refering to f() opening brace
> >         float>();
> > }
> 
> > this is not normal.
> 
> Indeed not.
> 
> I've fixed this, and committed it to the head in Savannah.  Here is the
> patch.  Please try it out and let me know if anything isn't as it should
> be.

I try to apply it but i get lots of rejected hunks so i suppose i don't
have the same version as the one you're working on (cvs latest?)
so i'll just wait for the next package release, i just hope it'll not be
in two years like we're used to :)

> 
> 
> 
> Index: cc-engine.el
> ===================================================================
> RCS file: /cvsroot/emacs/emacs/lisp/progmodes/cc-engine.el,v
> retrieving revision 1.79
> diff -c -r1.79 cc-engine.el
> *** cc-engine.el      3 Dec 2009 16:02:10 -0000       1.79
> --- cc-engine.el      10 Dec 2009 14:14:24 -0000
> ***************
> *** 3743,3748 ****
> --- 3743,3799 ----
>       (goto-char bound))
>         nil)))
>   
> + (defsubst c-ssb-lit-begin ()
> +   ;; Return the start of the literal point is in, or nil.
> +   ;; We read and write the variables `safe-pos', `safe-pos-list', `state'
> +   ;; bound in the caller.
> + 
> +   ;; Use `parse-partial-sexp' from a safe position down to the point to 
> check
> +   ;; if it's outside comments and strings.
> +   (save-excursion
> +     (let ((pos (point)) safe-pos state pps-end-pos)
> +       ;; Pick a safe position as close to the point as possible.
> +       ;;
> +       ;; FIXME: Consult `syntax-ppss' here if our cache doesn't give a good
> +       ;; position.
> +     
> +       (while (and safe-pos-list
> +               (> (car safe-pos-list) (point)))
> +     (setq safe-pos-list (cdr safe-pos-list)))
> +       (unless (setq safe-pos (car-safe safe-pos-list))
> +     (setq safe-pos (max (or (c-safe-position
> +                              (point) (or c-state-cache
> +                                          (c-parse-state)))
> +                             0)
> +                         (point-min))
> +           safe-pos-list (list safe-pos)))
> + 
> +       ;; Cache positions along the way to use if we have to back up more.  
> We
> +       ;; cache every closing paren on the same level.  If the paren cache is
> +       ;; relevant in this region then we're typically already on the same
> +       ;; level as the target position.  Note that we might cache positions
> +       ;; after opening parens in case safe-pos is in a nested list.  That's
> +       ;; both uncommon and harmless.
> +       (while (progn
> +            (setq state (parse-partial-sexp
> +                         safe-pos pos 0))
> +            (< (point) pos))
> +     (setq safe-pos (point)
> +           safe-pos-list (cons safe-pos safe-pos-list)))
> + 
> +       ;; If the state contains the start of the containing sexp we cache 
> that
> +       ;; position too, so that parse-partial-sexp in the next run has a 
> bigger
> +       ;; chance of starting at the same level as the target position and 
> thus
> +       ;; will get more good safe positions into the list.
> +       (if (elt state 1)
> +       (setq safe-pos (1+ (elt state 1))
> +             safe-pos-list (cons safe-pos safe-pos-list)))
> + 
> +       (if (or (elt state 3) (elt state 4))
> +       ;; Inside string or comment.  Continue search at the
> +       ;; beginning of it.
> +       (elt state 8)))))
> + 
>   (defun c-syntactic-skip-backward (skip-chars &optional limit paren-level)
>     "Like `skip-chars-backward' but only look at syntactically relevant chars,
>   i.e. don't stop at positions inside syntactic whitespace or string
> ***************
> *** 3761,3900 ****
>   comment at the start of cc-engine.el for more info."
>   
>     (let ((start (point))
> !     state
>       ;; A list of syntactically relevant positions in descending
>       ;; order.  It's used to avoid scanning repeatedly over
>       ;; potentially large regions with `parse-partial-sexp' to verify
> !     ;; each position.
>       safe-pos-list
> -     ;; The position at the beginning of `safe-pos-list'.
> -     safe-pos
>       ;; The result from `c-beginning-of-macro' at the start position or the
>       ;; start position itself if it isn't within a macro.  Evaluated on
>       ;; demand.
>       start-macro-beg
>       ;; The earliest position after the current one with the same paren
>       ;; level.  Used only when `paren-level' is set.
>       (paren-level-pos (point)))
>   
> !     (while (progn
> !          (while (and
> !                  (< (skip-chars-backward skip-chars limit) 0)
>   
> !                  ;; Use `parse-partial-sexp' from a safe position down to
> !                  ;; the point to check if it's outside comments and
> !                  ;; strings.
> !                  (let ((pos (point)) state-2 pps-end-pos)
> !                    ;; Pick a safe position as close to the point as
> !                    ;; possible.
> !                    ;;
> !                    ;; FIXME: Consult `syntax-ppss' here if our
> !                    ;; cache doesn't give a good position.
> !                    (while (and safe-pos-list
> !                                (> (car safe-pos-list) (point)))
> !                      (setq safe-pos-list (cdr safe-pos-list)))
> !                    (unless (setq safe-pos (car-safe safe-pos-list))
> !                      (setq safe-pos (max (or (c-safe-position
> !                                               (point) (or c-state-cache
> !                                                           (c-parse-state)))
> !                                              0)
> !                                          (point-min))
> !                            safe-pos-list (list safe-pos)))
> ! 
> !                    ;; Cache positions along the way to use if we have to
> !                    ;; back up more.  We cache every closing paren on the
> !                    ;; same level.  If the paren cache is relevant in this
> !                    ;; region then we're typically already on the same
> !                    ;; level as the target position.  Note that we might
> !                    ;; cache positions after opening parens in case
> !                    ;; safe-pos is in a nested list.  That's both uncommon
> !                    ;; and harmless.
> !                    (while (progn
> !                             (setq state (parse-partial-sexp
> !                                          safe-pos pos 0))
> !                             (< (point) pos))
> !                      (setq safe-pos (point)
> !                            safe-pos-list (cons safe-pos safe-pos-list)))
> ! 
> !                    (cond
> !                     ((or (elt state 3) (elt state 4))
> !                      ;; Inside string or comment.  Continue search at the
> !                      ;; beginning of it.
> !                      (goto-char (elt state 8))
> !                      t)
>   
> !                     ((and paren-level
> !                           (save-excursion
> !                             (setq state-2 (parse-partial-sexp
> !                                            pos paren-level-pos -1)
> !                                   pps-end-pos (point))
> !                             (/= (car state-2) 0)))
> !                      ;; Not at the right level.
> ! 
> !                      (if (and (< (car state-2) 0)
> !                               ;; We stop above if we go out of a paren.
> !                               ;; Now check whether it precedes or is
> !                               ;; nested in the starting sexp.
> !                               (save-excursion
> !                                 (setq state-2
> !                                       (parse-partial-sexp
> !                                        pps-end-pos paren-level-pos
> !                                        nil nil state-2))
> !                                 (< (car state-2) 0)))
> ! 
> !                          ;; We've stopped short of the starting position
> !                          ;; so the hit was inside a nested list.  Go up
> !                          ;; until we are at the right level.
> !                          (condition-case nil
>                                (progn
> !                                (goto-char (scan-lists pos -1
> !                                                       (- (car state-2))))
> !                                (setq paren-level-pos (point))
> !                                (if (and limit (>= limit paren-level-pos))
> !                                    (progn
> !                                      (goto-char limit)
> !                                      nil)
> !                                  t))
> !                            (error
> !                             (goto-char (or limit (point-min)))
> !                             nil))
> ! 
> !                        ;; The hit was outside the list at the start
> !                        ;; position.  Go to the start of the list and exit.
> !                        (goto-char (1+ (elt state-2 1)))
> !                        nil))
> ! 
> !                     ((c-beginning-of-macro limit)
> !                      ;; Inside a macro.
> !                      (if (< (point)
> !                             (or start-macro-beg
> !                                 (setq start-macro-beg
> !                                       (save-excursion
> !                                         (goto-char start)
> !                                         (c-beginning-of-macro limit)
> !                                         (point)))))
> !                          t
> ! 
> !                        ;; It's inside the same macro we started in so it's
> !                        ;; a relevant match.
> !                        (goto-char pos)
> !                        nil)))))
> ! 
> !            ;; If the state contains the start of the containing sexp we
> !            ;; cache that position too, so that parse-partial-sexp in the
> !            ;; next run has a bigger chance of starting at the same level
> !            ;; as the target position and thus will get more good safe
> !            ;; positions into the list.
> !            (if (elt state 1)
> !                (setq safe-pos (1+ (elt state 1))
> !                      safe-pos-list (cons safe-pos safe-pos-list))))
>   
> !          (> (point)
> !             (progn
> !               ;; Skip syntactic ws afterwards so that we don't stop at the
> !               ;; end of a comment if `skip-chars' is something like "^/".
> !               (c-backward-syntactic-ws)
> !               (point)))))
>   
>       ;; We might want to extend this with more useful return values in
>       ;; the future.
> --- 3812,3911 ----
>   comment at the start of cc-engine.el for more info."
>   
>     (let ((start (point))
> !     state-2
>       ;; A list of syntactically relevant positions in descending
>       ;; order.  It's used to avoid scanning repeatedly over
>       ;; potentially large regions with `parse-partial-sexp' to verify
> !     ;; each position.  Used in `c-ssb-lit-begin'
>       safe-pos-list
>       ;; The result from `c-beginning-of-macro' at the start position or the
>       ;; start position itself if it isn't within a macro.  Evaluated on
>       ;; demand.
>       start-macro-beg
>       ;; The earliest position after the current one with the same paren
>       ;; level.  Used only when `paren-level' is set.
> +     lit-beg
>       (paren-level-pos (point)))
>   
> !     (while
> !     (progn
> !       ;; The next loop "tries" to find the end point each time round,
> !       ;; loops when it hasn't succeeded.
> !       (while
> !           (and
> !            (< (skip-chars-backward skip-chars limit) 0)
>   
> !            (let ((pos (point)) state-2 pps-end-pos)
>   
> !              (cond
> !               ;; Don't stop inside a literal
> !               ((setq lit-beg (c-ssb-lit-begin))
> !                (goto-char lit-beg)
> !                t)
> ! 
> !               ((and paren-level
> !                     (save-excursion
> !                       (setq state-2 (parse-partial-sexp
> !                                      pos paren-level-pos -1)
> !                             pps-end-pos (point))
> !                       (/= (car state-2) 0)))
> !                ;; Not at the right level.
> ! 
> !                (if (and (< (car state-2) 0)
> !                         ;; We stop above if we go out of a paren.
> !                         ;; Now check whether it precedes or is
> !                         ;; nested in the starting sexp.
> !                         (save-excursion
> !                           (setq state-2
> !                                 (parse-partial-sexp
> !                                  pps-end-pos paren-level-pos
> !                                  nil nil state-2))
> !                           (< (car state-2) 0)))
> ! 
> !                    ;; We've stopped short of the starting position
> !                    ;; so the hit was inside a nested list.  Go up
> !                    ;; until we are at the right level.
> !                    (condition-case nil
> !                        (progn
> !                          (goto-char (scan-lists pos -1
> !                                                 (- (car state-2))))
> !                          (setq paren-level-pos (point))
> !                          (if (and limit (>= limit paren-level-pos))
>                                (progn
> !                                (goto-char limit)
> !                                nil)
> !                            t))
> !                      (error
> !                       (goto-char (or limit (point-min)))
> !                       nil))
>   
> !                  ;; The hit was outside the list at the start
> !                  ;; position.  Go to the start of the list and exit.
> !                  (goto-char (1+ (elt state-2 1)))
> !                  nil))
> ! 
> !               ((c-beginning-of-macro limit)
> !                ;; Inside a macro.
> !                (if (< (point)
> !                       (or start-macro-beg
> !                           (setq start-macro-beg
> !                                 (save-excursion
> !                                   (goto-char start)
> !                                   (c-beginning-of-macro limit)
> !                                   (point)))))
> !                    t
> ! 
> !                  ;; It's inside the same macro we started in so it's
> !                  ;; a relevant match.
> !                  (goto-char pos)
> !                  nil))))))
> !          
> !       (> (point)
> !          (progn
> !            ;; Skip syntactic ws afterwards so that we don't stop at the
> !            ;; end of a comment if `skip-chars' is something like "^/".
> !            (c-backward-syntactic-ws)
> !            (point)))))
>   
>       ;; We might want to extend this with more useful return values in
>       ;; the future.
> ***************
> *** 8426,8431 ****
> --- 8437,8443 ----
>          literal char-before-ip before-ws-ip char-after-ip macro-start
>          in-macro-expr c-syntactic-context placeholder c-in-literal-cache
>          step-type tmpsymbol keyword injava-inher special-brace-list tmp-pos
> +        containing-<
>          ;; The following record some positions for the containing
>          ;; declaration block if we're directly within one:
>          ;; `containing-decl-open' is the position of the open
> ***************
> *** 9040,9046 ****
>                 (back-to-indentation)))
>             ;; FIXME: Should use c-add-stmt-syntax, but it's not yet
>             ;; template aware.
> !           (c-add-syntax 'template-args-cont (point)))
>   
>            ;; CASE 5D.4: perhaps a multiple inheritance line?
>            ((and (c-major-mode-is 'c++-mode)
> --- 9052,9058 ----
>                 (back-to-indentation)))
>             ;; FIXME: Should use c-add-stmt-syntax, but it's not yet
>             ;; template aware.
> !           (c-add-syntax 'template-args-cont (point) placeholder))
>   
>            ;; CASE 5D.4: perhaps a multiple inheritance line?
>            ((and (c-major-mode-is 'c++-mode)
> ***************
> *** 9252,9261 ****
>          ;; arglist that begins on the previous line.
>          ((and c-recognize-<>-arglists
>                (eq (char-before) ?<)
>                (not (and c-overloadable-operators-regexp
>                          (c-after-special-operator-id lim))))
>           (c-beginning-of-statement-1 (c-safe-position (point) paren-state))
> !         (c-add-syntax 'template-args-cont (c-point 'boi)))
>   
>          ;; CASE 5Q: we are at a statement within a macro.
>          (macro-start
> --- 9264,9274 ----
>          ;; arglist that begins on the previous line.
>          ((and c-recognize-<>-arglists
>                (eq (char-before) ?<)
> +              (setq placeholder (1- (point)))
>                (not (and c-overloadable-operators-regexp
>                          (c-after-special-operator-id lim))))
>           (c-beginning-of-statement-1 (c-safe-position (point) paren-state))
> !         (c-add-syntax 'template-args-cont (c-point 'boi) placeholder))
>   
>          ;; CASE 5Q: we are at a statement within a macro.
>          (macro-start
> ***************
> *** 9277,9290 ****
>   
>        ;; (CASE 6 has been removed.)
>   
>        ;; CASE 7: line is an expression, not a statement.  Most
>        ;; likely we are either in a function prototype or a function
> !      ;; call argument list
>        ((not (or (and c-special-brace-lists
>                       (save-excursion
>                         (goto-char containing-sexp)
>                         (c-looking-at-special-brace-list)))
> !                (eq (char-after containing-sexp) ?{)))
>         (cond
>   
>          ;; CASE 7A: we are looking at the arglist closing paren.
> --- 9290,9327 ----
>   
>        ;; (CASE 6 has been removed.)
>   
> +      ;; CASE 19: line is an expression, not a statement, and is directly
> +      ;; contained by a template delimiter.  Most likely, we are in a
> +      ;; template arglist within a statement.  This case is based on CASE
> +      ;; 7.  At some point in the future, we may wish to create more
> +      ;; syntactic symbols such as `template-intro',
> +      ;; `template-cont-nonempty', etc., and distinguish between them as we
> +      ;; do for `arglist-intro' etc. (2009-12-07).
> +      ((and c-recognize-<>-arglists
> +            (setq containing-< (c-up-list-backward indent-point 
> containing-sexp))
> +            (eq (char-after containing-<) ?\<))
> +       (setq placeholder (c-point 'boi containing-<))
> +       (goto-char containing-sexp)   ; Most nested Lbrace/Lparen (but not
> +                                     ; '<') before indent-point.
> +       (if (>= (point) placeholder)
> +           (progn
> +             (forward-char)
> +             (skip-chars-forward " \t"))
> +         (goto-char placeholder))
> +       (c-add-stmt-syntax 'template-args-cont (list containing-<) t
> +                          (c-most-enclosing-brace c-state-cache (point))
> +                          paren-state))
> +                          
> + 
>        ;; CASE 7: line is an expression, not a statement.  Most
>        ;; likely we are either in a function prototype or a function
> !      ;; call argument list, or a template argument list.
>        ((not (or (and c-special-brace-lists
>                       (save-excursion
>                         (goto-char containing-sexp)
>                         (c-looking-at-special-brace-list)))
> !                (eq (char-after containing-sexp) ?{)
> !                (eq (char-after containing-sexp) ?<)))
>         (cond
>   
>          ;; CASE 7A: we are looking at the arglist closing paren.
> ***************
> *** 9381,9387 ****
>                  (c-forward-syntactic-ws)
>                  (point))
>                (c-point 'bonl)))
> !         (goto-char containing-sexp)
>           (setq placeholder (c-point 'boi))
>           (if (and (c-safe (backward-up-list 1) t)
>                    (>= (point) placeholder))
> --- 9418,9424 ----
>                  (c-forward-syntactic-ws)
>                  (point))
>                (c-point 'bonl)))
> !         (goto-char containing-sexp) ; paren opening the arglist
>           (setq placeholder (c-point 'boi))
>           (if (and (c-safe (backward-up-list 1) t)
>                    (>= (point) placeholder))
> Index: cc-mode.el
> ===================================================================
> RCS file: /cvsroot/emacs/emacs/lisp/progmodes/cc-mode.el,v
> retrieving revision 1.88
> diff -c -r1.88 cc-mode.el
> *** cc-mode.el        5 Dec 2009 11:16:04 -0000       1.88
> --- cc-mode.el        10 Dec 2009 14:14:24 -0000
> ***************
> *** 541,559 ****
>         (make-local-variable 'lookup-syntax-properties)
>         (setq lookup-syntax-properties t)))
>   
> !   ;; Use this in Emacs 21 to avoid meddling with the rear-nonsticky
>     ;; property on each character.
>     (when (boundp 'text-property-default-nonsticky)
>       (make-local-variable 'text-property-default-nonsticky)
> !     (let ((elem (assq 'syntax-table text-property-default-nonsticky)))
> !       (if elem
> !       (setcdr elem t)
> !     (setq text-property-default-nonsticky
> !           (cons '(syntax-table . t)
> !                 text-property-default-nonsticky))))
> !     (setq text-property-default-nonsticky
> !       (cons '(c-type . t)
> !             text-property-default-nonsticky)))
>   
>     ;; In Emacs 21 and later it's possible to turn off the ad-hoc
>     ;; heuristic that open parens in column 0 are defun starters.  Since
> --- 541,555 ----
>         (make-local-variable 'lookup-syntax-properties)
>         (setq lookup-syntax-properties t)))
>   
> !   ;; Use this in Emacs 21+ to avoid meddling with the rear-nonsticky
>     ;; property on each character.
>     (when (boundp 'text-property-default-nonsticky)
>       (make-local-variable 'text-property-default-nonsticky)
> !     (mapc (lambda (tprop)
> !         (unless (assq tprop text-property-default-nonsticky)
> !           (setq text-property-default-nonsticky
> !                 (cons `(,tprop . t) text-property-default-nonsticky))))
> !       '(syntax-table category c-type)))
>   
>     ;; In Emacs 21 and later it's possible to turn off the ad-hoc
>     ;; heuristic that open parens in column 0 are defun starters.  Since
> 
> > emacs 23.1.1
> 






reply via email to

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