aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYuan Fu2024-01-30 22:18:33 -0800
committerYuan Fu2024-01-30 22:28:47 -0800
commitf63bcf2dfeb26de511f468adc237e6ea8a3cb6cc (patch)
treef8e96198d175504d715e195e67ba07cf06833545
parentdd177b7b88c81ab71e1d5a97b872d85d524fee9b (diff)
downloademacs-f63bcf2dfeb26de511f468adc237e6ea8a3cb6cc.tar.gz
emacs-f63bcf2dfeb26de511f468adc237e6ea8a3cb6cc.zip
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.
-rw-r--r--lisp/treesit.el44
1 files changed, 31 insertions, 13 deletions
diff --git a/lisp/treesit.el b/lisp/treesit.el
index 96222ed81cb..fab2ddd88e6 100644
--- a/lisp/treesit.el
+++ b/lisp/treesit.el
@@ -655,37 +655,47 @@ those inside are kept."
655 if (<= start (car range) (cdr range) end) 655 if (<= start (car range) (cdr range) end)
656 collect range)) 656 collect range))
657 657
658(defun treesit-local-parsers-at (&optional pos language) 658(defun treesit-local-parsers-at (&optional pos language with-host)
659 "Return all the local parsers at POS. 659 "Return all the local parsers at POS.
660 660
661POS defaults to point. 661POS defaults to point.
662Local parsers are those which only parse a limited region marked 662Local parsers are those which only parse a limited region marked
663by an overlay with non-nil `treesit-parser' property. 663by an overlay with non-nil `treesit-parser' property.
664If LANGUAGE is non-nil, only return parsers for LANGUAGE." 664If LANGUAGE is non-nil, only return parsers for LANGUAGE.
665
666If WITH-HOST is non-nil, return a list of (PARSER . HOST-PARSER)
667instead. HOST-PARSER is the host parser which created the local
668PARSER."
665 (let ((res nil)) 669 (let ((res nil))
666 (dolist (ov (overlays-at (or pos (point)))) 670 (dolist (ov (overlays-at (or pos (point))))
667 (when-let ((parser (overlay-get ov 'treesit-parser))) 671 (when-let ((parser (overlay-get ov 'treesit-parser))
672 (host-parser (overlay-get ov 'treesit-host-parser)))
668 (when (or (null language) 673 (when (or (null language)
669 (eq (treesit-parser-language parser) 674 (eq (treesit-parser-language parser)
670 language)) 675 language))
671 (push parser res)))) 676 (push (if with-host (cons parser host-parser) parser) res))))
672 (nreverse res))) 677 (nreverse res)))
673 678
674(defun treesit-local-parsers-on (&optional beg end language) 679(defun treesit-local-parsers-on (&optional beg end language with-host)
675 "Return all the local parsers between BEG END. 680 "Return all the local parsers between BEG END.
676 681
677BEG and END default to the beginning and end of the buffer's 682BEG and END default to the beginning and end of the buffer's
678accessible portion. 683accessible portion.
679Local parsers are those which have an `embedded' tag, and only parse 684Local parsers are those which have an `embedded' tag, and only parse
680a limited region marked by an overlay with a non-nil `treesit-parser' 685a limited region marked by an overlay with a non-nil `treesit-parser'
681property. If LANGUAGE is non-nil, only return parsers for LANGUAGE." 686property. If LANGUAGE is non-nil, only return parsers for LANGUAGE.
687
688If WITH-HOST is non-nil, return a list of (PARSER . HOST-PARSER)
689instead. HOST-PARSER is the host parser which created the local
690PARSER."
682 (let ((res nil)) 691 (let ((res nil))
683 (dolist (ov (overlays-in (or beg (point-min)) (or end (point-max)))) 692 (dolist (ov (overlays-in (or beg (point-min)) (or end (point-max))))
684 (when-let ((parser (overlay-get ov 'treesit-parser))) 693 (when-let ((parser (overlay-get ov 'treesit-parser))
694 (host-parser (overlay-get ov 'treesit-host-parser)))
685 (when (or (null language) 695 (when (or (null language)
686 (eq (treesit-parser-language parser) 696 (eq (treesit-parser-language parser)
687 language)) 697 language))
688 (push parser res)))) 698 (push (if with-host (cons parser host-parser) parser) res))))
689 (nreverse res))) 699 (nreverse res)))
690 700
691(defun treesit--update-ranges-local 701(defun treesit--update-ranges-local
@@ -701,7 +711,8 @@ parser for EMBEDDED-LANG."
701 (treesit-parser-delete parser)))) 711 (treesit-parser-delete parser))))
702 ;; Update range. 712 ;; Update range.
703 (let* ((host-lang (treesit-query-language query)) 713 (let* ((host-lang (treesit-query-language query))
704 (ranges (treesit-query-range host-lang query beg end))) 714 (host-parser (treesit-parser-create host-lang))
715 (ranges (treesit-query-range host-parser query beg end)))
705 (pcase-dolist (`(,beg . ,end) ranges) 716 (pcase-dolist (`(,beg . ,end) ranges)
706 (let ((has-parser nil)) 717 (let ((has-parser nil))
707 (dolist (ov (overlays-in beg end)) 718 (dolist (ov (overlays-in beg end))
@@ -719,6 +730,7 @@ parser for EMBEDDED-LANG."
719 embedded-lang nil t 'embedded)) 730 embedded-lang nil t 'embedded))
720 (ov (make-overlay beg end nil nil t))) 731 (ov (make-overlay beg end nil nil t)))
721 (overlay-put ov 'treesit-parser embedded-parser) 732 (overlay-put ov 'treesit-parser embedded-parser)
733 (overlay-put ov 'treesit-host-parser host-parser)
722 (treesit-parser-set-included-ranges 734 (treesit-parser-set-included-ranges
723 embedded-parser `((,beg . ,end))))))))) 735 embedded-parser `((,beg . ,end)))))))))
724 736
@@ -1800,11 +1812,17 @@ Return (ANCHOR . OFFSET). This function is used by
1800 (forward-line 0) 1812 (forward-line 0)
1801 (skip-chars-forward " \t") 1813 (skip-chars-forward " \t")
1802 (point))) 1814 (point)))
1803 (local-parsers (treesit-local-parsers-at bol)) 1815 (local-parsers (treesit-local-parsers-at bol nil t))
1804 (smallest-node 1816 (smallest-node
1805 (cond ((null (treesit-parser-list)) nil) 1817 (cond ((car local-parsers)
1806 (local-parsers (treesit-node-at 1818 (let ((local-parser (caar local-parsers))
1807 bol (car local-parsers))) 1819 (host-parser (cdar local-parsers)))
1820 (if (eq (treesit-node-start
1821 (treesit-parser-root-node local-parser))
1822 bol)
1823 (treesit-node-at bol host-parser)
1824 (treesit-node-at bol local-parser))))
1825 ((null (treesit-parser-list)) nil)
1808 ((eq 1 (length (treesit-parser-list nil nil t))) 1826 ((eq 1 (length (treesit-parser-list nil nil t)))
1809 (treesit-node-at bol)) 1827 (treesit-node-at bol))
1810 ((treesit-language-at bol) 1828 ((treesit-language-at bol)