aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Mackenzie2009-12-10 14:29:11 +0000
committerAlan Mackenzie2009-12-10 14:29:11 +0000
commitd0fcee66986308f526578b35fde713be47f1bbab (patch)
tree01b9b1350ae675c74a528e3195278250329c1a48
parentf1943c1ba5cd799e4b24542ef2c0089a42542d69 (diff)
downloademacs-d0fcee66986308f526578b35fde713be47f1bbab.tar.gz
emacs-d0fcee66986308f526578b35fde713be47f1bbab.zip
Fix bug#5091: indentation in c++-mode.
* cc-mode.el (c-basic-common-init): make text property `category' rear non-sticky. * cc-engine.el (c-ssb-lit-begin): New defsubst, extracted from .... (c-syntactic-skip-backward): Refactor, extracting the above. (c-guess-basic-syntax CASEs 5D.3, 5L): Add extra anchor point; (c-guess-basic-syntax CASE 19): New CASE to handle template construct continued over line boundary. (c-guess-basic-syntax CASE 7): don't trigger on '<'.
-rw-r--r--lisp/progmodes/cc-engine.el289
-rw-r--r--lisp/progmodes/cc-mode.el16
2 files changed, 169 insertions, 136 deletions
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index 664ce0cb376..27118620acd 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -3743,6 +3743,57 @@ comment at the start of cc-engine.el for more info."
3743 (goto-char bound)) 3743 (goto-char bound))
3744 nil))) 3744 nil)))
3745 3745
3746(defsubst c-ssb-lit-begin ()
3747 ;; Return the start of the literal point is in, or nil.
3748 ;; We read and write the variables `safe-pos', `safe-pos-list', `state'
3749 ;; bound in the caller.
3750
3751 ;; Use `parse-partial-sexp' from a safe position down to the point to check
3752 ;; if it's outside comments and strings.
3753 (save-excursion
3754 (let ((pos (point)) safe-pos state pps-end-pos)
3755 ;; Pick a safe position as close to the point as possible.
3756 ;;
3757 ;; FIXME: Consult `syntax-ppss' here if our cache doesn't give a good
3758 ;; position.
3759
3760 (while (and safe-pos-list
3761 (> (car safe-pos-list) (point)))
3762 (setq safe-pos-list (cdr safe-pos-list)))
3763 (unless (setq safe-pos (car-safe safe-pos-list))
3764 (setq safe-pos (max (or (c-safe-position
3765 (point) (or c-state-cache
3766 (c-parse-state)))
3767 0)
3768 (point-min))
3769 safe-pos-list (list safe-pos)))
3770
3771 ;; Cache positions along the way to use if we have to back up more. We
3772 ;; cache every closing paren on the same level. If the paren cache is
3773 ;; relevant in this region then we're typically already on the same
3774 ;; level as the target position. Note that we might cache positions
3775 ;; after opening parens in case safe-pos is in a nested list. That's
3776 ;; both uncommon and harmless.
3777 (while (progn
3778 (setq state (parse-partial-sexp
3779 safe-pos pos 0))
3780 (< (point) pos))
3781 (setq safe-pos (point)
3782 safe-pos-list (cons safe-pos safe-pos-list)))
3783
3784 ;; If the state contains the start of the containing sexp we cache that
3785 ;; position too, so that parse-partial-sexp in the next run has a bigger
3786 ;; chance of starting at the same level as the target position and thus
3787 ;; will get more good safe positions into the list.
3788 (if (elt state 1)
3789 (setq safe-pos (1+ (elt state 1))
3790 safe-pos-list (cons safe-pos safe-pos-list)))
3791
3792 (if (or (elt state 3) (elt state 4))
3793 ;; Inside string or comment. Continue search at the
3794 ;; beginning of it.
3795 (elt state 8)))))
3796
3746(defun c-syntactic-skip-backward (skip-chars &optional limit paren-level) 3797(defun c-syntactic-skip-backward (skip-chars &optional limit paren-level)
3747 "Like `skip-chars-backward' but only look at syntactically relevant chars, 3798 "Like `skip-chars-backward' but only look at syntactically relevant chars,
3748i.e. don't stop at positions inside syntactic whitespace or string 3799i.e. don't stop at positions inside syntactic whitespace or string
@@ -3761,140 +3812,100 @@ Note that this function might do hidden buffer changes. See the
3761comment at the start of cc-engine.el for more info." 3812comment at the start of cc-engine.el for more info."
3762 3813
3763 (let ((start (point)) 3814 (let ((start (point))
3764 state 3815 state-2
3765 ;; A list of syntactically relevant positions in descending 3816 ;; A list of syntactically relevant positions in descending
3766 ;; order. It's used to avoid scanning repeatedly over 3817 ;; order. It's used to avoid scanning repeatedly over
3767 ;; potentially large regions with `parse-partial-sexp' to verify 3818 ;; potentially large regions with `parse-partial-sexp' to verify
3768 ;; each position. 3819 ;; each position. Used in `c-ssb-lit-begin'
3769 safe-pos-list 3820 safe-pos-list
3770 ;; The position at the beginning of `safe-pos-list'.
3771 safe-pos
3772 ;; The result from `c-beginning-of-macro' at the start position or the 3821 ;; The result from `c-beginning-of-macro' at the start position or the
3773 ;; start position itself if it isn't within a macro. Evaluated on 3822 ;; start position itself if it isn't within a macro. Evaluated on
3774 ;; demand. 3823 ;; demand.
3775 start-macro-beg 3824 start-macro-beg
3776 ;; The earliest position after the current one with the same paren 3825 ;; The earliest position after the current one with the same paren
3777 ;; level. Used only when `paren-level' is set. 3826 ;; level. Used only when `paren-level' is set.
3827 lit-beg
3778 (paren-level-pos (point))) 3828 (paren-level-pos (point)))
3779 3829
3780 (while (progn 3830 (while
3781 (while (and 3831 (progn
3782 (< (skip-chars-backward skip-chars limit) 0) 3832 ;; The next loop "tries" to find the end point each time round,
3783 3833 ;; loops when it hasn't succeeded.
3784 ;; Use `parse-partial-sexp' from a safe position down to 3834 (while
3785 ;; the point to check if it's outside comments and 3835 (and
3786 ;; strings. 3836 (< (skip-chars-backward skip-chars limit) 0)
3787 (let ((pos (point)) state-2 pps-end-pos) 3837
3788 ;; Pick a safe position as close to the point as 3838 (let ((pos (point)) state-2 pps-end-pos)
3789 ;; possible. 3839
3790 ;; 3840 (cond
3791 ;; FIXME: Consult `syntax-ppss' here if our 3841 ;; Don't stop inside a literal
3792 ;; cache doesn't give a good position. 3842 ((setq lit-beg (c-ssb-lit-begin))
3793 (while (and safe-pos-list 3843 (goto-char lit-beg)
3794 (> (car safe-pos-list) (point))) 3844 t)
3795 (setq safe-pos-list (cdr safe-pos-list))) 3845
3796 (unless (setq safe-pos (car-safe safe-pos-list)) 3846 ((and paren-level
3797 (setq safe-pos (max (or (c-safe-position 3847 (save-excursion
3798 (point) (or c-state-cache 3848 (setq state-2 (parse-partial-sexp
3799 (c-parse-state))) 3849 pos paren-level-pos -1)
3800 0) 3850 pps-end-pos (point))
3801 (point-min)) 3851 (/= (car state-2) 0)))
3802 safe-pos-list (list safe-pos))) 3852 ;; Not at the right level.
3803 3853
3804 ;; Cache positions along the way to use if we have to 3854 (if (and (< (car state-2) 0)
3805 ;; back up more. We cache every closing paren on the 3855 ;; We stop above if we go out of a paren.
3806 ;; same level. If the paren cache is relevant in this 3856 ;; Now check whether it precedes or is
3807 ;; region then we're typically already on the same 3857 ;; nested in the starting sexp.
3808 ;; level as the target position. Note that we might 3858 (save-excursion
3809 ;; cache positions after opening parens in case 3859 (setq state-2
3810 ;; safe-pos is in a nested list. That's both uncommon 3860 (parse-partial-sexp
3811 ;; and harmless. 3861 pps-end-pos paren-level-pos
3812 (while (progn 3862 nil nil state-2))
3813 (setq state (parse-partial-sexp 3863 (< (car state-2) 0)))
3814 safe-pos pos 0)) 3864
3815 (< (point) pos)) 3865 ;; We've stopped short of the starting position
3816 (setq safe-pos (point) 3866 ;; so the hit was inside a nested list. Go up
3817 safe-pos-list (cons safe-pos safe-pos-list))) 3867 ;; until we are at the right level.
3818 3868 (condition-case nil
3819 (cond 3869 (progn
3820 ((or (elt state 3) (elt state 4)) 3870 (goto-char (scan-lists pos -1
3821 ;; Inside string or comment. Continue search at the 3871 (- (car state-2))))
3822 ;; beginning of it. 3872 (setq paren-level-pos (point))
3823 (goto-char (elt state 8)) 3873 (if (and limit (>= limit paren-level-pos))
3824 t)
3825
3826 ((and paren-level
3827 (save-excursion
3828 (setq state-2 (parse-partial-sexp
3829 pos paren-level-pos -1)
3830 pps-end-pos (point))
3831 (/= (car state-2) 0)))
3832 ;; Not at the right level.
3833
3834 (if (and (< (car state-2) 0)
3835 ;; We stop above if we go out of a paren.
3836 ;; Now check whether it precedes or is
3837 ;; nested in the starting sexp.
3838 (save-excursion
3839 (setq state-2
3840 (parse-partial-sexp
3841 pps-end-pos paren-level-pos
3842 nil nil state-2))
3843 (< (car state-2) 0)))
3844
3845 ;; We've stopped short of the starting position
3846 ;; so the hit was inside a nested list. Go up
3847 ;; until we are at the right level.
3848 (condition-case nil
3849 (progn 3874 (progn
3850 (goto-char (scan-lists pos -1 3875 (goto-char limit)
3851 (- (car state-2)))) 3876 nil)
3852 (setq paren-level-pos (point)) 3877 t))
3853 (if (and limit (>= limit paren-level-pos)) 3878 (error
3854 (progn 3879 (goto-char (or limit (point-min)))
3855 (goto-char limit) 3880 nil))
3856 nil) 3881
3857 t)) 3882 ;; The hit was outside the list at the start
3858 (error 3883 ;; position. Go to the start of the list and exit.
3859 (goto-char (or limit (point-min))) 3884 (goto-char (1+ (elt state-2 1)))
3860 nil)) 3885 nil))
3861 3886
3862 ;; The hit was outside the list at the start 3887 ((c-beginning-of-macro limit)
3863 ;; position. Go to the start of the list and exit. 3888 ;; Inside a macro.
3864 (goto-char (1+ (elt state-2 1))) 3889 (if (< (point)
3865 nil)) 3890 (or start-macro-beg
3866 3891 (setq start-macro-beg
3867 ((c-beginning-of-macro limit) 3892 (save-excursion
3868 ;; Inside a macro. 3893 (goto-char start)
3869 (if (< (point) 3894 (c-beginning-of-macro limit)
3870 (or start-macro-beg 3895 (point)))))
3871 (setq start-macro-beg 3896 t
3872 (save-excursion 3897
3873 (goto-char start) 3898 ;; It's inside the same macro we started in so it's
3874 (c-beginning-of-macro limit) 3899 ;; a relevant match.
3875 (point))))) 3900 (goto-char pos)
3876 t 3901 nil))))))
3877 3902
3878 ;; It's inside the same macro we started in so it's 3903 (> (point)
3879 ;; a relevant match. 3904 (progn
3880 (goto-char pos) 3905 ;; Skip syntactic ws afterwards so that we don't stop at the
3881 nil))))) 3906 ;; end of a comment if `skip-chars' is something like "^/".
3882 3907 (c-backward-syntactic-ws)
3883 ;; If the state contains the start of the containing sexp we 3908 (point)))))
3884 ;; cache that position too, so that parse-partial-sexp in the
3885 ;; next run has a bigger chance of starting at the same level
3886 ;; as the target position and thus will get more good safe
3887 ;; positions into the list.
3888 (if (elt state 1)
3889 (setq safe-pos (1+ (elt state 1))
3890 safe-pos-list (cons safe-pos safe-pos-list))))
3891
3892 (> (point)
3893 (progn
3894 ;; Skip syntactic ws afterwards so that we don't stop at the
3895 ;; end of a comment if `skip-chars' is something like "^/".
3896 (c-backward-syntactic-ws)
3897 (point)))))
3898 3909
3899 ;; We might want to extend this with more useful return values in 3910 ;; We might want to extend this with more useful return values in
3900 ;; the future. 3911 ;; the future.
@@ -8426,6 +8437,7 @@ comment at the start of cc-engine.el for more info."
8426 literal char-before-ip before-ws-ip char-after-ip macro-start 8437 literal char-before-ip before-ws-ip char-after-ip macro-start
8427 in-macro-expr c-syntactic-context placeholder c-in-literal-cache 8438 in-macro-expr c-syntactic-context placeholder c-in-literal-cache
8428 step-type tmpsymbol keyword injava-inher special-brace-list tmp-pos 8439 step-type tmpsymbol keyword injava-inher special-brace-list tmp-pos
8440 containing-<
8429 ;; The following record some positions for the containing 8441 ;; The following record some positions for the containing
8430 ;; declaration block if we're directly within one: 8442 ;; declaration block if we're directly within one:
8431 ;; `containing-decl-open' is the position of the open 8443 ;; `containing-decl-open' is the position of the open
@@ -9040,7 +9052,7 @@ comment at the start of cc-engine.el for more info."
9040 (back-to-indentation))) 9052 (back-to-indentation)))
9041 ;; FIXME: Should use c-add-stmt-syntax, but it's not yet 9053 ;; FIXME: Should use c-add-stmt-syntax, but it's not yet
9042 ;; template aware. 9054 ;; template aware.
9043 (c-add-syntax 'template-args-cont (point))) 9055 (c-add-syntax 'template-args-cont (point) placeholder))
9044 9056
9045 ;; CASE 5D.4: perhaps a multiple inheritance line? 9057 ;; CASE 5D.4: perhaps a multiple inheritance line?
9046 ((and (c-major-mode-is 'c++-mode) 9058 ((and (c-major-mode-is 'c++-mode)
@@ -9252,10 +9264,11 @@ comment at the start of cc-engine.el for more info."
9252 ;; arglist that begins on the previous line. 9264 ;; arglist that begins on the previous line.
9253 ((and c-recognize-<>-arglists 9265 ((and c-recognize-<>-arglists
9254 (eq (char-before) ?<) 9266 (eq (char-before) ?<)
9267 (setq placeholder (1- (point)))
9255 (not (and c-overloadable-operators-regexp 9268 (not (and c-overloadable-operators-regexp
9256 (c-after-special-operator-id lim)))) 9269 (c-after-special-operator-id lim))))
9257 (c-beginning-of-statement-1 (c-safe-position (point) paren-state)) 9270 (c-beginning-of-statement-1 (c-safe-position (point) paren-state))
9258 (c-add-syntax 'template-args-cont (c-point 'boi))) 9271 (c-add-syntax 'template-args-cont (c-point 'boi) placeholder))
9259 9272
9260 ;; CASE 5Q: we are at a statement within a macro. 9273 ;; CASE 5Q: we are at a statement within a macro.
9261 (macro-start 9274 (macro-start
@@ -9277,14 +9290,38 @@ comment at the start of cc-engine.el for more info."
9277 9290
9278 ;; (CASE 6 has been removed.) 9291 ;; (CASE 6 has been removed.)
9279 9292
9293 ;; CASE 19: line is an expression, not a statement, and is directly
9294 ;; contained by a template delimiter. Most likely, we are in a
9295 ;; template arglist within a statement. This case is based on CASE
9296 ;; 7. At some point in the future, we may wish to create more
9297 ;; syntactic symbols such as `template-intro',
9298 ;; `template-cont-nonempty', etc., and distinguish between them as we
9299 ;; do for `arglist-intro' etc. (2009-12-07).
9300 ((and c-recognize-<>-arglists
9301 (setq containing-< (c-up-list-backward indent-point containing-sexp))
9302 (eq (char-after containing-<) ?\<))
9303 (setq placeholder (c-point 'boi containing-<))
9304 (goto-char containing-sexp) ; Most nested Lbrace/Lparen (but not
9305 ; '<') before indent-point.
9306 (if (>= (point) placeholder)
9307 (progn
9308 (forward-char)
9309 (skip-chars-forward " \t"))
9310 (goto-char placeholder))
9311 (c-add-stmt-syntax 'template-args-cont (list containing-<) t
9312 (c-most-enclosing-brace c-state-cache (point))
9313 paren-state))
9314
9315
9280 ;; CASE 7: line is an expression, not a statement. Most 9316 ;; CASE 7: line is an expression, not a statement. Most
9281 ;; likely we are either in a function prototype or a function 9317 ;; likely we are either in a function prototype or a function
9282 ;; call argument list 9318 ;; call argument list, or a template argument list.
9283 ((not (or (and c-special-brace-lists 9319 ((not (or (and c-special-brace-lists
9284 (save-excursion 9320 (save-excursion
9285 (goto-char containing-sexp) 9321 (goto-char containing-sexp)
9286 (c-looking-at-special-brace-list))) 9322 (c-looking-at-special-brace-list)))
9287 (eq (char-after containing-sexp) ?{))) 9323 (eq (char-after containing-sexp) ?{)
9324 (eq (char-after containing-sexp) ?<)))
9288 (cond 9325 (cond
9289 9326
9290 ;; CASE 7A: we are looking at the arglist closing paren. 9327 ;; CASE 7A: we are looking at the arglist closing paren.
@@ -9381,7 +9418,7 @@ comment at the start of cc-engine.el for more info."
9381 (c-forward-syntactic-ws) 9418 (c-forward-syntactic-ws)
9382 (point)) 9419 (point))
9383 (c-point 'bonl))) 9420 (c-point 'bonl)))
9384 (goto-char containing-sexp) 9421 (goto-char containing-sexp) ; paren opening the arglist
9385 (setq placeholder (c-point 'boi)) 9422 (setq placeholder (c-point 'boi))
9386 (if (and (c-safe (backward-up-list 1) t) 9423 (if (and (c-safe (backward-up-list 1) t)
9387 (>= (point) placeholder)) 9424 (>= (point) placeholder))
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el
index 49d9ebeb492..14a3533e0e2 100644
--- a/lisp/progmodes/cc-mode.el
+++ b/lisp/progmodes/cc-mode.el
@@ -541,19 +541,15 @@ that requires a literal mode spec at compile time."
541 (make-local-variable 'lookup-syntax-properties) 541 (make-local-variable 'lookup-syntax-properties)
542 (setq lookup-syntax-properties t))) 542 (setq lookup-syntax-properties t)))
543 543
544 ;; Use this in Emacs 21 to avoid meddling with the rear-nonsticky 544 ;; Use this in Emacs 21+ to avoid meddling with the rear-nonsticky
545 ;; property on each character. 545 ;; property on each character.
546 (when (boundp 'text-property-default-nonsticky) 546 (when (boundp 'text-property-default-nonsticky)
547 (make-local-variable 'text-property-default-nonsticky) 547 (make-local-variable 'text-property-default-nonsticky)
548 (let ((elem (assq 'syntax-table text-property-default-nonsticky))) 548 (mapc (lambda (tprop)
549 (if elem 549 (unless (assq tprop text-property-default-nonsticky)
550 (setcdr elem t) 550 (setq text-property-default-nonsticky
551 (setq text-property-default-nonsticky 551 (cons `(,tprop . t) text-property-default-nonsticky))))
552 (cons '(syntax-table . t) 552 '(syntax-table category c-type)))
553 text-property-default-nonsticky))))
554 (setq text-property-default-nonsticky
555 (cons '(c-type . t)
556 text-property-default-nonsticky)))
557 553
558 ;; In Emacs 21 and later it's possible to turn off the ad-hoc 554 ;; In Emacs 21 and later it's possible to turn off the ad-hoc
559 ;; heuristic that open parens in column 0 are defun starters. Since 555 ;; heuristic that open parens in column 0 are defun starters. Since