]> git.eshelyaron.com Git - emacs.git/commitdiff
Handle arbitrarily long C++ member initialisation lists.
authorAlan Mackenzie <acm@muc.de>
Tue, 30 Apr 2013 16:19:14 +0000 (16:19 +0000)
committerAlan Mackenzie <acm@muc.de>
Tue, 30 Apr 2013 16:19:14 +0000 (16:19 +0000)
        * 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.

lisp/ChangeLog
lisp/progmodes/cc-engine.el

index 00cfe32070137ec0cbf2ccc2c71ed812e7c3b803..0513d69d0fc0893639dbb358eb1cde0390856112 100644 (file)
@@ -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
index 4fc270792fc6367ac88ca9c80a2f7f75a9728afc..6a23da1f2cd34223d98dba91140d82b89e0755d4 100644 (file)
@@ -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))
+
 \f
 ;; 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))