From: Juri Linkov Date: Sun, 29 Dec 2024 18:08:11 +0000 (+0200) Subject: Treesit support for show-paren-mode (bug#75122) X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=de08532efb279d4da059b53e77ee7fba6c72f956;p=emacs.git Treesit support for show-paren-mode (bug#75122) * lisp/treesit.el (treesit-show-paren-data--categorize): New internal function. (treesit-show-paren-data): New function. (treesit-major-mode-setup): Set 'show-paren-data-function' to 'treesit-show-paren-data'. (cherry picked from commit 1addae07be1982a6cafc0e0b3955b59bd1fb481c) --- diff --git a/etc/NEWS b/etc/NEWS index f678751b2f3..e7199bef976 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -857,6 +857,10 @@ Tree-sitter conditionally sets 'up-list-function' for major modes that have defined 'sexp-list' in 'treesit-thing-settings' to enable the 'up-list' motion command. +*** New function 'treesit-show-paren-data'. +Tree-sitter sets 'show-paren-data-function' to this function +to support 'show-paren-mode'. + +++ *** New function 'treesit-language-display-name'. This new function returns the display name of a language given the diff --git a/lisp/treesit.el b/lisp/treesit.el index 84c29981f50..99468c91bf5 100644 --- a/lisp/treesit.el +++ b/lisp/treesit.el @@ -3381,6 +3381,49 @@ For BOUND, MOVE, BACKWARD, LOOKING-AT, see the descriptions in (setq level (1+ level))) (if (zerop level) 1 level))) +;;; Show paren mode + +(defun treesit-show-paren-data--categorize (pos &optional end-p) + (let* ((pred 'sexp-list) + (parent (treesit-node-parent (treesit-node-at (if end-p (1- pos) pos)))) + (parent (when (treesit-node-match-p parent pred t) parent)) + (first (when parent (treesit-node-child parent 0))) + (first-start (when first (treesit-node-start first))) + (first-end (when first (treesit-node-end first))) + (last (when parent (treesit-node-child parent -1))) + (last-start (when last (treesit-node-start last))) + (last-end (when last (treesit-node-end last))) + (dir (if show-paren-when-point-inside-paren + (cond + ((and first (<= first-start pos first-end)) 1) + ((and last (<= last-start pos last-end)) -1)) + (cond + ((and first (= first-start pos)) 1) + ((and last (= pos last-end)) -1))))) + (cond + ((eq dir 1) (list first-start first-end last-start last-end)) + ((eq dir -1) (list last-start last-end first-start first-end))))) + +(defun treesit-show-paren-data () + "A function suitable for `show-paren-data-function' (which see)." + (or (treesit-show-paren-data--categorize (point)) + (unless (bobp) (treesit-show-paren-data--categorize (point) t)) + (when show-paren-when-point-in-periphery + (let* ((ind-pos (save-excursion (back-to-indentation) (point))) + (eol-pos + (save-excursion + (end-of-line) (skip-chars-backward " \t" ind-pos) (point)))) + (cond + ((<= (point) ind-pos) + (or (treesit-show-paren-data--categorize ind-pos) + (unless (bobp) + (treesit-show-paren-data--categorize (1- eol-pos))))) + ((>= (point) eol-pos) + (unless (bobp) + (treesit-show-paren-data--categorize (1- eol-pos))))))) + ;; Fall back for parens in e.g. 'for_statement' + (show-paren--default))) + ;;; Activating tree-sitter (defun treesit-ready-p (language &optional quiet) @@ -3539,6 +3582,8 @@ before calling this function." (setq-local outline-search-function #'treesit-outline-search outline-level #'treesit-outline-level)) + (setq-local show-paren-data-function 'treesit-show-paren-data) + ;; Remove existing local parsers. (dolist (ov (overlays-in (point-min) (point-max))) (when-let ((parser (overlay-get ov 'treesit-parser)))