]> git.eshelyaron.com Git - emacs.git/commitdiff
Apply text properties for <, > in new after-change function (C++ Java Modes).
authorAlan Mackenzie <acm@muc.de>
Mon, 4 Jan 2016 22:29:33 +0000 (22:29 +0000)
committerAlan Mackenzie <acm@muc.de>
Mon, 4 Jan 2016 22:35:13 +0000 (22:35 +0000)
These are category/syntax-table properties to give < and > paren syntax.
Also apply certain `c-type' text properties to the insides of <..> constructs
to ensure that identifiers contained by them get fontified.  This patch fixes
bug #681.

* lisp/progmodes/cc-cmds.el (c-electric-lt-gt): Reformulate due to new
after-change action.

* lisp/progmodes/cc-engine.el (c-before-change-check-<>-operators): Expand
change region to include <s and >s which might not be already marked as
parens, rather than just when paren text properties are removed.
(c-restore-<>-properties): New after-change function, which applies text
properties marking < and > with paren syntax.

* lisp/progmodes/cc-fonts.el (c-font-lock-declarations): Ensure `c-type'
properties are applied to the interiors of <...> constructs, to ensure
fontification of identifiers there.

* lisp/progmodes/cc-langs.el (c-before-font-lock-functions): Add
c-restore-<>-properties to this list for C++ and Java.

* lisp/progmodes/cc-mode.el (c-common-init): When invoking
c-before-font-lock-functions, exclude c-restore-<>-properties from the
functions invoked.
(c-before-change): Initialize c-new-BEG/END here (rather than c-after-change)
to allow modification by before-change functions.
(c-after-change): Amend c-new-END here, rather than initializing it and
c-new-BEG.

lisp/progmodes/cc-cmds.el
lisp/progmodes/cc-engine.el
lisp/progmodes/cc-fonts.el
lisp/progmodes/cc-langs.el
lisp/progmodes/cc-mode.el

index a46f0488e76dff4148e3f53e4d20923f0cea50e5..6761de1170003e5c3c39704ebfaad2631fa8f3e4 100644 (file)
@@ -1121,35 +1121,15 @@ numeric argument is supplied, or the point is inside a literal."
                           (looking-at "<<"))
                         (>= (match-end 0) final-pos)))
 
