branch: elpa/typst-ts-mode commit 0454e449774bf2a6c3cae6759dc5f880b1576585 Author: Huan Nguyen <nguyenthieuh...@gmail.com> Commit: Huan Nguyen <nguyenthieuh...@gmail.com>
feat: Autoincrement on enter and fix heading insertion. --- typst-ts-mode.el | 70 ++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 53 insertions(+), 17 deletions(-) diff --git a/typst-ts-mode.el b/typst-ts-mode.el index b99d163545..e0f1695e64 100644 --- a/typst-ts-mode.el +++ b/typst-ts-mode.el @@ -992,28 +992,61 @@ the `GLOBAL-MAP' (example: `right-word')." ;; RETURN ================================================================================ +(defun typst-ts-mode--item-on-line-p () + "Does the current line have an item node? +Return the node when yes otherwise +return the node that is one character left from the end of line." + (treesit-node-parent + (treesit-node-at + (save-excursion + ;; starting from the beginning because line could be 1. wow. + (beginning-of-line) + (condition-case nil + (progn + (search-forward-regexp (rx (or "+" "-" ".")) + (pos-eol) + nil + nil) + (left-char)) + (search-failed + ;; need to go to the end of line and then one left because end of line is the next node + (goto-char (1- (pos-eol))))) + (point))))) + (defun typst-ts-mode-meta-return (&optional arg) "Depending on context, insert a heading or insert an item. The new heading is created after the ending of current heading. Using ARG argument will ignore the context and it will insert a heading instead." (interactive "P") - (let ((node (treesit-node-parent - (treesit-node-at - (save-excursion - (beginning-of-line) - (search-forward-regexp (rx (or "+" "-" ".")) - (pos-eol) - t - nil) - (left-char) - (point)))))) + (let ((node (typst-ts-mode--item-on-line-p))) (cond - (arg (typst-ts-mode-insert--heading node)) + (arg (typst-ts-mode-insert--heading nil)) ((string= (treesit-node-type node) "item") (typst-ts-mode-insert--item node)) (t (typst-ts-mode-insert--heading node))))) +(defun typst-ts-mode-return (&optional arg interactive) + "Do something smart when `typst-ts-mode-return-smart' is non nil. +Pressing enter will do something depending on context. +ARG and INTERACTIVE will be passed to `newline'. +INTERACTIVE will be non nil when called interactively. +`typst-ts-mode-return-smart' for more documentation." + (interactive "*P\np") + (if (or arg (not typst-ts-mode-return-smart)) + (newline (if arg arg 1) interactive) + (let ((node (typst-ts-mode--item-on-line-p))) + (cond + ((string= (treesit-node-type node) "item") + ;; does the item have text? + (if (> (treesit-node-child-count node) 1) + (typst-ts-mode-insert--item node) + ;; no text means delete the item on current line + (beginning-of-line) + (kill-line) + (indent-according-to-mode))) + (t (newline (if arg arg 1) interactive)))))) + (defun typst-ts-mode-insert--item (node) "Insert an item after NODE. NODE must be an item node! @@ -1032,7 +1065,7 @@ This function respects indentation." (defun typst-ts-mode-insert--heading (node) "Insert a heading after the section that NODE is part of. -When there is no section it will insert a heading after current point." +When there is no section it will insert a heading below point." (let* ((section (treesit-parent-until node @@ -1044,14 +1077,16 @@ When there is no section it will insert a heading after current point." (heading-level (treesit-node-type (treesit-node-child heading 0)))) (if section (goto-char (treesit-node-end section)) + ;; no headings so far (setq heading-level "=") - (end-of-line) (forward-line 1)) + ;; something can be in the next line/section, the heading needs be on its own line + ;; this has to be done after `goto-char' because it will invalidate the node + (newline) + (forward-line -1) + ;; insert the heading and indent (insert heading-level " ") - (indent-according-to-mode) - ;; something can be below the end of section - (save-excursion - (newline)))) + (indent-according-to-mode))) ;;;###autoload (defun typst-ts-mode-preview (file) @@ -1271,6 +1306,7 @@ TODO lack of documentation." (define-key map (kbd "M-<down>") #'typst-ts-mode-heading-down) (define-key map (kbd "M-<up>") #'typst-ts-mode-heading-up) (define-key map (kbd "M-<return>") #'typst-ts-mode-meta-return) + (define-key map (kbd "<return>") #'typst-ts-mode-return) (define-key map (kbd "TAB") #'typst-ts-mode-cycle) map))