Skip to content
This repository was archived by the owner on Sep 25, 2023. It is now read-only.

Commit a701063

Browse files
committed
feat: better indentation(code from zig-mode)
1 parent c2c25fe commit a701063

File tree

7 files changed

+63
-50
lines changed

7 files changed

+63
-50
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
\#*\#
22
*.pdf
3+
*~

Makefile

+4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ load_polymode := -L ~/.emacs.d/.local/straight/repos/polymode
22
load_typst_mode := -l ~/.emacs.d/modules/languages/typst-mode/typst-mode.el
33
general := ~/.emacs.d/modules/languages/typst-mode/tests/general.typ
44
syntax := ~/.emacs.d/modules/languages/typst-mode/tests/syntax.typ
5+
empty := ~/.emacs.d/modules/languages/typst-mode/tests/empty.typ
56
debug := --debug-init
67

78
.PHONY: test_1
@@ -10,3 +11,6 @@ general:
1011

1112
syntax:
1213
emacs -Q $(debug) $(load_polymode) $(load_typst_mode) $(syntax)
14+
15+
empty:
16+
emacs -Q $(debug) $(load_polymode) $(load_typst_mode) $(empty)

README.org

+5-8
Original file line numberDiff line numberDiff line change
@@ -69,18 +69,15 @@ faces and custom variables with prefix =typst= or =typst-mode=
6969
For those stuffs cannot be done in short future.
7070
1. no syntax support for the context block =[ ]= which is located in the code block ={ }= \\
7171
this problem possibly can be solved with *nested polymode*. However, currently there is no official support for this function?
72-
2. indentation in code mode(contents between '{' and '}') may not works well, like this: \\
73-
(hitting `tab` to indent has problem, but it works well when directly call `typst-indent-line`)
72+
2. indentation in the first line of code mode(contents between '{' and '}') may not works well, like this: \\
73+
(hitting `tab` to indent has problem, but it works well when directly call `typst-mode-indent-line`)
7474

