branch: elpa/typst-ts-mode commit 22ff816058c7ca6104e700a186298e761427f2e6 Author: Huan Nguyen <nguyenthieuh...@gmail.com> Commit: Huan Nguyen <nguyenthieuh...@gmail.com>
feat: #16 do something depending on point --- typst-ts-editing.el | 132 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 84 insertions(+), 48 deletions(-) diff --git a/typst-ts-editing.el b/typst-ts-editing.el index ebfdf990f8..7b920fa10d 100644 --- a/typst-ts-editing.el +++ b/typst-ts-editing.el @@ -28,22 +28,22 @@ (defun typst-ts-mode-heading-up () "Switch the current heading with the heading above." (interactive) - (typst-ts-mode-meta--dwim 'up)) + (call-interactively #'outline-move-subtree-up)) (defun typst-ts-mode-heading-down () "Switch the current heading with the heading below." (interactive) - (typst-ts-mode-meta--dwim 'down)) + (call-interactively #'outline-move-subtree-down)) -(defun typst-ts-mode-heading-increase () +(defun typst-ts-mode-heading-left () "Increase the heading level." (interactive) - (typst-ts-mode-meta--dwim 'right)) + (call-interactively #'outline-promote)) -(defun typst-ts-mode-heading-decrease () +(defun typst-ts-mode-heading-right () "Decrease heading level." (interactive) - (typst-ts-mode-meta--dwim 'left)) + (call-interactively #'outline-demote)) (defun typst-ts-mode-heading--at-point-p () "Whether the current line is a heading. @@ -58,6 +58,13 @@ Return the heading node when yes otherwise nil." nil))) (defun typst-ts-mode-item--at-point-p () + "Return item node when point is on item. +Otherwise nil." + (treesit-parent-until (treesit-node-at (point)) + (lambda (x) (string= (treesit-node-type x) + "item")))) + +(defun typst-ts-mode-item--with-siblings () "Return (prev current next numbered-p) items. The last item in the last tells you if the list is numbered (t) or not (nil). @@ -70,23 +77,23 @@ Being a different item type does not count as sibling, ex: - 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)))) + (when-let* ((node (typst-ts-mode-item--at-point-p)) + (get-item-type (lambda (x) + (treesit-node-text (treesit-node-child x 0)))) + (item-type (funcall get-item-type node)) + (node-numbered-p t) + (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 (string= (treesit-node-type x) + "item") + (funcall same-item-type x) + x)))) + (setq node-numbered-p (not (= (string-to-number item-type) 0))) (cond ((not node) node) (node (list (funcall only-if (treesit-node-prev-sibling node)) @@ -133,7 +140,7 @@ DIRECTION should be `up' or `down'." (setq swap-with next)) (_ (error "%s is not one of: `up' `down'" direction)))))) (seq-setq (previous current next numbered-p) - (typst-ts-mode-item--at-point-p)) + (typst-ts-mode-item--with-siblings)) (unless current (error "Point is not on an item")) (funcall bind) @@ -153,7 +160,7 @@ DIRECTION should be `up' or `down'." other-begin other-end)))) ;; the nodes must be reinitialized (seq-setq (previous current next numbered-p) - (typst-ts-mode-item--at-point-p)) + (typst-ts-mode-item--with-siblings)) (funcall bind) (let ((current-begin (treesit-node-start current)) (current-end (treesit-node-end current)) @@ -174,8 +181,29 @@ DIRECTION should be `up' or `down'." (interactive) (typst-ts-mode-item--move 'down)) +(defun typst-ts-mode-meta-up () + "See `typst-ts-mode-meta--dwim'." + (interactive) + (call-interactively (typst-ts-mode-meta--dwim 'up))) + +(defun typst-ts-mode-meta-down () + "See `typst-ts-mode-meta--dwim'." + (interactive) + (message "%s" (typst-ts-mode-meta--dwim 'down)) + (call-interactively (typst-ts-mode-meta--dwim 'down))) + +(defun typst-ts-mode-meta-left () + "See `typst-ts-mode-meta--dwim'." + (interactive) + (call-interactively (typst-ts-mode-meta--dwim 'left))) + +(defun typst-ts-mode-meta-right () + "See `typst-ts-mode-meta--dwim'." + (interactive) + (call-interactively (typst-ts-mode-meta--dwim 'right))) + (defun typst-ts-mode-meta--dwim (direction) - "Do something depending on the context with meta key + DIRECTION. + "Return function depending on the context with meta key + DIRECTION. When point is at heading: `left': `typst-ts-mode-heading-decrease', @@ -183,29 +211,37 @@ When point is at heading: `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 +When point is at item list: +`up': `typst-ts-mode-item-up' +`down': `typst-ts-mode-item-down' + +When there is no relevant action to do it will return the relevant function in the `GLOBAL-MAP' (example: `right-word')." - (let ((heading (typst-ts-mode-heading--at-point-p)) - ;; car function, cdr string of function for `substitute-command-keys' - (call-me/string - (pcase direction - ('left - (cons #'outline-promote - "\\[typst-ts-mode-heading-decrease]")) - ('right - (cons #'outline-demote - "\\[typst-ts-mode-heading-decrease]")) - ('up - (cons #'outline-move-subtree-up - "\\[typst-ts-mode-heading-up]")) - ('down - (cons #'outline-move-subtree-down - "\\[typst-ts-mode-heading-down]")) - (_ (error "%s is not one of: `right' `left'" direction))))) - (if heading - (call-interactively (car call-me/string)) - (call-interactively - (keymap-lookup global-map (substitute-command-keys (cdr call-me/string))))))) + (let* ((prefix "typst-ts-mode-") + (mid (cond + ((typst-ts-mode-heading--at-point-p) "heading") + ((and (typst-ts-mode-item--at-point-p) + ;; does not exist, maybe will exist at some point + (not (or (eq 'left direction) + (eq 'right direction)))) + "item") + (t nil))) + (end + (pcase direction + ('left + "-left") + ('right + "-right") + ('up + "-up") + ('down + "-down") + (_ (error "DIRECTION: %s is not one of: `right' `left', `up', `down'" + direction))))) + (if (not mid) + (keymap-lookup global-map (substitute-command-keys + (concat "\\[" prefix "meta" end "]"))) + (intern-soft (concat prefix mid end))))) (defun typst-ts-mode-meta-return (&optional arg) "Depending on context, insert a heading or insert an item.