-             ;; It's a >.  Either a C++ >> operator. ......
-             (or (and (c-major-mode-is 'c++-mode)
+             ;; It's a >.  Either a template/generic terminator ...
+             (or (c-get-char-property (1- final-pos) 'syntax-table)
+                 ;; or a C++ >> operator.
+                 (and (c-major-mode-is 'c++-mode)
                       (progn
                         (goto-char (1- final-pos))
                         (c-beginning-of-current-token)
                         (looking-at ">>"))
-                      (>= (match-end 0) final-pos))
-                 ;; ...., or search back for a < which isn't already marked as an
-                 ;; opening template delimiter.
-                 (save-restriction
-                   (widen)
-                   ;; Narrow to avoid `c-forward-<>-arglist' below searching past
-                   ;; our position.
-                   (narrow-to-region (point-min) final-pos)
-                   (goto-char final-pos)
-                   (while
-                       (and
-                        (progn
-                          (c-syntactic-skip-backward "^<;}" nil t)
-                          (eq (char-before) ?<))
-                        (progn
-                          (backward-char)
-                          (looking-at "\\s("))))
-                   (and (eq (char-after) ?<)
-                        (not (looking-at "\\s("))
-                        (progn (c-backward-syntactic-ws)
-                               (c-simple-skip-symbol-backward))
-                        (or (looking-at c-opt-<>-sexp-key)
-                            (not (looking-at c-keywords-regexp)))))))))
+                      (>= (match-end 0) final-pos))))))
 
     (goto-char final-pos)
     (when found-delim
@@ -1157,11 +1137,9 @@ numeric argument is supplied, or the point is inside a literal."
       (when (and (eq (char-before) ?>)
                 (not executing-kbd-macro)
                 blink-paren-function)
-       ;; Currently (2014-10-19), the syntax-table text properties on < and >
-       ;; are only applied in code called during Emacs redisplay.  We thus
-       ;; explicitly cause a redisplay so that these properties have been
-       ;; applied when `blink-paren-function' gets called.
-       (sit-for 0)
+       ;; From now (2016-01-01), the syntax-table text properties on < and >
+       ;; are applied in an after-change function, not during redisplay.  Hence
+       ;; we no longer need to call (sit-for 0) for blink paren to work.
        (funcall blink-paren-function)))))
 
 (defun c-electric-paren (arg)
index 617c94aae08599c8a488632bfd684bf3376d5b4f..2a35a647ff86e9fffa17b371456371bd1eb665fb 100644 (file)
@@ -5577,8 +5577,9 @@ comment at the start of cc-engine.el for more info."
 
 (defun c-before-change-check-<>-operators (beg end)
   ;; Unmark certain pairs of "< .... >" which are currently marked as
-  ;; template/generic delimiters.  (This marking is via syntax-table
-  ;; text properties).
+  ;; template/generic delimiters.  (This marking is via syntax-table text
+  ;; properties), and expand the (c-new-BEG c-new-END) region to include all
+  ;; unmarked < and > operators within the certain bounds (see below).
   ;;
   ;; These pairs are those which are in the current "statement" (i.e.,
   ;; the region between the {, }, or ; before BEG and the one after
@@ -5597,38 +5598,40 @@ comment at the start of cc-engine.el for more info."
   (save-excursion
     (let ((beg-lit-limits (progn (goto-char beg) (c-literal-limits)))
          (end-lit-limits (progn (goto-char end) (c-literal-limits)))
-         new-beg new-end need-new-beg need-new-end)
-      ;; Locate the barrier before the changed region
+         new-beg new-end beg-limit end-limit)
+      ;; Locate the earliest < after the barrier before the changed region,
+      ;; which isn't already marked as a paren.
       (goto-char  (if beg-lit-limits (car beg-lit-limits) beg))
-      (c-syntactic-skip-backward "^;{}" (c-determine-limit 512))
-      (setq new-beg (point))
+      (setq beg-limit (c-determine-limit 512))
 
       ;; Remove the syntax-table/category properties from each pertinent <...>
-      ;; pair.  Firsly, the ones with the < before beg and > after beg.
-      (while
-         (c-search-forward-char-property 'syntax-table c-<-as-paren-syntax beg)
-       (if (c-clear-<-pair-props-if-match-after beg (1- (point)))
-           (setq need-new-beg t)))
+      ;; pair.  Firstly, the ones with the < before beg and > after beg....
+      (while (progn (c-syntactic-skip-backward "^;{}<" beg-limit)
+                   (eq (char-before) ?<))
+       (c-backward-token-2)
+       (when (eq (char-after) ?<)
+         (c-clear-<-pair-props-if-match-after beg)))
+      (c-forward-syntactic-ws)
+      (setq new-beg (point))
 
-      ;; Locate the barrier after END.
+      ;; ...Then the ones with < before end and > after end.
       (goto-char (if end-lit-limits (cdr end-lit-limits) end))
-      (c-syntactic-re-search-forward "[;{}]" (c-determine-+ve-limit 512) 'end)
+      (setq end-limit (c-determine-+ve-limit 512))
+      (while (and (c-syntactic-re-search-forward "[;{}>]" end-limit 'end)
+                 (eq (char-before) ?>))
+       (c-end-of-current-token)
+       (when (eq (char-before) ?>)
+         (c-clear->-pair-props-if-match-before end (1- (point)))))
+      (c-backward-syntactic-ws)
       (setq new-end (point))
 
-      ;; Remove syntax-table properties from the remaining pertinent <...>
-      ;; pairs, those with a > after end and < before end.
-      (while (c-search-backward-char-property 'syntax-table c->-as-paren-syntax end)
-       (if (c-clear->-pair-props-if-match-before end)
-           (setq need-new-end t)))
-
       ;; Extend the fontification region, if needed.
-      (when need-new-beg
-       (goto-char new-beg)
-       (c-forward-syntactic-ws)
-       (and (< (point) c-new-BEG) (setq c-new-BEG (point))))
-
-      (when need-new-end
-       (and (> new-end c-new-END) (setq c-new-END new-end))))))
+      (and new-beg
+          (< new-beg c-new-BEG)
+          (setq c-new-BEG new-beg))
+      (and new-end
+          (> new-end c-new-END)
+          (setq c-new-END new-end)))))
 
 (defun c-after-change-check-<>-operators (beg end)
   ;; This is called from `after-change-functions' when
@@ -5668,7 +5671,28 @@ comment at the start of cc-engine.el for more info."
            (c-clear-<>-pair-props)
            (forward-char)))))))
 
-
+(defun c-restore-<>-properties (_beg _end _old-len)
+  ;; This function is called as an after-change function.  It restores the
+  ;; category/syntax-table properties on template/generic <..> pairs between
+  ;; c-new-BEG and c-new-END.  It may do hidden buffer changes.
+  (c-save-buffer-state ((c-parse-and-markup-<>-arglists t)
+                       c-restricted-<>-arglists lit-limits)
+    (goto-char c-new-BEG)
+    (if (setq lit-limits (c-literal-limits))
+       (goto-char (cdr lit-limits)))
+    (while (and (< (point) c-new-END)
+               (c-syntactic-re-search-forward "<" c-new-END 'bound))
+      (backward-char)
+      (save-excursion
+       (c-backward-token-2)
+       (setq c-restricted-<>-arglists
+            (and (not (looking-at c-opt-<>-sexp-key))
+                 (progn (c-backward-syntactic-ws) ; to < or ,
+                        (and (memq (char-before) '(?< ?,))
+                             (not (eq (c-get-char-property (point) 'c-type)
+                                      'c-decl-arg-start)))))))
+      (or (c-forward-<>-arglist nil)
+         (forward-char)))))
 \f
 ;; Handling of small scale constructs like types and names.
 
index c2b2d72649fb23f9d2558f0f11dcde8390fbf63c..f74e5cbf6783fe64e45b563e163d0c76c825605e 100644 (file)
@@ -1205,6 +1205,9 @@ casts and declarations are fontified.  Used on level 2 and higher."
          ;; Same as `max-type-decl-*', but used when we're before
          ;; `token-pos'.
          (max-type-decl-end-before-token 0)
+         ;; End of <..> construct which has had c-<>-arg-sep c-type
+         ;; properties set within it.
+         (max-<>-end 0)
          ;; Set according to the context to direct the heuristics for
          ;; recognizing C++ templates.
          c-restricted-<>-arglists
@@ -1347,6 +1350,28 @@ casts and declarations are fontified.  Used on level 2 and higher."
            (setq decl-or-cast (c-forward-decl-or-cast-1
                                match-pos context last-cast-end))
 
+           ;; Ensure that c-<>-arg-sep c-type properties are in place on the
+           ;; commas separating the arguments inside template/generic <..>s.
+           (when (and (eq (char-before match-pos) ?<)
+                      (> match-pos max-<>-end))
+             (save-excursion
+               (goto-char match-pos)
+               (c-backward-token-2)
+               (if (and
+                    (eq (char-after) ?<)
+                    (let ((c-restricted-<>-arglists
+                           (save-excursion
+                             (c-backward-token-2)
+                             (and
+                              (not (looking-at c-opt-<>-sexp-key))
+                              (progn (c-backward-syntactic-ws)
+                                     (memq (char-before) '(?\( ?,)))
+                              (not (eq (c-get-char-property (1- (point))
+                                                            'c-type)
+                                       'c-decl-arg-start))))))
+                      (c-forward-<>-arglist nil)))
+                   (setq max-<>-end (point)))))
+
            (cond
             ((eq decl-or-cast 'cast)
              ;; Save the position after the previous cast so we can feed
index 8ae75277925dc06d658540a65dd2ab31cefe3a75..d7972b4ef835bf928801e1b057a1163f1fe482a0 100644 (file)
@@ -499,8 +499,13 @@ parameters \(point-min) and \(point-max).")
   ;; For documentation see the following c-lang-defvar of the same name.
   ;; The value here may be a list of functions or a single function.
   t 'c-change-expand-fl-region
-  (c c++ objc) '(c-neutralize-syntax-in-and-mark-CPP
-                c-change-expand-fl-region)
+  (c objc) '(c-neutralize-syntax-in-and-mark-CPP
+            c-change-expand-fl-region)
+  c++ '(c-neutralize-syntax-in-and-mark-CPP
+       c-restore-<>-properties
+       c-change-expand-fl-region)
+  java '(c-restore-<>-properties
+        c-change-expand-fl-region)
   awk 'c-awk-extend-and-syntax-tablify-region)
 (c-lang-defvar c-before-font-lock-functions
               (let ((fs (c-lang-const c-before-font-lock-functions)))
index 7f71700c650b200007fcc460f0962948dd6c71bc..e5be0b53b12e400f88ac1632e63dfdfb33f29116 100644 (file)
@@ -631,8 +631,11 @@ that requires a literal mode spec at compile time."
     (font-lock-mode 1)))
 
 ;; Buffer local variables defining the region to be fontified by a font lock
-;; after-change function.  They are set in c-after-change to
-;; after-change-functions' BEG and END, and may be modified by functions in
+;; after-change function.  They are initialized in c-before-change to
+;; before-change-functions' BEG and END.  `c-new-END' is amended in
+;; c-after-change with after-change-functions' BEG, END, and OLD-LEN.  These
+;; variables may be modified by any before/after-change function, in
+;; particular by functions in `c-get-state-before-change-functions' and
 ;; `c-before-font-lock-functions'.
 (defvar c-new-BEG 0)
 (make-variable-buffer-local 'c-new-BEG)
@@ -671,8 +674,9 @@ compatible with old code; callers should always specify it."
                (funcall fn (point-min) (point-max)))
              c-get-state-before-change-functions)
        (mapc (lambda (fn)
-               (funcall fn (point-min) (point-max)
-                        (- (point-max) (point-min))))
+               (if (not (eq fn 'c-restore-<>-properties))
+                   (funcall fn (point-min) (point-max)
+                            (- (point-max) (point-min)))))
              c-before-font-lock-functions))))
 
   (set (make-local-variable 'outline-regexp) "[^#\n\^M]")
@@ -1032,6 +1036,8 @@ Note that the style variables are always made local to the buffer."
              c-just-done-before-change) ; guard against a spurious second
                                        ; invocation of before-change-functions.
     (setq c-just-done-before-change t)
+    ;; (c-new-BEG c-new-END) will be the region to fontify.
+    (setq c-new-BEG beg  c-new-END end)
     (setq c-maybe-stale-found-type nil)
     (save-restriction
       (save-match-data
@@ -1126,7 +1132,8 @@ Note that the style variables are always made local to the buffer."
 
   ;; (c-new-BEG c-new-END) will be the region to fontify.  It may become
   ;; larger than (beg end).
-  (setq c-new-BEG beg  c-new-END end)
+  ;; (setq c-new-BEG beg  c-new-END end)
+  (setq c-new-END (- (+ c-new-END (- end beg)) old-len))
 
   (unless (c-called-from-text-property-change-p)
     (setq c-just-done-before-change nil)