aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2015-09-11 20:00:05 -0400
committerStefan Monnier2015-09-11 20:00:05 -0400
commit3928ef2dd5b8febf3b1d9c1bfb22af3698d16bea (patch)
tree78c6b4d9eac102e97b6ef2a83edadef0c3152686
parent818f06eaa72d8e4f9ba314c1c2855613bf89f396 (diff)
downloademacs-3928ef2dd5b8febf3b1d9c1bfb22af3698d16bea.tar.gz
emacs-3928ef2dd5b8febf3b1d9c1bfb22af3698d16bea.zip
Merge syntax-propertize--done and parse-sexp-propertize-done
* lisp/emacs-lisp/syntax.el (syntax-propertize--done): Remove. (syntax-propertize): Set syntax-propertize--done even if syntax-propertize-function is nil. Avoid recursive invocations. (syntax-propertize-chunks): New var. (internal--syntax-propertize): Use it. Rename from syntax--jit-propertize. Simplify. (parse-sexp-propertize-function): Don't set any more. * src/syntax.c (SETUP_SYNTAX_TABLE): Call parse_sexp_propertize as needed. (parse_sexp_propertize): Don't assume charpos is not yet propertized. Call Qinternal__syntax_propertize instead of Vparse_sexp_propertize_function. Truncate e_property if needed. (update_syntax_table_forward): Streamline. (syms_of_syntax): Define Qinternal__syntax_propertize. (syntax_propertize__done): Rename from parse_sexp_propertize_done.
-rw-r--r--lisp/emacs-lisp/syntax.el105
-rw-r--r--src/syntax.c113
-rw-r--r--src/syntax.h5
3 files changed, 113 insertions, 110 deletions
diff --git a/lisp/emacs-lisp/syntax.el b/lisp/emacs-lisp/syntax.el
index 6c9cba3e563..51019254943 100644
--- a/lisp/emacs-lisp/syntax.el
+++ b/lisp/emacs-lisp/syntax.el
@@ -106,10 +106,6 @@ Put first the functions more likely to cause a change and cheaper to compute.")
106 (point-max)))) 106 (point-max))))
107 (cons beg end)) 107 (cons beg end))
108 108
109(defvar syntax-propertize--done -1
110 "Position up to which syntax-table properties have been set.")
111(make-variable-buffer-local 'syntax-propertize--done)
112
113(defun syntax-propertize--shift-groups (re n) 109(defun syntax-propertize--shift-groups (re n)
114 (replace-regexp-in-string 110 (replace-regexp-in-string
115 "\\\\(\\?\\([0-9]+\\):" 111 "\\\\(\\?\\([0-9]+\\):"
@@ -290,54 +286,59 @@ The return value is a function suitable for `syntax-propertize-function'."
290 286
291(defun syntax-propertize (pos) 287(defun syntax-propertize (pos)
292 "Ensure that syntax-table properties are set until POS." 288 "Ensure that syntax-table properties are set until POS."
293 (when (and syntax-propertize-function 289 (when (< syntax-propertize--done pos)
294 (< syntax-propertize--done pos)) 290 (if (null syntax-propertize-function)
295 ;; (message "Needs to syntax-propertize from %s to %s" 291 (setq syntax-propertize--done (max (point-max) pos))
296 ;; syntax-propertize--done pos) 292 ;; (message "Needs to syntax-propertize from %s to %s"
297 (set (make-local-variable 'parse-sexp-lookup-properties) t) 293 ;; syntax-propertize--done pos)
298 (save-excursion 294 (set (make-local-variable 'parse-sexp-lookup-properties) t)
299 (with-silent-modifications 295 (save-excursion
300 (make-local-variable 'parse-sexp-propertize-done) ;Just in case! 296 (with-silent-modifications
301 (let* ((start (max syntax-propertize--done (point-min))) 297 (make-local-variable 'syntax-propertize--done) ;Just in case!
302 ;; Avoid recursion! 298 (let* ((start (max (min syntax-propertize--done (point-max))
303 (parse-sexp-propertize-done most-positive-fixnum) 299 (point-min)))
304 (end (max pos 300 (end (max pos
305 (min (point-max) 301 (min (point-max)
306 (+ start syntax-propertize-chunk-size)))) 302 (+ start syntax-propertize-chunk-size))))
307 (funs syntax-propertize-extend-region-functions)) 303 (funs syntax-propertize-extend-region-functions))
308 (while funs 304 (while funs
309 (let ((new (funcall (pop funs) start end))) 305 (let ((new (funcall (pop funs) start end))
310 (if (or (null new) 306 ;; Avoid recursion!
311 (and (>= (car new) start) (<= (cdr new) end))) 307 (syntax-propertize--done most-positive-fixnum))
312 nil 308 (if (or (null new)
313 (setq start (car new)) 309 (and (>= (car new) start) (<= (cdr new) end)))
314 (setq end (cdr new)) 310 nil
315 ;; If there's been a change, we should go through the 311 (setq start (car new))
316 ;; list again since this new position may 312 (setq end (cdr new))
317 ;; warrant a different answer from one of the funs we've 313 ;; If there's been a change, we should go through the
318 ;; already seen. 314 ;; list again since this new position may
319 (unless (eq funs 315 ;; warrant a different answer from one of the funs we've
320 (cdr syntax-propertize-extend-region-functions)) 316 ;; already seen.
321 (setq funs syntax-propertize-extend-region-functions))))) 317 (unless (eq funs
322 ;; Move the limit before calling the function, so the function 318 (cdr syntax-propertize-extend-region-functions))
323 ;; can use syntax-ppss. 319 (setq funs syntax-propertize-extend-region-functions)))))
324 (setq syntax-propertize--done end) 320 ;; Move the limit before calling the function, so the function
325 ;; (message "syntax-propertizing from %s to %s" start end) 321 ;; can use syntax-ppss.
326 (remove-text-properties start end 322 (setq syntax-propertize--done end)
327 '(syntax-table nil syntax-multiline nil)) 323 ;; (message "syntax-propertizing from %s to %s" start end)
328 (funcall syntax-propertize-function start end)))))) 324 (remove-text-properties start end
329 325 '(syntax-table nil syntax-multiline nil))
330;;; Link syntax-propertize with the new parse-sexp-propertize. 326 ;; Avoid recursion!
331 327 (let ((syntax-propertize--done most-positive-fixnum))
332(setq-default parse-sexp-propertize-function #'syntax--jit-propertize) 328 (funcall syntax-propertize-function start end))))))))
333(defun syntax--jit-propertize (charpos) 329
334 (if (not syntax-propertize-function) 330;;; Link syntax-propertize with syntax.c.
335 (setq parse-sexp-propertize-done (1+ (point-max))) 331
336 (syntax-propertize charpos) 332(defvar syntax-propertize-chunks
337 (setq parse-sexp-propertize-done 333 ;; We're not sure how far we'll go. In my tests, using chunks of 20000
338 (if (= (point-max) syntax-propertize--done) 334 ;; brings to overhead to something negligible. Passing ‘charpos’ directly
339 (1+ (point-max)) 335 ;; also works (basically works line-by-line) but results in an overhead which
340 syntax-propertize--done)))) 336 ;; I thought was a bit too high (like around 50%).
337 2000)
338
339(defun internal--syntax-propertize (charpos)
340 ;; FIXME: Called directly from C.
341 (syntax-propertize (min (+ syntax-propertize-chunks charpos) (point-max))))
341 342
342;;; Incrementally compute and memoize parser state. 343;;; Incrementally compute and memoize parser state.
343 344
diff --git a/src/syntax.c b/src/syntax.c
index fcd6d017d33..de45c50ca3f 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -181,6 +181,7 @@ static void scan_sexps_forward (struct lisp_parse_state *,
181 ptrdiff_t, ptrdiff_t, ptrdiff_t, EMACS_INT, 181 ptrdiff_t, ptrdiff_t, ptrdiff_t, EMACS_INT,
182 bool, Lisp_Object, int); 182 bool, Lisp_Object, int);
183static bool in_classes (int, Lisp_Object); 183static bool in_classes (int, Lisp_Object);
184static void parse_sexp_propertize (ptrdiff_t charpos);
184 185
185/* This setter is used only in this file, so it can be private. */ 186/* This setter is used only in this file, so it can be private. */
186static void 187static void
@@ -247,12 +248,12 @@ SETUP_SYNTAX_TABLE (ptrdiff_t from, ptrdiff_t count)
247 gl_state.offset = 0; 248 gl_state.offset = 0;
248 if (parse_sexp_lookup_properties) 249 if (parse_sexp_lookup_properties)
249 { 250 {
250 if (count > 0 || from > BEGV) 251 if (count > 0)
251 update_syntax_table (count > 0 ? from : from - 1, count, true, Qnil); 252 update_syntax_table_forward (from, true, Qnil);
252 if (gl_state.e_property > parse_sexp_propertize_done) 253 else if (from > BEGV)
253 { 254 {
254 gl_state.e_property = parse_sexp_propertize_done; 255 update_syntax_table (from - 1, count, true, Qnil);
255 gl_state.e_property_truncated = true; 256 parse_sexp_propertize (from - 1);
256 } 257 }
257 } 258 }
258} 259}
@@ -478,33 +479,44 @@ update_syntax_table (ptrdiff_t charpos, EMACS_INT count, bool init,
478static void 479static void
479parse_sexp_propertize (ptrdiff_t charpos) 480parse_sexp_propertize (ptrdiff_t charpos)
480{ 481{
481 EMACS_INT modiffs = CHARS_MODIFF; 482 EMACS_INT zv = ZV;
482 safe_call1 (Vparse_sexp_propertize_function, 483 if (syntax_propertize__done <= charpos
483 make_number (1 + charpos)); 484 && syntax_propertize__done < zv)
484 if (modiffs != CHARS_MODIFF) 485 {
485 error ("parse-sexp-propertize-function modified the buffer!"); 486 EMACS_INT modiffs = CHARS_MODIFF;
486 if (parse_sexp_propertize_done <= charpos) 487 safe_call1 (Qinternal__syntax_propertize,
487 error ("parse-sexp-propertize-function did not move" 488 make_number (min (zv, 1 + charpos)));
488 " parse-sexp-propertize-done"); 489 if (modiffs != CHARS_MODIFF)
489 SETUP_SYNTAX_TABLE (charpos, 1); 490 error ("parse-sexp-propertize-function modified the buffer!");
491 if (syntax_propertize__done <= charpos
492 && syntax_propertize__done < zv)
493 error ("parse-sexp-propertize-function did not move"
494 " syntax-propertize--done");
495 SETUP_SYNTAX_TABLE (charpos, 1);
496 }
497 else if (gl_state.e_property > syntax_propertize__done)
498 {
499 gl_state.e_property = syntax_propertize__done;
500 gl_state.e_property_truncated = true;
501 }
490} 502}
491 503
492void 504void
493update_syntax_table_forward (ptrdiff_t charpos, bool init, 505update_syntax_table_forward (ptrdiff_t charpos, bool init,
494 Lisp_Object object) 506 Lisp_Object object)
495{ 507{
496 if (!(gl_state.e_property_truncated)) 508 if (gl_state.e_property_truncated)
497 update_syntax_table (charpos, 1, init, object);
498 if ((gl_state.e_property > parse_sexp_propertize_done
499 || gl_state.e_property_truncated)
500 && NILP (object))
501 { 509 {
502 if (parse_sexp_propertize_done > charpos) 510 eassert (NILP (object));
503 { 511 eassert (charpos >= gl_state.e_property);
504 gl_state.e_property = parse_sexp_propertize_done; 512 eassert (charpos >= syntax_propertize__done);
505 gl_state.e_property_truncated = true; 513 parse_sexp_propertize (charpos);
506 } 514 }
507 else 515 else
516 {
517 update_syntax_table (charpos, 1, init, object);
518 if (gl_state.e_property > syntax_propertize__done
519 && NILP (object))
508 parse_sexp_propertize (charpos); 520 parse_sexp_propertize (charpos);
509 } 521 }
510} 522}
@@ -2332,13 +2344,13 @@ forw_comment (ptrdiff_t from, ptrdiff_t from_byte, ptrdiff_t stop,
2332 && SYNTAX_FLAGS_COMMENT_STYLE (syntax, 0) == style 2344 && SYNTAX_FLAGS_COMMENT_STYLE (syntax, 0) == style
2333 && (SYNTAX_FLAGS_COMMENT_NESTED (syntax) ? 2345 && (SYNTAX_FLAGS_COMMENT_NESTED (syntax) ?
2334 (nesting > 0 && --nesting == 0) : nesting < 0)) 2346 (nesting > 0 && --nesting == 0) : nesting < 0))
2335 /* we have encountered a comment end of the same style 2347 /* We have encountered a comment end of the same style
2336 as the comment sequence which began this comment 2348 as the comment sequence which began this comment
2337 section */ 2349 section. */
2338 break; 2350 break;
2339 if (code == Scomment_fence 2351 if (code == Scomment_fence
2340 && style == ST_COMMENT_STYLE) 2352 && style == ST_COMMENT_STYLE)
2341 /* we have encountered a comment end of the same style 2353 /* We have encountered a comment end of the same style
2342 as the comment sequence which began this comment 2354 as the comment sequence which began this comment
2343 section. */ 2355 section. */
2344 break; 2356 break;
@@ -2346,8 +2358,8 @@ forw_comment (ptrdiff_t from, ptrdiff_t from_byte, ptrdiff_t stop,
2346 && code == Scomment 2358 && code == Scomment
2347 && SYNTAX_FLAGS_COMMENT_NESTED (syntax) 2359 && SYNTAX_FLAGS_COMMENT_NESTED (syntax)
2348 && SYNTAX_FLAGS_COMMENT_STYLE (syntax, 0) == style) 2360 && SYNTAX_FLAGS_COMMENT_STYLE (syntax, 0) == style)
2349 /* we have encountered a nested comment of the same style 2361 /* We have encountered a nested comment of the same style
2350 as the comment sequence which began this comment section */ 2362 as the comment sequence which began this comment section. */
2351 nesting++; 2363 nesting++;
2352 INC_BOTH (from, from_byte); 2364 INC_BOTH (from, from_byte);
2353 UPDATE_SYNTAX_TABLE_FORWARD (from); 2365 UPDATE_SYNTAX_TABLE_FORWARD (from);
@@ -2363,9 +2375,8 @@ forw_comment (ptrdiff_t from, ptrdiff_t from_byte, ptrdiff_t stop,
2363 ? nesting > 0 : nesting < 0)) 2375 ? nesting > 0 : nesting < 0))
2364 { 2376 {
2365 if (--nesting <= 0) 2377 if (--nesting <= 0)
2366 /* we have encountered a comment end of the same style 2378 /* We have encountered a comment end of the same style
2367 as the comment sequence which began this comment 2379 as the comment sequence which began this comment section. */
2368 section */
2369 break; 2380 break;
2370 else 2381 else
2371 { 2382 {
@@ -2382,9 +2393,8 @@ forw_comment (ptrdiff_t from, ptrdiff_t from_byte, ptrdiff_t stop,
2382 && SYNTAX_FLAGS_COMSTART_SECOND (other_syntax)) 2393 && SYNTAX_FLAGS_COMSTART_SECOND (other_syntax))
2383 && (SYNTAX_FLAGS_COMMENT_NESTED (syntax) || 2394 && (SYNTAX_FLAGS_COMMENT_NESTED (syntax) ||
2384 SYNTAX_FLAGS_COMMENT_NESTED (other_syntax))) 2395 SYNTAX_FLAGS_COMMENT_NESTED (other_syntax)))
2385 /* we have encountered a nested comment of the same style 2396 /* We have encountered a nested comment of the same style
2386 as the comment sequence which began this comment 2397 as the comment sequence which began this comment section. */
2387 section */
2388 { 2398 {
2389 INC_BOTH (from, from_byte); 2399 INC_BOTH (from, from_byte);
2390 UPDATE_SYNTAX_TABLE_FORWARD (from); 2400 UPDATE_SYNTAX_TABLE_FORWARD (from);
@@ -2628,9 +2638,9 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
2628 bool quoted; 2638 bool quoted;
2629 bool mathexit = 0; 2639 bool mathexit = 0;
2630 enum syntaxcode code; 2640 enum syntaxcode code;
2631 EMACS_INT min_depth = depth; /* Err out if depth gets less than this. */ 2641 EMACS_INT min_depth = depth; /* Err out if depth gets less than this. */
2632 int comstyle = 0; /* style of comment encountered */ 2642 int comstyle = 0; /* Style of comment encountered. */
2633 bool comnested = 0; /* whether the comment is nestable or not */ 2643 bool comnested = 0; /* Whether the comment is nestable or not. */
2634 ptrdiff_t temp_pos; 2644 ptrdiff_t temp_pos;
2635 EMACS_INT last_good = from; 2645 EMACS_INT last_good = from;
2636 bool found; 2646 bool found;
@@ -2674,11 +2684,11 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
2674 SYNTAX_FLAGS_COMSTART_SECOND (other_syntax)) 2684 SYNTAX_FLAGS_COMSTART_SECOND (other_syntax))
2675 && parse_sexp_ignore_comments) 2685 && parse_sexp_ignore_comments)
2676 { 2686 {
2677 /* we have encountered a comment start sequence and we 2687 /* We have encountered a comment start sequence and we
2678 are ignoring all text inside comments. We must record 2688 are ignoring all text inside comments. We must record
2679 the comment style this sequence begins so that later, 2689 the comment style this sequence begins so that later,
2680 only a comment end of the same style actually ends 2690 only a comment end of the same style actually ends
2681 the comment section */ 2691 the comment section. */
2682 code = Scomment; 2692 code = Scomment;
2683 comstyle = SYNTAX_FLAGS_COMMENT_STYLE (other_syntax, syntax); 2693 comstyle = SYNTAX_FLAGS_COMMENT_STYLE (other_syntax, syntax);
2684 comnested |= SYNTAX_FLAGS_COMMENT_NESTED (other_syntax); 2694 comnested |= SYNTAX_FLAGS_COMMENT_NESTED (other_syntax);
@@ -2696,7 +2706,7 @@ scan_lists (EMACS_INT from, EMACS_INT count, EMACS_INT depth, bool sexpflag)
2696 if (from == stop) 2706 if (from == stop)
2697 goto lose; 2707 goto lose;
2698 INC_BOTH (from, from_byte); 2708 INC_BOTH (from, from_byte);
2699 /* treat following character as a word constituent */ 2709 /* Treat following character as a word constituent. */
2700 case Sword: 2710 case Sword:
2701 case Ssymbol: 2711 case Ssymbol:
2702 if (depth || !sexpflag) break; 2712 if (depth || !sexpflag) break;
@@ -3501,7 +3511,7 @@ Sixth arg COMMENTSTOP non-nil means stop at the start of a comment.
3501 target = XINT (targetdepth); 3511 target = XINT (targetdepth);
3502 } 3512 }
3503 else 3513 else
3504 target = TYPE_MINIMUM (EMACS_INT); /* We won't reach this depth */ 3514 target = TYPE_MINIMUM (EMACS_INT); /* We won't reach this depth. */
3505 3515
3506 validate_region (&from, &to); 3516 validate_region (&from, &to);
3507 scan_sexps_forward (&state, XINT (from), CHAR_TO_BYTE (XINT (from)), 3517 scan_sexps_forward (&state, XINT (from), CHAR_TO_BYTE (XINT (from)),
@@ -3650,19 +3660,10 @@ Otherwise, that text property is simply ignored.
3650See the info node `(elisp)Syntax Properties' for a description of the 3660See the info node `(elisp)Syntax Properties' for a description of the
3651`syntax-table' property. */); 3661`syntax-table' property. */);
3652 3662
3653 DEFVAR_INT ("parse-sexp-propertize-done", parse_sexp_propertize_done, 3663 DEFVAR_INT ("syntax-propertize--done", syntax_propertize__done,
3654 doc: /* Position up to which syntax-table properties have been set. */); 3664 doc: /* Position up to which syntax-table properties have been set. */);
3655 parse_sexp_propertize_done = -1; 3665 syntax_propertize__done = -1;
3656 3666 DEFSYM (Qinternal__syntax_propertize, "internal--syntax-propertize");
3657 DEFVAR_LISP ("parse-sexp-propertize-function",
3658 Vparse_sexp_propertize_function,
3659 doc: /* Function to set the `syntax-table' text property.
3660Called with one argument, the position at which the property is needed.
3661After running it, `parse-sexp-propertize-done' should be strictly greater
3662than the argument passed. */);
3663 /* Note: Qnil is a temporary (and invalid) value; it will be properly set in
3664 syntax.el. */
3665 Vparse_sexp_propertize_function = Qnil;
3666 3667
3667 words_include_escapes = 0; 3668 words_include_escapes = 0;
3668 DEFVAR_BOOL ("words-include-escapes", words_include_escapes, 3669 DEFVAR_BOOL ("words-include-escapes", words_include_escapes,
diff --git a/src/syntax.h b/src/syntax.h
index 9c44181155f..34b652ba9c8 100644
--- a/src/syntax.h
+++ b/src/syntax.h
@@ -174,9 +174,10 @@ SYNTAX_TABLE_BYTE_TO_CHAR (ptrdiff_t bytepos)
174 174
175INLINE void 175INLINE void
176UPDATE_SYNTAX_TABLE_FORWARD (ptrdiff_t charpos) 176UPDATE_SYNTAX_TABLE_FORWARD (ptrdiff_t charpos)
177{ 177{ /* Performs just-in-time syntax-propertization. */
178 if (parse_sexp_lookup_properties && charpos >= gl_state.e_property) 178 if (parse_sexp_lookup_properties && charpos >= gl_state.e_property)
179 update_syntax_table_forward (charpos + gl_state.offset, false, gl_state.object); 179 update_syntax_table_forward (charpos + gl_state.offset,
180 false, gl_state.object);
180} 181}
181 182
182/* Make syntax table state (gl_state) good for CHARPOS, assuming it is 183/* Make syntax table state (gl_state) good for CHARPOS, assuming it is