branch: elpa/typst-ts-mode commit 52b6be61c02527c310be96ac6f028ba58c920331 Author: meowking <mr.meowk...@tutamail.com> Commit: meowking <mr.meowk...@tutamail.com>
pref: pre-compute font lock rules closes: https://codeberg.org/meow_king/typst-ts-mode/issues/22 --- typst-ts-faces.el | 31 +--- typst-ts-mode.el | 427 ++++++++++++++++++------------------------------------ 2 files changed, 147 insertions(+), 311 deletions(-) diff --git a/typst-ts-faces.el b/typst-ts-faces.el index 7c9f769d85..ca956ee1d1 100644 --- a/typst-ts-faces.el +++ b/typst-ts-faces.el @@ -27,21 +27,14 @@ :group 'typst-ts) (defcustom typst-ts-markup-header-same-height t - "Whether to make header face in markup context share the same height. -Note it only works when user choose `max' level of fontification precision -level. See `typst-ts-mode-fontification-precision-level'." + "Whether to make header face in markup context share the same height." :type 'boolean :group 'typst-ts-faces) (defcustom typst-ts-markup-header-scale '(2.0 1.7 1.4 1.1 1.0 1.0) "Header Scale." - :type '(list integer integer integer integer integer integer) - :set (lambda (symbol value) - (set-default symbol value) - (when typst-ts-markup-header-same-height - (set-default symbol (make-list (length value) 1.0)))) - :set-after '(typst-ts-markup-header-same-height) + :type '(list number number number number number number) :group 'typst-ts-faces) ;; Face ========================================================================= @@ -149,20 +142,10 @@ level. See `typst-ts-mode-fontification-precision-level'." '((t :inherit bold)) "Face for strong.") -(defface typst-ts-markup-item-face - '((t :inherit shadow)) - "Face for whole term, use in min and middle fontification level. -See `typst-ts-mode-fontification-precision-level'.") - (defface typst-ts-markup-item-indicator-face '((t :inherit shadow)) "Face for item.") -(defface typst-ts-markup-term-face - '((t :inherit shadow)) - "Face for whole term, use in min and middle fontification level. -See `typst-ts-mode-fontification-precision-level'.") - (defface typst-ts-markup-term-indicator-face '((t :inherit shadow)) "Face for term indicator.") @@ -195,11 +178,6 @@ See `typst-ts-mode-fontification-precision-level'.") '((t :inherit shadow)) "Face for rawblock and rawspan blob.") -(defface typst-ts-markup-rawblock-face - '((t :inherit shadow)) - "Face for whole raw block, use in min and middle fontification level. -See `typst-ts-mode-fontification-precision-level'.") - (defface typst-ts-markup-rawblock-indicator-face '((t :inherit typst-ts-markup-raw-indicator-face)) "Face for rawblock indicator.") @@ -212,11 +190,6 @@ See `typst-ts-mode-fontification-precision-level'.") '((t :inherit typst-ts-markup-raw-blob-face)) "Face for rawblock blob.") -(defface typst-ts-markup-rawspan-face - '((t :inherit shadow)) - "Face for whole raw span, use in min and middle fontification level. -See `typst-ts-mode-fontification-precision-level'.") - (defface typst-ts-markup-rawspan-indicator-face '((t :inherit typst-ts-markup-raw-indicator-face)) "Face for rawspan indicator.") diff --git a/typst-ts-mode.el b/typst-ts-mode.el index 6b34097887..11e154d973 100644 --- a/typst-ts-mode.el +++ b/typst-ts-mode.el @@ -64,17 +64,6 @@ This variable is used in `typst-ts-mode-check-grammar-version'." (defvar typst-ts-mode--grammar-minimum-version-timestamp 1713791627 "Timestamp for the minimum supported typst tree sitter grammar version.") -(defcustom typst-ts-mode-fontification-precision-level 'middle - "Whether to use precise face fontification. -Note that precise face fontification will case performance degrading. -The performance degrading is mainly on the first load of the file. Since -treesit incrementally fontifys regions (IMO), the later editing experience won't -be noticeably affected probably." - :type '(choice (const :tag "Minimum level" min) - (const :tag "Middle level" middle) - (const :tag "Maximum level" max)) - :group 'typst-ts) - (defcustom typst-ts-mode-enable-raw-blocks-highlight nil "Whether to enable raw block highlighting. NOTE: currently only support Emacs 30 (master branch)." @@ -93,58 +82,151 @@ NOTE: currently only support Emacs 30 (master branch)." st)) (defvar typst-ts-mode-font-lock-rules - nil - "You can customize this variable to override the whole default font lock rules. -Like this: - - (setq typst-ts-mode-font-lock-rules - (append - (typst-ts-mode-font-lock-rules) - \='( - :language typst - :type custom - ((el-psy-kongaroo) @el-psy-kongaroo)))) - -However, if you only want to modify specific part of the font lock rules, please -customize variables starts with `typst-ts-mode-font-lock-rules-'. The trailing -part of the name is in the `typst-ts-mode-font-lock-feature-list'. - -BTW, if you want to enable/disable specific font lock feature, please change + (treesit-font-lock-rules + :language 'typst + :feature 'comment + '((comment) @font-lock-comment-face) + + ;; `ref' should be placed before `shorthand' to render properly + ;; e.g. @CitationKey[p.~7] + :language 'typst + :feature 'markup-basic ; part 1 + '((ref) @typst-ts-markup-reference-face) + + :language 'typst + :feature 'common + '((shorthand) @typst-ts-shorthand-face + (ERROR) @typst-ts-error-face) + + :language 'typst + :feature 'markup-basic ; part 2 + `(,@(if typst-ts-markup-header-same-height + '((heading _ @typst-ts-markup-header-indicator-face (text) @typst-ts-markup-header-face)) + '((heading "=" @typst-ts-markup-header-indicator-face-1 + (text) @typst-ts-markup-header-face-1) + (heading "==" @typst-ts-markup-header-indicator-face-2 + (text) @typst-ts-markup-header-face-2) + (heading "===" @typst-ts-markup-header-indicator-face-3 + (text) @typst-ts-markup-header-face-3) + (heading "====" @typst-ts-markup-header-indicator-face-4 + (text) @typst-ts-markup-header-face-4) + (heading "=====" @typst-ts-markup-header-indicator-face-5 + (text) @typst-ts-markup-header-face-5) + (heading "======" @typst-ts-markup-header-indicator-face-6 + (text) @typst-ts-markup-header-face-6))) + (emph + "_" @typst-ts-markup-emphasis-indicator-face + (text) @typst-ts-markup-emphasis-face + "_" @typst-ts-markup-emphasis-indicator-face) + (strong + "*" @typst-ts-markup-strong-indicator-face + (text) @typst-ts-markup-strong-face + "*" @typst-ts-markup-strong-indicator-face) + (item + "-" @typst-ts-markup-item-indicator-face) + (term + "/" @typst-ts-markup-term-indicator-face + term: (text) @typst-ts-markup-term-term-face + ":" @typst-ts-markup-term-indicator-face + (text) @typst-ts-markup-term-description-face) + (escape) @typst-ts-markup-escape-face + (raw_span + "`" @typst-ts-markup-rawspan-indicator-face + (blob) @typst-ts-markup-rawspan-blob-face + "`" @typst-ts-markup-rawspan-indicator-face) + (raw_blck + "```" @typst-ts-markup-rawblock-indicator-face + (ident) :? @typst-ts-markup-rawblock-lang-face + ;; NOTE let embedded language fontify blob + ,@(if typst-ts-mode-enable-raw-blocks-highlight + '((blob) @typst-ts-mode-highlight-raw-block-fn) + '((blob) @typst-ts-markup-rawblock-blob-face)) + "```" @typst-ts-markup-rawblock-indicator-face) + (label) @typst-ts-markup-label-face ; TODO more precise highlight (upstream) + ) + + :language 'typst + :feature 'markup-standard + '((linebreak) @typst-ts-markup-linebreak-face + (url) @typst-ts-markup-url-face + (quote) @typst-ts-markup-quote-face) + + ;; please note that some feature there also in the math mode + :language 'typst + :feature 'code-basic + '("#" @typst-ts-code-indicator-face + ;; "end" @typst-ts-code-indicator-face ;; "end" is nothing but only a indicator + (string) @font-lock-string-face + (bool) @font-lock-constant-face + (none) @font-lock-constant-face + (auto) @font-lock-constant-face + + (in ["in" "not"] @font-lock-keyword-face) + (and "and" @font-lock-keyword-face) + (or "or" @font-lock-keyword-face) + (not "not" @font-lock-keyword-face) + (let "let" @font-lock-keyword-face) + (branch ["if" "else"] @font-lock-keyword-face) + (while "while" @font-lock-keyword-face) + (for ["for" "in"] @font-lock-keyword-face) + (import "import" @font-lock-keyword-face) + (as "as" @font-lock-keyword-face) + (include "include" @font-lock-keyword-face) + (show "show" @font-lock-keyword-face) + (set "set" @font-lock-keyword-face) + (context "context" @font-lock-keyword-face) + (return "return" @font-lock-keyword-face) + (flow ["break" "continue"] @font-lock-keyword-face) + + (call ;; function + item: (ident) @font-lock-function-call-face) + (call ;; method + item: (field field: (ident) @font-lock-function-call-face)) + (tagged field: (ident) @font-lock-variable-name-face) + (field field: (ident) @font-lock-constant-face)) + + :language 'typst + :feature 'code-standard + '((ident) @font-lock-variable-use-face) + + :language 'typst + :feature 'code-extended + '((number) @font-lock-number-face + + (content ["[" "]"] @font-lock-punctuation-face) + (sign ["+" "-"] @font-lock-operator-face) + (add "+" @font-lock-operator-face) + (sub "-" @font-lock-operator-face) + (mul "*" @font-lock-operator-face) + (div "/" @font-lock-operator-face) + (cmp ["==" "<=" ">=" "!=" "<" ">"] @font-lock-operator-face) + (wildcard) @font-lock-operator-face + + ["(" ")" "{" "}"] @font-lock-punctuation-face + ["," ";" ".." ":" "sep"] @font-lock-punctuation-face + "assign" @font-lock-punctuation-face + (field "." @font-lock-punctuation-face)) + + :language 'typst + :feature 'math-basic + '((math "$" @typst-ts-math-indicator-face)) + + :language 'typst + :feature 'math-standard + '((symbol) @font-lock-constant-face + (letter) @font-lock-constant-face) + + :language 'typst + :feature 'math-extended + '((fraction "/" @font-lock-operator-face) + (fac "!" @font-lock-operator-face) + (attach ["^" "_"] @font-lock-operator-face) + (align) @font-lock-operator-face)) + + "Font lock rules for `typst-ts-mode'. +If you want to enable/disable specific font lock feature, please change `treesit-font-lock-level' or modify `typst-ts-mode-font-lock-feature-list'.") -(defvar typst-ts-mode-font-lock-rules-comment nil - "See variable `typst-ts-mode-font-lock-rules'.") - -(defvar typst-ts-mode-font-lock-rules-common nil - "See variable `typst-ts-mode-font-lock-rules'.") - -(defvar typst-ts-mode-font-lock-rules-markup-basic nil - "See variable `typst-ts-mode-font-lock-rules'.") - -(defvar typst-ts-mode-font-lock-rules-code-basic nil - "See variable `typst-ts-mode-font-lock-rules'.") - -(defvar typst-ts-mode-font-lock-rules-math-basic nil - "See variable `typst-ts-mode-font-lock-rules'.") - -(defvar typst-ts-mode-font-lock-rules-markup-standard nil - "See variable `typst-ts-mode-font-lock-rules'.") - -(defvar typst-ts-mode-font-lock-rules-code-standard nil - "See variable `typst-ts-mode-font-lock-rules'.") - -(defvar typst-ts-mode-font-lock-rules-math-standard nil - "See variable `typst-ts-mode-font-lock-rules'.") - -(defvar typst-ts-mode-font-lock-rules-markup-extended nil - "See variable `typst-ts-mode-font-lock-rules'.") - -(defvar typst-ts-mode-font-lock-rules-code-extended nil - "See variable `typst-ts-mode-font-lock-rules'.") - -(defvar typst-ts-mode-font-lock-rules-math-extended nil - "See variable `typst-ts-mode-font-lock-rules'.") - (defun typst-ts-mode-highlight-raw-block-fn (blob-node _override _start _end) "A function used in function `typst-ts-mode-font-lock-rules'. This function assign `typst-ts-markup-rawblock-blob-face' to those raw block @@ -169,227 +251,11 @@ BLOB-NODE." (typst-ts-els-fontify-raw-block lang-mode bns bne) (put-text-property bns bne 'face 'typst-ts-markup-rawblock-blob-face)))) -(defun typst-ts-mode-font-lock-rules () - ;; use function `typst-ts/util/setup-fontification-debug-environment' in - ;; `side/utils.el' to setup test environment. - "Generate font lock rules for `treesit-font-lock-rules'. -If you want to customize the rules, please customize the same name variable -`typst-ts-mode-font-lock-rules'." - (let ((markup-basic - (pcase typst-ts-mode-fontification-precision-level - ('min - `((heading _ @typst-ts-markup-header-indicator-face (text) @typst-ts-markup-header-face) - (emph) @typst-ts-markup-emphasis-face - (strong) @typst-ts-markup-strong-face - (item) @typst-ts-markup-item-face - (term) @typst-ts-markup-term-face - (raw_span) @typst-ts-markup-rawspan-face - ,@(if typst-ts-mode-enable-raw-blocks-highlight - '((raw_blck - "```" @typst-ts-markup-rawblock-indicator-face - (ident) :? @typst-ts-markup-rawblock-lang-face - (blob) @typst-ts-mode-highlight-raw-block-fn - "```" @typst-ts-markup-rawblock-indicator-face)) - '((raw_blck) @typst-ts-markup-rawblock-face)) - (label) @typst-ts-markup-label-face - (ref) @typst-ts-markup-reference-face)) - ('middle - `((heading _ @typst-ts-markup-header-indicator-face (text) @typst-ts-markup-header-face) - (emph) @typst-ts-markup-emphasis-face - (strong) @typst-ts-markup-strong-face - (item - "-" @typst-ts-markup-item-indicator-face) - (term - "/" @typst-ts-markup-term-indicator-face - term: (text) @typst-ts-markup-term-term-face - ":" @typst-ts-markup-term-indicator-face - (text) @typst-ts-markup-term-description-face) - (raw_span - "`" @typst-ts-markup-rawspan-indicator-face - (blob) @typst-ts-markup-rawspan-blob-face - "`" @typst-ts-markup-rawspan-indicator-face) - (raw_blck - "```" @typst-ts-markup-rawblock-indicator-face - (ident) :? @typst-ts-markup-rawblock-lang-face - ;; NOTE let embedded language fontify blob - ,@(if typst-ts-mode-enable-raw-blocks-highlight - '((blob) @typst-ts-mode-highlight-raw-block-fn) - '((blob) @typst-ts-markup-rawblock-blob-face)) - "```" @typst-ts-markup-rawblock-indicator-face) - (label) @typst-ts-markup-label-face - (ref) @typst-ts-markup-reference-face)) - ('max - `(,@(if typst-ts-markup-header-same-height - '((heading _ @typst-ts-markup-header-indicator-face (text) @typst-ts-markup-header-face)) - '((heading "=" @typst-ts-markup-header-indicator-face-1 - (text) @typst-ts-markup-header-face-1) - (heading "==" @typst-ts-markup-header-indicator-face-2 - (text) @typst-ts-markup-header-face-2) - (heading "===" @typst-ts-markup-header-indicator-face-3 - (text) @typst-ts-markup-header-face-3) - (heading "====" @typst-ts-markup-header-indicator-face-4 - (text) @typst-ts-markup-header-face-4) - (heading "=====" @typst-ts-markup-header-indicator-face-5 - (text) @typst-ts-markup-header-face-5) - (heading "======" @typst-ts-markup-header-indicator-face-6 - (text) @typst-ts-markup-header-face-6))) - ;; TODO performance enhancement - (emph - "_" @typst-ts-markup-emphasis-indicator-face - (text) @typst-ts-markup-emphasis-face - "_" @typst-ts-markup-emphasis-indicator-face) - (strong - "*" @typst-ts-markup-strong-indicator-face - (text) @typst-ts-markup-strong-face - "*" @typst-ts-markup-strong-indicator-face) - (item - "-" @typst-ts-markup-item-indicator-face) - (term - "/" @typst-ts-markup-term-indicator-face - term: (text) @typst-ts-markup-term-term-face - ":" @typst-ts-markup-term-indicator-face - (text) @typst-ts-markup-term-description-face) - (escape) @typst-ts-markup-escape-face - (raw_span - "`" @typst-ts-markup-rawspan-indicator-face - (blob) @typst-ts-markup-rawspan-blob-face - "`" @typst-ts-markup-rawspan-indicator-face) - (raw_blck - "```" @typst-ts-markup-rawblock-indicator-face - (ident) :? @typst-ts-markup-rawblock-lang-face - ;; NOTE let embedded language fontify blob - ,@(if typst-ts-mode-enable-raw-blocks-highlight - '((blob) @typst-ts-mode-highlight-raw-block-fn) - '((blob) @typst-ts-markup-rawblock-blob-face)) - "```" @typst-ts-markup-rawblock-indicator-face) - (label) @typst-ts-markup-label-face ; TODO more precise highlight (upstream) - (ref) @typst-ts-markup-reference-face) - )))) - `(;; Typst font locking - :language typst - :feature comment - ,(if typst-ts-mode-font-lock-rules-comment - typst-ts-mode-font-lock-rules-comment - '((comment) @font-lock-comment-face)) - - ;; `ref' should be placed before `shorthand' to render properly - ;; e.g. @CitationKey[p.~7] - :language typst - :feature markup-basic - ,(if typst-ts-mode-font-lock-rules-markup-basic - typst-ts-mode-font-lock-rules-markup-basic - markup-basic) - - :language typst - :feature common - ,(if typst-ts-mode-font-lock-rules-common - typst-ts-mode-font-lock-rules-common - '((shorthand) @typst-ts-shorthand-face - (ERROR) @typst-ts-error-face)) - - :language typst - :feature markup-standard - ,(if typst-ts-mode-font-lock-rules-markup-standard - typst-ts-mode-font-lock-rules-markup-standard - '((linebreak) @typst-ts-markup-linebreak-face - (url) @typst-ts-markup-url-face - (quote) @typst-ts-markup-quote-face)) - - :language typst - :feature markup-extended - ,@(when typst-ts-mode-font-lock-rules-markup-extended - (list typst-ts-mode-font-lock-rules-markup-extended)) - - ;; please note that some feature there also in the math mode - :language typst - :feature code-basic - ,(if typst-ts-mode-font-lock-rules-code-basic - typst-ts-mode-font-lock-rules-code-basic - '("#" @typst-ts-code-indicator-face - ;; "end" @typst-ts-code-indicator-face ;; "end" is nothing but only a indicator - (string) @font-lock-string-face - (bool) @font-lock-constant-face - (none) @font-lock-constant-face - (auto) @font-lock-constant-face - - (in ["in" "not"] @font-lock-keyword-face) - (and "and" @font-lock-keyword-face) - (or "or" @font-lock-keyword-face) - (not "not" @font-lock-keyword-face) - (let "let" @font-lock-keyword-face) - (branch ["if" "else"] @font-lock-keyword-face) - (while "while" @font-lock-keyword-face) - (for ["for" "in"] @font-lock-keyword-face) - (import "import" @font-lock-keyword-face) - (as "as" @font-lock-keyword-face) - (include "include" @font-lock-keyword-face) - (show "show" @font-lock-keyword-face) - (set "set" @font-lock-keyword-face) - (context "context" @font-lock-keyword-face) - (return "return" @font-lock-keyword-face) - (flow ["break" "continue"] @font-lock-keyword-face) - - (call ;; function - item: (ident) @font-lock-function-call-face) - (call ;; method - item: (field field: (ident) @font-lock-function-call-face)) - (tagged field: (ident) @font-lock-variable-name-face) - (field field: (ident) @font-lock-constant-face))) - - :language typst - :feature code-standard - ,(if typst-ts-mode-font-lock-rules-code-standard - typst-ts-mode-font-lock-rules-code-standard - '((ident) @font-lock-variable-use-face)) - - :language typst - :feature code-extended - ,(if typst-ts-mode-font-lock-rules-code-extended - typst-ts-mode-font-lock-rules-code-extended - ;; TODO lambda symbol - '((number) @font-lock-number-face - - (content ["[" "]"] @font-lock-punctuation-face) - (sign ["+" "-"] @font-lock-operator-face) - (add "+" @font-lock-operator-face) - (sub "-" @font-lock-operator-face) - (mul "*" @font-lock-operator-face) - (div "/" @font-lock-operator-face) - (cmp ["==" "<=" ">=" "!=" "<" ">"] @font-lock-operator-face) - (wildcard) @font-lock-operator-face - - ["(" ")" "{" "}"] @font-lock-punctuation-face - ["," ";" ".." ":" "sep"] @font-lock-punctuation-face - "assign" @font-lock-punctuation-face - (field "." @font-lock-punctuation-face))) - - :language typst - :feature math-basic - ,(if typst-ts-mode-font-lock-rules-math-basic - typst-ts-mode-font-lock-rules-math-basic - '((math "$" @typst-ts-math-indicator-face))) - - :language typst - :feature math-standard - ,(if typst-ts-mode-font-lock-rules-math-standard - typst-ts-mode-font-lock-rules-math-standard - '((symbol) @font-lock-constant-face - (letter) @font-lock-constant-face)) - - :language typst - :feature math-extended - ,(if typst-ts-mode-font-lock-rules-math-extended - typst-ts-mode-font-lock-rules-math-extended - '((fraction "/" @font-lock-operator-face) - (fac "!" @font-lock-operator-face) - (attach ["^" "_"] @font-lock-operator-face) - (align) @font-lock-operator-face))))) - (defconst typst-ts-mode-font-lock-feature-list '((comment common) (markup-basic code-basic math-basic) (markup-standard code-standard math-standard) - (markup-extended code-extended math-extended))) + (code-extended math-extended))) (defun typst-ts-mode-indent--grand-parent-bol (_node parent _bol) @@ -731,10 +597,7 @@ typst tree sitter grammar (at least %s)!" (current-time-string min-time)) (?\$ . ?\$))) ;; Font Lock - (setq-local treesit-font-lock-settings - (apply #'treesit-font-lock-rules (if typst-ts-mode-font-lock-rules - typst-ts-mode-font-lock-rules - (typst-ts-mode-font-lock-rules)))) + (setq-local treesit-font-lock-settings typst-ts-mode-font-lock-rules) (setq-local treesit-font-lock-feature-list typst-ts-mode-font-lock-feature-list) ;; Indentation