Package: emacs;
Reported by: Wilhelm Kirschbaum <wkirschbaum <at> gmail.com>
Date: Sat, 22 Oct 2022 09:55:01 UTC
Severity: normal
Tags: moreinfo
Fixed in version 29.1
Done: Yuan Fu <casouri <at> gmail.com>
Bug is archived. No further changes may be made.
To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 58711 in the body.
You can then email your comments to 58711 AT debbugs.gnu.org in the normal way.
Toggle the display of automated, internal messages from the tracker.
View this report as an mbox folder, status mbox, maintainer mbox
bug-gnu-emacs <at> gnu.org
:bug#58711
; Package emacs
.
(Sat, 22 Oct 2022 09:55:02 GMT) Full text and rfc822 format available.Wilhelm Kirschbaum <wkirschbaum <at> gmail.com>
:bug-gnu-emacs <at> gnu.org
.
(Sat, 22 Oct 2022 09:55:02 GMT) Full text and rfc822 format available.Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):
From: Wilhelm Kirschbaum <wkirschbaum <at> gmail.com> To: bug-gnu-emacs <at> gnu.org Subject: Treesit hangs when calling treesit-search-forward Date: Sat, 22 Oct 2022 11:53:50 +0200
[Message part 1 (text/plain, inline)]
I am attempting to implement treesit for the current elixir-mode using the branch feature/trees-sitter. For implementing beginning-of-defun-function using treesit I am running into an issue where the Emacs will hang indefinitely. Using (setq-local treesit-defun-type-regexp (rx (or "call"))) yields the same result. For the following node-at-point output (do_block (call target: (identifier))) with Elixir code # foo.ex defmodule Foo do <<point/cursor here>>def bar(), do: "bar" end When I call `(treesit-search-forward-goto (rx (or "call")) 'start nil t)` the function `treesit-search-forward` seems to get stuck. Elixir does not strictly have a begin function, but can be determined as one of the following: ; * modules and protocols (call target: (identifier) @ignore (arguments (alias) @name) (#match? @ignore "^(defmodule|defprotocol)$")) @definition.module ; * functions/macros (call target: (identifier) @ignore (arguments [ ; zero-arity functions with no parentheses (identifier) @name ; regular function clause (call target: (identifier) @name) ; function clause with a guard clause (binary_operator left: (call target: (identifier) @name) operator: "when") ]) (#match? @ignore "^(def|defp|defdelegate|defguard|defguardp|defmacro|defmacrop|defn|defnp)$")) @definition.function The elixir tree sitter implementation is here: https://github.com/elixir-lang/tree-sitter-elixir I lack the knowledge to further debug this or find a clean workaround, but I'm almost sure that treesit-search-forward should never hang. In GNU Emacs 29.0.50 (build 3, x86_64-pc-linux-gnu, GTK+ Version 3.24.34, cairo version 1.17.6) of 2022-10-22 built on melissa.local Repository revision: 7c750343be6309a78d3fd289959bca241d9daf5d Repository branch: feature/tree-sitter Windowing system distributor 'The X.Org Foundation', version 11.0.12101004 System Description: Arch Linux Configured using: 'configure --with-tree-sitter --with-native-compilation' Configured features: ACL CAIRO DBUS FREETYPE GIF GLIB GMP GNUTLS GPM GSETTINGS HARFBUZZ JPEG JSON TREE-SITTER LCMS2 LIBSYSTEMD LIBXML2 MODULES NATIVE_COMP NOTIFY INOTIFY PDUMPER PNG RSVG SECCOMP SOUND SQLITE3 THREADS TIFF TOOLKIT_SCROLL_BARS WEBP X11 XDBE XIM XINPUT2 XPM GTK3 ZLIB Important settings: value of $LANG: en_ZA.UTF-8 locale-coding-system: utf-8-unix Major mode: Lisp Interaction Minor modes in effect: tooltip-mode: t global-eldoc-mode: t eldoc-mode: t show-paren-mode: t electric-indent-mode: t mouse-wheel-mode: t tool-bar-mode: t menu-bar-mode: t file-name-shadow-mode: t global-font-lock-mode: t font-lock-mode: t blink-cursor-mode: t line-number-mode: t indent-tabs-mode: t transient-mark-mode: t auto-composition-mode: t auto-encryption-mode: t auto-compression-mode: t Load-path shadows: None found. Features: (shadow sort mail-extr emacsbug message mailcap yank-media puny dired dired-loaddefs rfc822 mml mml-sec password-cache epa epg rfc6068 epg-config gnus-util text-property-search mm-decode mm-bodies mm-encode mail-parse rfc2231 mailabbrev gmm-utils mailheader sendmail rfc2047 rfc2045 ietf-drums mm-util mail-prsvr mail-utils time-date comp comp-cstr warnings icons subr-x cl-extra help-mode bytecomp byte-compile cconv elixir-mode derived rx pcase cl-macs gv treesit cl-seq cl-loaddefs cl-lib rmc iso-transl tooltip eldoc paren electric uniquify ediff-hook vc-hooks lisp-float-type elisp-mode mwheel term/x-win x-win term/common-win x-dnd tool-bar dnd fontset image regexp-opt fringe tabulated-list replace newcomment text-mode lisp-mode prog-mode register page tab-bar menu-bar rfn-eshadow isearch easymenu timer select scroll-bar mouse jit-lock font-lock syntax font-core term/tty-colors frame minibuffer nadvice seq simple cl-generic indonesian philippine cham georgian utf-8-lang misc-lang vietnamese tibetan thai tai-viet lao korean japanese eucjp-ms cp51932 hebrew greek romanian slovak czech european ethiopic indian cyrillic chinese composite emoji-zwj charscript charprop case-table epa-hook jka-cmpr-hook help abbrev obarray oclosure cl-preloaded button loaddefs faces cus-face macroexp files window text-properties overlay sha1 md5 base64 format env code-pages mule custom widget keymap hashtable-print-readable backquote threads dbusbind inotify lcms2 dynamic-setting system-font-setting font-render-setting cairo move-toolbar gtk x-toolkit xinput2 x multi-tty make-network-process native-compile emacs) Memory information: ((conses 16 81171 6071) (symbols 48 7449 0) (strings 32 20132 1351) (string-bytes 1 613689) (vectors 16 15685) (vector-slots 8 324392 11268) (floats 8 27 29) (intervals 56 211 0) (buffers 1008 11))
[Message part 2 (text/html, inline)]
bug-gnu-emacs <at> gnu.org
:bug#58711
; Package emacs
.
(Sat, 22 Oct 2022 10:27:01 GMT) Full text and rfc822 format available.Message #8 received at 58711 <at> debbugs.gnu.org (full text, mbox):
From: Wilhelm Kirschbaum <wkirschbaum <at> gmail.com> To: 58711 <at> debbugs.gnu.org Subject: The full tree-sitter parse output Date: Sat, 22 Oct 2022 12:26:02 +0200
[Message part 1 (text/plain, inline)]
This is the full tree-sitter parse output for the use case mentioned: (source [0, 0] - [4, 3] (call [0, 0] - [4, 3] target: (identifier [0, 0] - [0, 9]) (arguments [0, 10] - [0, 13] (alias [0, 10] - [0, 13])) (do_block [0, 14] - [4, 3] (call [1, 2] - [3, 5] target: (identifier [1, 2] - [1, 5]) (arguments [1, 6] - [1, 11] (call [1, 6] - [1, 11] target: (identifier [1, 6] - [1, 9]) (arguments [1, 9] - [1, 11]))) (do_block [1, 12] - [3, 5] (string [2, 4] - [2, 9] (quoted_content [2, 5] - [2, 8])))))))
[Message part 2 (text/html, inline)]
bug-gnu-emacs <at> gnu.org
:bug#58711
; Package emacs
.
(Sun, 23 Oct 2022 06:43:02 GMT) Full text and rfc822 format available.Message #11 received at 58711 <at> debbugs.gnu.org (full text, mbox):
From: Yuan Fu <casouri <at> gmail.com> To: Wilhelm Kirschbaum <wkirschbaum <at> gmail.com> Cc: 58711 <at> debbugs.gnu.org Subject: Re: bug#58711: Treesit hangs when calling treesit-search-forward Date: Sat, 22 Oct 2022 23:42:23 -0700
> On Oct 22, 2022, at 2:53 AM, Wilhelm Kirschbaum <wkirschbaum <at> gmail.com> wrote: > > I am attempting to implement treesit for the current elixir-mode using the branch feature/trees-sitter. For implementing beginning-of-defun-function using treesit I am running into an issue where the Emacs will hang indefinitely. Using (setq-local treesit-defun-type-regexp (rx (or "call"))) yields the same result. > > For the following node-at-point output > > (do_block (call target: (identifier))) > > with Elixir code > > # foo.ex > defmodule Foo do > <<point/cursor here>>def bar(), do: "bar" > end > > When I call `(treesit-search-forward-goto (rx (or "call")) 'start nil t)` the function `treesit-search-forward` seems to get stuck. > > Elixir does not strictly have a begin function, but can be determined as one of the following: > ; * modules and protocols > (call > target: (identifier) @ignore > (arguments (alias) @name) > (#match? @ignore "^(defmodule|defprotocol)$")) @definition.module > > ; * functions/macros > (call > target: (identifier) @ignore > (arguments > [ > ; zero-arity functions with no parentheses > (identifier) @name > ; regular function clause > (call target: (identifier) @name) > ; function clause with a guard clause > (binary_operator > left: (call target: (identifier) @name) > operator: "when") > ]) > (#match? @ignore "^(def|defp|defdelegate|defguard|defguardp|defmacro|defmacrop|defn|defnp)$")) @definition.function > > The elixir tree sitter implementation is here: https://github.com/elixir-lang/tree-sitter-elixir > > I lack the knowledge to further debug this or find a clean workaround, but I'm almost sure that treesit-search-forward should never hang. Thanks for reporting this. The way treesit-search-forward-goto works makes it very to have infinite loops. I revised the way it traverses the tree and now it should be impossible to fall into infinite loops. Yuan
bug-gnu-emacs <at> gnu.org
:bug#58711
; Package emacs
.
(Sun, 23 Oct 2022 23:21:02 GMT) Full text and rfc822 format available.Message #14 received at 58711 <at> debbugs.gnu.org (full text, mbox):
From: Yuan Fu <casouri <at> gmail.com> To: Wilhelm Kirschbaum <wkirschbaum <at> gmail.com> Cc: 58711 <at> debbugs.gnu.org Subject: Re: bug#58711: Treesit hangs when calling treesit-search-forward Date: Sun, 23 Oct 2022 16:20:01 -0700
> On Oct 22, 2022, at 11:42 PM, Yuan Fu <casouri <at> gmail.com> wrote: > > > >> On Oct 22, 2022, at 2:53 AM, Wilhelm Kirschbaum <wkirschbaum <at> gmail.com> wrote: >> >> I am attempting to implement treesit for the current elixir-mode using the branch feature/trees-sitter. For implementing beginning-of-defun-function using treesit I am running into an issue where the Emacs will hang indefinitely. Using (setq-local treesit-defun-type-regexp (rx (or "call"))) yields the same result. >> >> For the following node-at-point output >> >> (do_block (call target: (identifier))) >> >> with Elixir code >> >> # foo.ex >> defmodule Foo do >> <<point/cursor here>>def bar(), do: "bar" >> end >> >> When I call `(treesit-search-forward-goto (rx (or "call")) 'start nil t)` the function `treesit-search-forward` seems to get stuck. >> >> Elixir does not strictly have a begin function, but can be determined as one of the following: >> ; * modules and protocols >> (call >> target: (identifier) @ignore >> (arguments (alias) @name) >> (#match? @ignore "^(defmodule|defprotocol)$")) @definition.module >> >> ; * functions/macros >> (call >> target: (identifier) @ignore >> (arguments >> [ >> ; zero-arity functions with no parentheses >> (identifier) @name >> ; regular function clause >> (call target: (identifier) @name) >> ; function clause with a guard clause >> (binary_operator >> left: (call target: (identifier) @name) >> operator: "when") >> ]) >> (#match? @ignore "^(def|defp|defdelegate|defguard|defguardp|defmacro|defmacrop|defn|defnp)$")) @definition.function >> >> The elixir tree sitter implementation is here: https://github.com/elixir-lang/tree-sitter-elixir >> >> I lack the knowledge to further debug this or find a clean workaround, but I'm almost sure that treesit-search-forward should never hang. > > Thanks for reporting this. The way treesit-search-forward-goto works makes it very to have infinite loops. I revised the way it traverses the tree and now it should be impossible to fall into infinite loops. > > Yuan Just a heads up: I changed the function signature of treesit-search-forward-goto in the latest commit. Yuan
bug-gnu-emacs <at> gnu.org
:bug#58711
; Package emacs
.
(Mon, 24 Oct 2022 18:21:02 GMT) Full text and rfc822 format available.Message #17 received at 58711 <at> debbugs.gnu.org (full text, mbox):
From: Wilhelm Hugo Kirschbaum <wilhelm <at> floatpays.co.za> To: Yuan Fu <casouri <at> gmail.com> Cc: 58711 <at> debbugs.gnu.org Subject: Re: bug#58711: Treesit hangs when calling treesit-search-forward Date: Mon, 24 Oct 2022 19:06:58 +0200
On Monday, 24 October 2022 01:20:01 SAST Yuan Fu wrote: > > On Oct 22, 2022, at 11:42 PM, Yuan Fu <casouri <at> gmail.com> wrote: > >> On Oct 22, 2022, at 2:53 AM, Wilhelm Kirschbaum <wkirschbaum <at> gmail.com> > >> wrote: > >> > >> I am attempting to implement treesit for the current elixir-mode using > >> the branch feature/trees-sitter. For implementing > >> beginning-of-defun-function using treesit I am running into an issue > >> where the Emacs will hang indefinitely. Using (setq-local > >> treesit-defun-type-regexp (rx (or "call"))) yields the same result. > >> > >> For the following node-at-point output > >> > >> (do_block (call target: (identifier))) > >> > >> with Elixir code > >> > >> # foo.ex > >> defmodule Foo do > >> > >> <<point/cursor here>>def bar(), do: "bar" > >> > >> end > >> > >> When I call `(treesit-search-forward-goto (rx (or "call")) 'start nil t)` > >> the function `treesit-search-forward` seems to get stuck. > >> > >> Elixir does not strictly have a begin function, but can be determined as > >> one of the following: ; * modules and protocols > >> (call > >> > >> target: (identifier) @ignore > >> (arguments (alias) @name) > >> (#match? @ignore "^(defmodule|defprotocol)$")) @definition.module > >> > >> ; * functions/macros > >> (call > >> > >> target: (identifier) @ignore > >> (arguments > >> > >> [ > >> > >> ; zero-arity functions with no parentheses > >> (identifier) @name > >> ; regular function clause > >> (call target: (identifier) @name) > >> ; function clause with a guard clause > >> (binary_operator > >> > >> left: (call target: (identifier) @name) > >> operator: "when") > >> > >> ]) > >> > >> (#match? @ignore > >> "^(def|defp|defdelegate|defguard|defguardp|defmacro|defmacrop|defn|defn > >> p)$")) @definition.function>> > >> The elixir tree sitter implementation is here: > >> https://github.com/elixir-lang/tree-sitter-elixir > >> > >> I lack the knowledge to further debug this or find a clean workaround, > >> but I'm almost sure that treesit-search-forward should never hang.> > > Thanks for reporting this. The way treesit-search-forward-goto works makes > > it very to have infinite loops. I revised the way it traverses the tree > > and now it should be impossible to fall into infinite loops. > > > > Yuan > > Just a heads up: I changed the function signature of > treesit-search-forward-goto in the latest commit. > > Yuan Thanks, I would need some time to have a proper look. The reporting issue seems to have been fixed. There are some complications to identify the appropriate node for defun in elixir as a "call" node might, or might not be defun, depending on its child identifier ( i currently have to do a query on cycling up the parent ), but will try the respond in more detail in another thread.
bug-gnu-emacs <at> gnu.org
:bug#58711
; Package emacs
.
(Mon, 24 Oct 2022 20:20:01 GMT) Full text and rfc822 format available.Message #20 received at 58711 <at> debbugs.gnu.org (full text, mbox):
From: Yuan Fu <casouri <at> gmail.com> To: Wilhelm Hugo Kirschbaum <wilhelm <at> floatpays.co.za> Cc: 58711 <at> debbugs.gnu.org Subject: Re: bug#58711: Treesit hangs when calling treesit-search-forward Date: Mon, 24 Oct 2022 13:19:25 -0700
> > Thanks, I would need some time to have a proper look. The reporting issue > seems to have been fixed. There are some complications to identify the > appropriate node for defun in elixir as a "call" node might, or might not be > defun, depending on its child identifier ( i currently have to do a query on > cycling up the parent ), but will try the respond in more detail in another > thread. While fixing the hanging issue, I also improved treesit-beginning-of-defun, which now first goes backward to find a node that matches tresit-defun-type-regexp, then goes upward and finds the top-most parent matching treesit-defun-type-regexp, IOW, it now only stops at top-level defun matches. Does that help with your case? Yuan
bug-gnu-emacs <at> gnu.org
:bug#58711
; Package emacs
.
(Thu, 10 Nov 2022 06:46:02 GMT) Full text and rfc822 format available.Message #23 received at 58711 <at> debbugs.gnu.org (full text, mbox):
From: Wilhelm Kirschbaum <wilhelm <at> floatpays.co.za> To: Yuan Fu <casouri <at> gmail.com> Cc: 58711 <at> debbugs.gnu.org Subject: Re: bug#58711: Treesit hangs when calling treesit-search-forward Date: Thu, 10 Nov 2022 08:44:50 +0200
[Message part 1 (text/plain, inline)]
I finally had some time to have a look. I don't see any more issues, thank you for the fantastic work on this. The defun-type-regexp is not enough to identify a defun in elixir this is the query I am using currently: (defvar elixir--treesit-query-defun (let ((query `((call target: (identifier) @type (arguments [ (alias) @name (identifier) @name (call target: (identifier)) @name (binary_operator left: (call target: (identifier)) @name operator: "when") ]) (:match ,elixir--definition-keywords-re @type) )))) (treesit-query-compile 'elixir query))) Regex will work in most cases I guess, but does not really deal with more complex queries for more complex cases like in elixir as there is not one type which is always the defun. elixir relies heavily on macros and different defun macros can be defined on the fly. Maybe if there is an option for using either a regex or a function? I am also not sure how forward-sexp can work with the current treesit-search-forward-goto function as it does not take into consideration the level. Is there perhaps a way to move forward/backward, but do not jump to parents or children? On Mon, 24 Oct 2022 at 22:19, Yuan Fu <casouri <at> gmail.com> wrote: > > > > Thanks, I would need some time to have a proper look. The reporting > issue > > seems to have been fixed. There are some complications to identify the > > appropriate node for defun in elixir as a "call" node might, or might > not be > > defun, depending on its child identifier ( i currently have to do a > query on > > cycling up the parent ), but will try the respond in more detail in > another > > thread. > > While fixing the hanging issue, I also improved > treesit-beginning-of-defun, which now first goes backward to find a node > that matches tresit-defun-type-regexp, then goes upward and finds the > top-most parent matching treesit-defun-type-regexp, IOW, it now only stops > at top-level defun matches. Does that help with your case? > > Yuan
[Message part 2 (text/html, inline)]
bug-gnu-emacs <at> gnu.org
:bug#58711
; Package emacs
.
(Thu, 10 Nov 2022 08:15:02 GMT) Full text and rfc822 format available.Message #26 received at 58711 <at> debbugs.gnu.org (full text, mbox):
From: Yuan Fu <casouri <at> gmail.com> To: Wilhelm Kirschbaum <wilhelm <at> floatpays.co.za> Cc: 58711 <at> debbugs.gnu.org Subject: Re: bug#58711: Treesit hangs when calling treesit-search-forward Date: Thu, 10 Nov 2022 00:14:27 -0800
> On Nov 9, 2022, at 10:44 PM, Wilhelm Kirschbaum <wilhelm <at> floatpays.co.za> wrote: > > I finally had some time to have a look. I don't see any more issues, thank you for the fantastic work on this. The defun-type-regexp is not enough to identify a defun in elixir this is the query I am using currently: > > (defvar elixir--treesit-query-defun > (let ((query `((call > target: (identifier) @type > (arguments > [ > (alias) @name > (identifier) @name > (call target: (identifier)) @name > (binary_operator > left: (call target: (identifier)) @name > operator: "when") > ]) > (:match ,elixir--definition-keywords-re @type) > )))) > (treesit-query-compile 'elixir query))) > > Regex will work in most cases I guess, but does not really deal with more complex queries for more complex cases like in elixir as there is not one type which is always the defun. elixir relies heavily on macros and different defun macros can be defined on the fly. You can try the following procedure: use a regex to find the next/previous call, then perform some check on whether it’s indeed a defun, if not, keep searching for the next/previous call. > Maybe if there is an option for using either a regex or a function? Yes, instead of a regex you can pass a predicate function. > > I am also not sure how forward-sexp can work with the current treesit-search-forward-goto function as it does not take into consideration the level. Is there perhaps a way to move forward/backward, but do not jump to parents or children? If you want to move in the same level, perhaps you can use treesit-next/prev/sibling? Yuan
bug-gnu-emacs <at> gnu.org
:bug#58711
; Package emacs
.
(Thu, 10 Nov 2022 19:04:01 GMT) Full text and rfc822 format available.Message #29 received at 58711 <at> debbugs.gnu.org (full text, mbox):
From: Wilhelm Kirschbaum <wilhelm <at> floatpays.co.za> To: Yuan Fu <casouri <at> gmail.com> Cc: 58711 <at> debbugs.gnu.org Subject: Re: bug#58711: Treesit hangs when calling treesit-search-forward Date: Thu, 10 Nov 2022 21:03:06 +0200
[Message part 1 (text/plain, inline)]
forward-sexp works well with the below code, but when calling treesit-node-prev-sibling it will traverse up the list, which is then breaking backward-up-list when defining forward-sexp in the major mode. (defun heex--treesit-largest-node-at-point () "Find the largest node at point." (save-excursion (forward-comment (point-max)) (let ((node-list (cl-loop for node = (treesit-node-at (point)) then (treesit-node-parent node) while node 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* ((largest-node (heex--treesit-largest-node-at-point)) (sibling (treesit-node-prev-sibling largest-node))) (when sibling (goto-char (treesit-node-start sibling))))) (defun heex--treesit-forward-sexp () "Forward sexp for Heex using treesit." (let* ((largest-node (heex--treesit-largest-node-at-point)) (sibling (treesit-node-next-sibling largest-node))) (when sibling (goto-char (treesit-node-start sibling)) (forward-comment (- (point-max)))))) On Thu, 10 Nov 2022 at 10:14, Yuan Fu <casouri <at> gmail.com> wrote: > > > > On Nov 9, 2022, at 10:44 PM, Wilhelm Kirschbaum <wilhelm <at> floatpays.co.za> > wrote: > > > > I finally had some time to have a look. I don't see any more issues, > thank you for the fantastic work on this. The defun-type-regexp is not > enough to identify a defun in elixir this is the query I am using currently: > > > > (defvar elixir--treesit-query-defun > > (let ((query `((call > > target: (identifier) @type > > (arguments > > [ > > (alias) @name > > (identifier) @name > > (call target: (identifier)) @name > > (binary_operator > > left: (call target: (identifier)) @name > > operator: "when") > > ]) > > (:match ,elixir--definition-keywords-re @type) > > )))) > > (treesit-query-compile 'elixir query))) > > > > Regex will work in most cases I guess, but does not really deal with > more complex queries for more complex cases like in elixir as there is not > one type which is always the defun. elixir relies heavily on macros and > different defun macros can be defined on the fly. > > You can try the following procedure: use a regex to find the next/previous > call, then perform some check on whether it’s indeed a defun, if not, keep > searching for the next/previous call. > > > > Maybe if there is an option for using either a regex or a function? > > Yes, instead of a regex you can pass a predicate function. > > > > > I am also not sure how forward-sexp can work with the current > treesit-search-forward-goto function as it does not take into consideration > the level. Is there perhaps a way to move forward/backward, but do not jump > to parents or children? > > If you want to move in the same level, perhaps you can use > treesit-next/prev/sibling? > > Yuan
[Message part 2 (text/html, inline)]
bug-gnu-emacs <at> gnu.org
:bug#58711
; Package emacs
.
(Thu, 10 Nov 2022 19:06:02 GMT) Full text and rfc822 format available.Message #32 received at 58711 <at> debbugs.gnu.org (full text, mbox):
From: Wilhelm Kirschbaum <wilhelm <at> floatpays.co.za> To: Yuan Fu <casouri <at> gmail.com> Cc: 58711 <at> debbugs.gnu.org Subject: Re: bug#58711: Treesit hangs when calling treesit-search-forward Date: Thu, 10 Nov 2022 21:05:07 +0200
[Message part 1 (text/plain, inline)]
Full implementation here: https://github.com/wkirschbaum/elixir-mode/blob/main/heex-mode.el On Thu, 10 Nov 2022 at 21:03, Wilhelm Kirschbaum <wilhelm <at> floatpays.co.za> wrote: > forward-sexp works well with the below code, but when calling > treesit-node-prev-sibling it will traverse up the list, which is then > breaking backward-up-list when defining forward-sexp in the major mode. > > (defun heex--treesit-largest-node-at-point () > "Find the largest node at point." > (save-excursion > (forward-comment (point-max)) > (let ((node-list > (cl-loop for node = (treesit-node-at (point)) > then (treesit-node-parent node) > while node > 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* ((largest-node (heex--treesit-largest-node-at-point)) > (sibling (treesit-node-prev-sibling largest-node))) > (when sibling > (goto-char (treesit-node-start sibling))))) > > (defun heex--treesit-forward-sexp () > "Forward sexp for Heex using treesit." > (let* ((largest-node (heex--treesit-largest-node-at-point)) > (sibling (treesit-node-next-sibling largest-node))) > (when sibling > (goto-char (treesit-node-start sibling)) > (forward-comment (- (point-max)))))) > > On Thu, 10 Nov 2022 at 10:14, Yuan Fu <casouri <at> gmail.com> wrote: > >> >> >> > On Nov 9, 2022, at 10:44 PM, Wilhelm Kirschbaum < >> wilhelm <at> floatpays.co.za> wrote: >> > >> > I finally had some time to have a look. I don't see any more issues, >> thank you for the fantastic work on this. The defun-type-regexp is not >> enough to identify a defun in elixir this is the query I am using currently: >> > >> > (defvar elixir--treesit-query-defun >> > (let ((query `((call >> > target: (identifier) @type >> > (arguments >> > [ >> > (alias) @name >> > (identifier) @name >> > (call target: (identifier)) @name >> > (binary_operator >> > left: (call target: (identifier)) @name >> > operator: "when") >> > ]) >> > (:match ,elixir--definition-keywords-re @type) >> > )))) >> > (treesit-query-compile 'elixir query))) >> > >> > Regex will work in most cases I guess, but does not really deal with >> more complex queries for more complex cases like in elixir as there is not >> one type which is always the defun. elixir relies heavily on macros and >> different defun macros can be defined on the fly. >> >> You can try the following procedure: use a regex to find the >> next/previous call, then perform some check on whether it’s indeed a defun, >> if not, keep searching for the next/previous call. >> >> >> > Maybe if there is an option for using either a regex or a function? >> >> Yes, instead of a regex you can pass a predicate function. >> >> > >> > I am also not sure how forward-sexp can work with the current >> treesit-search-forward-goto function as it does not take into consideration >> the level. Is there perhaps a way to move forward/backward, but do not jump >> to parents or children? >> >> If you want to move in the same level, perhaps you can use >> treesit-next/prev/sibling? >> >> Yuan > >
[Message part 2 (text/html, inline)]
bug-gnu-emacs <at> gnu.org
:bug#58711
; Package emacs
.
(Thu, 10 Nov 2022 19:34:01 GMT) Full text and rfc822 format available.Message #35 received at 58711 <at> debbugs.gnu.org (full text, mbox):
From: Wilhelm Kirschbaum <wilhelm <at> floatpays.co.za> To: Yuan Fu <casouri <at> gmail.com> Cc: 58711 <at> debbugs.gnu.org Subject: Re: bug#58711: Treesit hangs when calling treesit-search-forward Date: Thu, 10 Nov 2022 21:32:56 +0200
[Message part 1 (text/plain, inline)]
Sorry, I see something like this makes sense and is not the prev-sibling issue. (defun heex--treesit-backward-sexp () "Forward sexp for Heex using treesit." (let* ((node (treesit-search-forward (treesit-node-at (point)) (rx (or "end_tag" "end_component" "end_slot")) t)) (sibling (treesit-node-prev-sibling node))) (when sibling (goto-char (treesit-node-start sibling))))) Just need to handle the outermost (fragment peace and should work then. Thanks for the help. On Thu, 10 Nov 2022 at 21:05, Wilhelm Kirschbaum <wilhelm <at> floatpays.co.za> wrote: > Full implementation here: > https://github.com/wkirschbaum/elixir-mode/blob/main/heex-mode.el > > On Thu, 10 Nov 2022 at 21:03, Wilhelm Kirschbaum <wilhelm <at> floatpays.co.za> > wrote: > >> forward-sexp works well with the below code, but when calling >> treesit-node-prev-sibling it will traverse up the list, which is then >> breaking backward-up-list when defining forward-sexp in the major mode. >> >> (defun heex--treesit-largest-node-at-point () >> "Find the largest node at point." >> (save-excursion >> (forward-comment (point-max)) >> (let ((node-list >> (cl-loop for node = (treesit-node-at (point)) >> then (treesit-node-parent node) >> while node >> 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* ((largest-node (heex--treesit-largest-node-at-point)) >> (sibling (treesit-node-prev-sibling largest-node))) >> (when sibling >> (goto-char (treesit-node-start sibling))))) >> >> (defun heex--treesit-forward-sexp () >> "Forward sexp for Heex using treesit." >> (let* ((largest-node (heex--treesit-largest-node-at-point)) >> (sibling (treesit-node-next-sibling largest-node))) >> (when sibling >> (goto-char (treesit-node-start sibling)) >> (forward-comment (- (point-max)))))) >> >> On Thu, 10 Nov 2022 at 10:14, Yuan Fu <casouri <at> gmail.com> wrote: >> >>> >>> >>> > On Nov 9, 2022, at 10:44 PM, Wilhelm Kirschbaum < >>> wilhelm <at> floatpays.co.za> wrote: >>> > >>> > I finally had some time to have a look. I don't see any more issues, >>> thank you for the fantastic work on this. The defun-type-regexp is not >>> enough to identify a defun in elixir this is the query I am using currently: >>> > >>> > (defvar elixir--treesit-query-defun >>> > (let ((query `((call >>> > target: (identifier) @type >>> > (arguments >>> > [ >>> > (alias) @name >>> > (identifier) @name >>> > (call target: (identifier)) @name >>> > (binary_operator >>> > left: (call target: (identifier)) @name >>> > operator: "when") >>> > ]) >>> > (:match ,elixir--definition-keywords-re @type) >>> > )))) >>> > (treesit-query-compile 'elixir query))) >>> > >>> > Regex will work in most cases I guess, but does not really deal with >>> more complex queries for more complex cases like in elixir as there is not >>> one type which is always the defun. elixir relies heavily on macros and >>> different defun macros can be defined on the fly. >>> >>> You can try the following procedure: use a regex to find the >>> next/previous call, then perform some check on whether it’s indeed a defun, >>> if not, keep searching for the next/previous call. >>> >>> >>> > Maybe if there is an option for using either a regex or a function? >>> >>> Yes, instead of a regex you can pass a predicate function. >>> >>> > >>> > I am also not sure how forward-sexp can work with the current >>> treesit-search-forward-goto function as it does not take into consideration >>> the level. Is there perhaps a way to move forward/backward, but do not jump >>> to parents or children? >>> >>> If you want to move in the same level, perhaps you can use >>> treesit-next/prev/sibling? >>> >>> Yuan >> >>
[Message part 2 (text/html, inline)]
bug-gnu-emacs <at> gnu.org
:bug#58711
; Package emacs
.
(Thu, 10 Nov 2022 20:44:02 GMT) Full text and rfc822 format available.Message #38 received at 58711 <at> debbugs.gnu.org (full text, mbox):
From: Wilhelm Kirschbaum <wilhelm <at> floatpays.co.za> To: Yuan Fu <casouri <at> gmail.com> Cc: 58711 <at> debbugs.gnu.org Subject: Re: bug#58711: Treesit hangs when calling treesit-search-forward Date: Thu, 10 Nov 2022 22:43:31 +0200
[Message part 1 (text/plain, inline)]
Given the following code <.foo> ;; component, start_component <bar> ;; tag, start_tag </bar>;; [cursor here 1)] end_tag </.foo> ;; [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 <bar> and from cursor position 2 to start of <.foo> 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 parent and then find the prev sibling to goto. Hope this makes sense. On Thu, 10 Nov 2022 at 21:32, Wilhelm Kirschbaum <wilhelm <at> floatpays.co.za> wrote: > Sorry, I see something like this makes sense and is not the prev-sibling > issue. > > (defun heex--treesit-backward-sexp () > "Forward sexp for Heex using treesit." > (let* ((node (treesit-search-forward > (treesit-node-at (point)) > (rx (or "end_tag" "end_component" "end_slot")) > t)) > (sibling (treesit-node-prev-sibling node))) > (when sibling > (goto-char (treesit-node-start sibling))))) > > Just need to handle the outermost (fragment peace and should work then. > > Thanks for the help. > > On Thu, 10 Nov 2022 at 21:05, Wilhelm Kirschbaum <wilhelm <at> floatpays.co.za> > wrote: > >> Full implementation here: >> https://github.com/wkirschbaum/elixir-mode/blob/main/heex-mode.el >> >> On Thu, 10 Nov 2022 at 21:03, Wilhelm Kirschbaum <wilhelm <at> floatpays.co.za> >> wrote: >> >>> forward-sexp works well with the below code, but when calling >>> treesit-node-prev-sibling it will traverse up the list, which is then >>> breaking backward-up-list when defining forward-sexp in the major mode. >>> >>> (defun heex--treesit-largest-node-at-point () >>> "Find the largest node at point." >>> (save-excursion >>> (forward-comment (point-max)) >>> (let ((node-list >>> (cl-loop for node = (treesit-node-at (point)) >>> then (treesit-node-parent node) >>> while node >>> 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* ((largest-node (heex--treesit-largest-node-at-point)) >>> (sibling (treesit-node-prev-sibling largest-node))) >>> (when sibling >>> (goto-char (treesit-node-start sibling))))) >>> >>> (defun heex--treesit-forward-sexp () >>> "Forward sexp for Heex using treesit." >>> (let* ((largest-node (heex--treesit-largest-node-at-point)) >>> (sibling (treesit-node-next-sibling largest-node))) >>> (when sibling >>> (goto-char (treesit-node-start sibling)) >>> (forward-comment (- (point-max)))))) >>> >>> On Thu, 10 Nov 2022 at 10:14, Yuan Fu <casouri <at> gmail.com> wrote: >>> >>>> >>>> >>>> > On Nov 9, 2022, at 10:44 PM, Wilhelm Kirschbaum < >>>> wilhelm <at> floatpays.co.za> wrote: >>>> > >>>> > I finally had some time to have a look. I don't see any more issues, >>>> thank you for the fantastic work on this. The defun-type-regexp is not >>>> enough to identify a defun in elixir this is the query I am using currently: >>>> > >>>> > (defvar elixir--treesit-query-defun >>>> > (let ((query `((call >>>> > target: (identifier) @type >>>> > (arguments >>>> > [ >>>> > (alias) @name >>>> > (identifier) @name >>>> > (call target: (identifier)) @name >>>> > (binary_operator >>>> > left: (call target: (identifier)) @name >>>> > operator: "when") >>>> > ]) >>>> > (:match ,elixir--definition-keywords-re @type) >>>> > )))) >>>> > (treesit-query-compile 'elixir query))) >>>> > >>>> > Regex will work in most cases I guess, but does not really deal with >>>> more complex queries for more complex cases like in elixir as there is not >>>> one type which is always the defun. elixir relies heavily on macros and >>>> different defun macros can be defined on the fly. >>>> >>>> You can try the following procedure: use a regex to find the >>>> next/previous call, then perform some check on whether it’s indeed a defun, >>>> if not, keep searching for the next/previous call. >>>> >>>> >>>> > Maybe if there is an option for using either a regex or a function? >>>> >>>> Yes, instead of a regex you can pass a predicate function. >>>> >>>> > >>>> > I am also not sure how forward-sexp can work with the current >>>> treesit-search-forward-goto function as it does not take into consideration >>>> the level. Is there perhaps a way to move forward/backward, but do not jump >>>> to parents or children? >>>> >>>> If you want to move in the same level, perhaps you can use >>>> treesit-next/prev/sibling? >>>> >>>> Yuan >>> >>>
[Message part 2 (text/html, inline)]
bug-gnu-emacs <at> gnu.org
:bug#58711
; Package emacs
.
(Thu, 10 Nov 2022 22:08:02 GMT) Full text and rfc822 format available.Message #41 received at 58711 <at> debbugs.gnu.org (full text, mbox):
From: Yuan Fu <casouri <at> gmail.com> To: Wilhelm Kirschbaum <wilhelm <at> floatpays.co.za> Cc: 58711 <at> debbugs.gnu.org Subject: Re: bug#58711: Treesit hangs when calling treesit-search-forward Date: Thu, 10 Nov 2022 14:07:40 -0800
> On Nov 10, 2022, at 12:43 PM, Wilhelm Kirschbaum <wilhelm <at> floatpays.co.za> wrote: > > Given the following code > > <.foo> ;; component, start_component > <bar> ;; tag, start_tag > </bar>;; [cursor here 1)] end_tag > </.foo> ;; [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 <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 (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, 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 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’ll see how to add this functionality. Yuan
bug-gnu-emacs <at> gnu.org
:bug#58711
; Package emacs
.
(Fri, 11 Nov 2022 06:32:02 GMT) Full text and rfc822 format available.Message #44 received at 58711 <at> debbugs.gnu.org (full text, mbox):
From: Wilhelm Kirschbaum <wilhelm <at> floatpays.co.za> To: Yuan Fu <casouri <at> gmail.com> Cc: 58711 <at> debbugs.gnu.org Subject: Re: bug#58711: Treesit hangs when calling treesit-search-forward Date: Fri, 11 Nov 2022 08:30:56 +0200
[Message part 1 (text/plain, inline)]
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 <at> gmail.com> wrote: > > > > On Nov 10, 2022, at 12:43 PM, Wilhelm Kirschbaum < > wilhelm <at> floatpays.co.za> wrote: > > > > Given the following code > > > > <.foo> ;; component, start_component > > <bar> ;; tag, start_tag > > </bar>;; [cursor here 1)] end_tag > > </.foo> ;; [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 > <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 > (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, 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 > 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’ll see how to add this > functionality. > > Yuan
[Message part 2 (text/html, inline)]
Stefan Kangas <stefankangas <at> gmail.com>
to control <at> debbugs.gnu.org
.
(Sun, 13 Nov 2022 04:02:02 GMT) Full text and rfc822 format available.bug-gnu-emacs <at> gnu.org
:bug#58711
; Package emacs
.
(Mon, 14 Nov 2022 06:33:02 GMT) Full text and rfc822 format available.Message #49 received at 58711 <at> debbugs.gnu.org (full text, mbox):
From: Wilhelm Kirschbaum <wilhelm <at> floatpays.co.za> To: Yuan Fu <casouri <at> gmail.com> Cc: 58711 <at> debbugs.gnu.org Subject: Re: bug#58711: Treesit hangs when calling treesit-search-forward Date: Mon, 14 Nov 2022 08:32:40 +0200
[Message part 1 (text/plain, inline)]
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 = (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 <wilhelm <at> floatpays.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 <at> gmail.com> wrote: > >> >> >> > On Nov 10, 2022, at 12:43 PM, Wilhelm Kirschbaum < >> wilhelm <at> floatpays.co.za> wrote: >> > >> > Given the following code >> > >> > <.foo> ;; component, start_component >> > <bar> ;; tag, start_tag >> > </bar>;; [cursor here 1)] end_tag >> > </.foo> ;; [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 >> <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 >> (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, 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 >> 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’ll see how to add this >> functionality. >> >> Yuan > >
[Message part 2 (text/html, inline)]
bug-gnu-emacs <at> gnu.org
:bug#58711
; Package emacs
.
(Mon, 14 Nov 2022 08:46:02 GMT) Full text and rfc822 format available.Message #52 received at 58711 <at> debbugs.gnu.org (full text, mbox):
From: Yuan Fu <casouri <at> gmail.com> To: Wilhelm Kirschbaum <wilhelm <at> floatpays.co.za> Cc: 58711 <at> debbugs.gnu.org Subject: Re: bug#58711: Treesit hangs when calling treesit-search-forward Date: Mon, 14 Nov 2022 00:44:59 -0800
> On Nov 13, 2022, at 10:32 PM, Wilhelm Kirschbaum <wilhelm <at> floatpays.co.za> wrote: > > 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 = (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))))) For largest node at point, you can probably use something like (treesit-parent-while (or node (treesit-node-at (point))) (lambda (n) (eq (treesit-node-start n) (point)))) Yuan
bug-gnu-emacs <at> gnu.org
:bug#58711
; Package emacs
.
(Mon, 14 Nov 2022 10:04:02 GMT) Full text and rfc822 format available.Message #55 received at 58711 <at> debbugs.gnu.org (full text, mbox):
From: Wilhelm Kirschbaum <wilhelm <at> floatpays.co.za> To: Yuan Fu <casouri <at> gmail.com> Cc: 58711 <at> debbugs.gnu.org Subject: Re: bug#58711: Treesit hangs when calling treesit-search-forward Date: Mon, 14 Nov 2022 12:03:11 +0200
[Message part 1 (text/plain, inline)]
Thank you, the treesit-parent-while is better. On Mon, 14 Nov 2022 at 10:45, Yuan Fu <casouri <at> gmail.com> wrote: > > > > On Nov 13, 2022, at 10:32 PM, Wilhelm Kirschbaum < > wilhelm <at> floatpays.co.za> wrote: > > > > 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 = (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))))) > > For largest node at point, you can probably use something like > > (treesit-parent-while (or node (treesit-node-at (point))) > (lambda (n) (eq (treesit-node-start n) (point)))) > > Yuan
[Message part 2 (text/html, inline)]
Yuan Fu <casouri <at> gmail.com>
to control <at> debbugs.gnu.org
.
(Sat, 07 Jan 2023 23:10:02 GMT) Full text and rfc822 format available.Debbugs Internal Request <help-debbugs <at> gnu.org>
to internal_control <at> debbugs.gnu.org
.
(Sun, 05 Feb 2023 12:24:05 GMT) Full text and rfc822 format available.
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.