diff options
| author | Yuan Fu | 2022-06-16 17:55:07 -0700 |
|---|---|---|
| committer | Yuan Fu | 2022-06-16 17:55:07 -0700 |
| commit | 246dbb540a32fd5e68ae0665527717943ebb69b1 (patch) | |
| tree | 7a2520f82c4775edc9da948630d4db11d5868f68 | |
| parent | 33f7e10a29dad475f7872d6af87ecefaccdb55fc (diff) | |
| download | emacs-246dbb540a32fd5e68ae0665527717943ebb69b1.tar.gz emacs-246dbb540a32fd5e68ae0665527717943ebb69b1.zip | |
Change treesit-parser-list from variable to function
Effectively making the list internal. Now Emacs user cannot shoot
themselves in the foot by removing a parser from the list, make
chaanges to buffer and add that parser back to the list.
* doc/lispref/parsing.texi (Language Definitions, Using Parser)
(Retrieving Node, Multiple Languages): Change variable to function.
* lisp/treesit.el (treesit-language-at, treesit-node-on)
(treesit-buffer-root-node, treesit-indent, treesit-check-indent)
(treesit-search-forward, treesit-search-beginning)
(treesit-end-of-defun, treesit-inspect-mode): Change variable to
function.
* src/buffer.c (bset_ts_parser_list, reset_buffer, init_buffer_once):
Add ts_parser_list.
* src/buffer.h (struct buffer): Add ts_parser_list.
* src/treesit.c (ts_record_change, Ftreesit_parser_create): Use the
buffer field instead of the old buffer local variable.
(Ftreesit_parser_delete, Ftreesit_parser_list): New functions.
(syms_of_treesit): Remove treesit-parser-list.
* test/src/treesit-tests.el (treesit-basic-parsing): Use the new
function.
| -rw-r--r-- | doc/lispref/parsing.texi | 36 | ||||
| -rw-r--r-- | lisp/treesit.el | 24 | ||||
| -rw-r--r-- | src/buffer.c | 16 | ||||
| -rw-r--r-- | src/buffer.h | 4 | ||||
| -rw-r--r-- | src/treesit.c | 76 | ||||
| -rw-r--r-- | test/src/treesit-tests.el | 2 |
6 files changed, 107 insertions, 51 deletions
diff --git a/doc/lispref/parsing.texi b/doc/lispref/parsing.texi index b077f557432..27755e0caa5 100644 --- a/doc/lispref/parsing.texi +++ b/doc/lispref/parsing.texi | |||
| @@ -184,7 +184,7 @@ of a node, then the mode-line only displays the smallest node that | |||
| 184 | spans point, and its immediate parent. | 184 | spans point, and its immediate parent. |
| 185 | 185 | ||
| 186 | This minor mode doesn't create parsers on its own. It simply uses the | 186 | This minor mode doesn't create parsers on its own. It simply uses the |
| 187 | first parser in @var{treesit-parser-list} (@pxref{Using Parser}). | 187 | first parser in @code{(treesit-parser-list)} (@pxref{Using Parser}). |
| 188 | @end deffn | 188 | @end deffn |
| 189 | 189 | ||
| 190 | @heading Reading the grammar definition | 190 | @heading Reading the grammar definition |
| @@ -407,15 +407,19 @@ Tree-sitter can only handle buffer no larger than about 4GB. If the | |||
| 407 | size exceeds that, Emacs signals @var{treesit-buffer-too-large} | 407 | size exceeds that, Emacs signals @var{treesit-buffer-too-large} |
| 408 | with signal data being the buffer size. | 408 | with signal data being the buffer size. |
| 409 | 409 | ||
| 410 | @vindex treesit-parser-list | ||
| 411 | Once a parser is created, Emacs automatically adds it to the | 410 | Once a parser is created, Emacs automatically adds it to the |
| 412 | buffer-local variable @var{treesit-parser-list}. Every time a | 411 | buffer-local parser list. Every time a change is made to the buffer, |
| 413 | change is made to the buffer, Emacs updates parsers in this list so | 412 | Emacs updates parsers in this list so they can update their syntax |
| 414 | they can update their syntax tree incrementally. Therefore, one must | 413 | tree incrementally. |
| 415 | not remove parsers from this list and put the parser back in: if any | 414 | |
| 416 | change is made when that parser is absent, the parser will be | 415 | @defun treesit-parser-list &optional buffer |
| 417 | permanently out-of-sync with the buffer content, and shouldn't be used | 416 | This function returns the parser list of @var{buffer}. And |
| 418 | anymore. | 417 | @var{buffer} defaults to the current buffer. |
| 418 | @end defun | ||
| 419 | |||
| 420 | @defun treesit-parser-delete parser | ||
| 421 | This function deletes @var{parser}. | ||
| 422 | @end defun | ||
| 419 | 423 | ||
| 420 | @cindex tree-sitter narrowing | 424 | @cindex tree-sitter narrowing |
| 421 | @anchor{tree-sitter narrowing} Normally, a parser ``sees'' the whole | 425 | @anchor{tree-sitter narrowing} Normally, a parser ``sees'' the whole |
| @@ -477,10 +481,10 @@ the @var{point}. In other words, the start of the node is equal or | |||
| 477 | greater than @var{point}. | 481 | greater than @var{point}. |
| 478 | 482 | ||
| 479 | When @var{parser-or-lang} is nil, this function uses the first parser | 483 | When @var{parser-or-lang} is nil, this function uses the first parser |
| 480 | in @var{treesit-parser-list} in the current buffer. If | 484 | in @code{(treesit-parser-list)} in the current buffer. If |
| 481 | @var{parser-or-lang} is a parser object, it use that parser; if | 485 | @var{parser-or-lang} is a parser object, it use that parser; if |
| 482 | @var{parser-or-lang} is a language, it finds the first parser using | 486 | @var{parser-or-lang} is a language, it finds the first parser using |
| 483 | that language in @var{treesit-parser-list} and use that. | 487 | that language in @code{(treesit-parser-list)} and use that. |
| 484 | 488 | ||
| 485 | If @var{named} is non-nil, this function looks for a named node | 489 | If @var{named} is non-nil, this function looks for a named node |
| 486 | instead (@pxref{tree-sitter named node, named node}). | 490 | instead (@pxref{tree-sitter named node, named node}). |
| @@ -507,10 +511,10 @@ smallest node that covers that empty line. You probably want to use | |||
| 507 | @code{treesit-node-at} instead. | 511 | @code{treesit-node-at} instead. |
| 508 | 512 | ||
| 509 | When @var{parser-or-lang} is nil, this function uses the first parser | 513 | When @var{parser-or-lang} is nil, this function uses the first parser |
| 510 | in @var{treesit-parser-list} in the current buffer. If | 514 | in @code{(treesit-parser-list)} in the current buffer. If |
| 511 | @var{parser-or-lang} is a parser object, it use that parser; if | 515 | @var{parser-or-lang} is a parser object, it use that parser; if |
| 512 | @var{parser-or-lang} is a language, it finds the first parser using | 516 | @var{parser-or-lang} is a language, it finds the first parser using |
| 513 | that language in @var{treesit-parser-list} and use that. | 517 | that language in @code{(treesit-parser-list)} and use that. |
| 514 | 518 | ||
| 515 | If @var{named} is non-nil, this function looks for a named node | 519 | If @var{named} is non-nil, this function looks for a named node |
| 516 | instead (@pxref{tree-sitter named node, named node}). | 520 | instead (@pxref{tree-sitter named node, named node}). |
| @@ -523,7 +527,7 @@ This function returns the root node of the syntax tree generated by | |||
| 523 | 527 | ||
| 524 | @defun treesit-buffer-root-node &optional language | 528 | @defun treesit-buffer-root-node &optional language |
| 525 | This function finds the first parser that uses @var{language} in | 529 | This function finds the first parser that uses @var{language} in |
| 526 | @var{treesit-parser-list} in the current buffer, and returns the | 530 | @code{(treesit-parser-list)} in the current buffer, and returns the |
| 527 | root node of that buffer. If it cannot find an appropriate parser, it | 531 | root node of that buffer. If it cannot find an appropriate parser, it |
| 528 | returns nil. | 532 | returns nil. |
| 529 | @end defun | 533 | @end defun |
| @@ -1267,7 +1271,7 @@ Like @code{treesit-parser-set-included-ranges}, this function sets | |||
| 1267 | the ranges of @var{parser-or-lang} to @var{ranges}. Conveniently, | 1271 | the ranges of @var{parser-or-lang} to @var{ranges}. Conveniently, |
| 1268 | @var{parser-or-lang} could be either a parser or a language. If it is | 1272 | @var{parser-or-lang} could be either a parser or a language. If it is |
| 1269 | a language, this function looks for the first parser in | 1273 | a language, this function looks for the first parser in |
| 1270 | @var{treesit-parser-list} for that language in the current buffer, | 1274 | @code{(treesit-parser-list)} for that language in the current buffer, |
| 1271 | and set range for it. | 1275 | and set range for it. |
| 1272 | @end defun | 1276 | @end defun |
| 1273 | 1277 | ||
| @@ -1301,7 +1305,7 @@ Like other query functions, this function raises an | |||
| 1301 | @defun treesit-language-at point | 1305 | @defun treesit-language-at point |
| 1302 | This function tries to figure out which language is responsible for | 1306 | This function tries to figure out which language is responsible for |
| 1303 | the text at @var{point}. It goes over each parser in | 1307 | the text at @var{point}. It goes over each parser in |
| 1304 | @var{treesit-parser-list} and see if that parser's range covers | 1308 | @code{(treesit-parser-list)} and see if that parser's range covers |
| 1305 | @var{point}. | 1309 | @var{point}. |
| 1306 | @end defun | 1310 | @end defun |
| 1307 | 1311 | ||
diff --git a/lisp/treesit.el b/lisp/treesit.el index 5b65e00e078..3cfafd0d156 100644 --- a/lisp/treesit.el +++ b/lisp/treesit.el | |||
| @@ -75,7 +75,7 @@ Return the root node of the syntax tree." | |||
| 75 | 75 | ||
| 76 | (defun treesit-language-at (point) | 76 | (defun treesit-language-at (point) |
| 77 | "Return the language used at POINT." | 77 | "Return the language used at POINT." |
| 78 | (cl-loop for parser in treesit-parser-list | 78 | (cl-loop for parser in (treesit-parser-list) |
| 79 | if (treesit-node-on point point parser) | 79 | if (treesit-node-on point point parser) |
| 80 | return (treesit-parser-language parser))) | 80 | return (treesit-parser-language parser))) |
| 81 | 81 | ||
| @@ -122,7 +122,7 @@ greater or larger than POINT. Return nil if none find. If NAMED | |||
| 122 | non-nil, only look for named node. | 122 | non-nil, only look for named node. |
| 123 | 123 | ||
| 124 | If PARSER-OR-LANG is nil, use the first parser in | 124 | If PARSER-OR-LANG is nil, use the first parser in |
| 125 | `treesit-parser-list'; if PARSER-OR-LANG is a parser, use | 125 | (`treesit-parser-list'); if PARSER-OR-LANG is a parser, use |
| 126 | that parser; if PARSER-OR-LANG is a language, find a parser using | 126 | that parser; if PARSER-OR-LANG is a language, find a parser using |
| 127 | that language in the current buffer, and use that." | 127 | that language in the current buffer, and use that." |
| 128 | (let ((node (if (treesit-parser-p parser-or-lang) | 128 | (let ((node (if (treesit-parser-p parser-or-lang) |
| @@ -150,7 +150,7 @@ Return nil if none find. If NAMED non-nil, only look for named | |||
| 150 | node. | 150 | node. |
| 151 | 151 | ||
| 152 | If PARSER-OR-LANG is nil, use the first parser in | 152 | If PARSER-OR-LANG is nil, use the first parser in |
| 153 | `treesit-parser-list'; if PARSER-OR-LANG is a parser, use | 153 | (`treesit-parser-list'); if PARSER-OR-LANG is a parser, use |
| 154 | that parser; if PARSER-OR-LANG is a language, find a parser using | 154 | that parser; if PARSER-OR-LANG is a language, find a parser using |
| 155 | that language in the current buffer, and use that." | 155 | that language in the current buffer, and use that." |
| 156 | (let ((root (if (treesit-parser-p parser-or-lang) | 156 | (let ((root (if (treesit-parser-p parser-or-lang) |
| @@ -160,13 +160,13 @@ that language in the current buffer, and use that." | |||
| 160 | 160 | ||
| 161 | (defun treesit-buffer-root-node (&optional language) | 161 | (defun treesit-buffer-root-node (&optional language) |
| 162 | "Return the root node of the current buffer. | 162 | "Return the root node of the current buffer. |
| 163 | Use the first parser in `treesit-parser-list', if LANGUAGE is | 163 | Use the first parser in (`treesit-parser-list'), if LANGUAGE is |
| 164 | non-nil, use the first parser for LANGUAGE." | 164 | non-nil, use the first parser for LANGUAGE." |
| 165 | (if-let ((parser | 165 | (if-let ((parser |
| 166 | (or (if language | 166 | (or (if language |
| 167 | (or (treesit-parser-create language) | 167 | (or (treesit-parser-create language) |
| 168 | (error "Cannot find a parser for %s" language)) | 168 | (error "Cannot find a parser for %s" language)) |
| 169 | (or (car treesit-parser-list) | 169 | (or (car (treesit-parser-list)) |
| 170 | (error "Buffer has no parser")))))) | 170 | (error "Buffer has no parser")))))) |
| 171 | (treesit-parser-root-node parser))) | 171 | (treesit-parser-root-node parser))) |
| 172 | 172 | ||
| @@ -770,7 +770,7 @@ of the current line.") | |||
| 770 | (skip-chars-forward " \t") | 770 | (skip-chars-forward " \t") |
| 771 | (point))) | 771 | (point))) |
| 772 | (smallest-node | 772 | (smallest-node |
| 773 | (cl-loop for parser in treesit-parser-list | 773 | (cl-loop for parser in (treesit-parser-list) |
| 774 | for node = (treesit-node-at bol parser) | 774 | for node = (treesit-node-at bol parser) |
| 775 | if node return node)) | 775 | if node return node)) |
| 776 | (node (treesit-parent-while | 776 | (node (treesit-parent-while |
| @@ -856,7 +856,7 @@ This is a more primitive function, you might want to use | |||
| 856 | 856 | ||
| 857 | QUERY has to capture the node to match. LANG specifies the | 857 | QUERY has to capture the node to match. LANG specifies the |
| 858 | language in which we search for nodes. If LANG is nil, use the | 858 | language in which we search for nodes. If LANG is nil, use the |
| 859 | first parser in `treesit-parser-list'. | 859 | first parser in (`treesit-parser-list'). |
| 860 | 860 | ||
| 861 | Move forward/backward ARG times, positive ARG means go forward, | 861 | Move forward/backward ARG times, positive ARG means go forward, |
| 862 | negative ARG means go backward. | 862 | negative ARG means go backward. |
| @@ -875,7 +875,7 @@ the tree." | |||
| 875 | (cl-loop for idx from 1 to (abs arg) | 875 | (cl-loop for idx from 1 to (abs arg) |
| 876 | for parser = (if lang | 876 | for parser = (if lang |
| 877 | (treesit-parser-create lang) | 877 | (treesit-parser-create lang) |
| 878 | (car treesit-parser-list)) | 878 | (car (treesit-parser-list))) |
| 879 | for node = | 879 | for node = |
| 880 | (if-let ((starting-point (point)) | 880 | (if-let ((starting-point (point)) |
| 881 | (node (treesit-node-at (point) parser t))) | 881 | (node (treesit-node-at (point) parser t))) |
| @@ -914,7 +914,7 @@ Stops at the beginning of matched node. | |||
| 914 | 914 | ||
| 915 | QUERY has to capture the node to match. LANG specifies the | 915 | QUERY has to capture the node to match. LANG specifies the |
| 916 | language in which we search for nodes. If LANG is nil, use the | 916 | language in which we search for nodes. If LANG is nil, use the |
| 917 | first parser in `treesit-parser-list'. | 917 | first parser in (`treesit-parser-list'). |
| 918 | 918 | ||
| 919 | Move forward/backward ARG times, positive ARG means go forward, | 919 | Move forward/backward ARG times, positive ARG means go forward, |
| 920 | negative ARG means go backward. | 920 | negative ARG means go backward. |
| @@ -937,7 +937,7 @@ Stops at the end of matched node. | |||
| 937 | 937 | ||
| 938 | QUERY has to capture the node to match. LANG specifies the | 938 | QUERY has to capture the node to match. LANG specifies the |
| 939 | language in which we search for nodes. If LANG is nil, use the | 939 | language in which we search for nodes. If LANG is nil, use the |
| 940 | first parser in `treesit-parser-list'. | 940 | first parser in (`treesit-parser-list'). |
| 941 | 941 | ||
| 942 | Move forward/backward ARG times, positive ARG means go forward, | 942 | Move forward/backward ARG times, positive ARG means go forward, |
| 943 | negative ARG means go backward. | 943 | negative ARG means go backward. |
| @@ -993,7 +993,7 @@ ARGth preceding end of defun. Defun is defined according to | |||
| 993 | If called interactively, show in echo area, otherwise set | 993 | If called interactively, show in echo area, otherwise set |
| 994 | `treesit--inspect-name' (which will appear in the mode-line | 994 | `treesit--inspect-name' (which will appear in the mode-line |
| 995 | if `treesit-inspect-mode' is enabled). Uses the first parser | 995 | if `treesit-inspect-mode' is enabled). Uses the first parser |
| 996 | in `treesit-parser-list'." | 996 | in (`treesit-parser-list')." |
| 997 | (interactive "p") | 997 | (interactive "p") |
| 998 | ;; NODE-LIST contains all the node that starts at point. | 998 | ;; NODE-LIST contains all the node that starts at point. |
| 999 | (let* ((node-list | 999 | (let* ((node-list |
| @@ -1053,7 +1053,7 @@ node, then we just display the smallest node that spans point and | |||
| 1053 | its immediate parent. | 1053 | its immediate parent. |
| 1054 | 1054 | ||
| 1055 | This minor mode doesn't create parsers on its own. It simply | 1055 | This minor mode doesn't create parsers on its own. It simply |
| 1056 | uses the first parser in `treesit-parser-list'." | 1056 | uses the first parser in (`treesit-parser-list')." |
| 1057 | :lighter nil | 1057 | :lighter nil |
| 1058 | (if treesit-inspect-mode | 1058 | (if treesit-inspect-mode |
| 1059 | (progn | 1059 | (progn |
diff --git a/src/buffer.c b/src/buffer.c index a0761f5b59a..97e9e227386 100644 --- a/src/buffer.c +++ b/src/buffer.c | |||
| @@ -231,6 +231,13 @@ bset_extra_line_spacing (struct buffer *b, Lisp_Object val) | |||
| 231 | { | 231 | { |
| 232 | b->extra_line_spacing_ = val; | 232 | b->extra_line_spacing_ = val; |
| 233 | } | 233 | } |
| 234 | #ifdef HAVE_TREE_SITTER | ||
| 235 | static void | ||
| 236 | bset_ts_parser_list (struct buffer *b, Lisp_Object val) | ||
| 237 | { | ||
| 238 | b->ts_parser_list_ = val; | ||
| 239 | } | ||
| 240 | #endif | ||
| 234 | static void | 241 | static void |
| 235 | bset_file_format (struct buffer *b, Lisp_Object val) | 242 | bset_file_format (struct buffer *b, Lisp_Object val) |
| 236 | { | 243 | { |
| @@ -1004,6 +1011,9 @@ reset_buffer (register struct buffer *b) | |||
| 1004 | (b, BVAR (&buffer_defaults, enable_multibyte_characters)); | 1011 | (b, BVAR (&buffer_defaults, enable_multibyte_characters)); |
| 1005 | bset_cursor_type (b, BVAR (&buffer_defaults, cursor_type)); | 1012 | bset_cursor_type (b, BVAR (&buffer_defaults, cursor_type)); |
| 1006 | bset_extra_line_spacing (b, BVAR (&buffer_defaults, extra_line_spacing)); | 1013 | bset_extra_line_spacing (b, BVAR (&buffer_defaults, extra_line_spacing)); |
| 1014 | #ifdef HAVE_TREE_SITTER | ||
| 1015 | bset_ts_parser_list (b, Qnil); | ||
| 1016 | #endif | ||
| 1007 | 1017 | ||
| 1008 | b->display_error_modiff = 0; | 1018 | b->display_error_modiff = 0; |
| 1009 | } | 1019 | } |
| @@ -5273,6 +5283,9 @@ init_buffer_once (void) | |||
| 5273 | XSETFASTINT (BVAR (&buffer_local_flags, tab_line_format), idx); ++idx; | 5283 | XSETFASTINT (BVAR (&buffer_local_flags, tab_line_format), idx); ++idx; |
| 5274 | XSETFASTINT (BVAR (&buffer_local_flags, cursor_type), idx); ++idx; | 5284 | XSETFASTINT (BVAR (&buffer_local_flags, cursor_type), idx); ++idx; |
| 5275 | XSETFASTINT (BVAR (&buffer_local_flags, extra_line_spacing), idx); ++idx; | 5285 | XSETFASTINT (BVAR (&buffer_local_flags, extra_line_spacing), idx); ++idx; |
| 5286 | #ifdef HAVE_TREE_SITTER | ||
| 5287 | XSETFASTINT (BVAR (&buffer_local_flags, ts_parser_list), idx); ++idx; | ||
| 5288 | #endif | ||
| 5276 | XSETFASTINT (BVAR (&buffer_local_flags, cursor_in_non_selected_windows), idx); ++idx; | 5289 | XSETFASTINT (BVAR (&buffer_local_flags, cursor_in_non_selected_windows), idx); ++idx; |
| 5277 | 5290 | ||
| 5278 | /* buffer_local_flags contains no pointers, so it's safe to treat it | 5291 | /* buffer_local_flags contains no pointers, so it's safe to treat it |
| @@ -5343,6 +5356,9 @@ init_buffer_once (void) | |||
| 5343 | bset_bidi_paragraph_separate_re (&buffer_defaults, Qnil); | 5356 | bset_bidi_paragraph_separate_re (&buffer_defaults, Qnil); |
| 5344 | bset_cursor_type (&buffer_defaults, Qt); | 5357 | bset_cursor_type (&buffer_defaults, Qt); |
| 5345 | bset_extra_line_spacing (&buffer_defaults, Qnil); | 5358 | bset_extra_line_spacing (&buffer_defaults, Qnil); |
| 5359 | #ifdef HAVE_TREE_SITTER | ||
| 5360 | bset_ts_parser_list (&buffer_defaults, Qnil); | ||
| 5361 | #endif | ||
| 5346 | bset_cursor_in_non_selected_windows (&buffer_defaults, Qt); | 5362 | bset_cursor_in_non_selected_windows (&buffer_defaults, Qt); |
| 5347 | 5363 | ||
| 5348 | bset_enable_multibyte_characters (&buffer_defaults, Qt); | 5364 | bset_enable_multibyte_characters (&buffer_defaults, Qt); |
diff --git a/src/buffer.h b/src/buffer.h index 135eaf72d30..bc07a63b537 100644 --- a/src/buffer.h +++ b/src/buffer.h | |||
| @@ -561,6 +561,10 @@ struct buffer | |||
| 561 | in the display of this buffer. */ | 561 | in the display of this buffer. */ |
| 562 | Lisp_Object extra_line_spacing_; | 562 | Lisp_Object extra_line_spacing_; |
| 563 | 563 | ||
| 564 | #ifdef HAVE_TREE_SITTER | ||
| 565 | /* A list of tree-sitter parsers for this buffer. */ | ||
| 566 | Lisp_Object ts_parser_list_; | ||
| 567 | #endif | ||
| 564 | /* Cursor type to display in non-selected windows. | 568 | /* Cursor type to display in non-selected windows. |
| 565 | t means to use hollow box cursor. | 569 | t means to use hollow box cursor. |
| 566 | See `cursor-type' for other values. */ | 570 | See `cursor-type' for other values. */ |
diff --git a/src/treesit.c b/src/treesit.c index fcb333b8ec4..be0955805cc 100644 --- a/src/treesit.c +++ b/src/treesit.c | |||
| @@ -342,8 +342,8 @@ void | |||
| 342 | ts_record_change (ptrdiff_t start_byte, ptrdiff_t old_end_byte, | 342 | ts_record_change (ptrdiff_t start_byte, ptrdiff_t old_end_byte, |
| 343 | ptrdiff_t new_end_byte) | 343 | ptrdiff_t new_end_byte) |
| 344 | { | 344 | { |
| 345 | for (Lisp_Object parser_list = | 345 | for (Lisp_Object parser_list |
| 346 | Fsymbol_value (Qtreesit_parser_list); | 346 | = BVAR (current_buffer, ts_parser_list); |
| 347 | !NILP (parser_list); | 347 | !NILP (parser_list); |
| 348 | parser_list = XCDR (parser_list)) | 348 | parser_list = XCDR (parser_list)) |
| 349 | { | 349 | { |
| @@ -704,23 +704,24 @@ parser. If NO-REUSE is non-nil, always create a new parser. */) | |||
| 704 | ts_initialize (); | 704 | ts_initialize (); |
| 705 | 705 | ||
| 706 | CHECK_SYMBOL (language); | 706 | CHECK_SYMBOL (language); |
| 707 | struct buffer *old_buffer = current_buffer; | 707 | struct buffer *buf; |
| 708 | if (!NILP (buffer)) | 708 | if (NILP (buffer)) |
| 709 | buf = current_buffer; | ||
| 710 | else | ||
| 709 | { | 711 | { |
| 710 | CHECK_BUFFER (buffer); | 712 | CHECK_BUFFER (buffer); |
| 711 | set_buffer_internal (XBUFFER (buffer)); | 713 | buf = XBUFFER (buffer); |
| 712 | } | 714 | } |
| 713 | ts_check_buffer_size (current_buffer); | 715 | ts_check_buffer_size (buf); |
| 714 | 716 | ||
| 715 | /* See if we can reuse a parser. */ | 717 | /* See if we can reuse a parser. */ |
| 716 | for (Lisp_Object tail = Fsymbol_value (Qtreesit_parser_list); | 718 | for (Lisp_Object tail = BVAR (buf, ts_parser_list); |
| 717 | NILP (no_reuse) && !NILP (tail); | 719 | NILP (no_reuse) && !NILP (tail); |
| 718 | tail = XCDR (tail)) | 720 | tail = XCDR (tail)) |
| 719 | { | 721 | { |
| 720 | struct Lisp_TS_Parser *parser = XTS_PARSER (XCAR (tail)); | 722 | struct Lisp_TS_Parser *parser = XTS_PARSER (XCAR (tail)); |
| 721 | if (EQ (parser->language_symbol, language)) | 723 | if (EQ (parser->language_symbol, language)) |
| 722 | { | 724 | { |
| 723 | set_buffer_internal (old_buffer); | ||
| 724 | return XCAR (tail); | 725 | return XCAR (tail); |
| 725 | } | 726 | } |
| 726 | } | 727 | } |
| @@ -734,13 +735,53 @@ parser. If NO-REUSE is non-nil, always create a new parser. */) | |||
| 734 | Lisp_Object lisp_parser | 735 | Lisp_Object lisp_parser |
| 735 | = make_ts_parser (Fcurrent_buffer (), parser, NULL, language); | 736 | = make_ts_parser (Fcurrent_buffer (), parser, NULL, language); |
| 736 | 737 | ||
| 737 | Fset (Qtreesit_parser_list, | 738 | BVAR (buf, ts_parser_list) |
| 738 | Fcons (lisp_parser, Fsymbol_value (Qtreesit_parser_list))); | 739 | = Fcons (lisp_parser, BVAR (buf, ts_parser_list)); |
| 739 | 740 | ||
| 740 | set_buffer_internal (old_buffer); | ||
| 741 | return lisp_parser; | 741 | return lisp_parser; |
| 742 | } | 742 | } |
| 743 | 743 | ||
| 744 | DEFUN ("treesit-parser-delete", | ||
| 745 | Ftreesit_parser_delete, Streesit_parser_delete, | ||
| 746 | 1, 1, 0, | ||
| 747 | doc: /* Delete PARSER from its buffer. */) | ||
| 748 | (Lisp_Object parser) | ||
| 749 | { | ||
| 750 | CHECK_TS_PARSER (parser); | ||
| 751 | Lisp_Object buffer = XTS_PARSER (parser)->buffer; | ||
| 752 | struct buffer *buf = XBUFFER (buffer); | ||
| 753 | BVAR (buf, ts_parser_list) | ||
| 754 | = Fdelete (parser, BVAR (buf, ts_parser_list)); | ||
| 755 | return Qnil; | ||
| 756 | } | ||
| 757 | |||
| 758 | DEFUN ("treesit-parser-list", | ||
| 759 | Ftreesit_parser_list, Streesit_parser_list, | ||
| 760 | 0, 1, 0, | ||
| 761 | doc: /* Return BUFFER's parser list. | ||
| 762 | BUFFER defaults to the current buffer. */) | ||
| 763 | (Lisp_Object buffer) | ||
| 764 | { | ||
| 765 | struct buffer *buf; | ||
| 766 | if (NILP (buffer)) | ||
| 767 | buf = current_buffer; | ||
| 768 | else | ||
| 769 | { | ||
| 770 | CHECK_BUFFER (buffer); | ||
| 771 | buf = XBUFFER (buffer); | ||
| 772 | } | ||
| 773 | /* Return a fresh list so messing with that list doesn't affect our | ||
| 774 | internal data. */ | ||
| 775 | Lisp_Object return_list = Qnil; | ||
| 776 | for (Lisp_Object tail = BVAR (buf, ts_parser_list); | ||
| 777 | !NILP (tail); | ||
| 778 | tail = XCDR (tail)) | ||
| 779 | { | ||
| 780 | return_list = Fcons (XCAR (tail), return_list); | ||
| 781 | } | ||
| 782 | return Freverse (return_list); | ||
| 783 | } | ||
| 784 | |||
| 744 | DEFUN ("treesit-parser-buffer", | 785 | DEFUN ("treesit-parser-buffer", |
| 745 | Ftreesit_parser_buffer, Streesit_parser_buffer, | 786 | Ftreesit_parser_buffer, Streesit_parser_buffer, |
| 746 | 1, 1, 0, | 787 | 1, 1, 0, |
| @@ -1799,17 +1840,6 @@ syms_of_treesit (void) | |||
| 1799 | "This node is outdated, please retrieve a new one", | 1840 | "This node is outdated, please retrieve a new one", |
| 1800 | Qtreesit_error); | 1841 | Qtreesit_error); |
| 1801 | 1842 | ||
| 1802 | DEFSYM (Qtreesit_parser_list, "treesit-parser-list"); | ||
| 1803 | DEFVAR_LISP ("treesit-parser-list", Vtreesit_parser_list, | ||
| 1804 | doc: /* A list of tree-sitter parsers. | ||
| 1805 | |||
| 1806 | If you removed a parser from this list, do not put it back in. Emacs | ||
| 1807 | keeps the parser in this list updated with any change in the buffer. | ||
| 1808 | If removed and put back in, there is no guarantee that the parser is in | ||
| 1809 | sync with the buffer's content. */); | ||
| 1810 | Vtreesit_parser_list = Qnil; | ||
| 1811 | Fmake_variable_buffer_local (Qtreesit_parser_list); | ||
| 1812 | |||
| 1813 | DEFVAR_LISP ("treesit-load-name-override-list", | 1843 | DEFVAR_LISP ("treesit-load-name-override-list", |
| 1814 | Vtreesit_load_name_override_list, | 1844 | Vtreesit_load_name_override_list, |
| 1815 | doc: | 1845 | doc: |
| @@ -1848,6 +1878,8 @@ dynamic libraries, in that order. */); | |||
| 1848 | defsubr (&Streesit_node_parser); | 1878 | defsubr (&Streesit_node_parser); |
| 1849 | 1879 | ||
| 1850 | defsubr (&Streesit_parser_create); | 1880 | defsubr (&Streesit_parser_create); |
| 1881 | defsubr (&Streesit_parser_delete); | ||
| 1882 | defsubr (&Streesit_parser_list); | ||
| 1851 | defsubr (&Streesit_parser_buffer); | 1883 | defsubr (&Streesit_parser_buffer); |
| 1852 | defsubr (&Streesit_parser_language); | 1884 | defsubr (&Streesit_parser_language); |
| 1853 | 1885 | ||
diff --git a/test/src/treesit-tests.el b/test/src/treesit-tests.el index 416329d94dd..ebfe650dc08 100644 --- a/test/src/treesit-tests.el +++ b/test/src/treesit-tests.el | |||
| @@ -27,7 +27,7 @@ | |||
| 27 | (with-temp-buffer | 27 | (with-temp-buffer |
| 28 | (let ((parser (treesit-parser-create 'json))) | 28 | (let ((parser (treesit-parser-create 'json))) |
| 29 | (should | 29 | (should |
| 30 | (eq parser (car treesit-parser-list))) | 30 | (eq parser (car (treesit-parser-list)))) |
| 31 | (should | 31 | (should |
| 32 | (equal (treesit-node-string | 32 | (equal (treesit-node-string |
| 33 | (treesit-parser-root-node parser)) | 33 | (treesit-parser-root-node parser)) |