branch: elpa/typst-ts-mode commit 6037bc1866f453bc1391981fd9d84244570e8935 Author: meowking <mr.meowk...@tutamail.com> Commit: meowking <mr.meowk...@tutamail.com>
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'."