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

    refactor!(indentation): extensive modification
---
 basic-syntax.typ |   2 +-
 typst-ts-mode.el | 184 ++++++++++++++++++++++++++-----------------------------
 2 files changed, 89 insertions(+), 97 deletions(-)

diff --git a/basic-syntax.typ b/basic-syntax.typ
index ad85254c64..46b30275e1 100644
--- a/basic-syntax.typ
+++ b/basic-syntax.typ
@@ -20,7 +20,7 @@ sudo rm -rf *
 ```
 <label> // label
 @reference // reference
-
+   
 Hello\nWorld // escape
 
 
diff --git a/typst-ts-mode.el b/typst-ts-mode.el
index 00febccc90..eec10dff33 100644
--- a/typst-ts-mode.el
+++ b/typst-ts-mode.el
@@ -99,16 +99,6 @@ the current buffer."
   :type 'hook
   :group 'typst-ts)
 
-(defcustom typst-ts-mode-tab-function 'indent-for-tab-command
-  "Default function for `typst-ts-mode-cycle' when conditions don't match."
-  :type 'function
-  :group 'typst-ts)
-
-(defcustom typst-ts-mode-return-function 'newline
-  "Default function for `typst-ts-mode-return' when conditions don't match."
-  :type 'function
-  :group 'typst-ts)
-
 (defcustom typst-ts-mode-watch-options ""
   "User defined compile options for `typst-ts-mode-watch'.
 The compile options will be passed to the
@@ -736,20 +726,11 @@ If you want to customize the rules, please customize the 
same name variable
     (markup-standard code-standard math-standard)
     (markup-extended code-extended math-extended)))
 
-(defconst typst-ts-mode--container-node-types
+(defconst typst-ts-mode--container-node-types-regexp
   ;; '_math_group' here is because `treesit-parent-until' doesn't hanlde node 
type alias well
   ;; TODO file a bug
-  '("block" "content" "group" "math" "_math_group")
-  "Bracket node types.")
-
-(defun typst-ts-mode--node-inside-brackets (parent)
-  "Return the bracket node if the PARENT of node is a bracket or inside 
bracket.
-Return nil if the node is not inside brackets."
-  (treesit-parent-until
-   parent
-   (lambda (parent)
-     (member (treesit-node-type parent) typst-ts-mode--container-node-types))
-   t))
+  (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)."
@@ -758,30 +739,6 @@ Return nil if the node is not inside brackets."
     (back-to-indentation)
     (point)))
 
-(defun typst-ts-mode--ancestor-in (types &optional return-bol)
-  "Return a function to check whether one of the ancestors of a node is in 
TYPES.
-The returned function suits `treesit-simple-indent-rules' Match.
-If RETURN-BOL is non-nil, then return returns the beginning of line position of
-the corresponding ancestor node that its type is in TYPES, else return the
-corresponding ancestor node.  Return nil if ancestor not matching."
-  (let ((re (regexp-opt types)))
-    (lambda (_node parent _bol)
-      (let* ((query-node parent)
-             (ancestor (treesit-parent-until
-                        query-node
-                        (lambda (parent)
-                          (string-match-p re (treesit-node-type parent)))
-                        t)))
-        (if return-bol
-            (when ancestor
-              (typst-ts-mode--get-node-bol ancestor))
-          ancestor)))))
-
-(defun typst-ts-mode--ancestor-bol (types)
-  "See `typst-ts-mode--ancestor-in'.
-TYPES."
-  (typst-ts-mode--ancestor-in types t))
-
 (defun typst-ts-mode--identation-item-linebreak (_node _parent bol)
   "Where the current line is underneath a item with linebreak as ending.
 Ignore whitespaces.
@@ -826,7 +783,52 @@ work well.  Example:
     (back-to-indentation)
     (point)))
 
