diff --git a/doc/emacs/help.texi b/doc/emacs/help.texi index 6bd2d53b3b1..6572da9c323 100644 --- a/doc/emacs/help.texi +++ b/doc/emacs/help.texi @@ -45,22 +45,27 @@ window displaying the @samp{*Help*} buffer will be reused instead. @cindex searching documentation efficiently @cindex looking for a subject in documentation If you are looking for a certain feature, but don't know what it is -called or where to look, we recommend three methods. First, try an -apropos command, then try searching the manual index, then look in the +called or where to look, we recommend three methods. First, try +apropos commands, then try searching the manual index, then look in the FAQ and the package keywords, and finally try listing external packages. @table @kbd @item C-h a @var{topics} @key{RET} This searches for commands whose names match the argument -@var{topics}. The argument can be a keyword, a list of keywords, or a -regular expression (@pxref{Regexps}). @xref{Apropos}. +@var{topics}. The argument can be a keyword, a list of keywords +separated by whitespace, or a regular expression (@pxref{Regexps}). +@xref{Apropos}. -@item C-h i d m emacs @key{RET} i @var{topic} @key{RET} +@item C-h d @var{topics} @key{RET} +Similar, but searches the @emph{text} of the documentation strings +rather than the names of commands and functions. + +@item C-h r i @var{topic} @key{RET} This searches for @var{topic} in the indices of the Emacs Info manual, displaying the first match found. Press @kbd{,} to see subsequent matches. You can use a regular expression as @var{topic}. -@item C-h i d m emacs @key{RET} s @var{topic} @key{RET} +@item C-h r s @var{topic} @key{RET} Similar, but searches the @emph{text} of the manual rather than the indices. @@ -384,10 +389,12 @@ are included varies depending on the command used. @section Apropos @cindex apropos +@cindex apropos pattern +@cindex apropos commands, list of keywords The @dfn{apropos} commands answer questions like, ``What are the commands for working with files?'' More precisely, you specify your query as an @dfn{apropos pattern}, which is either a word, a list of -words, or a regular expression. +words separated by whitespace, or a regular expression. Each of the following apropos commands reads an apropos pattern in the minibuffer, searches for items that match the pattern, and diff --git a/lisp/treesit.el b/lisp/treesit.el index bcabf98f1d1..ee67c2349f9 100644 --- a/lisp/treesit.el +++ b/lisp/treesit.el @@ -126,10 +126,13 @@ of max unsigned 32-bit value for byte offsets into buffer text." (defun treesit-parse-string (string language) "Parse STRING using a parser for LANGUAGE. Return the root node of the syntax tree." - (with-temp-buffer - (insert string) - (treesit-parser-root-node - (treesit-parser-create language)))) + ;; We can't use `with-temp-buffer' because it kills the buffer when + ;; returning from the form. + (let ((buf (generate-new-buffer " *treesit-parse-string*"))) + (with-current-buffer buf + (insert string) + (treesit-parser-root-node + (treesit-parser-create language))))) (defvar-local treesit-language-at-point-function nil "A function that returns the language at point. diff --git a/src/print.c b/src/print.c index 7aacd2b2e90..6a27ceac5f0 100644 --- a/src/print.c +++ b/src/print.c @@ -2033,6 +2033,11 @@ print_vectorlike_unreadable (Lisp_Object obj, Lisp_Object printcharfun, print_c_string ("-outdated>", printcharfun); return; } + if (!treesit_node_buffer_live_p (obj)) + { + print_c_string ("-in-killed-buffer>", printcharfun); + break; + } printchar (' ', printcharfun); /* Now the node must be up-to-date, and calling functions like Ftreesit_node_start will not signal. */ diff --git a/src/treesit.c b/src/treesit.c index d86ab501187..9f0eb061056 100644 --- a/src/treesit.c +++ b/src/treesit.c @@ -1837,6 +1837,13 @@ treesit_check_node (Lisp_Object obj) CHECK_TS_NODE (obj); if (!treesit_node_uptodate_p (obj)) xsignal1 (Qtreesit_node_outdated, obj); + + /* Technically a lot of node functions can work without the + associated buffer being alive, but I doubt there're any real + use-cases for that; OTOH putting the buffer-liveness check here is + simple, clean, and safe. */ + if (!treesit_node_buffer_live_p (obj)) + xsignal1 (Qtreesit_node_buffer_killed, obj); } /* Checks that OBJ is a positive integer and it is within the visible @@ -1857,6 +1864,14 @@ treesit_node_uptodate_p (Lisp_Object obj) return XTS_NODE (obj)->timestamp == XTS_PARSER (lisp_parser)->timestamp; } +bool +treesit_node_buffer_live_p (Lisp_Object obj) +{ + struct buffer *buffer + = XBUFFER (XTS_PARSER (XTS_NODE (obj)->parser)->buffer); + return BUFFER_LIVE_P (buffer); +} + DEFUN ("treesit-node-type", Ftreesit_node_type, Streesit_node_type, 1, 1, 0, doc: /* Return the NODE's type as a string. @@ -4016,6 +4031,8 @@ syms_of_treesit (void) "treesit-load-language-error"); DEFSYM (Qtreesit_node_outdated, "treesit-node-outdated"); + DEFSYM (Qtreesit_node_buffer_killed, + "treesit-node-buffer-killed"); DEFSYM (Quser_emacs_directory, "user-emacs-directory"); DEFSYM (Qtreesit_parser_deleted, "treesit-parser-deleted"); @@ -4046,6 +4063,9 @@ syms_of_treesit (void) define_error (Qtreesit_node_outdated, "This node is outdated, please retrieve a new one", Qtreesit_error); + define_error (Qtreesit_node_buffer_killed, + "The buffer associated with this node is killed", + Qtreesit_error); define_error (Qtreesit_parser_deleted, "This parser is deleted and cannot be used", Qtreesit_error); diff --git a/src/treesit.h b/src/treesit.h index bb81bf0e2b3..d3c6aa4c250 100644 --- a/src/treesit.h +++ b/src/treesit.h @@ -194,6 +194,7 @@ extern Lisp_Object make_treesit_parser (Lisp_Object, TSParser *, TSTree *, extern Lisp_Object make_treesit_node (Lisp_Object, TSNode); extern bool treesit_node_uptodate_p (Lisp_Object); +extern bool treesit_node_buffer_live_p (Lisp_Object); extern void treesit_delete_parser (struct Lisp_TS_Parser *); extern void treesit_delete_query (struct Lisp_TS_Query *);