branch: elpa/typst-ts-mode
commit 96d82bc4ba38a6d2d1fcabca5e413c58cb278a80
Author: Meow King <mr.meowk...@anche.no>
Commit: Meow King <mr.meowk...@anche.no>

    refactor: separate editing commands into another file
---
 README.md                             |   7 +
 typst-ts-utils.el => typst-ts-core.el |  21 ++-
 typst-ts-editing.el                   | 294 ++++++++++++++++++++++++++++++++++
 typst-ts-embedding-lang-settings.el   |  10 +-
 typst-ts-mode.el                      | 287 +--------------------------------
 5 files changed, 327 insertions(+), 292 deletions(-)

diff --git a/README.md b/README.md
index e654c8a718..c7beaefeb9 100644
--- a/README.md
+++ b/README.md
@@ -160,6 +160,13 @@ and `defcustom' forms reset their default values."
       (eval-defun nil))))
 ```
 
+### How to use different version of Emacs to test
+
+``` shell
+# change `emacs` to `emacs29`, `emacs30` or the path of your emacs executable 
+emacs -Q -L . --eval "(require 'typst-ts-mode)"
+```
+
 #### How to do lint
 I recommend you to use [makem.sh](https://github.com/alphapapa/makem.sh). 
However, you can choose anything you like.   
 To use it, first `cd` into the project root directory, then: 
diff --git a/typst-ts-utils.el b/typst-ts-core.el
similarity index 86%
rename from typst-ts-utils.el
rename to typst-ts-core.el
index 8113b71138..bdc6195173 100644
--- a/typst-ts-utils.el
+++ b/typst-ts-core.el
@@ -1,4 +1,4 @@
-;;; typst-ts-utils.el --- utility functions for typst-ts-mode -*- 
lexical-binding: t; -*-
+;;; typst-ts-core.el --- core functions for typst-ts-mode -*- lexical-binding: 
t; -*-
 ;; Copyright (C) 2023 The typst-ts-mode Project Contributors
 
 ;; This file is NOT part of Emacs.
@@ -27,7 +27,14 @@
 ;; code from Emacs binary
 (declare-function treesit-parser-list "treesit" t t)
 
-(defun typst-ts-utils-parser-list (&optional buffer language)
+(defun typst-ts-core-get-node-bol (node)
+  "Get the NODE's indentation offset (at node beginning)."
+  (save-excursion
+    (goto-char (treesit-node-start node))
+    (back-to-indentation)
+    (point)))
+
+(defun typst-ts-core-parser-list (&optional buffer language)
   "An comptibility function for Emacs 29's `treesit-parser-list' function.
 BUFFER defaults to the current buffer.  If that buffer is an indirect
 buffer, its base buffer is used instead.  That is, indirect buffers
@@ -43,7 +50,7 @@ If LANGUAGE is non-nil, only return parsers for that 
language."
        parsers))))
 
 ;; code is from treesit.el inside Emacs Source
-(defun typst-ts-utils-local-parsers-at (&optional pos language with-host)
+(defun typst-ts-core-local-parsers-at (&optional pos language with-host)
   "Return all the local parsers at POS.
 It's a copy of Emacs 30's `treesit-local-parsers-at' function.
 POS LANGUAGE WITH-HOST."
@@ -60,7 +67,7 @@ POS LANGUAGE WITH-HOST."
       (nreverse res))))
 
 ;; code is from treesit.el inside Emacs Source
-(defun typst-ts-utils-local-parsers-on (&optional beg end language with-host)
+(defun typst-ts-core-local-parsers-on (&optional beg end language with-host)
   "Return all the local parsers between BEG END.
 It's a copy of Emacs 30's `treesit-local-parsers-on' function.
 BEG END LANGUAGE WITH-HOST."
@@ -76,7 +83,7 @@ BEG END LANGUAGE WITH-HOST."
             (push (if with-host (cons parser host-parser) parser) res))))
       (nreverse res))))
 
-(defun typst-ts-utils-node-get (node instructions)
+(defun typst-ts-core-node-get (node instructions)
   "Get things from NODE by INSTRUCTIONS.
 It's a copy of Emacs 30's `treesit-node-get' function."
   (declare (indent 1))
@@ -98,6 +105,6 @@ It's a copy of Emacs 30's `treesit-node-get' function."
                         (treesit-node-prev-sibling node named)))))))
     node))
 
