mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-15 10:30:25 -08:00
Fix treesit--indent-1 regarding local parsers
Take this code as an example:
1 class Foo
2 {
3 /**
4 * Block comment
5 */
6 function foo($c) {
7 }
8 }
Suppose the block comment is covered by a local parser. When we
indent line 3, treesit--indent-1 will try to get the local parser at
the BOL, and it'll get the local parser. But it shouldn't use the
local parser to indent this line, it should use the host parser of
that local parser instead.
So now, if treesit--indent-1 gets a local parser, but the local
parser's root node's start coincides with BOL, treesit--indent-1 will
use the host parser to indent this line.
We also need to make treesit--update-ranges-local to save the host
parser along with the local parser, and make
treesit-local-parsers-at/on extract and return the host parser.
I also switch the two cases in the cond form in treesit--indent-1:
(null (treesit-parser-list)) and (car local-parsers), (car
local-parsers) now takes precedence.
* lisp/treesit.el (treesit-local-parsers-at):
(treesit-local-parsers-on): Add WITH-HOST parameter.
(treesit--update-ranges-local): Save the host parser to the local
overlay.
(treesit--indent-1): If the root node of the local parser is at BOL,
use the host parser instead.
This commit is contained in:
parent
dd177b7b88
commit
f63bcf2dfe
1 changed files with 31 additions and 13 deletions
|
|
@ -655,37 +655,47 @@ those inside are kept."
|
|||
if (<= start (car range) (cdr range) end)
|
||||
collect range))
|
||||
|
||||
(defun treesit-local-parsers-at (&optional pos language)
|
||||
(defun treesit-local-parsers-at (&optional pos language with-host)
|
||||
"Return all the local parsers at POS.
|
||||
|
||||
POS defaults to point.
|
||||
Local parsers are those which only parse a limited region marked
|
||||
by an overlay with non-nil `treesit-parser' property.
|
||||
If LANGUAGE is non-nil, only return parsers for LANGUAGE."
|
||||
If LANGUAGE is non-nil, only return parsers for LANGUAGE.
|
||||
|
||||
If WITH-HOST is non-nil, return a list of (PARSER . HOST-PARSER)
|
||||
instead. HOST-PARSER is the host parser which created the local
|
||||
PARSER."
|
||||
(let ((res nil))
|
||||
(dolist (ov (overlays-at (or pos (point))))
|
||||
(when-let ((parser (overlay-get ov 'treesit-parser)))
|
||||
(when-let ((parser (overlay-get ov 'treesit-parser))
|
||||
(host-parser (overlay-get ov 'treesit-host-parser)))
|
||||
(when (or (null language)
|
||||
(eq (treesit-parser-language parser)
|
||||
language))
|
||||
(push parser res))))
|
||||
(push (if with-host (cons parser host-parser) parser) res))))
|
||||
(nreverse res)))
|
||||
|
||||
(defun treesit-local-parsers-on (&optional beg end language)
|
||||
(defun treesit-local-parsers-on (&optional beg end language with-host)
|
||||
"Return all the local parsers between BEG END.
|
||||
|
||||
BEG and END default to the beginning and end of the buffer's
|
||||
accessible portion.
|
||||
Local parsers are those which have an `embedded' tag, and only parse
|
||||
a limited region marked by an overlay with a non-nil `treesit-parser'
|
||||
property. If LANGUAGE is non-nil, only return parsers for LANGUAGE."
|
||||
property. If LANGUAGE is non-nil, only return parsers for LANGUAGE.
|
||||
|
||||
If WITH-HOST is non-nil, return a list of (PARSER . HOST-PARSER)
|
||||
instead. HOST-PARSER is the host parser which created the local
|
||||
PARSER."
|
||||
(let ((res nil))
|
||||
(dolist (ov (overlays-in (or beg (point-min)) (or end (point-max))))
|
||||
(when-let ((parser (overlay-get ov 'treesit-parser)))
|
||||
(when-let ((parser (overlay-get ov 'treesit-parser))
|
||||
(host-parser (overlay-get ov 'treesit-host-parser)))
|
||||
(when (or (null language)
|
||||
(eq (treesit-parser-language parser)
|
||||
language))
|
||||
(push parser res))))
|
||||
(push (if with-host (cons parser host-parser) parser) res))))
|
||||
(nreverse res)))
|
||||
|
||||
(defun treesit--update-ranges-local
|
||||
|
|
@ -701,7 +711,8 @@ parser for EMBEDDED-LANG."
|
|||
(treesit-parser-delete parser))))
|
||||
;; Update range.
|
||||
(let* ((host-lang (treesit-query-language query))
|
||||
(ranges (treesit-query-range host-lang query beg end)))
|
||||
(host-parser (treesit-parser-create host-lang))
|
||||
(ranges (treesit-query-range host-parser query beg end)))
|
||||
(pcase-dolist (`(,beg . ,end) ranges)
|
||||
(let ((has-parser nil))
|
||||
(dolist (ov (overlays-in beg end))
|
||||
|
|
@ -719,6 +730,7 @@ parser for EMBEDDED-LANG."
|
|||
embedded-lang nil t 'embedded))
|
||||
(ov (make-overlay beg end nil nil t)))
|
||||
(overlay-put ov 'treesit-parser embedded-parser)
|
||||
(overlay-put ov 'treesit-host-parser host-parser)
|
||||
(treesit-parser-set-included-ranges
|
||||
embedded-parser `((,beg . ,end)))))))))
|
||||
|
||||
|
|
@ -1800,11 +1812,17 @@ Return (ANCHOR . OFFSET). This function is used by
|
|||
(forward-line 0)
|
||||
(skip-chars-forward " \t")
|
||||
(point)))
|
||||
(local-parsers (treesit-local-parsers-at bol))
|
||||
(local-parsers (treesit-local-parsers-at bol nil t))
|
||||
(smallest-node
|
||||
(cond ((null (treesit-parser-list)) nil)
|
||||
(local-parsers (treesit-node-at
|
||||
bol (car local-parsers)))
|
||||
(cond ((car local-parsers)
|
||||
(let ((local-parser (caar local-parsers))
|
||||
(host-parser (cdar local-parsers)))
|
||||
(if (eq (treesit-node-start
|
||||
(treesit-parser-root-node local-parser))
|
||||
bol)
|
||||
(treesit-node-at bol host-parser)
|
||||
(treesit-node-at bol local-parser))))
|
||||
((null (treesit-parser-list)) nil)
|
||||
((eq 1 (length (treesit-parser-list nil nil t)))
|
||||
(treesit-node-at bol))
|
||||
((treesit-language-at bol)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue