From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Wilhelm Kirschbaum Newsgroups: gmane.emacs.bugs Subject: bug#58711: Treesit hangs when calling treesit-search-forward Date: Mon, 14 Nov 2022 08:32:40 +0200 Message-ID: References: <895A3C87-507A-4FC5-8BAE-B138B35CD40C@gmail.com> <46B629C0-1413-41CE-BDA8-CE14C12B4449@gmail.com> <3054006.Zh9iicr411@melissa.local> <106B8822-FE37-4590-BC77-5FB24FB0758C@gmail.com> <82A013FB-9A94-4E57-9FD2-AF8E892241A9@gmail.com> <7B22DC5E-CCC6-4981-AC61-7774FE2846AA@gmail.com> Mime-Version: 1.0 Content-Type: multipart/alternative; boundary="000000000000a7f1aa05ed686807" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="18901"; mail-complaints-to="usenet@ciao.gmane.io" Cc: 58711@debbugs.gnu.org To: Yuan Fu Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Tue Nov 15 01:19:45 2022 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1oujg0-0004jf-LP for geb-bug-gnu-emacs@m.gmane-mx.org; Tue, 15 Nov 2022 01:19:45 +0100 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ouiqy-0003wN-NQ; Mon, 14 Nov 2022 18:27:00 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ouih2-0003HL-1f for bug-gnu-emacs@gnu.org; Mon, 14 Nov 2022 18:16:44 -0500 Original-Received: from debbugs.gnu.org ([209.51.188.43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1ouT1i-0006Bj-Qz for bug-gnu-emacs@gnu.org; Mon, 14 Nov 2022 01:33:02 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1ouT1i-000816-Em for bug-gnu-emacs@gnu.org; Mon, 14 Nov 2022 01:33:02 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Wilhelm Kirschbaum Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Mon, 14 Nov 2022 06:33:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 58711 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: moreinfo Original-Received: via spool by 58711-submit@debbugs.gnu.org id=B58711.166840758030808 (code B ref 58711); Mon, 14 Nov 2022 06:33:02 +0000 Original-Received: (at 58711) by debbugs.gnu.org; 14 Nov 2022 06:33:00 +0000 Original-Received: from localhost ([127.0.0.1]:48814 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ouT1g-00080p-2D for submit@debbugs.gnu.org; Mon, 14 Nov 2022 01:33:00 -0500 Original-Received: from mail-lf1-f47.google.com ([209.85.167.47]:40555) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ouT1e-00080Z-5h for 58711@debbugs.gnu.org; Mon, 14 Nov 2022 01:32:59 -0500 Original-Received: by mail-lf1-f47.google.com with SMTP id c1so17722777lfi.7 for <58711@debbugs.gnu.org>; Sun, 13 Nov 2022 22:32:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=floatpays.co.za; s=google; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=n9kNX+LpoSeSs+pIAJPz+2bZZIB7O/TUjaClzw0Ak1s=; b=alfefOHW6qrEEXCs1VODVGgrtHWYkbkRMU1at37fmPtVtSG9Qc6gZJFtaSiaRPoHKm Ldu3dnsqnMbNEexrfOPYnpfI4QvK8G1reMPvmMwKedJNeJkcAhgd5Fj23Qp2/GXkyKLS A7Iqz8gVhrO3BjliXMczV7n3SA3VTARAmkP1M= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=n9kNX+LpoSeSs+pIAJPz+2bZZIB7O/TUjaClzw0Ak1s=; b=Tzu+2BJWikCUW2QuUNYfy+PcFDCJYSO6t+IK+OnbyhDzH52VtLJH5n587ZIRqgpIdL Q6GxUnbbMJan9whvPhuozbULPIHLmPC3qwEuHXbBrRMSOtm8hteUcbQLRgxnHRP9yrOx Qn7E46m4ftlVkUjC/Cy3THeanqk4uDzTq6bsS8HjkaujSPX9Uyusu4cJeUe5Jk1mitXW A5BBeAyGrXY3t172Bi/2crbTZX51hGo3e+KoYuR07OVhXDZHJEXFfOTGX0du8ojUpOFc MTpOePIxLb52sdp+K5hwFEsvuu4VQ1cIyKf4p9IurLaAPZaaVRdVGMvwccxGK05OLQY2 whgg== X-Gm-Message-State: ANoB5pm+S5/s8erGA4n9PgLmxds18n1GT8QSIjFZDY/l8JwDE9A1jHN+ eYWQhWdjCaO6ZnFn99hNWWKVE2OFH1bX7wQrW2aGZA== X-Google-Smtp-Source: AA0mqf5FS96CfCCNXsjrr/aiTM39yWLhrHircDwQFLlvPY2Vm91pCAwhrKpvFdPtYkf3lBCZlK7BM7cNr/6tzYR7m6Y= X-Received: by 2002:ac2:4ac9:0:b0:4ac:102e:5c93 with SMTP id m9-20020ac24ac9000000b004ac102e5c93mr4234396lfp.352.1668407571765; Sun, 13 Nov 2022 22:32:51 -0800 (PST) In-Reply-To: X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.bugs:247854 Archived-At: --000000000000a7f1aa05ed686807 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable This works for me for all cases I managed to test: ( I have to keep track of the EOL and BOL to ensure that we don't jump to parents or children. ) (defun heex--treesit-largest-node-at-point (&optional node) "Find the largest node at point or from specified NODE." (save-excursion (forward-comment (point-max)) (let ((node-list (cl-loop for node =3D (or node (treesit-node-at (point))) then (treesit-node-parent node) while (and node (not (equal (treesit-node-type node) "fragment"))) if (eq (treesit-node-start node) (point)) collect node))) (car (last node-list))))) (defun heex--treesit-backward-sexp () "Forward sexp for Heex using treesit." (let ((node (save-excursion (forward-comment (- (point-max))) (let ((bol (pos-bol)) (end-node (treesit-search-forward-goto (treesit-node-at (point)) (rx (or "end_tag" "end_component" "end_slot")) t t))) (if (and end-node (> (treesit-node-end end-node) bol)) (treesit-node-start (treesit-node-parent end-node))))))) (when node (goto-char node)))) (defun heex--treesit-forward-sexp () "Forward sexp for Heex using treesit." (let* ((node (heex--treesit-largest-node-at-point)) (sibling (treesit-node-next-sibling node))) (if sibling (progn (goto-char (treesit-node-start sibling)) (forward-comment (- (point-max)))) (when node (pcase (treesit-node-type node) ((or "end_tag" "end_component" "end_slot") nil) (_ (goto-char (treesit-node-end node)))))))) On Fri, 11 Nov 2022 at 08:30, Wilhelm Kirschbaum wrote: > Thank you. I will spend some time over the weekend to try and have a look= . > > On Fri, 11 Nov 2022 at 00:07, Yuan Fu wrote: > >> >> >> > On Nov 10, 2022, at 12:43 PM, Wilhelm Kirschbaum < >> wilhelm@floatpays.co.za> wrote: >> > >> > Given the following code >> > >> > <.foo> ;; component, start_component >> > ;; tag, start_tag >> > ;; [cursor here 1)] end_tag >> > ;; [cursor here 2] end_component >> > >> > and ast >> > >> > (fragment [0, 0] - [5, 0] >> > (component [0, 0] - [3, 7] >> > (start_component [0, 0] - [0, 6] >> > (component_name [0, 1] - [0, 5] >> > (function [0, 2] - [0, 5]))) >> > (tag [1, 2] - [2, 8] >> > (start_tag [1, 2] - [1, 7] >> > (tag_name [1, 3] - [1, 6])) >> > (end_tag [2, 2] - [2, 8] >> > (tag_name [2, 4] - [2, 7]))) >> > (end_component [3, 0] - [3, 7] >> > (component_name [3, 2] - [3, 6] >> > (function [3, 3] - [3, 6]))))) >> > >> > I do not know how to reliably move from cursor position 1 to start of >> and from cursor position 2 to start of <.foo> >> >> The snippet below should take you to the corresponding open tag. >> >> (let ((end-node (treesit-search-forward-goto >> (treesit-node-at (point)) >> (rx (or "end_tag" "end_component" "end_slot")) t t))) >> ;; Go to the corresponding start tag. >> (goto-char (treesit-node-start (treesit-node-parent end-node)))) >> >> > >> > as (treesit-search-forward (treesit-node-at (point)) (rx (or "end_tag" >> "end_component" "end_slot")) t) on position 1 will not look backwards, b= ut >> find the <./foo> end_component. >> > >> > if i am at the point after the node, how do I find the node before the >> point? once we have the node before the point we can find the correct >> parent and then find the prev sibling to goto. >> > >> > Hope this makes sense. >> >> Yeah, if there is a function that gives you the node right before point, >> treesit-search-forward would work as expected. I=E2=80=99ll see how to a= dd this >> functionality. >> >> Yuan > > --000000000000a7f1aa05ed686807 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
This works for me for all cases I managed to test:

( I have to keep track of the EOL and BOL to ensure = that we don't jump to parents or children. )

(defun heex--= treesit-largest-node-at-point (&optional node)
=C2=A0 "Find the= largest node at point or from specified NODE."
=C2=A0 (save-excurs= ion
=C2=A0 =C2=A0 (forward-comment (point-max))
=C2=A0 =C2=A0 (let ((= node-list
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(cl-loop for node =3D= (or node (treesit-node-at (point)))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 then (treesit-node-parent node)
=C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 while (a= nd node (not (equal (treesit-node-type node) "fragment")))
=C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (eq (= treesit-node-start node)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(point))
=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 collect node)))=
=C2=A0 =C2=A0 =C2=A0 (car (last node-list)))))

(defun heex--tree= sit-backward-sexp ()
=C2=A0 "Forward sexp for Heex using treesit.&q= uot;
=C2=A0 (let ((node
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(save-excur= sion
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(forward-comment (- (point= -max)))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(let ((bol (pos-bol))=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(end-node (= treesit-search-forward-goto
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (treesit-node-at (p= oint))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (rx (or "end_tag" "end_co= mponent" "end_slot")) t t)))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0(if (and end-node (> (treesit-node-end end-node) bol= ))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(treesi= t-node-start (treesit-node-parent end-node)))))))
=C2=A0 =C2=A0 (when no= de (goto-char node))))

(defun heex--treesit-forward-sexp ()
=C2= =A0 "Forward sexp for Heex using treesit."
=C2=A0 (let* ((node= (heex--treesit-largest-node-at-point))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0(sibling (treesit-node-next-sibling node)))
=C2=A0 =C2=A0 (if sibling=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 (progn
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 (goto-char (treesit-node-start sibling))
=C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 (forward-comment (- (point-max))))
=C2=A0 =C2=A0 =C2=A0 (when no= de
=C2=A0 =C2=A0 =C2=A0 =C2=A0 (pcase (treesit-node-type node)
=C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 ((or "end_tag" "end_component&q= uot; "end_slot") nil)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (_ (g= oto-char (treesit-node-end node))))))))

On Fri, 11 Nov 2022 at 08:30, Wilhel= m Kirschbaum <wilhelm@floatpa= ys.co.za> wrote:
Thank you. I will spend some time over the weekend= to try and have a look.

On Fri, 11 Nov 2022 at 00:07, Yuan Fu <casouri@gmail.com&g= t; wrote:


> On Nov 10, 2022, at 12:43 PM, Wilhelm Kirschbaum <wilhelm@floatpays.co.za>= wrote:
>
> Given the following code
>
>=C2=A0 <.foo>=C2=A0 ;; component, start_component
>=C2=A0 <bar>=C2=A0 ;; tag, start_tag
>=C2=A0 =C2=A0</bar>;; [cursor here 1)] end_tag
> </.foo> ;; [cursor here 2] end_component
>
> and ast
>
> (fragment [0, 0] - [5, 0]
>=C2=A0 =C2=A0(component [0, 0] - [3, 7]
>=C2=A0 =C2=A0 =C2=A0(start_component [0, 0] - [0, 6]
>=C2=A0 =C2=A0 =C2=A0 =C2=A0(component_name [0, 1] - [0, 5]
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(function [0, 2] - [0, 5])))
>=C2=A0 =C2=A0 =C2=A0(tag [1, 2] - [2, 8]
>=C2=A0 =C2=A0 =C2=A0 =C2=A0(start_tag [1, 2] - [1, 7]
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(tag_name [1, 3] - [1, 6]))
>=C2=A0 =C2=A0 =C2=A0 =C2=A0(end_tag [2, 2] - [2, 8]
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(tag_name [2, 4] - [2, 7])))
>=C2=A0 =C2=A0 =C2=A0(end_component [3, 0] - [3, 7]
>=C2=A0 =C2=A0 =C2=A0 =C2=A0(component_name [3, 2] - [3, 6]
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(function [3, 3] - [3, 6])))))
>
> I do not know how to reliably move from cursor position 1 to start of = <bar> and from cursor position 2 to start of <.foo>

The snippet below should take you to the corresponding open tag.

(let ((end-node (treesit-search-forward-goto
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(treesit-node= -at (point))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(rx (or "= ;end_tag" "end_component" "end_slot")) t t)))
=C2=A0 ;; Go to the corresponding start tag.
=C2=A0 (goto-char (treesit-node-start (treesit-node-parent end-node))))

>
> as (treesit-search-forward (treesit-node-at (point)) (rx (or "end= _tag" "end_component" "end_slot")) t) on position = 1 will not look backwards, but find the <./foo> end_component.
>
> if i am at the point after the node, how do I find the node before the= point? once we have the node before the point we can find the correct pare= nt and then find the prev sibling to goto.
>
> Hope this makes sense.

Yeah, if there is a function that gives you the node right before point, tr= eesit-search-forward would work as expected. I=E2=80=99ll see how to add th= is functionality.

Yuan
--000000000000a7f1aa05ed686807--