1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-15 10:30:25 -08:00

Add treesit-transpose-sexps (bug#60128)

We don't really need to rely on forward-sexp to define what to
transpose.  In tree-sitter we can consider siblings as "balanced
expressions", and swap them without doing any movement to calculate
where the siblings in question are.

* lisp/simple.el (transpose-sexps-function): New defvar-local.
(transpose-sexps): Use the new defvar-local if available.
(transpose-subr): Check whether the mover function returns a cons of
conses, then run transpose-subr-1 on the position-pairs.
* lisp/treesit.el (treesit-transpose-sexps): New function.
This commit is contained in:
Theodor Thornhill 2022-12-25 20:11:59 +01:00 committed by Stefan Monnier
parent 7dc24fb611
commit 7e98b8a0fa
3 changed files with 86 additions and 40 deletions

View file

@ -1582,6 +1582,32 @@ BACKWARD and ALL are the same as in `treesit-search-forward'."
(goto-char current-pos)))
node))
(defun treesit-transpose-sexps (&optional arg)
"Tree-sitter `transpose-sexps' function.
Arg is the same as in `transpose-sexps'.
Locate the node closest to POINT, and transpose that node with
its sibling node ARG nodes away.
Return a pair of positions as described by
`transpose-sexps-function' for use in `transpose-subr' and
friends."
(let* ((parent (treesit-node-parent (treesit-node-at (point))))
(child (treesit-node-child parent 0 t)))
(named-let loop ((prev child)
(next (treesit-node-next-sibling child t)))
(when (and prev next)
(if (< (point) (treesit-node-end next))
(if (= arg -1)
(cons (treesit-node-start prev)
(treesit-node-end prev))
(when-let ((n (treesit-node-child
parent (+ arg (treesit-node-index prev t)) t)))
(cons (treesit-node-end n)
(treesit-node-start n))))
(loop (treesit-node-next-sibling prev t)
(treesit-node-next-sibling next t)))))))
;;; Navigation, defun, things
;;
;; Emacs lets you define "things" by a regexp that matches the type of
@ -2111,7 +2137,8 @@ before calling this function."
;; Defun name.
(when treesit-defun-name-function
(setq-local add-log-current-defun-function
#'treesit-add-log-current-defun)))
#'treesit-add-log-current-defun))
(setq-local transpose-sexps-function #'treesit-transpose-sexps))
;;; Debugging