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 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 > 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 wrote: >> >>> >>> >>> > On Nov 9, 2022, at 10:44 PM, Wilhelm Kirschbaum < >>> wilhelm@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 >> >>