From: Yuan Fu Date: Mon, 16 Sep 2024 06:32:51 +0000 (-0700) Subject: Add accessors for treesit-font-lock-settings X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=f2908eb2362f87fc9066d2adb9f2e17cf975860b;p=emacs.git Add accessors for treesit-font-lock-settings Since each SETTING in treesit-font-lock-settings is considered an opaque object, provide accessor functions for each field. * lisp/treesit.el: (treesit-font-lock-settings): Update docstring. (treesit-font-lock-setting-query): (treesit-font-lock-setting-enable): (treesit-font-lock-setting-feature): (treesit-font-lock-setting-override): New functions. (treesit--font-lock-setting-feature): Remove function. (treesit--font-lock-setting-enable): Rename to treesit--font-lock-setting-clone-enable to avoid confusion with treesit-font-lock-setting-enable. (treesit-add-font-lock-rules): Use renamed function. (treesit-font-lock-fontify-region): Add a comment. * doc/lispref/modes.texi (Parser-based Font Lock): Update manual. (cherry picked from commit f9fa75c1ef31ee78b43509f15b50cf0603757181) --- diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi index a7d1d7ed8f6..d7909e78384 100644 --- a/doc/lispref/modes.texi +++ b/doc/lispref/modes.texi @@ -4424,11 +4424,22 @@ For this variable to take effect, a Lisp program should call @code{treesit-font-lock-recompute-features}). @end defvar +@findex treesit-font-lock-setting-query +@findex treesit-font-lock-setting-feature +@findex treesit-font-lock-setting-enable +@findex treesit-font-lock-setting-override @defvar treesit-font-lock-settings -A list of settings for tree-sitter based font lock. The exact format -of each setting is considered internal. One should always use +A list of settings for tree-sitter based font lock. The exact format of +each individual setting is considered internal. One should always use @code{treesit-font-lock-rules} to set this variable. +Even though the setting object is opaque, Emacs provides accessors for +the setting's query, feature, enable flag and override flag: +@code{treesit-font-lock-setting-query}, +@code{treesit-font-lock-setting-feature}, +@code{treesit-font-lock-setting-enable}, +@code{treesit-font-lock-setting-override}. + @c Because the format is internal, we don't document them here. Though @c we do have it explained in the docstring. We also expose the fact @c that it is a list of settings, so one could combine two of them with diff --git a/etc/NEWS b/etc/NEWS index 7feb5d37613..63e4dcc2a54 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -373,6 +373,13 @@ This is useful for reusing font-lock rules and indentation rules of language A for language B, when language B is a strict superset of language A. ++++ +*** New accessor functions for each setting in 'treesit-font-lock-settings'. +Now users can access a setting's query, feature, enable flag, and +override flag by 'treesit-font-lock-setting-query', +'treesit-font-lock-setting-feature', 'treesit-font-lock-setting-enable', +and 'treesit-font-lock-setting-override'. + +++ ** New optional BUFFER argument for 'string-pixel-width'. If supplied, 'string-pixel-width' will use any face remappings from diff --git a/lisp/treesit.el b/lisp/treesit.el index 473152c109e..5b763d0a9ce 100644 --- a/lisp/treesit.el +++ b/lisp/treesit.el @@ -653,9 +653,8 @@ Return the merged list of ranges." (setq new-ranges (cdr new-ranges))) (nreverse result))) -;; TODO: truncate ranges that exceeds START and END instead of -;; discarding them. Merge into treesit--merge-ranges so we don't loop -;; over the ranges twice (might be premature optimization tho). +;; TODO: Instead of throwing away ranges that exceeds START and END, +;; truncate the head and tail ranges so they stay within START and END. (defun treesit--clip-ranges (ranges start end) "Clip RANGES in between START and END. RANGES is a list of ranges of the form (BEG . END). Ranges @@ -848,10 +847,15 @@ opposed to embedded parsers which parses only part of the buffer.") (defvar-local treesit-font-lock-settings nil "A list of SETTINGs for treesit-based fontification. -The exact format of each SETTING is considered internal. Use -`treesit-font-lock-rules' to set this variable. +Use `treesit-font-lock-rules' to set this variable. The exact format of +each individual SETTING is considered internal and will change in the +future. Use `treesit-font-lock-setting-query', +`treesit-font-lock-setting-enable', etc, to access each field. -Each SETTING has the form: +Below information is considered internal and only provided to help +debugging: + +Currently each SETTING has the form: (QUERY ENABLE FEATURE OVERRIDE) @@ -869,12 +873,25 @@ OVERRIDE is the override flag for this query. Its value can be t, nil, append, prepend, keep. See more in `treesit-font-lock-rules'.") -(defsubst treesit--font-lock-setting-feature (setting) - "Return the feature of SETTING. -SETTING should be a setting in `treesit-font-lock-settings'." +;; Follow cl-defstruct naming conventions, in case we use cl-defstruct +;; in the future. +(defsubst treesit-font-lock-setting-query (setting) + "Return the QUERY of SETTING in `treesit-font-lock-settings'." + (nth 0 setting)) + +(defsubst treesit-font-lock-setting-enable (setting) + "Return the ENABLE flag of SETTING in `treesit-font-lock-settings'." + (nth 1 setting)) + +(defsubst treesit-font-lock-setting-feature (setting) + "Return the FEATURE symbol of SETTING in `treesit-font-lock-settings'." (nth 2 setting)) -(defsubst treesit--font-lock-setting-enable (setting) +(defsubst treesit-font-lock-setting-override (setting) + "Return the OVERRIDE flag of SETTING in `treesit-font-lock-settings'." + (nth 3 setting)) + +(defsubst treesit--font-lock-setting-clone-enable (setting) "Return enabled SETTING." (let ((new-setting (copy-tree setting))) (setf (nth 1 new-setting) t) @@ -1172,12 +1189,12 @@ all existing rules. If FEATURE is non-nil, add RULES before/after rules for FEATURE. See docstring of `treesit-font-lock-rules' for what is a feature." - (let ((rules (seq-map #'treesit--font-lock-setting-enable rules)) + (let ((rules (seq-map #'treesit--font-lock-setting-clone-enable rules)) (feature-idx (when feature (cl-position-if (lambda (setting) - (eq (treesit--font-lock-setting-feature setting) feature)) + (eq (treesit-font-lock-setting-feature setting) feature)) treesit-font-lock-settings)))) (pcase (cons how feature) ((or '(:after . nil) '(nil . nil)) @@ -1349,6 +1366,10 @@ If LOUDLY is non-nil, display some debugging information." (root-nodes (mapcar #'treesit-parser-root-node (append local-parsers global-parsers)))) + ;; Can't we combine all the queries in each setting into one big + ;; query? That should make font-lock faster? I tried, it shaved off + ;; 1ms in xdisp.c, and 0.3ms in a small C file (for typing a single + ;; character), not worth it. --yuan (dolist (setting treesit-font-lock-settings) (let* ((query (nth 0 setting)) (enable (nth 1 setting))