summaryrefslogtreecommitdiff
path: root/lisp
diff options
context:
space:
mode:
authorAlan Mackenzie <acm@muc.de>2013-04-30 16:19:14 +0000
committerAlan Mackenzie <acm@muc.de>2013-04-30 16:19:14 +0000
commit3d1c39faa4744f87838ecd07fdf01787d5235186 (patch)
tree1495bb55a5fd47b4a80e57b7e356d1b9220396cb /lisp
parent5147fc177367a3d41a98bc651b02af3660aeafbd (diff)
downloademacs-3d1c39faa4744f87838ecd07fdf01787d5235186.tar.gz
emacs-3d1c39faa4744f87838ecd07fdf01787d5235186.tar.bz2
emacs-3d1c39faa4744f87838ecd07fdf01787d5235186.zip
Handle arbitrarily long C++ member initialisation lists.
* progmodes/cc-engine.el (c-back-over-member-initializers): new function. (c-guess-basic-syntax): New CASE 5R (extracted from 5B) to handle (most) member init lists.
Diffstat (limited to 'lisp')
-rw-r--r--lisp/ChangeLog8
-rw-r--r--lisp/progmodes/cc-engine.el78
2 files changed, 76 insertions, 10 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 00cfe320701..0513d69d0fc 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,11 @@
+2013-04-30 Alan Mackenzie <acm@muc.de>
+
+ Handle arbitrarily long C++ member initialisation lists.
+ * progmodes/cc-engine.el (c-back-over-member-initializers): new
+ function.
+ (c-guess-basic-syntax): New CASE 5R (extracted from 5B) to handle
+ (most) member init lists.
+
2013-04-30 RĂ¼diger Sonderfeld <ruediger@c-plusplus.de>
* progmodes/octave.el (inferior-octave-prompt-read-only): New user
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index 4fc270792fc..6a23da1f2cd 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -6475,6 +6475,52 @@ comment at the start of cc-engine.el for more info."
(c-go-list-forward)
t)))
+(defun c-back-over-member-initializers ()
+ ;; Test whether we are in a C++ member initializer list, and if so, go back
+ ;; to the introducing ":", returning the position of the opening paren of
+ ;; the function's arglist. Otherwise return nil, leaving point unchanged.
+ (let ((here (point))
+ (paren-state (c-parse-state))
+ res)
+
+ (setq res
+ (catch 'done
+ (if (not (c-at-toplevel-p))
+ (progn
+ (while (not (c-at-toplevel-p))
+ (goto-char (c-pull-open-brace paren-state)))
+ (c-backward-syntactic-ws)
+ (when (not (c-simple-skip-symbol-backward))
+ (throw 'done nil))
+ (c-backward-syntactic-ws))
+ (c-backward-syntactic-ws)
+ (when (memq (char-before) '(?\) ?}))
+ (when (not (c-go-list-backward))
+ (throw 'done nil))
+ (c-backward-syntactic-ws))
+ (when (c-simple-skip-symbol-backward)
+ (c-backward-syntactic-ws)))
+
+ (while (eq (char-before) ?,)
+ (backward-char)
+ (c-backward-syntactic-ws)
+
+ (when (not (memq (char-before) '(?\) ?})))
+ (throw 'done nil))
+ (when (not (c-go-list-backward))
+ (throw 'done nil))
+ (c-backward-syntactic-ws)
+ (when (not (c-simple-skip-symbol-backward))
+ (throw 'done nil))
+ (c-backward-syntactic-ws))
+
+ (and
+ (eq (char-before) ?:)
+ (c-just-after-func-arglist-p))))
+
+ (or res (goto-char here))
+ res))
+
;; Handling of large scale constructs like statements and declarations.
@@ -9677,18 +9723,13 @@ comment at the start of cc-engine.el for more info."
;; 2007-11-09)
))))
- ;; CASE 5B: After a function header but before the body (or
- ;; the ending semicolon if there's no body).
+ ;; CASE 5R: Member init list. (Used to be part of CASE 5B.1)
+ ;; Note there is no limit on the backward search here, since member
+ ;; init lists can, in practice, be very large.
((save-excursion
- (when (setq placeholder (c-just-after-func-arglist-p
- (max lim (c-determine-limit 500))))
+ (when (setq placeholder (c-back-over-member-initializers))
(setq tmp-pos (point))))
- (cond
-
- ;; CASE 5B.1: Member init list.
- ((eq (char-after tmp-pos) ?:)
- (if (or (>= tmp-pos indent-point)
- (= (c-point 'bosws) (1+ tmp-pos)))
+ (if (= (c-point 'bosws) (1+ tmp-pos))
(progn
;; There is no preceding member init clause.
;; Indent relative to the beginning of indentation
@@ -9701,6 +9742,23 @@ comment at the start of cc-engine.el for more info."
(c-forward-syntactic-ws)
(c-add-syntax 'member-init-cont (point))))
+ ;; CASE 5B: After a function header but before the body (or
+ ;; the ending semicolon if there's no body).
+ ((save-excursion
+ (when (setq placeholder (c-just-after-func-arglist-p
+ (max lim (c-determine-limit 500))))
+ (setq tmp-pos (point))))
+ (cond
+
+ ;; CASE 5B.1: Member init list.
+ ((eq (char-after tmp-pos) ?:)
+ ;; There is no preceding member init clause.
+ ;; Indent relative to the beginning of indentation
+ ;; for the topmost-intro line that contains the
+ ;; prototype's open paren.
+ (goto-char placeholder)
+ (c-add-syntax 'member-init-intro (c-point 'boi)))
+
;; CASE 5B.2: K&R arg decl intro
((and c-recognize-knr-p
(c-in-knr-argdecl lim))