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))
 

Reply via email to