-(provide 'typst-ts-utils)
+(provide 'typst-ts-core)
 
-;;; typst-ts-utils.el ends here
+;;; typst-ts-core.el ends here
diff --git a/typst-ts-editing.el b/typst-ts-editing.el
new file mode 100644
index 0000000000..7abcad9124
--- /dev/null
+++ b/typst-ts-editing.el
@@ -0,0 +1,294 @@
+;;; typst-ts-editing.el --- Helper functions for editing Typst documents -*- 
lexical-binding: t; -*-
+;; Copyright (C) 2023 The typst-ts-mode Project Contributors
+
+;; This file is NOT part of Emacs.
+;; This program is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;; Code:
+
+(require 'outline)
+(require 'typst-ts-core)
+
+;;;###autoload
+(defun typst-ts-mode-heading-up ()
+  "Switch the current heading with the heading above."
+  (interactive)
+  (typst-ts-mode-meta--dwim 'up))
+
+;;;###autoload
+(defun typst-ts-mode-heading-down ()
+  "Switch the current heading with the heading below."
+  (interactive)
+  (typst-ts-mode-meta--dwim 'down))
+
+;;;###autoload
+(defun typst-ts-mode-heading-increase ()
+  "Increase the heading level."
+  (interactive)
+  (typst-ts-mode-meta--dwim 'right))
+
+;;;###autoload
+(defun typst-ts-mode-heading-decrease ()
+  "Decrease heading level."
+  (interactive)
+  (typst-ts-mode-meta--dwim 'left))
+
+(defun typst-ts-mode-heading--at-point-p ()
+  "Whether the current line is a heading.
+Return the heading node when yes otherwise nil."
+  (let ((node (treesit-node-parent
+                    (treesit-node-at
+                (save-excursion
+                  (beginning-of-line-text)
+                  (point))))))
+    (if (string= (treesit-node-type node) "heading")
+        node
+      nil)))
+
+(defun typst-ts-mode-meta--dwim (direction)
+  "Do something depending on the context with meta key + DIRECTION.
+`left': `typst-ts-mode-heading-decrease',
+`right': `typst-ts-mode-heading-increase',
+`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
+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)))))))
+
+(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 (typst-ts-mode--item-on-line-p)))
+    (cond
+     (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)
+  "Handle RET depends on condition.
+When prefix ARG is non-nil, call global return function."
+  (interactive "P")
+  (let (execute-result node)
+    (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)))
+         (cond
+          (arg (throw 'execute-result 'default))
+          ;; on item node end
+          ((and (eolp)
+                (setq node (typst-ts-mode--item-on-line-p))
+                (string= (treesit-node-type node) "item")
+                (not (string= (typst-ts-core-node-get node '((child -1 nil) 
(type))) "linebreak")))
+           (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))
+           (throw 'execute-result 'success))
+          ))))
+    ;; execute default action if not successful
+    (unless (eq execute-result 'success)
+      (let ((global-ret-function
+             (global-key-binding (kbd "RET"))))
+        (if (and current-prefix-arg
+                 (yes-or-no-p
+                  (format
+                   "Execute function `%s' with the given prefix argument?"
+                   global-ret-function)))
+            (call-interactively global-ret-function)
+          (let ((current-prefix-arg nil))
+            (call-interactively global-ret-function)))))))
+
+(defun typst-ts-mode-insert--item (node)
+  "Insert an item after NODE.
+NODE must be an item node!
+This function respects indentation."
+  (let* (;; +, -, or <num>.
+              (item-type (treesit-node-text
+                          (treesit-node-child node 0)))
+         (item-number (string-to-number item-type))
+         (item-end (treesit-node-end node))
+         (node-bol-column (typst-ts-mode-column-at-pos
+                           (typst-ts-core-get-node-bol node))))
+    (goto-char item-end)
+    (newline)
+    (indent-line-to node-bol-column)
+    (insert (if (= item-number 0)
+                item-type
+              (concat (number-to-string (1+ item-number)) "."))
+            " ")))
+
+(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 below point."
+  (let* ((section
+               (treesit-parent-until
+                node
+                (lambda (node)
+                  (string= (treesit-node-type node) "section"))
+                t))
+              ;; first child is heading
+              (heading (treesit-node-child section 0))
+              (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 "=")
+      (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)))
+
+(defun typst-ts-mode-column-at-pos (point)
+  "Get the column at position POINT."
+  (save-excursion
+    (goto-char point)
+    (current-column)))
+
+;;;###autoload
+(defun typst-ts-mode-cycle (&optional _arg)
+  "Cycle."
+  (interactive "P")
+  (let (execute-result)
+    (setq
+     execute-result
+     ;; plz manually throw `\'success' to `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)))
+         (cond
+          ((equal parent-node-type "raw_blck")
+           (insert-tab)
+           (throw 'execute-result 'success))
+          
+          ((or (equal cur-node-type "parbreak")
+               (equal parent-node-type "item")
+               ;; please turn on whitespace-mode to test the following 
conditions
+               (eobp)
+               (eq (point) (1- (point-max))))
+           (when-let* ((cur-line-bol
+                        (save-excursion
+                          (back-to-indentation)
+                          (point)))
+                       (prev-nonwhite-pos (save-excursion
+                                            (goto-char cur-line-bol)
+                                            (skip-chars-backward "\s\r\n\t")
+                                            (1- (point))))
+                       ((and (not (eq prev-nonwhite-pos 0))  ; first line
+                             (not (eq  ; has previous sibling
+                                   (line-number-at-pos prev-nonwhite-pos)
+                                   (line-number-at-pos (point))))))
+                       (prev-nonwhite-line-node
+                        (treesit-node-at prev-nonwhite-pos))
+                       (prev-nonwhite-line-bol
+                        ;; TODO typst-ts-core-get-node-bol
+                        (save-excursion
+                          (goto-char prev-nonwhite-pos)
+                          (back-to-indentation)
+                          (point)))
+                       (prev-nonwhite-line-heading-node
+                        (treesit-node-at prev-nonwhite-line-bol))
+                       (prev-nonwhite-line-top-node (treesit-node-parent
+                                                     
prev-nonwhite-line-heading-node))
+                       (cur-line-bol-column (typst-ts-mode-column-at-pos 
cur-line-bol))
+                       (prev-nonwhite-line-bol-column
+                        (typst-ts-mode-column-at-pos prev-nonwhite-line-bol)))
+             (cond
+              ;; 1. el
+              ;; 2. psy| <- can toggle indent
+              ((and
+                (equal (treesit-node-type prev-nonwhite-line-top-node) "item")
+                (equal (treesit-node-type prev-nonwhite-line-heading-node) "-")
+                ;; previous nonwhite-line ending is not '\' character
+                (not (equal (treesit-node-type prev-nonwhite-line-node) 
"linebreak")))
+               ;; TODO cycle all its children
+               (let (point)
+                 (if (not (eq cur-line-bol-column 
prev-nonwhite-line-bol-column))
+                     (progn
+                       (setq point (point))
+                       (indent-line-to prev-nonwhite-line-bol-column)
+                       (goto-char (- point typst-ts-mode-indent-offset)))
+                   (setq point (point))
+                   (indent-line-to (+ typst-ts-mode-indent-offset
+                                      prev-nonwhite-line-bol-column))
+                   (goto-char (+ typst-ts-mode-indent-offset point)))
+                 (throw 'execute-result 'success))))))
+          (t nil)))))
+    ;; execute default action if not successful
+    (unless (eq execute-result 'success)
+      (call-interactively (global-key-binding (kbd "TAB"))))))
+
+(provide 'typst-ts-editing)
+
+;;; typst-ts-editing.el ends here
diff --git a/typst-ts-embedding-lang-settings.el 
b/typst-ts-embedding-lang-settings.el
index f5d6039a88..c663fb8c53 100644
--- a/typst-ts-embedding-lang-settings.el
+++ b/typst-ts-embedding-lang-settings.el
@@ -21,7 +21,7 @@
 
 ;;; Code:
 (require 'treesit)
-(require 'typst-ts-utils)
+(require 'typst-ts-core)
 
 (defcustom typst-ts-highlight-raw-block-langs-not-in-predefined-settings t
   "Whether to highlight raw block of language that is not in settings.
@@ -773,10 +773,10 @@ Use this function as one notifier of 
`treesit-parser-notifiers'."
            ;; parsers created by `treesit-language-at-point-function' (
            ;; `typst-ts-mode--language-at-point'.)
            ;; i.e. parsers cannot be created by `treesit-range-settings'
-           (mapcar #'treesit-parser-language (typst-ts-utils-parser-list))
+           (mapcar #'treesit-parser-language (typst-ts-core-parser-list))
            ;; parsers created by `treesit-range-settings'
            (mapcar #'treesit-parser-language
-                   (typst-ts-utils-local-parsers-on (point-min) 
(point-max))))))
+                   (typst-ts-core-local-parsers-on (point-min) (point-max))))))
         lang-ts-mode settings)
     (dolist (lang parser-langs)
       (unless (member lang typst-ts-els--include-languages)
@@ -789,7 +789,7 @@ Use this function as one notifier of 
`treesit-parser-notifiers'."
                   (typst-ts-els-merge-lang-settings lang)
                   ;; some feature like cmake-ts-mode will create a parser when
                   ;; the feature is required, so we need to clean thease 
parsers
-                  (mapc #'treesit-parser-delete (typst-ts-utils-parser-list 
nil lang))
+                  (mapc #'treesit-parser-delete (typst-ts-core-parser-list nil 
lang))
                   (message "Load %s language settings from configuration." 
lang))
               (error
                ;; if language not in setting or encounter error during loading,
@@ -801,7 +801,7 @@ Use this function as one notifier of 
`treesit-parser-notifiers'."
                        (typst-ts-els--add-treesit-range-rules lang)
                        ;; delete top level parsers, so range rules works (i.e. 
local parsers)
                        ;; so that highlighting will not exceed the desired 
range
-                       (mapc #'treesit-parser-delete 
(typst-ts-utils-parser-list nil lang))
+                       (mapc #'treesit-parser-delete 
(typst-ts-core-parser-list nil lang))
                        
                        ;; find and merge settings
                        (setq lang-ts-mode
diff --git a/typst-ts-mode.el b/typst-ts-mode.el
index 37c24aca3c..15896330fb 100644
--- a/typst-ts-mode.el
+++ b/typst-ts-mode.el
@@ -34,11 +34,12 @@
 (require 'outline)
 
 (require 'typst-ts-embedding-lang-settings)
-(require 'typst-ts-utils)
+(require 'typst-ts-core)
 (require 'typst-ts-faces)
 (require 'typst-ts-compile)
 (require 'typst-ts-watch-mode)
 (require 'typst-ts-edit-indirect)
+(require 'typst-ts-editing)
 
 (defgroup typst-ts nil
   "Tree Sitter enabled Typst Writing."
@@ -396,13 +397,6 @@ If you want to customize the rules, please customize the 
same name variable
   (regexp-opt '("block" "content" "group" "math" "_math_group"))
   "Container node types regexp.")
 
-(defun typst-ts-mode--get-node-bol (node)
-  "Get the NODE's indentation offset (at node beginning)."
-  (save-excursion
-    (goto-char (treesit-node-start node))
-    (back-to-indentation)
-    (point)))
-
 (defun typst-ts-mode--identation-item-linebreak (_node _parent bol)
   "Where the current line is underneath a item with linebreak as ending.
 Ignore whitespaces.
@@ -483,7 +477,7 @@ Used in `typst-ts-mode-indent-rules'."
          (bol-col
           (typst-ts-mode-column-at-pos bol))
          (raw-block-bol
-          (typst-ts-mode--get-node-bol (treesit-node-parent parent)))
+          (typst-ts-core-get-node-bol (treesit-node-parent parent)))
          (raw-block-bol-col
           (typst-ts-mode-column-at-pos raw-block-bol)))
     (if (equal "blob" prev-line-node-type)
@@ -595,14 +589,14 @@ NODE, PARENT and BOL see `treesit-indent-function'."
     (error "Variable `typst-ts-mode-indent-function' shouldn't be null!"))
   (let ((res (funcall typst-ts-mode-indent-function node parent bol)))
     ;; if it is a highlighted raw block region (i.e. contains at least one 
local parser)
-    (when (typst-ts-utils-local-parsers-at (treesit-node-start node))
+    (when (typst-ts-core-local-parsers-at (treesit-node-start node))
       ;; when there is no matching rules
       (unless (car res)
         (setcar res bol)
         (setcdr res 0))
       (let* ((blob_node (treesit-node-at bol 'typst))
              (raw_block_node (treesit-node-parent blob_node))
-             (raw_block_bol (typst-ts-mode--get-node-bol raw_block_node))
+             (raw_block_bol (typst-ts-core-get-node-bol raw_block_node))
              (raw_block_bol_column (typst-ts-mode-column-at-pos raw_block_bol))
              (res-column (+ (typst-ts-mode-column-at-pos (car res)) (cdr 
res))))
         (when (> raw_block_bol_column res-column)
@@ -635,8 +629,7 @@ NODE, PARENT and BOL see `treesit-indent-function'."
   "Generate name of NODE for displaying in Imenu."
   (treesit-node-text node))
 
-;; outline-minor-mode 
================================================================================
-
+;; outline-minor-mode
 (defconst typst-ts-mode-outline-regexp "^[[:space:]]*\\(=+\\) "
   "Regexp identifying Typst header.")
 
@@ -648,272 +641,6 @@ NODE, PARENT and BOL see `treesit-indent-function'."
              (- (match-end 1) (match-beginning 1))
       0)))
 
-(defun typst-ts-mode-heading--at-point-p ()
-  "Whether the current line is a heading.
-Return the heading node when yes otherwise nil."
-  (let ((node (treesit-node-parent
-                    (treesit-node-at
-                (save-excursion
-                  (beginning-of-line-text)
-                  (point))))))
-    (if (string= (treesit-node-type node) "heading")
-        node
-      nil)))
-
-;;;###autoload
-(defun typst-ts-mode-heading-up ()
-  "Switch the current heading with the heading above."
-  (interactive)
-  (typst-ts-mode-meta--dwim 'up))
-
-;;;###autoload
-(defun typst-ts-mode-heading-down ()
-  "Switch the current heading with the heading below."
-  (interactive)
-  (typst-ts-mode-meta--dwim 'down))
-
-;;;###autoload
-(defun typst-ts-mode-heading-increase ()
-  "Increase the heading level."
-  (interactive)
-  (typst-ts-mode-meta--dwim 'right))
-
-;;;###autoload
-(defun typst-ts-mode-heading-decrease ()
-  "Decrease heading level."
-  (interactive)
-  (typst-ts-mode-meta--dwim 'left))
-
-(defun typst-ts-mode-meta--dwim (direction)
-  "Do something depending on the context with meta key + DIRECTION.
-`left': `typst-ts-mode-heading-decrease',
-`right': `typst-ts-mode-heading-increase',
-`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
-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)))))))
-
-(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 (typst-ts-mode--item-on-line-p)))
-    (cond
-     (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)
-  "Handle RET depends on condition.
-When prefix ARG is non-nil, call global return function."
-  (interactive "P")
-  (let (execute-result node)
-    (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)))
-         (cond
-          (arg (throw 'execute-result 'default))
-          ;; on item node end
-          ((and (eolp)
-                (setq node (typst-ts-mode--item-on-line-p))
-                (string= (treesit-node-type node) "item")
-                (not (string= (typst-ts-utils-node-get node '((child -1 nil) 
(type))) "linebreak")))
-           (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))
-           (throw 'execute-result 'success))
-          ))))
-    ;; execute default action if not successful
-    (unless (eq execute-result 'success)
-      (let ((global-ret-function
-             (global-key-binding (kbd "RET"))))
-        (if (and current-prefix-arg
-                 (yes-or-no-p
-                  (format
-                   "Execute function `%s' with the given prefix argument?"
-                   global-ret-function)))
-            (call-interactively global-ret-function)
-          (let ((current-prefix-arg nil))
-            (call-interactively global-ret-function)))))))
-
-(defun typst-ts-mode-insert--item (node)
-  "Insert an item after NODE.
-NODE must be an item node!
-This function respects indentation."
-  (let* (;; +, -, or <num>.
-              (item-type (treesit-node-text
-                          (treesit-node-child node 0)))
-         (item-number (string-to-number item-type))
-         (item-end (treesit-node-end node))
-         (node-bol-column (typst-ts-mode-column-at-pos
-                           (typst-ts-mode--get-node-bol node))))
-    (goto-char item-end)
-    (newline)
-    (indent-line-to node-bol-column)
-    (insert (if (= item-number 0)
-                item-type
-              (concat (number-to-string (1+ item-number)) "."))
-            " ")))
-
-(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 below point."
-  (let* ((section
-               (treesit-parent-until
-                node
-                (lambda (node)
-                  (string= (treesit-node-type node) "section"))
-                t))
-              ;; first child is heading
-              (heading (treesit-node-child section 0))
-              (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 "=")
-      (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)))
-
-(defun typst-ts-mode-column-at-pos (point)
-  "Get the column at position POINT."
-  (save-excursion
-    (goto-char point)
-    (current-column)))
-
-;;;###autoload
-(defun typst-ts-mode-cycle (&optional _arg)
-  "Cycle."
-  (interactive "P")
-  (let (execute-result)
-    (setq
-     execute-result
-     ;; plz manually throw `\'success' to `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)))
-         (cond
-          ((equal parent-node-type "raw_blck")
-           (insert-tab)
-           (throw 'execute-result 'success))
-          
-          ((or (equal cur-node-type "parbreak")
-               (equal parent-node-type "item")
-               ;; please turn on whitespace-mode to test the following 
conditions
-               (eobp)
-               (eq (point) (1- (point-max))))
-           (when-let* ((cur-line-bol
-                        (save-excursion
-                          (back-to-indentation)
-                          (point)))
-                       (prev-nonwhite-pos (save-excursion
-                                            (goto-char cur-line-bol)
-                                            (skip-chars-backward "\s\r\n\t")
-                                            (1- (point))))
-                       ((and (not (eq prev-nonwhite-pos 0))  ; first line
-                             (not (eq  ; has previous sibling
-                                   (line-number-at-pos prev-nonwhite-pos)
-                                   (line-number-at-pos (point))))))
-                       (prev-nonwhite-line-node
-                        (treesit-node-at prev-nonwhite-pos))
-                       (prev-nonwhite-line-bol
-                        ;; TODO typst-ts-mode--get-node-bol
-                        (save-excursion
-                          (goto-char prev-nonwhite-pos)
-                          (back-to-indentation)
-                          (point)))
-                       (prev-nonwhite-line-heading-node
-                        (treesit-node-at prev-nonwhite-line-bol))
-                       (prev-nonwhite-line-top-node (treesit-node-parent
-                                                     
prev-nonwhite-line-heading-node))
-                       (cur-line-bol-column (typst-ts-mode-column-at-pos 
cur-line-bol))
-                       (prev-nonwhite-line-bol-column
-                        (typst-ts-mode-column-at-pos prev-nonwhite-line-bol)))
-             (cond
-              ;; 1. el
-              ;; 2. psy| <- can toggle indent
-              ((and
-                (equal (treesit-node-type prev-nonwhite-line-top-node) "item")
-                (equal (treesit-node-type prev-nonwhite-line-heading-node) "-")
-                ;; previous nonwhite-line ending is not '\' character
-                (not (equal (treesit-node-type prev-nonwhite-line-node) 
"linebreak")))
-               ;; TODO cycle all its children
-               (let (point)
-                 (if (not (eq cur-line-bol-column 
prev-nonwhite-line-bol-column))
-                     (progn
-                       (setq point (point))
-                       (indent-line-to prev-nonwhite-line-bol-column)
-                       (goto-char (- point typst-ts-mode-indent-offset)))
-                   (setq point (point))
-                   (indent-line-to (+ typst-ts-mode-indent-offset
-                                      prev-nonwhite-line-bol-column))
-                   (goto-char (+ typst-ts-mode-indent-offset point)))
-                 (throw 'execute-result 'success))))))
-          (t nil)))))
-    ;; execute default action if not successful
-    (unless (eq execute-result 'success)
-      (call-interactively (global-key-binding (kbd "TAB"))))))
 
 ;;;###autoload
 (defun typst-ts-mode-preview (file)
@@ -1042,7 +769,7 @@ typst tree sitter grammar (at least %s)!" 
(current-time-string min-time))
                  (typst-ts-els-merge-settings config)
                ;; some feature like cmake-ts-mode will create a parser when
                ;; the feature is required, so we need to clean thease parsers
-               (mapc #'treesit-parser-delete (typst-ts-utils-parser-list nil 
lang))
+               (mapc #'treesit-parser-delete (typst-ts-core-parser-list nil 
lang))
                (add-to-list 'typst-ts-els--include-languages lang))))
 
   (typst-ts-mode-check-grammar-version))

Reply via email to