-(defvar typst-ts-mode--indent-rules
+(defun typst-ts-mode-indent--grand-parent-bol (_node parent _bol)
+  "Return the grand parent beginning of line position.
+NODE, PARENT and BOL see `treesit-simple-indent-rules'."
+  (save-excursion
+    (goto-char (treesit-node-start (treesit-node-parent parent)))
+    (back-to-indentation)
+    (point)))
+
+(defun typst-ts-mode-indent--no-node-section-container-p (node parent _bol)
+  "Whether the current structure is nil -> parbreak -> container -> section.
+NODE, PARENT and BOL see `treesit-simple-indent-rules'."
+  (unless node
+    (let* ((parent-type (treesit-node-type parent))
+           (gp-node (treesit-node-parent parent))
+           (gp-node-type (treesit-node-type gp-node))
+           (ggp-node-type (treesit-node-type (treesit-node-parent gp-node))))
+      (and
+       (equal "parbreak" parent-type)
+       (string-match-p typst-ts-mode--container-node-types-regexp gp-node-type)
+       (equal "section" ggp-node-type)))))
+
+(defun typst-ts-mode-indent--raw-block-blob-anchor (_node parent bol)
+  "Get the correct anchor for raw block blob.
+Please make sure the passed in NODE, PARENT and BOL is nil, blob and raw_blck.
+Used in `typst-ts-mode-indent-rules'."
+  (let* ((prev-line-bol
+          (save-excursion
+            (forward-line -1)
+            (back-to-indentation)
+            (point)))
+         (prev-line-node
+          (treesit-node-at prev-line-bol))
+         (prev-line-node-type (treesit-node-type prev-line-node))
+         (bol-col
+          (typst-ts-mode-column-at-pos bol))
+         (raw-block-bol
+          (typst-ts-mode--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)
+        (if (> raw-block-bol-col bol-col)
+            raw-block-bol
+          bol)
+      prev-line-bol)))
+
+(defvar typst-ts-mode-indent-rules
   ;; debug tips:
   ;; use `typst-ts/util/setup-indent-debug-environment' function in 
`side/utils.el'
   ;; it basically does these (with some extra trivial stuffs):
@@ -842,6 +844,7 @@ work well.  Example:
   
   ;; Note electric-pair-mode will auto insert newline character when condition 
meets
   ;; see `typst-ts-mode-electric-pair-open-newline-between-pairs-psif'
+  ;; It may be better to turn off `electric-pair-open-newline-between-pairs'
   `((typst
      ;; ((lambda (node parent bol)  ; NOTE
      ;;    (message "%s %s %s %s %s" node parent
@@ -853,7 +856,7 @@ work well.  Example:
      ((parent-is "source_file") column-0 0)
 
      ((n-p-gp ,(regexp-opt '(")" "]" "}" "$"))
-              ,(regexp-opt typst-ts-mode--container-node-types)
+              ,typst-ts-mode--container-node-types-regexp
               nil)
       parent-bol 0)
      
@@ -888,29 +891,21 @@ work well.  Example:
       0)
 
      ;; raw block
-     ;; (TODO add indent offset when 
`typst-ts-mode-enable-raw-blocks-highlight' is t)
-     ;; the last "```" notation for raw block
+     ;; whether normally or in insertion, the current node is always nil...
      ((n-p-gp nil "blob" "raw_blck")
-      no-indent 0)
-
-     ;; inside container, coping with difficult conditions including no-node
-     ;; container is a direct child of "section"
-     ((lambda (node parent bol)
-        (let ((ancestor-node
-               (funcall
-                (typst-ts-mode--ancestor-in 
typst-ts-mode--container-node-types)
-                node parent bol)))
-          (when ancestor-node
-            (equal (treesit-node-type (treesit-node-parent ancestor-node)) 
"section"))))
-      ,(typst-ts-mode--ancestor-bol typst-ts-mode--container-node-types)
-      0)
+      typst-ts-mode-indent--raw-block-blob-anchor 0)
+
+     ;; inside container && container is direct child of "section" (headline)
+     (typst-ts-mode-indent--no-node-section-container-p
+      great-grand-parent 0)
+     ((n-p-gp nil ,typst-ts-mode--container-node-types-regexp "section")
+      grand-parent 0)
+
      ;; inside container
-     (,(typst-ts-mode--ancestor-in typst-ts-mode--container-node-types)
-      ,(typst-ts-mode--ancestor-bol typst-ts-mode--container-node-types)
-      typst-ts-mode-indent-offset)
-     
-     ;; TODO to be examined
-     (,(typst-ts-mode--ancestor-in '("ERROR")) no-indent 0)
+     ((and no-node (n-p-gp nil "parbreak" 
,typst-ts-mode--container-node-types-regexp))
+      typst-ts-mode-indent--grand-parent-bol typst-ts-mode-indent-offset)
+     ((parent-is ,typst-ts-mode--container-node-types-regexp)
+      parent-bol typst-ts-mode-indent-offset)
 
      (no-node parent-bol 0)
 
@@ -933,17 +928,19 @@ 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)
-    (unless (car res) (setcar res (save-excursion (beginning-of-line) 
(point))))
     (when (treesit-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_column (typst-ts-mode-column-at-pos
-                                    (typst-ts-mode--get-node-bol 
raw_block_node)))
-             (cur-line-bol (save-excursion (back-to-indentation) (point)))
-             (cur-line-bol-column (typst-ts-mode-column-at-pos cur-line-bol))
-             (offset (- raw_block_bol_column cur-line-bol-column)))
-        (when (> offset 0)
-          (setcdr res raw_block_bol_column))))
+             (raw_block_bol (typst-ts-mode--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)
+          ;; (message "%s %s %s" res raw_block_bol_column res-column)
+          (setcar res raw_block_bol))))
     res))
 
 (defun typst-ts-mode-comment-setup()
@@ -1117,7 +1114,7 @@ Using ARG argument will ignore the context and it will 
insert a heading instead.
 
 (defun typst-ts-mode-return (&optional arg)
   "Handle RET depends on condition.
-When prefix ARG is non-nil, call `typst-ts-mode-return-function'."
+When prefix ARG is non-nil, call global return function."
   (interactive "P")
   (let (execute-result node)
     (setq
@@ -1129,7 +1126,6 @@ When prefix ARG is non-nil, call 
`typst-ts-mode-return-function'."
                    (parent-node (treesit-node-parent cur-node))  ; could be nil
                    (parent-node-type (treesit-node-type parent-node)))
          (cond
-          ;; if provided with a prefix-argument, then do 
`typst-ts-mode-return-function'
           (arg (throw 'execute-result 'default))
           ;; on item node end
           ((and (eolp)
@@ -1146,16 +1142,16 @@ When prefix ARG is non-nil, call 
`typst-ts-mode-return-function'."
           ))))
     ;; execute default action if not successful
     (unless (eq execute-result 'success)
-      (if (commandp typst-ts-mode-return-function)
-          (if (and current-prefix-arg
-                   (yes-or-no-p
-                    (format
-                     "Execute function `%s' with the given prefix argument?"
-                     typst-ts-mode-return-function)))
-              (call-interactively typst-ts-mode-return-function)
-            (let ((current-prefix-arg nil))
-              (call-interactively typst-ts-mode-return-function)))
-        (funcall typst-ts-mode-return-function)))))
+      (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.
@@ -1347,9 +1343,7 @@ PROC: process; OUTPUT: new output from PROC."
 
 ;;;###autoload
 (defun typst-ts-mode-cycle (&optional _arg)
-  "Cycle.
-Customize `typst-ts-mode-tab-function' for default tab function when no
-condition matches."
+  "Cycle."
   (interactive "P")
   (let (execute-result)
     (setq
@@ -1421,9 +1415,7 @@ condition matches."
           (t nil)))))
     ;; execute default action if not successful
     (unless (eq execute-result 'success)
-      (if (commandp typst-ts-mode-tab-function)
-          (call-interactively typst-ts-mode-tab-function)
-        (funcall typst-ts-mode-tab-function)))))
+      (call-interactively (global-key-binding (kbd "TAB"))))))
 
 ;;;###autoload
 (defvar typst-ts-mode-map
@@ -1567,7 +1559,7 @@ It provide the ability to automatically open a new line 
for '$' character."
   (setq-local treesit-font-lock-feature-list 
typst-ts-mode-font-lock-feature-list)
 
   ;; Indentation
-  (setq-local treesit-simple-indent-rules typst-ts-mode--indent-rules)
+  (setq-local treesit-simple-indent-rules typst-ts-mode-indent-rules)
 
   ;; Imenu
   (setq-local treesit-simple-imenu-settings

Reply via email to