diff options
| author | Stefan Monnier | 2015-09-09 15:14:52 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2015-09-09 15:14:52 -0400 |
| commit | ab21f61a552f038485d40218dfd94a16b843eb52 (patch) | |
| tree | 876a849cbfffc86a355480c17f93589fab012f82 /src | |
| parent | 74baea086d1ea606bae99bfc8c9195c21d5530fc (diff) | |
| download | emacs-ab21f61a552f038485d40218dfd94a16b843eb52.tar.gz emacs-ab21f61a552f038485d40218dfd94a16b843eb52.zip | |
Make syntax.c call syntax-propertize on demand
* lisp/emacs-lisp/syntax.el (syntax--jit-propertize): New function.
(parse-sexp-propertize-function): Use it.
(syntax-propertize): Disable parse-sexp-propertize-function.
* src/syntax.c (parse_sexp_propertize, update_syntax_table_forward):
New functions.
(syms_of_syntax): New vars `parse-sexp-propertize-done' and
`parse-sexp-propertize-function'.
* src/syntax.h (struct gl_state_s): Add `e_property_truncated' field.
(UPDATE_SYNTAX_TABLE_FORWARD): Use update_syntax_table_forward.
(SETUP_BUFFER_SYNTAX_TABLE): Set e_property_truncated.
* lisp/progmodes/elisp-mode.el (elisp-byte-code-syntax-propertize):
Don't assume `point' is set.
Diffstat (limited to 'src')
| -rw-r--r-- | src/syntax.c | 78 | ||||
| -rw-r--r-- | src/syntax.h | 30 |
2 files changed, 84 insertions, 24 deletions
diff --git a/src/syntax.c b/src/syntax.c index dc82210e79d..776ff984369 100644 --- a/src/syntax.c +++ b/src/syntax.c | |||
| @@ -247,7 +247,7 @@ SETUP_SYNTAX_TABLE (ptrdiff_t from, ptrdiff_t count) | |||
| 247 | gl_state.offset = 0; | 247 | gl_state.offset = 0; |
| 248 | if (parse_sexp_lookup_properties) | 248 | if (parse_sexp_lookup_properties) |
| 249 | if (count > 0 || from > BEGV) | 249 | if (count > 0 || from > BEGV) |
| 250 | update_syntax_table (count > 0 ? from : from - 1, count, 1, Qnil); | 250 | update_syntax_table (count > 0 ? from : from - 1, count, true, Qnil); |
| 251 | } | 251 | } |
| 252 | 252 | ||
| 253 | /* Same as above, but in OBJECT. If OBJECT is nil, use current buffer. | 253 | /* Same as above, but in OBJECT. If OBJECT is nil, use current buffer. |
| @@ -313,7 +313,7 @@ update_syntax_table (ptrdiff_t charpos, EMACS_INT count, bool init, | |||
| 313 | { | 313 | { |
| 314 | Lisp_Object tmp_table; | 314 | Lisp_Object tmp_table; |
| 315 | int cnt = 0; | 315 | int cnt = 0; |
| 316 | bool invalidate = 1; | 316 | bool invalidate = true; |
| 317 | INTERVAL i; | 317 | INTERVAL i; |
| 318 | 318 | ||
| 319 | if (init) | 319 | if (init) |
| @@ -323,7 +323,7 @@ update_syntax_table (ptrdiff_t charpos, EMACS_INT count, bool init, | |||
| 323 | gl_state.stop = gl_state.e_property; | 323 | gl_state.stop = gl_state.e_property; |
| 324 | i = interval_of (charpos, object); | 324 | i = interval_of (charpos, object); |
| 325 | gl_state.backward_i = gl_state.forward_i = i; | 325 | gl_state.backward_i = gl_state.forward_i = i; |
| 326 | invalidate = 0; | 326 | invalidate = false; |
| 327 | if (!i) | 327 | if (!i) |
| 328 | return; | 328 | return; |
| 329 | /* interval_of updates only ->position of the return value, so | 329 | /* interval_of updates only ->position of the return value, so |
| @@ -359,7 +359,7 @@ update_syntax_table (ptrdiff_t charpos, EMACS_INT count, bool init, | |||
| 359 | i = update_interval (i, charpos); | 359 | i = update_interval (i, charpos); |
| 360 | if (INTERVAL_LAST_POS (i) != gl_state.b_property) | 360 | if (INTERVAL_LAST_POS (i) != gl_state.b_property) |
| 361 | { | 361 | { |
| 362 | invalidate = 0; | 362 | invalidate = false; |
| 363 | gl_state.forward_i = i; | 363 | gl_state.forward_i = i; |
| 364 | gl_state.e_property = INTERVAL_LAST_POS (i) - gl_state.offset; | 364 | gl_state.e_property = INTERVAL_LAST_POS (i) - gl_state.offset; |
| 365 | } | 365 | } |
| @@ -372,7 +372,7 @@ update_syntax_table (ptrdiff_t charpos, EMACS_INT count, bool init, | |||
| 372 | i = update_interval (i, charpos); | 372 | i = update_interval (i, charpos); |
| 373 | if (i->position != gl_state.e_property) | 373 | if (i->position != gl_state.e_property) |
| 374 | { | 374 | { |
| 375 | invalidate = 0; | 375 | invalidate = false; |
| 376 | gl_state.backward_i = i; | 376 | gl_state.backward_i = i; |
| 377 | gl_state.b_property = i->position - gl_state.offset; | 377 | gl_state.b_property = i->position - gl_state.offset; |
| 378 | } | 378 | } |
| @@ -460,14 +460,56 @@ update_syntax_table (ptrdiff_t charpos, EMACS_INT count, bool init, | |||
| 460 | } | 460 | } |
| 461 | eassert (i == NULL); /* This property goes to the end. */ | 461 | eassert (i == NULL); /* This property goes to the end. */ |
| 462 | if (count > 0) | 462 | if (count > 0) |
| 463 | gl_state.e_property = gl_state.stop; | 463 | { |
| 464 | gl_state.e_property = gl_state.stop; | ||
| 465 | gl_state.forward_i = i; | ||
| 466 | } | ||
| 464 | else | 467 | else |
| 465 | gl_state.b_property = gl_state.start; | 468 | gl_state.b_property = gl_state.start; |
| 466 | } | 469 | } |
| 470 | |||
| 471 | static void | ||
| 472 | parse_sexp_propertize (ptrdiff_t charpos) | ||
| 473 | { | ||
| 474 | EMACS_INT modiffs = CHARS_MODIFF; | ||
| 475 | safe_call1 (Vparse_sexp_propertize_function, | ||
| 476 | make_number (1 + charpos)); | ||
| 477 | if (modiffs != CHARS_MODIFF) | ||
| 478 | error ("parse-sexp-propertize-function modified the buffer!"); | ||
| 479 | if (parse_sexp_propertize_done <= charpos) | ||
| 480 | error ("parse-sexp-propertize-function did not move" | ||
| 481 | " parse-sexp-propertize-done"); | ||
| 482 | SETUP_SYNTAX_TABLE (charpos, 1); | ||
| 483 | if (gl_state.e_property > parse_sexp_propertize_done) | ||
| 484 | { | ||
| 485 | gl_state.e_property = parse_sexp_propertize_done; | ||
| 486 | gl_state.e_property_truncated = true; | ||
| 487 | } | ||
| 488 | } | ||
| 489 | |||
| 490 | void | ||
| 491 | update_syntax_table_forward (ptrdiff_t charpos, bool init, | ||
| 492 | Lisp_Object object) | ||
| 493 | { | ||
| 494 | if (!(gl_state.e_property_truncated)) | ||
| 495 | update_syntax_table (charpos, 1, init, object); | ||
| 496 | if ((gl_state.e_property > parse_sexp_propertize_done | ||
| 497 | || gl_state.e_property_truncated) | ||
| 498 | && NILP (object)) | ||
| 499 | { | ||
| 500 | if (parse_sexp_propertize_done > charpos) | ||
| 501 | { | ||
| 502 | gl_state.e_property = parse_sexp_propertize_done; | ||
| 503 | gl_state.e_property_truncated = true; | ||
| 504 | } | ||
| 505 | else | ||
| 506 | parse_sexp_propertize (charpos); | ||
| 507 | } | ||
| 508 | } | ||
| 467 | 509 | ||
| 468 | /* Returns true if char at CHARPOS is quoted. | 510 | /* Returns true if char at CHARPOS is quoted. |
| 469 | Global syntax-table data should be set up already to be good at CHARPOS | 511 | Global syntax-table data should be set up already to be good at CHARPOS |
| 470 | or after. On return global syntax data is good for lookup at CHARPOS. */ | 512 | or after. On return global syntax data is good for lookup at CHARPOS. */ |
| 471 | 513 | ||
| 472 | static bool | 514 | static bool |
| 473 | char_quoted (ptrdiff_t charpos, ptrdiff_t bytepos) | 515 | char_quoted (ptrdiff_t charpos, ptrdiff_t bytepos) |
| @@ -628,7 +670,7 @@ back_comment (ptrdiff_t from, ptrdiff_t from_byte, ptrdiff_t stop, | |||
| 628 | OFROM[I] is position of the earliest comment-starter seen | 670 | OFROM[I] is position of the earliest comment-starter seen |
| 629 | which is I+2X quotes from the comment-end. | 671 | which is I+2X quotes from the comment-end. |
| 630 | PARITY is current parity of quotes from the comment end. */ | 672 | PARITY is current parity of quotes from the comment end. */ |
| 631 | int string_style = -1; /* Presumed outside of any string. */ | 673 | int string_style = -1; /* Presumed outside of any string. */ |
| 632 | bool string_lossage = 0; | 674 | bool string_lossage = 0; |
| 633 | /* Not a real lossage: indicates that we have passed a matching comment | 675 | /* Not a real lossage: indicates that we have passed a matching comment |
| 634 | starter plus a non-matching comment-ender, meaning that any matching | 676 | starter plus a non-matching comment-ender, meaning that any matching |
| @@ -645,7 +687,7 @@ back_comment (ptrdiff_t from, ptrdiff_t from_byte, ptrdiff_t stop, | |||
| 645 | ptrdiff_t defun_start = 0; | 687 | ptrdiff_t defun_start = 0; |
| 646 | ptrdiff_t defun_start_byte = 0; | 688 | ptrdiff_t defun_start_byte = 0; |
| 647 | enum syntaxcode code; | 689 | enum syntaxcode code; |
| 648 | ptrdiff_t nesting = 1; /* current comment nesting */ | 690 | ptrdiff_t nesting = 1; /* Current comment nesting. */ |
| 649 | int c; | 691 | int c; |
| 650 | int syntax = 0; | 692 | int syntax = 0; |
| 651 | 693 | ||
| @@ -876,7 +918,7 @@ back_comment (ptrdiff_t from, ptrdiff_t from_byte, ptrdiff_t stop, | |||
| 876 | is nested, so we need to try again from within the | 918 | is nested, so we need to try again from within the |
| 877 | surrounding comment. Example: { a (* " *) */ | 919 | surrounding comment. Example: { a (* " *) */ |
| 878 | { | 920 | { |
| 879 | /* FIXME: We should advance by one or two chars. */ | 921 | /* FIXME: We should advance by one or two chars. */ |
| 880 | defun_start = state.comstr_start + 2; | 922 | defun_start = state.comstr_start + 2; |
| 881 | defun_start_byte = CHAR_TO_BYTE (defun_start); | 923 | defun_start_byte = CHAR_TO_BYTE (defun_start); |
| 882 | } | 924 | } |
| @@ -3588,7 +3630,7 @@ syms_of_syntax (void) | |||
| 3588 | staticpro (&gl_state.current_syntax_table); | 3630 | staticpro (&gl_state.current_syntax_table); |
| 3589 | staticpro (&gl_state.old_prop); | 3631 | staticpro (&gl_state.old_prop); |
| 3590 | 3632 | ||
| 3591 | /* Defined in regex.c */ | 3633 | /* Defined in regex.c. */ |
| 3592 | staticpro (&re_match_object); | 3634 | staticpro (&re_match_object); |
| 3593 | 3635 | ||
| 3594 | DEFSYM (Qscan_error, "scan-error"); | 3636 | DEFSYM (Qscan_error, "scan-error"); |
| @@ -3606,6 +3648,20 @@ Otherwise, that text property is simply ignored. | |||
| 3606 | See the info node `(elisp)Syntax Properties' for a description of the | 3648 | See the info node `(elisp)Syntax Properties' for a description of the |
| 3607 | `syntax-table' property. */); | 3649 | `syntax-table' property. */); |
| 3608 | 3650 | ||
| 3651 | DEFVAR_INT ("parse-sexp-propertize-done", parse_sexp_propertize_done, | ||
| 3652 | doc: /* Position up to which syntax-table properties have been set. */); | ||
| 3653 | parse_sexp_propertize_done = -1; | ||
| 3654 | |||
| 3655 | DEFVAR_LISP ("parse-sexp-propertize-function", | ||
| 3656 | Vparse_sexp_propertize_function, | ||
| 3657 | doc: /* Function to set the `syntax-table' text property. | ||
| 3658 | Called with one argument, the position at which the property is needed. | ||
| 3659 | After running it, `parse-sexp-propertize-done' should be strictly greater | ||
| 3660 | than the argument passed. */); | ||
| 3661 | /* Note: Qnil is a temporary (and invalid) value; it will be properly set in | ||
| 3662 | syntax.el. */ | ||
| 3663 | Vparse_sexp_propertize_function = Qnil; | ||
| 3664 | |||
| 3609 | words_include_escapes = 0; | 3665 | words_include_escapes = 0; |
| 3610 | DEFVAR_BOOL ("words-include-escapes", words_include_escapes, | 3666 | DEFVAR_BOOL ("words-include-escapes", words_include_escapes, |
| 3611 | doc: /* Non-nil means `forward-word', etc., should treat escape chars part of words. */); | 3667 | doc: /* Non-nil means `forward-word', etc., should treat escape chars part of words. */); |
diff --git a/src/syntax.h b/src/syntax.h index bfcb87168ba..9c44181155f 100644 --- a/src/syntax.h +++ b/src/syntax.h | |||
| @@ -21,6 +21,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 21 | INLINE_HEADER_BEGIN | 21 | INLINE_HEADER_BEGIN |
| 22 | 22 | ||
| 23 | extern void update_syntax_table (ptrdiff_t, EMACS_INT, bool, Lisp_Object); | 23 | extern void update_syntax_table (ptrdiff_t, EMACS_INT, bool, Lisp_Object); |
| 24 | extern void update_syntax_table_forward (ptrdiff_t, bool, Lisp_Object); | ||
| 24 | 25 | ||
| 25 | /* The standard syntax table is stored where it will automatically | 26 | /* The standard syntax table is stored where it will automatically |
| 26 | be used in all new buffers. */ | 27 | be used in all new buffers. */ |
| @@ -52,30 +53,32 @@ enum syntaxcode | |||
| 52 | other side by any char with the same syntaxcode. */ | 53 | other side by any char with the same syntaxcode. */ |
| 53 | Sstring_fence, /* Starts/ends string which is delimited on the | 54 | Sstring_fence, /* Starts/ends string which is delimited on the |
| 54 | other side by any char with the same syntaxcode. */ | 55 | other side by any char with the same syntaxcode. */ |
| 55 | Smax /* Upper bound on codes that are meaningful */ | 56 | Smax /* Upper bound on codes that are meaningful. */ |
| 56 | }; | 57 | }; |
| 57 | 58 | ||
| 58 | 59 | ||
| 59 | struct gl_state_s | 60 | struct gl_state_s |
| 60 | { | 61 | { |
| 61 | Lisp_Object object; /* The object we are scanning. */ | 62 | Lisp_Object object; /* The object we are scanning. */ |
| 62 | ptrdiff_t start; /* Where to stop. */ | 63 | ptrdiff_t start; /* Where to stop. */ |
| 63 | ptrdiff_t stop; /* Where to stop. */ | 64 | ptrdiff_t stop; /* Where to stop. */ |
| 64 | bool use_global; /* Whether to use global_code | 65 | bool use_global; /* Whether to use global_code |
| 65 | or c_s_t. */ | 66 | or c_s_t. */ |
| 66 | Lisp_Object global_code; /* Syntax code of current char. */ | 67 | Lisp_Object global_code; /* Syntax code of current char. */ |
| 67 | Lisp_Object current_syntax_table; /* Syntax table for current pos. */ | 68 | Lisp_Object current_syntax_table; /* Syntax table for current pos. */ |
| 68 | Lisp_Object old_prop; /* Syntax-table prop at prev pos. */ | 69 | Lisp_Object old_prop; /* Syntax-table prop at prev pos. */ |
| 69 | ptrdiff_t b_property; /* First index where c_s_t is valid. */ | 70 | ptrdiff_t b_property; /* First index where c_s_t is valid. */ |
| 70 | ptrdiff_t e_property; /* First index where c_s_t is | 71 | ptrdiff_t e_property; /* First index where c_s_t is |
| 71 | not valid. */ | 72 | not valid. */ |
| 72 | INTERVAL forward_i; /* Where to start lookup on forward */ | 73 | bool e_property_truncated; /* true if e_property if was truncated |
| 74 | by parse_sexp_propertize_done. */ | ||
| 75 | INTERVAL forward_i; /* Where to start lookup on forward. */ | ||
| 73 | INTERVAL backward_i; /* or backward movement. The | 76 | INTERVAL backward_i; /* or backward movement. The |
| 74 | data in c_s_t is valid | 77 | data in c_s_t is valid |
| 75 | between these intervals, | 78 | between these intervals, |
| 76 | and possibly at the | 79 | and possibly at the |
| 77 | intervals too, depending | 80 | intervals too, depending |
| 78 | on: */ | 81 | on: */ |
| 79 | /* Offset for positions specified to UPDATE_SYNTAX_TABLE. */ | 82 | /* Offset for positions specified to UPDATE_SYNTAX_TABLE. */ |
| 80 | ptrdiff_t offset; | 83 | ptrdiff_t offset; |
| 81 | }; | 84 | }; |
| @@ -173,7 +176,7 @@ INLINE void | |||
| 173 | UPDATE_SYNTAX_TABLE_FORWARD (ptrdiff_t charpos) | 176 | UPDATE_SYNTAX_TABLE_FORWARD (ptrdiff_t charpos) |
| 174 | { | 177 | { |
| 175 | if (parse_sexp_lookup_properties && charpos >= gl_state.e_property) | 178 | if (parse_sexp_lookup_properties && charpos >= gl_state.e_property) |
| 176 | update_syntax_table (charpos + gl_state.offset, 1, false, gl_state.object); | 179 | update_syntax_table_forward (charpos + gl_state.offset, false, gl_state.object); |
| 177 | } | 180 | } |
| 178 | 181 | ||
| 179 | /* Make syntax table state (gl_state) good for CHARPOS, assuming it is | 182 | /* Make syntax table state (gl_state) good for CHARPOS, assuming it is |
| @@ -201,6 +204,7 @@ INLINE void | |||
| 201 | SETUP_BUFFER_SYNTAX_TABLE (void) | 204 | SETUP_BUFFER_SYNTAX_TABLE (void) |
| 202 | { | 205 | { |
| 203 | gl_state.use_global = false; | 206 | gl_state.use_global = false; |
| 207 | gl_state.e_property_truncated = false; | ||
| 204 | gl_state.current_syntax_table = BVAR (current_buffer, syntax_table); | 208 | gl_state.current_syntax_table = BVAR (current_buffer, syntax_table); |
| 205 | } | 209 | } |
| 206 | 210 | ||