about summary refs log tree commit diff
path: root/users/Profpatsch/emacs-tree-sitter-move
diff options
context:
space:
mode:
authorProfpatsch <mail@profpatsch.de>2020-12-19T19·05+0100
committerProfpatsch <mail@profpatsch.de>2021-01-01T22·39+0000
commit9da760fba4ebd16b4255663a399efff551ab95aa (patch)
treeb3f0bb20952a2a723d4074a5c34f6815ea95012e /users/Profpatsch/emacs-tree-sitter-move
parent806c281b3491b165d01be561f005dada24107363 (diff)
feat(emacs-tree-sitter-move): Add tree-sitter-move-reset r/2043
Resets the cursor to the named node under the cursor.
`-right` does not do it anymore, so it’s possible to navigate on
higher levels of the tree instead of always resetting to a leaf.

Change-Id: Id330854c72ea24da0cc8611f30f5617e0f127c1b
Reviewed-on: https://cl.tvl.fyi/c/depot/+/2259
Reviewed-by: Profpatsch <mail@profpatsch.de>
Tested-by: BuildkiteCI
Diffstat (limited to 'users/Profpatsch/emacs-tree-sitter-move')
-rw-r--r--users/Profpatsch/emacs-tree-sitter-move/tmp.el1
-rw-r--r--users/Profpatsch/emacs-tree-sitter-move/tree-sitter-move.el46
2 files changed, 27 insertions, 20 deletions
diff --git a/users/Profpatsch/emacs-tree-sitter-move/tmp.el b/users/Profpatsch/emacs-tree-sitter-move/tmp.el
index dcd17aa575..fa13da1207 100644
--- a/users/Profpatsch/emacs-tree-sitter-move/tmp.el
+++ b/users/Profpatsch/emacs-tree-sitter-move/tmp.el
@@ -7,6 +7,7 @@
       '((python-mode . python)))
 
 
+(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-<left>") 'sp-backward-parallel-sexp)
 ;; (define-key evil-normal-state-map (kbd "C-<down>") 'sp-down-sexp)
diff --git a/users/Profpatsch/emacs-tree-sitter-move/tree-sitter-move.el b/users/Profpatsch/emacs-tree-sitter-move/tree-sitter-move.el
index 37aafefb0e..0a5e34e4be 100644
--- a/users/Profpatsch/emacs-tree-sitter-move/tree-sitter-move.el
+++ b/users/Profpatsch/emacs-tree-sitter-move/tree-sitter-move.el
@@ -44,34 +44,31 @@
   (tree-sitter-mode nil))
 
 ;; Get the syntax node the cursor is on.
-(defun tsc-node-named-node-at-point ()
+(defun tsc-get-named-node-at-point ()
   (let ((p (point)))
     (tsc-get-named-descendant-for-position-range
      (tsc-root-node tree-sitter-tree) p p)))
 
-(defun tsc-get-node-at-point ()
-  (let ((p (point)))
-    (tsc-get-descendant-for-position-range
-     (tsc-root-node tree-sitter-tree) p p)))
-
 (defun tsc-get-first-named-node-with-siblings-up (node)
   "Returns the first 'upwards' node that has siblings. That includes the current
-  node, so if the given node has siblings, it is returned."
-  (let ((has-siblings-p
-         (lambda (n)
-           (> (tsc-count-named-children (tsc-get-parent n))
-              1)))
-        (res node))
-    (while (not (funcall has-siblings-p res))
-      ;; TODO tsc-get-parent is called twice, nicer somehow?
-      (setq res (tsc-get-parent res)))
-    res))
+  node, so if the given node has siblings, it is returned. Returns nil if there
+  is no such node until the root"
+  (when-let ((has-siblings-p
+            (lambda (parent-node)
+              (> (tsc-count-named-children parent-node)
+                 1)))
+           (cur node)
+           (parent (tsc-get-parent node)))
+      (while (not (funcall has-siblings-p parent))
+        (setq cur parent)
+        (setq parent (tsc-get-parent cur)))
+    cur))
 
 (defun tree-sitter-move--set-cursor-to-node (node)
   (setq tree-sitter-move--cursor node))
 
 (defun tree-sitter-move--set-cursor-to-node-at-point ()
-  (tree-sitter-move--set-cursor-to-node (tsc-get-node-at-point)))
+  (tree-sitter-move--set-cursor-to-node (tsc-get-named-node-at-point)))
 
 (defun tree-sitter-move--move-point-to-node (node)
   (set-window-point
@@ -81,13 +78,22 @@
 
 ;; interactive commands (“do what I expect” section)
 
+(defun tree-sitter-move-reset ()
+  (interactive)
+  (tree-sitter-move--set-cursor-to-node-at-point))
+
 (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)
-  (tree-sitter-move--set-cursor-to-node-at-point)
-  (let ((next (tsc-get-next-named-sibling
-               (tsc-get-first-named-node-with-siblings-up tree-sitter-move--cursor))))
+  (tree-sitter-move--move-if-possible
+   (lambda (cur)
+     (when-let ((with-siblings
+                 (tsc-get-first-named-node-with-siblings-up cur)))
+       (tsc-get-next-named-sibling with-siblings)))))
+
+(defun tree-sitter-move--move-if-possible (dir-fn)
+  (let ((next (funcall dir-fn tree-sitter-move--cursor)))
     (when next
       (tree-sitter-move--set-cursor-to-node next)
       (tree-sitter-move--move-point-to-node next))))