unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#75122: Treesit support for show-paren-mode
@ 2024-12-26 18:31 Juri Linkov
  2024-12-26 20:07 ` Dmitry Gutov
  0 siblings, 1 reply; 3+ messages in thread
From: Juri Linkov @ 2024-12-26 18:31 UTC (permalink / raw)
  To: 75122; +Cc: Yuan Fu

[-- Attachment #1: Type: text/plain, Size: 444 bytes --]

For example, ruby-mode used smie-setup that sets
buffer-local show-paren-data-function.

This patch does the same for ts-modes: when point at the start/end
of the sexp list, then both "def" and "end" are highlighted
as opening and closing nodes:

  def method
    puts "This is method definition"
  end-!-

This also indicates that implementing 'down-list' to move after the
opening node will be the right thing to do (currently in progress).


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: treesit-show-paren-data.patch --]
[-- Type: text/x-diff, Size: 2018 bytes --]

diff --git a/lisp/treesit.el b/lisp/treesit.el
index 2616d16e800..a62f63d0d6c 100644
--- a/lisp/treesit.el
+++ b/lisp/treesit.el
@@ -3331,6 +3333,34 @@ treesit-outline-level
       (setq level (1+ level)))
     (if (zerop level) 1 level)))
 
+;;; Show paren mode
+
+(defun treesit-show-paren-data ()
+  "A function suitable for `show-paren-data-function' (which see)."
+  (let* ((node (treesit-thing-at (point) 'sexp-list))
+         (beg (when node (treesit-node-start node)))
+         (end (when node (treesit-node-end node))))
+    ;; When after the closing node, try the previous position inside the node
+    (unless (or (eq (point) beg) (eq (point) end) (bobp))
+      (setq node (treesit-thing-at (1- (point)) 'sexp-list)
+            beg (when node (treesit-node-start node))
+            end (when node (treesit-node-end node))))
+    (when (or (eq (point) beg) (eq (point) end))
+      (let ((beg-node (treesit-node-child node 0))
+            (end-node (treesit-node-child node -1)))
+        (when (and beg-node end-node (not (eq beg-node end-node)))
+          (if (eq beg (point))
+              (list (treesit-node-start beg-node)
+                    (treesit-node-end beg-node)
+                    (treesit-node-start end-node)
+                    (treesit-node-end end-node)
+                    nil)
+            (list (treesit-node-start end-node)
+                  (treesit-node-end end-node)
+                  (treesit-node-start beg-node)
+                  (treesit-node-end beg-node)
+                  nil)))))))
+
 ;;; Activating tree-sitter
 
 (defun treesit-ready-p (language &optional quiet)
@@ -3486,6 +3516,8 @@ treesit-major-mode-setup
     (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)))

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* bug#75122: Treesit support for show-paren-mode
  2024-12-26 18:31 bug#75122: Treesit support for show-paren-mode Juri Linkov
@ 2024-12-26 20:07 ` Dmitry Gutov
  2024-12-27  7:37   ` Juri Linkov
  0 siblings, 1 reply; 3+ messages in thread
From: Dmitry Gutov @ 2024-12-26 20:07 UTC (permalink / raw)
  To: Juri Linkov, 75122; +Cc: Yuan Fu

Hi!

On 26/12/2024 20:31, Juri Linkov wrote:
> For example, ruby-mode used smie-setup that sets
> buffer-local show-paren-data-function.
> 
> This patch does the same for ts-modes: when point at the start/end
> of the sexp list, then both "def" and "end" are highlighted
> as opening and closing nodes:
> 
>    def method
>      puts "This is method definition"
>    end-!-

This is working great, thanks!

Some comments below.

> treesit-show-paren-data.patch
> 
> diff --git a/lisp/treesit.el b/lisp/treesit.el
> index 2616d16e800..a62f63d0d6c 100644
> --- a/lisp/treesit.el
> +++ b/lisp/treesit.el
> @@ -3331,6 +3333,34 @@ treesit-outline-level
>         (setq level (1+ level)))
>       (if (zerop level) 1 level)))
>   
> +;;; Show paren mode
> +
> +(defun treesit-show-paren-data ()
> +  "A function suitable for `show-paren-data-function' (which see)."
> +  (let* ((node (treesit-thing-at (point) 'sexp-list))
> +         (beg (when node (treesit-node-start node)))
> +         (end (when node (treesit-node-end node))))
> +    ;; When after the closing node, try the previous position inside the node

The comment doesn't seem to correspond to the code, or anyway to all the 
cases the code might be handling? I might misunderstand, though.

> +    (unless (or (eq (point) beg) (eq (point) end) (bobp))
> +      (setq node (treesit-thing-at (1- (point)) 'sexp-list)
> +            beg (when node (treesit-node-start node))
> +            end (when node (treesit-node-end node))))

Without getting into more details, it seems the user options 
show-paren-when-point-inside-paren and 
show-paren-when-point-in-periphery are not handled (don't have any effect).

Not sure what's needed for that, but FWIW SMIE's show-paren integration 
seems to react to the value of the first of these options (even though 
it's never referenced directly in smie.el), while the second one is not 
supported there either.





^ permalink raw reply	[flat|nested] 3+ messages in thread

* bug#75122: Treesit support for show-paren-mode
  2024-12-26 20:07 ` Dmitry Gutov
@ 2024-12-27  7:37   ` Juri Linkov
  0 siblings, 0 replies; 3+ messages in thread
From: Juri Linkov @ 2024-12-27  7:37 UTC (permalink / raw)
  To: Dmitry Gutov; +Cc: Yuan Fu, 75122

>> +(defun treesit-show-paren-data ()
>> +  "A function suitable for `show-paren-data-function' (which see)."
>> +  (let* ((node (treesit-thing-at (point) 'sexp-list))
>> +         (beg (when node (treesit-node-start node)))
>> +         (end (when node (treesit-node-end node))))
>> +    ;; When after the closing node, try the previous position inside the node
>
> The comment doesn't seem to correspond to the code, or anyway to all the
> cases the code might be handling? I might misunderstand, though.

Sorry for the unclear comment.  I meant that when detecting
the opening node we should use (point).  But for detecting
the closing node we need to check (1- (point)) that is
inside the balanced node at the end of the node.

>> +    (unless (or (eq (point) beg) (eq (point) end) (bobp))
>> +      (setq node (treesit-thing-at (1- (point)) 'sexp-list)
>> +            beg (when node (treesit-node-start node))
>> +            end (when node (treesit-node-end node))))
>
> Without getting into more details, it seems the user options
> show-paren-when-point-inside-paren and show-paren-when-point-in-periphery
> are not handled (don't have any effect).

Thanks for referencing these options.  I didn't dig deeper since
I didn't see these options in the SMIE implementation.  But
these options definitely should be consulted to adjust the location
used in '(treesit-thing-at (1- (point)) ...'

> Not sure what's needed for that, but FWIW SMIE's show-paren integration
> seems to react to the value of the first of these options (even though it's
> never referenced directly in smie.el), while the second one is not
> supported there either.

This is strange since neither is referenced in smie.el.
Ok, need to investigate more.





^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2024-12-27  7:37 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-12-26 18:31 bug#75122: Treesit support for show-paren-mode Juri Linkov
2024-12-26 20:07 ` Dmitry Gutov
2024-12-27  7:37   ` Juri Linkov

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).