branch: elpa/typst-ts-mode commit 8234ba29f341b34ad7f64d611aabce5fe2d8a8d8 Author: meowking <mr.meowk...@tutamail.com> Commit: meowking <mr.meowk...@tutamail.com>
fix: indentation & editing commands --- typst-ts-core.el | 34 +++++++++++++++++++++++++++------- typst-ts-editing.el | 31 ++++++++++++++++++------------- typst-ts-mode.el | 35 ++++++++++++++++++----------------- 3 files changed, 63 insertions(+), 37 deletions(-) diff --git a/typst-ts-core.el b/typst-ts-core.el index b105940a8f..6b7b8357ca 100644 --- a/typst-ts-core.el +++ b/typst-ts-core.el @@ -32,6 +32,12 @@ :type 'natnum :group 'typst-ts) +(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 + (regexp-opt '("block" "content" "group" "math" "_math_group")) + "Container node types regexp.") + (defun typst-ts-core-column-at-pos (point) "Get the column at position POINT." (save-excursion @@ -87,15 +93,29 @@ Currently the effect of FN shouldn't change line number." ;; Emacs 29 doesn't support string type PRED, so this function is created for ;; convenience -(defun typst-ts-core-parent-util-type (node type include-node) +(defun typst-ts-core-parent-util-type (node type &optional include-node same-context) "See `treesit-parent-until'. TYPE is an regexp expression for matching types. -NODE TYPE INCLUDE-NODE." - (treesit-parent-until - node - (lambda (node) - (string-match-p type (treesit-node-type node))) - include-node)) +SAME-CONTEXT: whether the parent should be in the current context with NODE. +The following example means parent item node is in a different context with +`hi' text node +- #[ +hi +] +NODE TYPE INCLUDE-NODE see `treesit-parent-until'." + (let ((matched-node + (treesit-parent-until + node + (lambda (node) + (let ((node-type (treesit-node-type node))) + (or (and same-context + (string-match-p + typst-ts-mode--container-node-types-regexp node-type)) + (string-match-p type node-type)))) + include-node))) + (when (and matched-node + (string-match-p type (treesit-node-type matched-node))) + matched-node))) (defun typst-ts-core-prev-sibling-ignore-types (node types) "Find previous sibling node ignoring nodes whose type matches TYPES. diff --git a/typst-ts-editing.el b/typst-ts-editing.el index 39b4344962..1f20d2d20c 100644 --- a/typst-ts-editing.el +++ b/typst-ts-editing.el @@ -119,19 +119,21 @@ When prefix ARG is non-nil, call global return function." (cond ;; on item node end ((and (eolp) - (setq node (typst-ts-core-get-parent-of-node-at-bol-nonwhite)) - (equal (treesit-node-type node) "item")) + (setq node (typst-ts-core-parent-util-type + (typst-ts-core-get-parent-of-node-at-bol-nonwhite) + "item" t t))) (let* ((item-node node) - (child-node (treesit-node-child item-node 1)) + (has-children (treesit-node-child item-node 1)) (next-line-node (typst-ts-core-get-parent-of-node-at-bol-nonwhite (save-excursion (forward-line 1) (point)))) - (next-line-node-type - (treesit-node-type next-line-node))) - (if child-node - (if (and (equal next-line-node-type "item") + (next-line-top-item-node + (typst-ts-core-parent-util-type + next-line-node "item" t t))) + (if has-children + (if (and next-line-top-item-node ;; end of buffer situation (or next line is the end ;; line (and no newline character)) (not (equal @@ -146,15 +148,18 @@ When prefix ARG is non-nil, call global return function." (beginning-of-line) (kill-line) ;; whether the previous line is in an item - (let* ((prev-line-node-type - (treesit-node-type + (let* ((prev-line-item-node + (typst-ts-core-parent-util-type (typst-ts-core-get-parent-of-node-at-bol-nonwhite (save-excursion (forward-line -1) - (point)))))) - (if (equal "item" prev-line-node-type) + (point))) + "item" t t))) + (if prev-line-item-node (progn - (kill-line) + ;; sometimes there is no newlines characters at the EOL + (ignore-errors + (kill-line)) (forward-line -1) (end-of-line) (call-interactively #'newline)) @@ -259,7 +264,7 @@ When there is no section it will insert a heading below point." ((setq node (typst-ts-core-parent-util-type - cur-line-nonwhite-bol-node "item" t)) + cur-line-nonwhite-bol-node "item" t t)) (let* ((cur-item-node node) (prev-significant-node (typst-ts-core-prev-sibling-ignore-types diff --git a/typst-ts-mode.el b/typst-ts-mode.el index baa5e3e5c3..fbaae6266e 100644 --- a/typst-ts-mode.el +++ b/typst-ts-mode.el @@ -388,12 +388,6 @@ 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-regexp - ;; '_math_group' here is because `treesit-parent-until' doesn't hanlde node type alias well - ;; TODO file a bug - (regexp-opt '("block" "content" "group" "math" "_math_group")) - "Container node types regexp.") - (defun typst-ts-mode--identation-item-linebreak (_node _parent bol) "Where the current line is underneath a item with linebreak as ending. Ignore whitespaces. @@ -516,7 +510,7 @@ NODE, PARENT and BOL see `treesit-simple-indent-rules'." typst-ts-mode-indent-offset) ;; multi-line item - ;; - [hi] foo + ;; - #[hi] foo ;; bar ;; my try with `prev-adaptive-prefix' failed even after set the ;; `adaptive-fill-regexp' @@ -565,20 +559,22 @@ NODE, PARENT and BOL see `treesit-simple-indent-rules'." This function is meant to be used when user hits a return key." (treesit-node-start (treesit-node-child - (treesit-node-parent + (typst-ts-core-parent-util-type (treesit-node-at (save-excursion - (beginning-of-line-text 0) - (point)))) + (forward-line -1) + (back-to-indentation) + (point))) + "item" t) 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))))))) + (typst-ts-core-parent-util-type + (treesit-node-at (point)) + "item" t))) (defun typst-ts-mode-comment-setup() @@ -719,6 +715,15 @@ typst tree sitter grammar (at least %s)!" (current-time-string min-time)) (file-name-nondirectory buffer-file-name) typst-ts-compile-options)))) + ;; Although without enabling `outline-minor-mode' also works, enabling it + ;; provides outline ellipsis (if you use `set-display-table-slot' to set) + (outline-minor-mode t) + + ;; necessary for + ;; `typst-ts-mode-cycle'(`typst-ts-editing--indent-item-node-lines') + ;; and indentation to work + ;; (indent-tabs-mode -1) + (typst-ts-mode-check-grammar-version)) ;;;###autoload @@ -780,10 +785,6 @@ typst tree sitter grammar (at least %s)!" (current-time-string min-time)) (setq-local outline-regexp typst-ts-mode-outline-regexp) (setq-local outline-level #'typst-ts-mode-outline-level)) (setq-local outline-heading-alist typst-ts-mode-outline-heading-alist) - ;; Although without enabling `outline-minor-mode' also works, enabling it - ;; provides outline ellipsis - ;; TODO add it to after-hook - (outline-minor-mode t) (treesit-major-mode-setup)