; Minor fixes to documentation
* lisp/treesit.el (treesit-ready-p, treesit-inspect-mode) (treesit-range-settings, treesit-range-rules) (treesit--merge-ranges, treesit-update-ranges) (treesit-font-lock-rules, treesit-font-lock-feature-list) (treesit-font-lock-contextual-post-process) (treesit-font-lock-recompute-features): Doc fixes. * lisp/progmodes/js.el (js--fontify-template-string): Doc fix. * doc/lispref/modes.texi (Parser-based Indentation): * doc/lispref/positions.texi (List Motion): * doc/lispref/parsing.texi (Tree-sitter major modes): * doc/lispref/parsing.texi (Multiple Languages): Fix wording and markup.
This commit is contained in:
@@ -4841,8 +4841,8 @@ arguments: @var{node}, @var{parent}, and @var{bol}. The argument
|
||||
position of the first non-whitespace character after the beginning of
|
||||
the line. The argument @var{node} is the largest (highest-in-tree)
|
||||
node that starts at that position; and @var{parent} is the parent of
|
||||
@var{node}. However, when that position is on a whitespace or inside
|
||||
a multi-line string, no node that starts at that position, so
|
||||
@var{node}. However, when that position is in a whitespace or inside
|
||||
a multi-line string, no node can start at that position, so
|
||||
@var{node} is @code{nil}. In that case, @var{parent} would be the
|
||||
smallest node that spans that position.
|
||||
|
||||
|
||||
@@ -1318,7 +1318,6 @@ pattern-matching, which can be found at
|
||||
|
||||
@node Multiple Languages
|
||||
@section Parsing Text in Multiple Languages
|
||||
|
||||
@cindex multiple languages, parsing with tree-sitter
|
||||
@cindex parsing multiple languages with tree-sitter
|
||||
Sometimes, the source of a programming language could contain snippets
|
||||
@@ -1329,6 +1328,14 @@ achieved by using narrowing. While tree-sitter works with narrowing
|
||||
(@pxref{tree-sitter narrowing, narrowing}), the recommended way is
|
||||
instead to set regions of buffer text in which a parser will operate.
|
||||
|
||||
@c FIXME: This text should be expanded, as it doesn't explain who do
|
||||
@c the other functions in this node related to supporting multiple
|
||||
@c languages.
|
||||
Specifically, a multi-language major mode should set
|
||||
@code{treesit-language-at-point-function} and
|
||||
@code{treesit-range-settings} for Emacs to handle multiple languages
|
||||
in the same buffer.
|
||||
|
||||
@defun treesit-parser-set-included-ranges parser ranges
|
||||
This function sets up @var{parser} to operate on @var{ranges}. The
|
||||
@var{parser} will only read the text of the specified ranges. Each
|
||||
@@ -1420,11 +1427,12 @@ Like other query functions, this function raises the
|
||||
@end defun
|
||||
|
||||
@defun treesit-update-ranges &optional beg end
|
||||
This function is used by fontification and indentation to update
|
||||
ranges before using any parser. It makes sure the parsers' range are
|
||||
This function is used by fontifications and indentation to update
|
||||
ranges before using any parser. It makes sure the parsers' ranges are
|
||||
set correctly between @var{beg} and @var{end}, according to
|
||||
@code{treesit-range-settings}. If omitted, @var{beg} defaults to the
|
||||
beginning of the buffer, and @var{end} defaults to the end.
|
||||
beginning of the buffer, and @var{end} defaults to the end of the
|
||||
buffer.
|
||||
@end defun
|
||||
|
||||
@vindex treesit-language-at-point-function
|
||||
@@ -1496,7 +1504,7 @@ to write query patterns, @pxref{Pattern Matching}.
|
||||
Emacs can automate the above process in @code{treesit-update-ranges}.
|
||||
For it to work, a Lisp program should set
|
||||
@code{treesit-range-settings} to the output of
|
||||
@code{treesit-range-rules}, like the following.
|
||||
@code{treesit-range-rules}, like in the following example:
|
||||
|
||||
@example
|
||||
@group
|
||||
@@ -1514,30 +1522,41 @@ For it to work, a Lisp program should set
|
||||
@end group
|
||||
@end example
|
||||
|
||||
@c FIXME: This is NOT how we document series of 3 arguments! It is
|
||||
@c better to use ``&rest query-specs'' instead, and then tell that
|
||||
@c each query-spec is a triplet of :keyword, value, and the query
|
||||
@c itself. But then the doc string of the function and its advertised
|
||||
@c calling sequence, should be changed accordingly.
|
||||
@defun treesit-range-rules :keyword value query...
|
||||
This function is used to set @var{treesit-range-settings}. It
|
||||
takes care of compiling queries and other post-processing, and outputs
|
||||
a value that @var{treesit-range-settings} accepts.
|
||||
a value that @var{treesit-range-settings} can have.
|
||||
|
||||
It takes a series of @var{queries} in either string, s-expression or
|
||||
compiled form. Before each QUERY there must be @var{:keyword}
|
||||
@var{value} pairs that configure the query (and only that query).
|
||||
It takes a series of one or more @var{query}s in either the string,
|
||||
s-expression or compiled form. Each @var{query} should be preceded by
|
||||
a pair of @var{:keyword} and @var{value} that configure the query (and
|
||||
only that query).
|
||||
|
||||
For each query, @code{:embed} keyword specifies the embedded language,
|
||||
and @code{:host} keyword specified the host language. Emacs queries
|
||||
the @var{query} in the host language and uses the result to set ranges
|
||||
for the embedded language.
|
||||
@c FIXME: The notion of ``host language'' was never explained. We do
|
||||
@c mention ``embedded language'', but without a @dfn and without an
|
||||
@c index entry to find it; that should also be fixed.
|
||||
For each query, the @code{:embed} keyword specifies the embedded
|
||||
language, and the @code{:host} keyword specified the host language.
|
||||
@c FIXME: The next sentence is not clear: what does it mean ``to set
|
||||
@c ranges in the embedded language''?
|
||||
Emacs queries the @var{query} in the host language and uses the result
|
||||
to set ranges for the embedded language.
|
||||
|
||||
@c FIXME: ``It only needs to ensure...'' is not clear. What does
|
||||
@c ``only'' refer to? does it mean that's the only purpose of such a
|
||||
@c function?
|
||||
A @var{query} can also be a function that takes two arguments,
|
||||
@var{start} and @var{end}, and sets the range for parsers. It only
|
||||
needs to ensure ranges between @var{start} and @var{end} is correct.
|
||||
@c FIXME: This should be at the beginning of the description.
|
||||
When @var{query} is a function, it doesn't need keywords before it.
|
||||
@end defun
|
||||
|
||||
In summary, a multi-langauge major mode should set
|
||||
@code{treesit-language-at-function} and @code{treesit-range-settings}
|
||||
for Emacs to handle multiple languages in the same buffer.
|
||||
|
||||
@node Tree-sitter major modes
|
||||
@section Developing major modes with tree-sitter
|
||||
@cindex major mode, developing with tree-sitter
|
||||
@@ -1571,23 +1590,25 @@ and whether tree-sitter can be activated in this mode.
|
||||
|
||||
@defun treesit-ready-p mode language &optional quiet
|
||||
This function checks for conditions for activating tree-sitter. It
|
||||
checks whether the users turns tree-sitter on for @var{mode}
|
||||
(according to @code{treesit-settings}), whether tree-sitter is built
|
||||
with Emacs, the buffer's size, and whether @var{languag} is available.
|
||||
checks whether the user turned on tree-sitter for @var{mode}
|
||||
(according to @code{treesit-settings}), whether Emacs was built with
|
||||
tree-sitter, whether the buffer's size is not too large for
|
||||
tree-sitter to handle it, and whether support for @var{language} is
|
||||
available in tree-sitter.
|
||||
|
||||
When user sets @var{mode} to @var{demand} in @code{treesit-settings},
|
||||
When the user sets @var{mode} to @var{demand} in @code{treesit-settings},
|
||||
this function emits a warning if tree-sitter cannot be activated. If
|
||||
@var{quiet} is @code{message}, the warning is turned into a message,
|
||||
@var{quiet} is @code{message}, the warning is turned into a message;
|
||||
if @var{quiet} is @code{nil}, no warning or message is displayed.
|
||||
|
||||
If @var{mode} is nil, this function doesn't check user's preference in
|
||||
@code{treesit-settings}.
|
||||
|
||||
If all conditions are met, this function returns non-@code{nil}.
|
||||
Otherwise it return @code{nil}.
|
||||
If all the necessary conditions are met, this function returns
|
||||
non-@code{nil}; otherwise it return @code{nil}.
|
||||
@end defun
|
||||
|
||||
Then, the major mode should setup tree-sitter variables, and call
|
||||
Next, the major mode should set up tree-sitter variables and call
|
||||
@code{treesit-major-mode-setup}.
|
||||
|
||||
@defun treesit-major-mode-setup
|
||||
|
||||
@@ -836,15 +836,15 @@ of using its normal method.
|
||||
|
||||
@findex treesit-beginning-of-defun
|
||||
@findex treesit-end-of-defun
|
||||
If Emacs is compiled with tree-sitter, it can use the parsed
|
||||
If Emacs is compiled with tree-sitter, it can use the tree-sitter parser
|
||||
information to move across syntax constructs. A major mode can set
|
||||
@code{treesit-defun-type-regexp} and get navigation functionality for
|
||||
free, by using @code{treesit-beginning-of-defun} and
|
||||
@code{treesit-end-of-defun}.
|
||||
|
||||
@defvar treesit-defun-type-regexp
|
||||
This is a regexp matching the node type of defun nodes. (For
|
||||
``node'', ``node type'', @pxref{Parsing Program Source}.)
|
||||
The value of this variable is a regexp matching the node type of defun
|
||||
nodes. (For ``node'', ``node type'', @pxref{Parsing Program Source}.)
|
||||
|
||||
For example, @code{python-mode} sets this variable to a regexp that
|
||||
matches either @code{function_definition} or @code{class_definition}.
|
||||
|
||||
@@ -3588,7 +3588,7 @@ This function is intended for use in `after-change-functions'."
|
||||
|
||||
(defun js--fontify-template-string (node override start end &rest _)
|
||||
"Fontify template string but not substitution inside it.
|
||||
NODE is the template_string node. START and END marks the region
|
||||
NODE is the template_string node. START and END mark the region
|
||||
to be fontified.
|
||||
|
||||
OVERRIDE is the override flag described in
|
||||
|
||||
128
lisp/treesit.el
128
lisp/treesit.el
@@ -353,18 +353,15 @@ captured node. Capture names don't matter."
|
||||
(defvar-local treesit-range-settings nil
|
||||
"A list of range settings.
|
||||
|
||||
A list of list of the form
|
||||
|
||||
(QUERY LANGUAGE)
|
||||
|
||||
Each element of the list is of the form (QUERY LANGUAGE).
|
||||
When updating the range of each parser in the buffer,
|
||||
`treesit-update-ranges' queries each QUERY, and set LANGUAGE's
|
||||
`treesit-update-ranges' queries each QUERY, and sets LANGUAGE's
|
||||
range to the range spanned by captured nodes. QUERY must be a
|
||||
compiled query.
|
||||
|
||||
QUERY can also be a function, in which case it is called with 2
|
||||
arguments, START and END. It should ensure parsers' range are
|
||||
correct in that region.
|
||||
arguments, START and END. It should ensure parsers' ranges are
|
||||
correct in the region between START and END.
|
||||
|
||||
The exact form of the variable is considered internal and subject
|
||||
to change. Use `treesit-range-rules' to set this variable.")
|
||||
@@ -372,26 +369,26 @@ to change. Use `treesit-range-rules' to set this variable.")
|
||||
(defun treesit-range-rules (&rest args)
|
||||
"Produce settings for `treesit-range-settings'.
|
||||
|
||||
Take a series of QUERIES in either string, s-expression or
|
||||
compiled form. For example,
|
||||
Take a series of QUERYs in either the string, s-expression or
|
||||
compiled form.
|
||||
|
||||
Before each QUERY there must be :KEYWORD VALUE pairs that
|
||||
configure the query (and only that query). For example,
|
||||
Each QUERY should be preceded by a :KEYWORD VALUE pair that
|
||||
configures the query (and only that query). For example,
|
||||
|
||||
(treesit-range-rules
|
||||
:embed \\='javascript
|
||||
:host \\='html
|
||||
\\='((script_element (raw_text) @cap)))
|
||||
|
||||
For each query, :embed keyword specifies the embedded language,
|
||||
and :host keyword specified the host language. Emacs queries the
|
||||
QUERY in the host language and uses the result to set ranges for
|
||||
For each query, the `:embed' keyword specifies the embedded language,
|
||||
the `:host' keyword specified the host (main) language. Emacs queries
|
||||
the QUERY in the host language and uses the result to set ranges for
|
||||
the embedded language.
|
||||
|
||||
QUERY can also be a function that takes two arguments, START and
|
||||
END, and sets the range for parsers. The function only needs to
|
||||
ensure ranges between START and END is correct. If QUERY is a
|
||||
function, it doesn't need to have keywords before it.
|
||||
function, it doesn't need to have the :KEYWORD VALUE pair before it.
|
||||
|
||||
\(:KEYWORD VALUE QUERY...)"
|
||||
(let (host embed result)
|
||||
@@ -418,14 +415,14 @@ function, it doesn't need to have keywords before it.
|
||||
(nreverse result)))
|
||||
|
||||
(defun treesit--merge-ranges (old-ranges new-ranges start end)
|
||||
"Merge OLD-RANGES and NEW-RANGES.
|
||||
Each range is a list of cons of the form (BEG . END). When
|
||||
"Merge OLD-RANGES and NEW-RANGES, discarding ranges between START and END.
|
||||
OLD-RANGES and NEW-RANGES are lists of cons of the form (BEG . END). When
|
||||
merging the two ranges, if a range in OLD-RANGES intersects with
|
||||
another range in NEW-RANGES, discard the one in OLD-RANGES and
|
||||
keep the one in NEW-RANGES. Also discard any range in OLD-RANGES
|
||||
that intersects the region marked by START and END.
|
||||
|
||||
Return the merged range list."
|
||||
Return the merged list of ranges."
|
||||
(let ((result nil))
|
||||
(while (and old-ranges new-ranges)
|
||||
(let ((new-beg (caar new-ranges))
|
||||
@@ -456,12 +453,12 @@ Return the merged range list."
|
||||
|
||||
(defun treesit-update-ranges (&optional beg end)
|
||||
"Update the ranges for each language in the current buffer.
|
||||
If BEG and END not omitted, only update parser ranges in that
|
||||
If BEG and END are non-nil, only update parser ranges in that
|
||||
region."
|
||||
;; When updating ranges, we want to avoid querying the whole buffer
|
||||
;; which could be slow in very large buffers. Instead, we only
|
||||
;; query for nodes that intersect with the region between BEG and
|
||||
;; END. And we only update the ranges intersecting BEG and END,
|
||||
;; END. Also, we only update the ranges intersecting BEG and END;
|
||||
;; outside of that region we inherit old ranges.
|
||||
(dolist (setting treesit-range-settings)
|
||||
(let ((query (nth 0 setting))
|
||||
@@ -506,7 +503,7 @@ omitted, default END to BEG."
|
||||
(defvar-local treesit-font-lock-feature-list nil
|
||||
"A list of lists of feature symbols.
|
||||
|
||||
End-user should use `treesit-font-lock-recompute-features' and
|
||||
Use `treesit-font-lock-recompute-features' and
|
||||
`font-lock-maximum-decoration' to configure enabled features.
|
||||
|
||||
Each sublist represents a decoration level.
|
||||
@@ -591,15 +588,15 @@ Capture names in QUERY should be face names like
|
||||
with that face.
|
||||
|
||||
Capture names can also be function names, in which case the
|
||||
function should have a signature
|
||||
function will be called with the following argument list:
|
||||
|
||||
(NODE OVERRIDE START END &rest _)
|
||||
|
||||
where NODE is the tree-sitter node object, OVERRIDE is the
|
||||
override option of that rule, and START and END marks the region
|
||||
override option of that rule, and START and END specify the region
|
||||
to be fontified. This function should accept more arguments as
|
||||
optional arguments for future extensibility. And this function
|
||||
shouldn't fontify text outside START and END.
|
||||
optional arguments for future extensibility, and it shouldn't
|
||||
fontify text outside the region given by START and END.
|
||||
|
||||
If a capture name is both a face and a function, the face takes
|
||||
priority. If a capture name is not a face name nor a function
|
||||
@@ -681,13 +678,13 @@ name, it is ignored.
|
||||
"Enable/disable font-lock settings according to decoration level.
|
||||
|
||||
First compute the enabled features according to
|
||||
`treesit-font-lock-feature-list' and
|
||||
`font-lock-maximum-decoration', then if ADD-LIST or REMOVE-LIST
|
||||
are not omitted, further add and remove features accordingly.
|
||||
`treesit-font-lock-feature-list' and `font-lock-maximum-decoration',
|
||||
then, if ADD-LIST or REMOVE-LIST are not omitted, further add and
|
||||
remove features accordingly.
|
||||
|
||||
ADD-LIST and REMOVE-LIST are each list of feature symbols. The
|
||||
same feature symbol cannot not appear in both lists. Otherwise
|
||||
signal `treesit-font-lock-error'."
|
||||
ADD-LIST and REMOVE-LIST are each a list of feature symbols. The
|
||||
same feature symbol cannot appear in both lists; the function
|
||||
signals the `treesit-font-lock-error' error if so."
|
||||
(when-let ((intersection (cl-intersection add-list remove-list)))
|
||||
(signal 'treesit-font-lock-error
|
||||
(list "ADD-LIST and REMOVE-LIST contain the same feature"
|
||||
@@ -752,26 +749,26 @@ instead."
|
||||
(put-text-property start end 'rear-nonsticky new-prop))))
|
||||
|
||||
;; This post-processing tries to deal with the following scenario:
|
||||
;; User inserts "/*", then go down the buffer and inserts "*/".
|
||||
;; Before the user inserts "*/", tree-sitter cannot construct a
|
||||
;; comment node and the parse tree is incomplete, and we can't fontify
|
||||
;; the comment. But once the user inserts the "*/", the parse-tree is
|
||||
;; complete and we want to refontify the whole comment, and possibly
|
||||
;; text after comment (the "/*" could damage the parse tree enough
|
||||
;; that makes tree-sitter unable to produce reasonable information for
|
||||
;; text after it).
|
||||
;; User inserts "/*" in a buffer under C mode, then goes down the
|
||||
;; buffer and inserts "*/". Before the user inserts "*/", tree-sitter
|
||||
;; cannot construct a comment node and the parse tree is incomplete,
|
||||
;; and we can't fontify the comment. But once the user inserts the
|
||||
;; "*/", the parse-tree is complete and we want to refontify the whole
|
||||
;; comment, and possibly text after comment (the "/*" could damage the
|
||||
;; parse tree enough that makes tree-sitter unable to produce
|
||||
;; reasonable information for text after it).
|
||||
;;
|
||||
;; So we set jit-lock-context-unfontify-pos to comment start, and
|
||||
;; jit-lock-context will refontify text after that position in a
|
||||
;; timer. Refontifying those text will end up calling this function
|
||||
;; again, and we don't want to fall into infinite recursion. So we
|
||||
;; mark the end of the comment with a text property, so we can
|
||||
;; distinguish between initial and follow up invocation of this
|
||||
;; mark the end of the comment with a text property, to be able to
|
||||
;; distinguish between initial and follow-up invocation of this
|
||||
;; function.
|
||||
(defun treesit-font-lock-contextual-post-process
|
||||
(node start end &optional verbose)
|
||||
"Post-processing for contextual syntax nodes.
|
||||
NODE is a comment or string node, START and END are the region
|
||||
"Post-process contextual syntax NODE for fontification between START and END.
|
||||
NODE is a comment or string node, START and END specify the region
|
||||
being fontified.
|
||||
|
||||
If VERBOSE is non-nil, print debugging information."
|
||||
@@ -1070,7 +1067,7 @@ prev-line
|
||||
(defun treesit--simple-indent-eval (exp)
|
||||
"Evaluate EXP.
|
||||
|
||||
If EXPis an application and the function is a key in
|
||||
If EXP is an application and the function is a key in
|
||||
`treesit-simple-indent-presets', use the corresponding value as
|
||||
the function."
|
||||
;; We don't want to match uncompiled lambdas, so make sure this cons
|
||||
@@ -1091,7 +1088,8 @@ the function."
|
||||
;; Matchers only return lambdas, anchors only return
|
||||
;; integer, so we should never see a variable.
|
||||
(signal 'treesit-indent-error
|
||||
'("Couldn't find the preset corresponding to %s") exp)))
|
||||
(list "Couldn't find the preset corresponding to expression"
|
||||
exp))))
|
||||
(t exp)))
|
||||
|
||||
;; This variable might seem unnecessary: why split
|
||||
@@ -1428,20 +1426,20 @@ MODE is a major mode symbol. SETTINGS should be `treesit-settings'."
|
||||
(cdar applicable)))))
|
||||
|
||||
(defun treesit-ready-p (mode language &optional quiet)
|
||||
"Check that tree-sitter is ready to be used for MODE.
|
||||
"Check whether tree-sitter is ready to be used for MODE and LANGUAGE.
|
||||
|
||||
Checks the user setting in `treesit-settings', if user sets
|
||||
`demand' for MODE, and tree-sitter is not ready, emit a warning
|
||||
and return nil. If user chose to activate tree-sitter for MODE
|
||||
and tree-sitter is ready, return non-nil. If QUIET is t, no
|
||||
warning is emitted in any case, if quiet is `message', message
|
||||
LANGUAGE is the language symbol to check for availability.
|
||||
It can also be a list of language symbols.
|
||||
|
||||
This function checks the user setting in `treesit-settings'. If the
|
||||
user has set `demand' for MODE, and tree-sitter is not ready, emit a
|
||||
warning and return nil. If the user has chosen to activate tree-sitter
|
||||
for MODE and tree-sitter is ready, return non-nil. If QUIET is t, don't
|
||||
emit warning in either case; if quiet is `message', display a message
|
||||
instead of emitting warning.
|
||||
|
||||
If MODE is nil, don't check for user setting and assume the
|
||||
setting is t.
|
||||
|
||||
LANGUAGE is the language symbol we want to check for availability.
|
||||
It can also be a list of language symbols."
|
||||
setting is t."
|
||||
(let ((language-list (if (consp language)
|
||||
language
|
||||
(list language)))
|
||||
@@ -1565,23 +1563,23 @@ in `treesit-parser-list'."
|
||||
(message "%s" treesit--inspect-name)
|
||||
(message "No node at point")))))
|
||||
|
||||
;; FIXME: in the next doc string, what is FIELD-NAME?
|
||||
(define-minor-mode treesit-inspect-mode
|
||||
"Show the node that _starts_ at point in the mode-line.
|
||||
"Minor mode that displays in the mode-line the node which starts at point.
|
||||
|
||||
The mode-line displays
|
||||
When this mode is enabled, the mode-line displays
|
||||
|
||||
PARENT FIELD-NAME: (NODE FIELD_NAME: (CHILD (...)))
|
||||
PARENT FIELD-NAME: (NODE FIELD-NAME: (CHILD (...)))
|
||||
|
||||
NODE, CHILD, and GRAND-CHILD, etc, are nodes that have their
|
||||
beginning at point. And PARENT is the parent of NODE. NODE is
|
||||
displayed in bold face.
|
||||
where NODE, CHILD, etc, are nodes which begin at point.
|
||||
PARENT is the parent of NODE. NODE is displayed in bold typeface.
|
||||
|
||||
If no node starts at point, i.e., point is in the middle of a
|
||||
node, then just display the smallest node that spans point and
|
||||
its immediate parent.
|
||||
node, then the mode line displays the earliest node that spans point,
|
||||
and its immediate parent.
|
||||
|
||||
This minor mode doesn't create parsers on its own. It simply
|
||||
uses the first parser in `treesit-parser-list'."
|
||||
This minor mode doesn't create parsers on its own. It uses the first
|
||||
parser in `treesit-parser-list'."
|
||||
:lighter nil
|
||||
(if treesit-inspect-mode
|
||||
(progn
|
||||
|
||||
Reference in New Issue
Block a user