7575
#+begin_src plain
7676
begin_code {
77-
[ // no indentation on this line.
78-
[ // indentation works well
77+
[ // wrong indentation
78+
[ // indentation works well
79+
]
7980
]
80-
]
8181
}
8282
#+end_src
8383
The issue may caused by Polymode. I have created an issue here: [[https://github.com/polymode/polymode/issues/328][https://github.com/polymode/polymode/issues/328]]
84-
85-
*Temporary solution*: \\
86-
Manually execute the =typst-indent-line= command on the first line of the code block. Then the following indentations will work properly.

tests/empty.typ

Whitespace-only changes.

tests/general.typ

+1-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
#let cv(author: "", contacts: (), body) = {
2-
set document(author: author, title: author)
3-
set text(font: "Linux Libertine", lang: "en")
4-
5-
show heading: it => [
2+
show heading: it => [
63
#pad(bottom: -10pt, [#smallcaps(it.body)])
74
#line(length: 100%, stroke: 1pt)
85
]
@@ -142,4 +139,3 @@ A software developer interested in various programming domains. Core memeber of
142139
= Miscellaneous
143140
- Languages: English - fluent, Chinese - native, Taiwanese - native.
144141
- Member of `Tauri`, `rust-tw`, and more, contributed to `rust`, `async-std`, `veloren`, `tauri`, `riscv-opcodes`, `grcov`, `windows-rs`, `gtk-rs`, `winit`, and other projects.
145-

tests/syntax.typ

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ none, auto, false, true, 1, 1.1, 1e1
77
100.0%, 1.1fr
88
}
99

10+
1011
= styles<label>
1112
*strong* _emphasized_ `hello` https://typst.app/ @label
1213

typst-mode.el

+51-37
Original file line numberDiff line numberDiff line change
@@ -468,43 +468,57 @@
468468
map))
469469

470470
;;; Indentation =============================================
471-
(defun typst-indent-line ()
472-
"Indent current line in Typst mode.
473-
(1)If current line is the beginning line of the buffer, then indentation -> 0;
474-
Else [ (2)If the beginning of the visual part of the current line is close delimiter character -> indentation decreases,
475-
(3)Then check if the end of previous line contains an open delimiter character and there is no close delimiter after it -> indentation increases]"
471+
;; NOTE: this code is from zig-mode: https://github.com/ziglang/zig-mode/blob/master/zig-mode.el
472+
(defun typst-paren-nesting-level () (nth 0 (syntax-ppss)))
473+
474+
;; NOTE: this code is from zig-mode: https://github.com/ziglang/zig-mode/blob/master/zig-mode.el
475+
(defun typst-mode-indent-line ()
476476
(interactive)
477-
;; (message "%s" (current-indentation))
478-
(save-excursion
479-
(beginning-of-line)
480-
(let ((not-indented t)
481-
(cur-indent 0))
482-
(if (bobp) ;; (1)
483-
(progn (indent-line-to 0)
484-
(setq not-indented nil)))
485-
(when not-indented
486-
;; (3)
487-
(save-excursion
488-
(forward-line -1)
489-
(setq cur-indent (current-indentation))
490-
;; also works for complex scenario like {{}} [] () { (
491-
;; func {(
492-
;; code
493-
;; )}
494-
;; hello (a: {
495-
;; value
496-
;; }, b: {
497-
;; value
498-
;; })
499-
(if (looking-at (rx (*? not-newline) (or (syntax open-parenthesis) "{") (* (not (syntax close-parenthesis))) eol))
500-
(setq cur-indent (+ cur-indent typst-indent-offset))))
501-
;; (2)
502-
(if (looking-at (rx (* blank) (syntax close-parenthesis)))
503-
(setq cur-indent (- cur-indent typst-indent-offset)))
504-
;; (message cur-indent)
505-
(if (< cur-indent 0) ;; special cases
506-
(setq cur-indent 0))
507-
(indent-line-to cur-indent)))))
477+
;; First, calculate the column that this line should be indented to.
478+
(let ((indent-col
479+
(save-excursion
480+
(back-to-indentation)
481+
(let* (;; paren-level: How many sets of parens (or other delimiters)
482+
;; we're within, except that if this line closes the
483+
;; innermost set(s) (e.g. the line is just "}"), then we
484+
;; don't count those set(s).
485+
(paren-level
486+
(save-excursion
487+
(while (looking-at "[]})]") (forward-char))
488+
(typst-paren-nesting-level)))
489+
;; prev-block-indent-col: If we're within delimiters, this is
490+
;; the column to which the start of that block is indented
491+
;; (if we're not, this is just zero).
492+
(prev-block-indent-col
493+
(if (<= paren-level 0) 0
494+
(save-excursion
495+
(while (>= (typst-paren-nesting-level) paren-level)
496+
(backward-up-list)
497+
(back-to-indentation))
498+
(current-column))))
499+
;; base-indent-col: The column to which a complete expression
500+
;; on this line should be indented.
501+
(base-indent-col
502+
(if (<= paren-level 0)
503+
prev-block-indent-col
504+
(or (save-excursion
505+
(backward-up-list)
506+
(forward-char)
507+
(and (not (looking-at " *\\(//[^\n]*\\)?\n"))
508+
(current-column)))
509+
(+ prev-block-indent-col typst-indent-offset)))))
510+
;; (message "%s %s %s %s" paren-level prev-block-indent-col base-indent-col is-expr-continutation)
511+
base-indent-col))))
512+
;; If point is within the indentation whitespace, move it to the end of the
513+
;; new indentation whitespace (which is what the indent-line-to function
514+
;; always does). Otherwise, we don't want point to move, so we use a
515+
;; save-excursion.
516+
(if (<= (current-column) (current-indentation))
517+
;; (progn
518+
(indent-line-to indent-col)
519+
;; (message "%s %s" (current-column) (current-indentation))
520+
;; )
521+
(save-excursion (indent-line-to indent-col)))))
508522

509523
;;; Functions ===============================================
510524
(defun typst--process-exists-p (process-name)
@@ -564,7 +578,7 @@ concrete implementations. Currently there are two concrete
564578
implementations: `typst-mode' and `typst-ts-mode'."
565579
;; :syntax-table typst-syntax-table
566580
(setq-local tab-width 4
567-
indent-line-function 'typst-indent-line
581+
indent-line-function 'typst-mode-indent-line
568582
tab-width typst-code-tab-width
569583
font-lock-keywords-only t))
570584

0 commit comments

Comments
 (0)