feat(emacs-tree-sitter-move): left and up movements, skip unnamed

We skip intermediate nodes that do not have any siblings, because they
are irrelevant to navigation and just add extra keypresses without any
highlight changes. This might not be the best choice, we’ll see.

Change-Id: I75fbf79aa7915172e426442a076d57cfbebf5421
Reviewed-on: https://cl.tvl.fyi/c/depot/+/2260
Reviewed-by: Profpatsch <mail@profpatsch.de>
Tested-by: BuildkiteCI
This commit is contained in:
Profpatsch 2020-12-19 20:18:40 +01:00
parent 9da760fba4
commit e07e88d81d
2 changed files with 22 additions and 6 deletions

View file

@ -9,6 +9,6 @@
(define-key evil-normal-state-map (kbd "C-.") #'tree-sitter-move-reset) (define-key evil-normal-state-map (kbd "C-.") #'tree-sitter-move-reset)
(define-key evil-normal-state-map (kbd "C-<right>") #'tree-sitter-move-right) (define-key evil-normal-state-map (kbd "C-<right>") #'tree-sitter-move-right)
;; (define-key evil-normal-state-map (kbd "C-<left>") 'sp-backward-parallel-sexp) (define-key evil-normal-state-map (kbd "C-<left>") #'tree-sitter-move-left)
;; (define-key evil-normal-state-map (kbd "C-<down>") 'sp-down-sexp) (define-key evil-normal-state-map (kbd "C-<up>") 'tree-sitter-move-up)
;; (define-key evil-normal-state-map (kbd "C-<up>") 'sp-backward-up-sexp) (define-key evil-normal-state-map (kbd "C-<down>") 'tree-sitter-move-down)

View file

@ -83,14 +83,30 @@
(tree-sitter-move--set-cursor-to-node-at-point)) (tree-sitter-move--set-cursor-to-node-at-point))
(defun tree-sitter-move-right () (defun tree-sitter-move-right ()
"Moves to the next sibling. If the current node does not have siblings, go
upwards until something has siblings and then move right."
(interactive) (interactive)
(tree-sitter-move--move-skip-non-sibling-nodes 'tsc-get-next-named-sibling))
(defun tree-sitter-move-left ()
(interactive)
(tree-sitter-move--move-skip-non-sibling-nodes 'tsc-get-prev-named-sibling))
(defun tree-sitter-move-up ()
(interactive)
(tree-sitter-move--move-skip-non-sibling-nodes 'tsc-get-parent))
;; TODO doesnt work yet because sibling nodes are only skipped upwards
;; (defun tree-sitter-move-down ()
;; (interactive)
;; (tree-sitter-move--move-skip-non-sibling-nodes (lambda (n) (tsc-get-nth-named-child n 0))))
(defun tree-sitter-move--move-skip-non-sibling-nodes (move-fn)
"Moves to the sidewards next sibling. If the current node does not have siblings, go
upwards until something has siblings and then move to the side (right or left)."
(tree-sitter-move--move-if-possible (tree-sitter-move--move-if-possible
(lambda (cur) (lambda (cur)
(when-let ((with-siblings (when-let ((with-siblings
(tsc-get-first-named-node-with-siblings-up cur))) (tsc-get-first-named-node-with-siblings-up cur)))
(tsc-get-next-named-sibling with-siblings))))) (funcall move-fn with-siblings)))))
(defun tree-sitter-move--move-if-possible (dir-fn) (defun tree-sitter-move--move-if-possible (dir-fn)
(let ((next (funcall dir-fn tree-sitter-move--cursor))) (let ((next (funcall dir-fn tree-sitter-move--cursor)))