branch: elpa/typst-ts-mode commit b1deb2d667d4cc976e091d4d7194bb24149e600f Author: Huan Nguyen <nguyenthieuh...@gmail.com> Commit: Huan Nguyen <nguyenthieuh...@gmail.com>
feat: #16 code for reordering list items --- typst-ts-editing.el | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) diff --git a/typst-ts-editing.el b/typst-ts-editing.el index d08cd40e97..5fc6087a89 100644 --- a/typst-ts-editing.el +++ b/typst-ts-editing.el @@ -57,12 +57,115 @@ Return the heading node when yes otherwise nil." node nil))) +(defun test () + (interactive) + (message "%s" (treesit-node-text + (treesit-node-child (treesit-parent-until + (treesit-node-at (point)) + (lambda (x) (string= "item" (treesit-node-type x)))) + 0)))) + +(defun typst-ts-mode-item--at-point-p () + "Return (prev current next) items. + +When there are no item nodes return for the specific list index will be nil. +Being a different item type does not count as sibling either, ex: +1. foo +- bar + +When point is not on an item node return nil." + (let* ((item-p (lambda (x) (string= (treesit-node-type x) + "item"))) + (node (treesit-parent-until (treesit-node-at (point)) + item-p)) + (get-item-type (lambda (x) + (treesit-node-text (treesit-node-child x 0)))) + (item-type (funcall get-item-type node)) + (node-numbered-p (not (= (string-to-number item-type) 0))) + (same-item-type (lambda (x) + (let ((type (funcall get-item-type x))) + (or (string= type item-type) + ;; are they numbers? + (and node-numbered-p + (not (= (string-to-number type) 0))))))) + (only-if (lambda (x) (and (funcall item-p x) + (funcall same-item-type x) + x)))) + (cond + ((not node) node) + (node (list (funcall only-if (treesit-node-prev-sibling node)) + node + (funcall only-if (treesit-node-next-sibling node))))))) + +(defun typst-ts-mode--swap-regions (start1 end1 start2 end2) + "Swap region between START1 and END1 with region between START2 and END2." + (let ((text1 (buffer-substring start1 end1)) + (text2 (buffer-substring start2 end2)) + (marker1-start (make-marker)) + (marker1-end (make-marker)) + (marker2-start (make-marker)) + (marker2-end (make-marker))) + (set-marker marker1-start start1) + (set-marker marker1-end end1) + (set-marker marker2-start start2) + (set-marker marker2-end end2) + + (delete-region marker1-start marker1-end) + (delete-region marker2-start marker2-end) + + (goto-char marker1-start) + (insert text2) + + (goto-char marker2-start) + (insert text1) + + (set-marker marker1-start nil) + (set-marker marker1-end nil) + (set-marker marker2-start nil) + (set-marker marker2-end nil))) + +(defun typst-ts-mode-item--move (direction) + "Moves item node up or down (swap). +DIRECTION should be `up' or `down'." + (let (previous current next swap-with) + (seq-setq (previous current next) (typst-ts-mode-item--at-point-p)) + (unless current + (error "Point is not on an item")) + (pcase direction + ('up + (setq swap-with previous)) + ('down + (setq swap-with next)) + (_ (error "%s is not one of: `up' `down'" direction))) + (unless swap-with + (user-error "There is no %s item to swap with" + (if (eq direction 'up) "previous" "next"))) + (let ((current-begin (treesit-node-start current)) + (current-end (treesit-node-end current)) + (other-begin (treesit-node-start previous)) + (other-end (treesit-node-end previous))) + (typst-ts-mode--swap-regions current-begin current-end + other-begin other-end)))) + +(defun typst-ts-mode-item-up () + "Move the item at point up." + (interactive) + (typst-ts-mode-item--move 'up)) + +(defun typst-ts-mode-item-down () + "Move the item at point down." + (interactive) + (typst-ts-mode-item--move 'down)) + (defun typst-ts-mode-meta--dwim (direction) "Do something depending on the context with meta key + DIRECTION. + +When point is at heading: `left': `typst-ts-mode-heading-decrease', `right': `typst-ts-mode-heading-increase', `up': `typst-ts-mode-heading-up', `down': `typst-ts-mode-heading-down'. + When there is no relevant action to do it will execute the relevant function in the `GLOBAL-MAP' (example: `right-word')." (let ((heading (typst-ts-mode-heading--at-point-p))