branch: elpa/typst-ts-mode
commit 22ff816058c7ca6104e700a186298e761427f2e6
Author: Huan Nguyen <[email protected]>
Commit: Huan Nguyen <[email protected]>
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.