|
468 | 468 | map))
|
469 | 469 |
|
470 | 470 | ;;; 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 () |
476 | 476 | (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))))) |
508 | 522 |
|
509 | 523 | ;;; Functions ===============================================
|
510 | 524 | (defun typst--process-exists-p (process-name)
|
@@ -564,7 +578,7 @@ concrete implementations. Currently there are two concrete
|
564 | 578 | implementations: `typst-mode' and `typst-ts-mode'."
|
565 | 579 | ;; :syntax-table typst-syntax-table
|
566 | 580 | (setq-local tab-width 4
|
567 |
| - indent-line-function 'typst-indent-line |
| 581 | + indent-line-function 'typst-mode-indent-line |
568 | 582 | tab-width typst-code-tab-width
|
569 | 583 | font-lock-keywords-only t))
|
570 | 584 |
|
|
0 commit comments