aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/font-lock.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/font-lock.el')
-rw-r--r--lisp/font-lock.el177
1 files changed, 152 insertions, 25 deletions
diff --git a/lisp/font-lock.el b/lisp/font-lock.el
index f001a0bfaac..093780c3914 100644
--- a/lisp/font-lock.el
+++ b/lisp/font-lock.el
@@ -893,7 +893,11 @@ The value of this variable is used when Font Lock mode is turned on."
893 (set (make-local-variable 'font-lock-fontified) t) 893 (set (make-local-variable 'font-lock-fontified) t)
894 ;; Use jit-lock. 894 ;; Use jit-lock.
895 (jit-lock-register 'font-lock-fontify-region 895 (jit-lock-register 'font-lock-fontify-region
896 (not font-lock-keywords-only)))))) 896 (not font-lock-keywords-only))
897 ;; Tell jit-lock how we extend the region to refontify.
898 (add-hook 'jit-lock-after-change-extend-region-functions
899 'font-lock-extend-jit-lock-region-after-change
900 nil t)))))
897 901
898(defun font-lock-turn-off-thing-lock () 902(defun font-lock-turn-off-thing-lock ()
899 (cond ((and (boundp 'fast-lock-mode) fast-lock-mode) 903 (cond ((and (boundp 'fast-lock-mode) fast-lock-mode)
@@ -971,6 +975,21 @@ The value of this variable is used when Font Lock mode is turned on."
971;; directives correctly and cleanly. (It is the same problem as fontifying 975;; directives correctly and cleanly. (It is the same problem as fontifying
972;; multi-line strings and comments; regexps are not appropriate for the job.) 976;; multi-line strings and comments; regexps are not appropriate for the job.)
973 977
978(defvar font-lock-extend-after-change-region-function nil
979 "A function that determines the region to refontify after a change.
980
981This variable is either nil, or is a function that determines the
982region to refontify after a change.
983It is usually set by the major mode via `font-lock-defaults'.
984Font-lock calls this function after each buffer change.
985
986The function is given three parameters, the standard BEG, END, and OLD-LEN
987from `after-change-functions'. It should return either a cons of the beginning
988and end buffer positions \(in that order) of the region to refontify, or nil
989\(which directs the caller to fontify a default region).
990This function should preserve the match-data.
991The region it returns may start or end in the middle of a line.")
992
974(defun font-lock-fontify-buffer () 993(defun font-lock-fontify-buffer ()
975 "Fontify the current buffer the way the function `font-lock-mode' would." 994 "Fontify the current buffer the way the function `font-lock-mode' would."
976 (interactive) 995 (interactive)
@@ -1021,6 +1040,59 @@ The value of this variable is used when Font Lock mode is turned on."
1021Useful for things like RMAIL and Info where the whole buffer is not 1040Useful for things like RMAIL and Info where the whole buffer is not
1022a very meaningful entity to highlight.") 1041a very meaningful entity to highlight.")
1023 1042
1043
1044(defvar font-lock-beg) (defvar font-lock-end)
1045(defvar font-lock-extend-region-functions
1046 '(font-lock-extend-region-wholelines
1047 ;; This use of font-lock-multiline property is unreliable but is just
1048 ;; a handy heuristic: in case you don't have a function that does
1049 ;; /identification/ of multiline elements, you may still occasionally
1050 ;; discover them by accident (or you may /identify/ them but not in all
1051 ;; cases), in which case the font-lock-multiline property can help make
1052 ;; sure you will properly *re*identify them during refontification.
1053 font-lock-extend-region-multiline)
1054 "Special hook run just before proceeding to fontify a region.
1055This is used to allow major modes to help font-lock find safe buffer positions
1056as beginning and end of the fontified region. Its most common use is to solve
1057the problem of /identification/ of multiline elements by providing a function
1058that tries to find such elements and move the boundaries such that they do
1059not fall in the middle of one.
1060Each function is called with no argument; it is expected to adjust the
1061dynamically bound variables `font-lock-beg' and `font-lock-end'; and return
1062non-nil iff it did make such an adjustment.
1063These functions are run in turn repeatedly until they all return nil.
1064Put first the functions more likely to cause a change and cheaper to compute.")
1065;; Mark it as a special hook which doesn't use any global setting
1066;; (i.e. doesn't obey the element t in the buffer-local value).
1067(make-variable-buffer-local 'font-lock-extend-region-functions)
1068
1069(defun font-lock-extend-region-multiline ()
1070 "Move fontification boundaries away from any `font-lock-multiline' property."
1071 (let ((changed nil))
1072 (when (and (> font-lock-beg (point-min))
1073 (get-text-property (1- font-lock-beg) 'font-lock-multiline))
1074 (setq changed t)
1075 (setq font-lock-beg (or (previous-single-property-change
1076 font-lock-beg 'font-lock-multiline)
1077 (point-min))))
1078 ;;
1079 (when (get-text-property font-lock-end 'font-lock-multiline)
1080 (setq changed t)
1081 (setq font-lock-end (or (text-property-any font-lock-end (point-max)
1082 'font-lock-multiline nil)
1083 (point-max))))
1084 changed))
1085
1086
1087(defun font-lock-extend-region-wholelines ()
1088 "Move fontification boundaries to beginning of lines."
1089 (let ((changed nil))
1090 (goto-char font-lock-beg)
1091 (unless (bolp) (setq changed t font-lock-beg (line-beginning-position)))
1092 (goto-char font-lock-end)
1093 (unless (bolp) (setq changed t font-lock-end (line-beginning-position 2)))
1094 changed))
1095
1024(defun font-lock-default-fontify-region (beg end loudly) 1096(defun font-lock-default-fontify-region (beg end loudly)
1025 (save-buffer-state 1097 (save-buffer-state
1026 ((parse-sexp-lookup-properties 1098 ((parse-sexp-lookup-properties
@@ -1032,24 +1104,21 @@ a very meaningful entity to highlight.")
1032 ;; Use the fontification syntax table, if any. 1104 ;; Use the fontification syntax table, if any.
1033 (when font-lock-syntax-table 1105 (when font-lock-syntax-table
1034 (set-syntax-table font-lock-syntax-table)) 1106 (set-syntax-table font-lock-syntax-table))
1035 (goto-char beg) 1107 ;; Extend the region to fontify so that it starts and ends at
1036 (setq beg (line-beginning-position)) 1108 ;; safe places.
1037 ;; check to see if we should expand the beg/end area for 1109 (let ((funs font-lock-extend-region-functions)
1038 ;; proper multiline matches 1110 (font-lock-beg beg)
1039 (when (and (> beg (point-min)) 1111 (font-lock-end end))
1040 (get-text-property (1- beg) 'font-lock-multiline)) 1112 (while funs
1041 ;; We are just after or in a multiline match. 1113 (setq funs (if (or (not (funcall (car funs)))
1042 (setq beg (or (previous-single-property-change 1114 (eq funs font-lock-extend-region-functions))
1043 beg 'font-lock-multiline) 1115 (cdr funs)
1044 (point-min))) 1116 ;; If there's been a change, we should go through
1045 (goto-char beg) 1117 ;; the list again since this new position may
1046 (setq beg (line-beginning-position))) 1118 ;; warrant a different answer from one of the fun
1047 (setq end (or (text-property-any end (point-max) 1119 ;; we've already seen.
1048 'font-lock-multiline nil) 1120 font-lock-extend-region-functions)))
1049 (point-max))) 1121 (setq beg font-lock-beg end font-lock-end))
1050 (goto-char end)
1051 ;; Round up to a whole line.
1052 (unless (bolp) (setq end (line-beginning-position 2)))
1053 ;; Now do the fontification. 1122 ;; Now do the fontification.
1054 (font-lock-unfontify-region beg end) 1123 (font-lock-unfontify-region beg end)
1055 (when font-lock-syntactic-keywords 1124 (when font-lock-syntactic-keywords
@@ -1083,19 +1152,77 @@ what properties to clear before refontifying a region.")
1083 1152
1084;; Called when any modification is made to buffer text. 1153;; Called when any modification is made to buffer text.
1085(defun font-lock-after-change-function (beg end old-len) 1154(defun font-lock-after-change-function (beg end old-len)
1086 (let ((inhibit-point-motion-hooks t) 1155 (save-excursion
1087 (inhibit-quit t) 1156 (let ((inhibit-point-motion-hooks t)
1088 (region (font-lock-extend-region beg end old-len))) 1157 (inhibit-quit t)
1089 (save-excursion 1158 (region (if font-lock-extend-after-change-region-function
1159 (funcall font-lock-extend-after-change-region-function
1160 beg end old-len))))
1090 (save-match-data 1161 (save-match-data
1091 (if region 1162 (if region
1092 ;; Fontify the region the major mode has specified. 1163 ;; Fontify the region the major mode has specified.
1093 (setq beg (car region) end (cdr region)) 1164 (setq beg (car region) end (cdr region))
1094 ;; Fontify the whole lines which enclose the region. 1165 ;; Fontify the whole lines which enclose the region.
1095 (setq beg (progn (goto-char beg) (line-beginning-position)) 1166 ;; Actually, this is not needed because
1096 end (progn (goto-char end) (line-beginning-position 2)))) 1167 ;; font-lock-default-fontify-region already rounds up to a whole
1168 ;; number of lines.
1169 ;; (setq beg (progn (goto-char beg) (line-beginning-position))
1170 ;; end (progn (goto-char end) (line-beginning-position 2)))
1171 )
1097 (font-lock-fontify-region beg end))))) 1172 (font-lock-fontify-region beg end)))))
1098 1173
1174(defvar jit-lock-start) (defvar jit-lock-end)
1175(defun font-lock-extend-jit-lock-region-after-change (beg end old-len)
1176 "Function meant for `jit-lock-after-change-extend-region-functions'.
1177This function does 2 things:
1178- extend the region so that it not only includes the part that was modified
1179 but also the surrounding text whose highlighting may change as a consequence.
1180- anticipate (part of) the region extension that will happen later in
1181 `font-lock-default-fontify-region', in order to avoid the need for
1182 double-redisplay in `jit-lock-fontify-now'."
1183 (save-excursion
1184 ;; First extend the region as font-lock-after-change-function would.
1185 (let ((region (if font-lock-extend-after-change-region-function
1186 (funcall font-lock-extend-after-change-region-function
1187 beg end old-len))))
1188 (if region
1189 (setq beg (min jit-lock-start (car region))
1190 end (max jit-lock-end (cdr region))))
1191 ;; Then extend the region obeying font-lock-multiline properties,
1192 ;; indicating which part of the buffer needs to be refontified.
1193 ;; !!! This is the *main* user of font-lock-multiline property !!!
1194 ;; font-lock-after-change-function could/should also do that, but it
1195 ;; doesn't need to because font-lock-default-fontify-region does
1196 ;; it anyway. Here OTOH we have no guarantee that
1197 ;; font-lock-default-fontify-region will be executed on this region
1198 ;; any time soon.
1199 ;; Note: contrary to font-lock-default-fontify-region, we do not do
1200 ;; any loop here because we are not looking for a safe spot: we just
1201 ;; mark the text whose appearance may need to change as a result of
1202 ;; the buffer modification.
1203 (when (and (> beg (point-min))
1204 (get-text-property (1- beg) 'font-lock-multiline))
1205 (setq beg (or (previous-single-property-change
1206 beg 'font-lock-multiline)
1207 (point-min))))
1208 (setq end (or (text-property-any end (point-max)
1209 'font-lock-multiline nil)
1210 (point-max)))
1211 ;; Finally, pre-enlarge the region to a whole number of lines, to try
1212 ;; and anticipate what font-lock-default-fontify-region will do, so as to
1213 ;; avoid double-redisplay.
1214 ;; We could just run `font-lock-extend-region-functions', but since
1215 ;; the only purpose is to avoid the double-redisplay, we prefer to
1216 ;; do here only the part that is cheap and most likely to be useful.
1217 (when (memq 'font-lock-extend-region-wholelines
1218 font-lock-extend-region-functions)
1219 (goto-char beg)
1220 (forward-line 0)
1221 (setq jit-lock-start (min jit-lock-start (point)))
1222 (goto-char end)
1223 (forward-line 1)
1224 (setq jit-lock-end (max jit-lock-end (point)))))))
1225
1099(defun font-lock-fontify-block (&optional arg) 1226(defun font-lock-fontify-block (&optional arg)
1100 "Fontify some lines the way `font-lock-fontify-buffer' would. 1227 "Fontify some lines the way `font-lock-fontify-buffer' would.
1101The lines could be a function or paragraph, or a specified number of lines. 1228The lines could be a function or paragraph, or a specified number of lines.