aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Mackenzie2011-12-24 19:32:31 +0000
committerAlan Mackenzie2011-12-24 19:32:31 +0000
commitbe8b11bb321086c7edfdcf4ac079d694e6a8b97b (patch)
treea2edb2d8feaa4b09d55988c2eeb8cb8df5e42480
parent3ba1a2ad82e1936f03b46b1db284945af806788b (diff)
downloademacs-be8b11bb321086c7edfdcf4ac079d694e6a8b97b.tar.gz
emacs-be8b11bb321086c7edfdcf4ac079d694e6a8b97b.zip
Introduce a mechanism to widen the region used in context font locking.
Use this to protect declarations from losing their contexts.
-rw-r--r--lisp/ChangeLog23
-rw-r--r--lisp/progmodes/cc-langs.el26
-rw-r--r--lisp/progmodes/cc-mode.el204
3 files changed, 187 insertions, 66 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index f8f8e7eb695..8c368473871 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,26 @@
12011-12-24 Alan Mackenzie <acm@muc.de>
2
3 Introduce a mechanism to widen the region used in context font
4 locking. Use this to protect declarations from losing their
5 contexts.
6
7 * progmodes/cc-langs.el (c-before-font-lock-functions): replace
8 c-set-fl-decl-start with c-change-set-fl-decl-start (Renaming).
9 (c-before-context-fontification-functions): new defvar, a list of
10 functions to be run just before context (etc.) font locking.
11
12 * progmodes/cc-mode.el (c-extend-font-lock-region-for-macros):
13 new, functionality extracted from
14 c-neutralize-syntax-in-and-mark-CPP.
15 (c-in-after-change-fontification): new variable.
16 (c-after-change): Set c-in-after-change-fontification.
17 (c-set-fl-decl-start): Rejig its interface, so it can be called
18 from both after-change and context fontifying.
19 (c-change-set-fl-decl-start, c-context-set-fl-decl-start): new
20 functions.
21 (c-standard-font-lock-fontify-region-function): new variable.
22 (c-font-lock-fontify-region): new function.
23
12011-12-24 Juri Linkov <juri@jurta.org> 242011-12-24 Juri Linkov <juri@jurta.org>
2 25
3 * window.el (window--state-get-1): Set `FORCE' arg of `mark' to t. 26 * window.el (window--state-get-1): Set `FORCE' arg of `mark' to t.
diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el
index 2b6dc7a9df7..2aca885ca35 100644
--- a/lisp/progmodes/cc-langs.el
+++ b/lisp/progmodes/cc-langs.el
@@ -488,8 +488,9 @@ parameters \(point-min) and \(point-max).")
488(c-lang-defconst c-before-font-lock-functions 488(c-lang-defconst c-before-font-lock-functions
489 ;; For documentation see the following c-lang-defvar of the same name. 489 ;; For documentation see the following c-lang-defvar of the same name.
490 ;; The value here may be a list of functions or a single function. 490 ;; The value here may be a list of functions or a single function.
491 t 'c-set-fl-decl-start 491 t 'c-change-set-fl-decl-start
492 (c c++ objc) '(c-neutralize-syntax-in-and-mark-CPP c-set-fl-decl-start) 492 (c c++ objc) '(c-neutralize-syntax-in-and-mark-CPP
493 c-change-set-fl-decl-start)
493 awk 'c-awk-extend-and-syntax-tablify-region) 494 awk 'c-awk-extend-and-syntax-tablify-region)
494(c-lang-defvar c-before-font-lock-functions 495(c-lang-defvar c-before-font-lock-functions
495 (let ((fs (c-lang-const c-before-font-lock-functions))) 496 (let ((fs (c-lang-const c-before-font-lock-functions)))
@@ -514,6 +515,27 @@ The functions are called even when font locking is disabled.
514When the mode is initialized, these functions are called with 515When the mode is initialized, these functions are called with
515parameters \(point-min), \(point-max) and <buffer size>.") 516parameters \(point-min), \(point-max) and <buffer size>.")
516 517
518(c-lang-defconst c-before-context-fontification-functions
519 awk nil
520 t 'c-context-set-fl-decl-start)
521 ;; For documentation see the following c-lang-defvar of the same name.
522 ;; The value here may be a list of functions or a single function.
523(c-lang-defvar c-before-context-fontification-functions
524 (let ((fs (c-lang-const c-before-context-fontification-functions)))
525 (if (listp fs)
526 fs
527 (list fs)))
528 "If non-nil, a list of functions called just before context (or
529other non-change) fontification is done. Typically they will
530extend the region.
531
532These functions will be run in the order given. Each of them
533takes 2 parameters, the BEG and END of the region to be
534fontified. Point is undefined on both entry and exit. On entry,
535the buffer will have been widened and match-data will have been
536saved; the return value is a cons of the adjusted
537region, (NEW-BEG . NEW-END).")
538
517 539
518;;; Syntactic analysis ("virtual semicolons") for line-oriented languages (AWK). 540;;; Syntactic analysis ("virtual semicolons") for line-oriented languages (AWK).
519(c-lang-defconst c-at-vsemi-p-fn 541(c-lang-defconst c-at-vsemi-p-fn
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el
index 01111d2b536..1bc0741b0aa 100644
--- a/lisp/progmodes/cc-mode.el
+++ b/lisp/progmodes/cc-mode.el
@@ -599,8 +599,8 @@ that requires a literal mode spec at compile time."
599 599
600;; Buffer local variables defining the region to be fontified by a font lock 600;; Buffer local variables defining the region to be fontified by a font lock
601;; after-change function. They are set in c-after-change to 601;; after-change function. They are set in c-after-change to
602;; after-change-function's BEG and END, and may be modified by a 602;; after-change-functions' BEG and END, and may be modified by functions in
603;; `c-before-font-lock-function'. 603;; `c-before-font-lock-functions'.
604(defvar c-new-BEG 0) 604(defvar c-new-BEG 0)
605(make-variable-buffer-local 'c-new-BEG) 605(make-variable-buffer-local 'c-new-BEG)
606(defvar c-new-END 0) 606(defvar c-new-END 0)
@@ -830,6 +830,35 @@ Note that the style variables are always made local to the buffer."
830 ; with a c-cpp-delimiter category property 830 ; with a c-cpp-delimiter category property
831 (setq c-old-EOM (point))) 831 (setq c-old-EOM (point)))
832 832
833(defun c-extend-font-lock-region-for-macros (begg endd &optional old-len)
834 ;; Extend the region (BEGG ENDD) to cover all (possibly changed)
835 ;; preprocessor macros; return the cons (new-BEG . new-END). OLD-LEN should
836 ;; be either the old length parameter when called from an
837 ;; after-change-function, or nil otherwise. This defun uses the variables
838 ;; c-old-BOM, c-new-BOM.
839 ;;
840 ;; Point is undefined on both entry and exit to this function. The buffer
841 ;; will have been widened on entry.
842 (let (limits new-beg new-end)
843 (goto-char c-old-BOM) ; already set to old start of macro or begg.
844 (setq new-beg
845 (min begg
846 (if (setq limits (c-state-literal-at (point)))
847 (cdr limits) ; go forward out of any string or comment.
848 (point))))
849
850 (goto-char endd)
851 (if (setq limits (c-state-literal-at (point)))
852 (goto-char (car limits))) ; go backward out of any string or comment.
853 (if (c-beginning-of-macro)
854 (c-end-of-macro))
855 (setq new-end (max endd
856 (if old-len
857 (+ (- c-old-EOM old-len) (- endd begg))
858 c-old-EOM)
859 (point)))
860 (cons new-beg new-end)))
861
833(defun c-neutralize-CPP-line (beg end) 862(defun c-neutralize-CPP-line (beg end)
834 ;; BEG and END bound a region, typically a preprocessor line. Put a 863 ;; BEG and END bound a region, typically a preprocessor line. Put a
835 ;; "punctuation" syntax-table property on syntactically obtrusive 864 ;; "punctuation" syntax-table property on syntactically obtrusive
@@ -886,26 +915,14 @@ Note that the style variables are always made local to the buffer."
886 ;; Note: SPEED _MATTERS_ IN THIS FUNCTION!!! 915 ;; Note: SPEED _MATTERS_ IN THIS FUNCTION!!!
887 ;; 916 ;;
888 ;; This function might make hidden buffer changes. 917 ;; This function might make hidden buffer changes.
889 (c-save-buffer-state (limits) 918 (c-save-buffer-state (new-bounds)
890 ;; First determine the region, (c-new-BEG c-new-END), which will get font 919 ;; First determine the region, (c-new-BEG c-new-END), which will get font
891 ;; locked. It might need "neutralizing". This region may not start 920 ;; locked. It might need "neutralizing". This region may not start
892 ;; inside a string, comment, or macro. 921 ;; inside a string, comment, or macro.
893 (goto-char c-old-BOM) ; already set to old start of macro or begg. 922 (setq new-bounds (c-extend-font-lock-region-for-macros
894 (setq c-new-BEG 923 c-new-BEG c-new-END old-len))
895 (min c-new-BEG 924 (setq c-new-BEG (car new-bounds)
896 (if (setq limits (c-state-literal-at (point))) 925 c-new-END (cdr new-bounds))
897 (cdr limits) ; go forward out of any string or comment.
898 (point))))
899
900 (goto-char endd)
901 (if (setq limits (c-state-literal-at (point)))
902 (goto-char (car limits))) ; go backward out of any string or comment.
903 (if (c-beginning-of-macro)
904 (c-end-of-macro))
905 (setq c-new-END (max c-new-END
906 (+ (- c-old-EOM old-len) (- endd begg))
907 (point)))
908
909 ;; Clear all old relevant properties. 926 ;; Clear all old relevant properties.
910 (c-clear-char-property-with-value c-new-BEG c-new-END 'syntax-table '(1)) 927 (c-clear-char-property-with-value c-new-BEG c-new-END 'syntax-table '(1))
911 (c-clear-char-property-with-value c-new-BEG c-new-END 'category 'c-cpp-delimiter) 928 (c-clear-char-property-with-value c-new-BEG c-new-END 'category 'c-cpp-delimiter)
@@ -1015,6 +1032,11 @@ Note that the style variables are always made local to the buffer."
1015 c-get-state-before-change-functions)) 1032 c-get-state-before-change-functions))
1016 )))) 1033 ))))
1017 1034
1035(defvar c-in-after-change-fontification nil)
1036(make-variable-buffer-local 'c-in-after-change-fontification)
1037;; A flag to prevent region expanding stuff being done twice for after-change
1038;; fontification.
1039
1018(defun c-after-change (beg end old-len) 1040(defun c-after-change (beg end old-len)
1019 ;; Function put on `after-change-functions' to adjust various caches 1041 ;; Function put on `after-change-functions' to adjust various caches
1020 ;; etc. Prefer speed to finesse here, since there will be an order 1042 ;; etc. Prefer speed to finesse here, since there will be an order
@@ -1066,63 +1088,113 @@ Note that the style variables are always made local to the buffer."
1066 ;; larger than (beg end). 1088 ;; larger than (beg end).
1067 (setq c-new-BEG beg 1089 (setq c-new-BEG beg
1068 c-new-END end) 1090 c-new-END end)
1091 (setq c-in-after-change-fontification t)
1069 (save-excursion 1092 (save-excursion
1070 (mapc (lambda (fn) 1093 (mapc (lambda (fn)
1071 (funcall fn beg end old-len)) 1094 (funcall fn beg end old-len))
1072 c-before-font-lock-functions)))))) 1095 c-before-font-lock-functions))))))
1073 1096
1074(defun c-set-fl-decl-start (beg end old-len) 1097(defun c-set-fl-decl-start (pos)
1075 ;; If the beginning of line containing c-new-BEG is in the middle of a 1098 ;; If the beginning of the line containing POS is in the middle of a "local"
1076 ;; "local" declaration (i.e. one which does not start outside of braces 1099 ;; declaration (i.e. one which does not start outside of braces enclosing
1077 ;; enclosing this pos, such as a struct), set c-new-BEG to (at most) the 1100 ;; POS, such as a struct), return the beginning of that declaration.
1078 ;; beginning of that declaration. Note that declarations, in this sense, 1101 ;; Otherwise return POS. Note that declarations, in this sense, can be
1079 ;; can be nested. c-new-BEG will be used later by c-font-lock-declarations. 1102 ;; nested.
1080 ;; 1103 ;;
1081 ;; This function is an element of c-before-font-lock-functions, being called 1104 ;; This function is called indirectly from font locking stuff - either from
1082 ;; (indirectly) from an after-change function. The after-change-functions' 1105 ;; c-after-change (to prepare for after-change font-lockng) or from font
1083 ;; parameters BEG, OLD and OLD-LEN are ignored here. 1106 ;; lock context (etc.) fontification.
1084 (when font-lock-mode 1107 (let ((lit-limits (c-literal-limits))
1085 (goto-char (c-point 'bol c-new-BEG)) 1108 (new-pos pos)
1086 (let ((lit-limits (c-literal-limits)) 1109 bod-lim bo-decl)
1087 bod-lim bo-decl) 1110 (goto-char (c-point 'bol new-pos))
1088 1111 (when lit-limits ; Comment or string.
1089 (when lit-limits ; Comment or string. 1112 (goto-char (car lit-limits)))
1090 (goto-char (car lit-limits))) 1113 (setq bod-lim (max (- (point) 500) (point-min)))
1091 (setq bod-lim (max (- (point) 500) (point-min))) 1114
1092 1115 (while
1093 (while 1116 ;; Go to a less nested declaration each time round this loop.
1094 ;; Go to a less nested declaration each time round this loop. 1117 (and
1095 (and 1118 (eq (car (c-beginning-of-decl-1 bod-lim)) 'same)
1096 (eq (car (c-beginning-of-decl-1 bod-lim)) 'same) 1119 (progn (setq bo-decl (point))
1097 (progn (setq bo-decl (point)) 1120 ;; Are we looking at a keyword such as "template" or
1098 ;; Are we looking at a keyword such as "template" or 1121 ;; "typedef" which can decorate a type, or the type itself?
1099 ;; "typedef" which can decorate a type, or the type itself? 1122 (when (or (looking-at c-prefix-spec-kwds-re)
1100 (when (or (looking-at c-prefix-spec-kwds-re) 1123 (c-forward-type t))
1101 (c-forward-type t)) 1124 ;; We've found another candidate position.
1102 ;; We've found another candidate position. 1125 (setq new-pos (min new-pos bo-decl))
1103 (setq c-new-BEG (min c-new-BEG bo-decl)) 1126 (goto-char bo-decl))
1104 (goto-char bo-decl)) 1127 t)
1105 t) 1128 ;; Try and go out a level to search again.
1106 ;; Try and go out a level to search again. 1129 (progn
1107 (progn 1130 (c-backward-syntactic-ws bod-lim)
1108 (c-backward-syntactic-ws bod-lim) 1131 (or (memq (char-before) '(?\( ?\[))
1109 (or (memq (char-before) '(?\( ?\[)) 1132 (and (eq (char-before) ?\<)
1110 (and (eq (char-before) ?\<) 1133 (eq (c-get-char-property
1111 (eq (c-get-char-property 1134 (1- (point)) 'syntax-table)
1112 (1- (point)) 'syntax-table) 1135 c-<-as-paren-syntax))))
1113 c-<-as-paren-syntax)))) 1136 (not (bobp)))
1114 (not (bobp))) 1137 (backward-char))
1115 (backward-char))))) ; back over (, [, <. 1138 new-pos)) ; back over (, [, <.
1116 1139
1140(defun c-change-set-fl-decl-start (beg end old-len)
1141 ;; Set c-new-BEG to the beginning of a "local" declaration if it('s BOL) is
1142 ;; inside one. This is called from an after-change-function, but the
1143 ;; parameters BEG END and OLD-LEN are ignored. See `c-set-fl-decl-start'
1144 ;; for the detailed functionality.
1145 (if font-lock-mode
1146 (setq c-new-BEG (c-set-fl-decl-start c-new-BEG))))
1147
1148(defun c-context-set-fl-decl-start (beg end)
1149 ;; Return a cons (NEW-BEG . END), where NEW-BEG is the beginning of a
1150 ;; "local" declaration (BOL at) NEW is inside or BEG. See
1151 ;; `c-set-fl-decl-start' for the detailed functionality.
1152 (cons (c-set-fl-decl-start beg) end))
1153
1154(defvar c-standard-font-lock-fontify-region-function nil
1155 "Standard value of `font-lock-fontify-region-function'")
1156
1157(defun c-font-lock-fontify-region (beg end &optional verbose)
1158 ;; Effectively advice around `font-lock-fontify-region' which extends the
1159 ;; region (BEG END), for example, to avoid context fontification chopping
1160 ;; off the start of the context. Do not do anything if it's already been
1161 ;; done (i.e. from and after-change fontification. An example (C++) where
1162 ;; this used to happen is this:
1163 ;;
1164 ;; template <typename T>
1165 ;;
1166 ;;
1167 ;; void myfunc(T* p) {}
1168 ;;
1169 ;; Type a space in the first blank line, and the fontification of the next
1170 ;; line was fouled up by context fontification.
1171 (let ((new-beg beg) (new-end end) new-region)
1172 (if c-in-after-change-fontification
1173 (setq c-in-after-change-fontification nil)
1174 (save-restriction
1175 (widen)
1176 (save-excursion
1177 (mapc (lambda (fn)
1178 (setq new-region (funcall fn new-beg new-end))
1179 (setq new-beg (car new-region) new-end (cdr new-region)))
1180 c-before-context-fontification-functions))))
1181 (funcall c-standard-font-lock-fontify-region-function
1182 new-beg new-end verbose)))
1183
1117(defun c-after-font-lock-init () 1184(defun c-after-font-lock-init ()
1118 ;; Put on `font-lock-mode-hook'. 1185 ;; Put on `font-lock-mode-hook'. This function ensures our after-change
1186 ;; function will get excuted before the font-lock one. Amongst other
1187 ;; things.
1119 (remove-hook 'after-change-functions 'c-after-change t) 1188 (remove-hook 'after-change-functions 'c-after-change t)
1120 (add-hook 'after-change-functions 'c-after-change nil t)) 1189 (add-hook 'after-change-functions 'c-after-change nil t)
1190 (setq c-standard-font-lock-fontify-region-function
1191 (default-value 'font-lock-fontify-region-function)))
1121 1192
1122(defun c-font-lock-init () 1193(defun c-font-lock-init ()
1123 "Set up the font-lock variables for using the font-lock support in CC Mode. 1194 "Set up the font-lock variables for using the font-lock support in CC Mode.
1124This does not load the font-lock package. Use after 1195This does not load the font-lock package. Use after
1125`c-basic-common-init' and after cc-fonts has been loaded." 1196`c-basic-common-init' and after cc-fonts has been loaded.
1197This function is called from `c-common-init', once per mode initialization."
1126 1198
1127 (set (make-local-variable 'font-lock-defaults) 1199 (set (make-local-variable 'font-lock-defaults)
1128 `(,(if (c-major-mode-is 'awk-mode) 1200 `(,(if (c-major-mode-is 'awk-mode)
@@ -1136,6 +1208,10 @@ This does not load the font-lock package. Use after
1136 c-beginning-of-syntax 1208 c-beginning-of-syntax
1137 (font-lock-mark-block-function 1209 (font-lock-mark-block-function
1138 . c-mark-function))) 1210 . c-mark-function)))
1211
1212 (make-local-variable 'font-lock-fontify-region-function)
1213 (setq font-lock-fontify-region-function 'c-font-lock-fontify-region)
1214
1139 (if (featurep 'xemacs) 1215 (if (featurep 'xemacs)
1140 (make-local-hook 'font-lock-mode-hook)) 1216 (make-local-hook 'font-lock-mode-hook))
1141 (add-hook 'font-lock-mode-hook 'c-after-font-lock-init nil t)) 1217 (add-hook 'font-lock-mode-hook 'c-after-font-lock-init nil t))