branch: elpa/typst-ts-mode
commit 6037bc1866f453bc1391981fd9d84244570e8935
Author: meowking <[email protected]>
Commit: meowking <[email protected]>
refactor: item editing
---
typst-ts-editing.el | 52 +++++++++++++++++++++++++++++++++++++++-------------
typst-ts-mode.el | 53 ++++++++++++++++++++++++++++++++++++-----------------
2 files changed, 75 insertions(+), 30 deletions(-)
diff --git a/typst-ts-editing.el b/typst-ts-editing.el
index d757421513..7412a8213a 100644
--- a/typst-ts-editing.el
+++ b/typst-ts-editing.el
@@ -104,29 +104,55 @@ Using ARG argument will ignore the context and it will
insert a heading instead.
"Handle RET depends on condition.
When prefix ARG is non-nil, call global return function."
(interactive "P")
- (let (execute-result node)
+ (let (execute-result)
(unless current-prefix-arg
(setq
execute-result
(catch 'execute-result
- (when-let* ((cur-pos (point))
- (cur-node (treesit-node-at cur-pos))
- (cur-node-type (treesit-node-type cur-node))
- (parent-node (treesit-node-parent cur-node)) ; could be
nil
- (parent-node-type (treesit-node-type parent-node)))
+ (let* ((cur-pos (point))
+ (cur-node (treesit-node-at cur-pos))
+ (cur-node-type (treesit-node-type cur-node))
+ (parent-node (treesit-node-parent cur-node)) ; could be nil
+ (parent-node-type (treesit-node-type parent-node))
+ node)
;; (message "%s %s" cur-node parent-node)
(cond
- (arg (throw 'execute-result 'default))
;; on item node end
((and (eolp)
(setq node
(typst-ts-core-get-parent-of-node-at-bol-nonwhite))
(equal (treesit-node-type node) "item"))
- (if (> (treesit-node-child-count node) 1)
- (typst-ts-mode-insert--item node)
- ;; no text means delete the item on current line: (item -)
instead of (item - (text))
- (beginning-of-line)
- (kill-line)
- (indent-according-to-mode))
+ (let* ((child-node (treesit-node-child node 1))
+ (next-line-bol-text-pos
+ (save-excursion
+ (beginning-of-line-text 2)
+ (point)))
+ (next-line-node-type
+ (treesit-node-type
+ (treesit-node-parent
+ (treesit-node-at next-line-bol-text-pos)))))
+ (if child-node
+ (if (not (equal next-line-node-type "item"))
+ (typst-ts-mode-insert--item node)
+ (call-interactively #'newline))
+ ;; no text means delete the item on current line: (item -)
+ (beginning-of-line)
+ (kill-line)
+ ;; whether the previous line is in an item
+ (let* ((prev-line-bol-text-pos
+ (save-excursion
+ (beginning-of-line-text 0)
+ (point)))
+ (prev-line-node-type
+ (treesit-node-type
+ (treesit-node-parent
+ (treesit-node-at prev-line-bol-text-pos)))))
+ (if (equal "item" prev-line-node-type)
+ (progn
+ (kill-line)
+ (forward-line -1)
+ (end-of-line)
+ (call-interactively #'newline))
+ (indent-according-to-mode)))))
(throw 'execute-result 'success))
)))))
;; execute default action if not successful
diff --git a/typst-ts-mode.el b/typst-ts-mode.el
index 4b9c705201..baa5e3e5c3 100644
--- a/typst-ts-mode.el
+++ b/typst-ts-mode.el
@@ -503,31 +503,30 @@ NODE, PARENT and BOL see `treesit-simple-indent-rules'."
;; .split(" ")
((n-p-gp "." "field" nil) parent-bol typst-ts-mode-indent-offset)
+ ((parent-is "comment") prev-adaptive-prefix 0)
;; item - child item
- ((and (node-is "item") (parent-is "item")) parent-bol
typst-ts-mode-indent-offset)
-
+ ((and (node-is "item") (parent-is "item")) parent-bol
+ typst-ts-mode-indent-offset)
+
+ ;; TODO
;; item - previous nonwhite line is item type and the ending is a
linebreak
(typst-ts-mode--identation-item-linebreak
- typst-ts-mode--indentation-item-linebreak-get-pos
typst-ts-mode-indent-offset)
-
+ typst-ts-mode--indentation-item-linebreak-get-pos
+ typst-ts-mode-indent-offset)
+
;; multi-line item
- ;; - foo
- ;; bar
+ ;; - [hi] foo
+ ;; bar
+ ;; my try with `prev-adaptive-prefix' failed even after set the
+ ;; `adaptive-fill-regexp'
((match nil "item" nil 2 nil)
typst-ts-mode--indentation-multiline-item-get-anchor 0)
- ;; item - item should follow its previous line item's indentation level
- ((and no-node
- (lambda (node parent &rest _)
- (save-excursion
- (forward-line -1)
- (back-to-indentation)
- (string= "item" (treesit-node-type
- (treesit-node-parent
- (treesit-node-at (point))))))))
- prev-line
- 0)
+ ;; item - new item content should follow its previous line's indentation
+ ;; level
+ ((and no-node typst-ts-mode--indentation-prev-line-is-item-p)
+ typst-ts-mode--indentation-multiline-item-get-anchor_ 0)
;; raw block
;; whether normally or in insertion, the current node is always nil...
@@ -561,6 +560,26 @@ NODE, PARENT and BOL see `treesit-simple-indent-rules'."
"Return the start of second child of PARENT."
(treesit-node-start (treesit-node-child parent 1)))
+(defun typst-ts-mode--indentation-multiline-item-get-anchor_ (_node _parent
_bol)
+ "Return the start of second child of the current item.
+This function is meant to be used when user hits a return key."
+ (treesit-node-start
+ (treesit-node-child
+ (treesit-node-parent
+ (treesit-node-at
+ (save-excursion
+ (beginning-of-line-text 0)
+ (point))))
+ 1)))
+
+(defun typst-ts-mode--indentation-prev-line-is-item-p (_node _parent _bol)
+ (save-excursion
+ (forward-line -1)
+ (back-to-indentation)
+ (string= "item" (treesit-node-type
+ (treesit-node-parent
+ (treesit-node-at (point)))))))
+
(defun typst-ts-mode-comment-setup()
"Setup comment related stuffs for `typst-ts-mode'."