diff options
| author | Yuan Fu | 2022-10-31 15:03:49 -0700 |
|---|---|---|
| committer | Yuan Fu | 2022-10-31 15:03:49 -0700 |
| commit | eeeae5e9ee34da5539046ff8dac4f4fffa19a5b9 (patch) | |
| tree | b815a383714dc3ee9d33c61fc39e91429709f344 | |
| parent | 9fab83ed7a90209e3873039e7ae4993c667e2759 (diff) | |
| download | emacs-eeeae5e9ee34da5539046ff8dac4f4fffa19a5b9.tar.gz emacs-eeeae5e9ee34da5539046ff8dac4f4fffa19a5b9.zip | |
Add an argument OVERRIDE to tree-sitter font-lock functions
* doc/lispref/modes.texi (Parser-based Font Lock): Reflect this change
in manual.
* lisp/progmodes/js.el (js--fontify-template-string): Add _OVERRIDE
argument.
* lisp/progmodes/python.el (python--treesit-fontify-string): Add
_OVERRIDE argument.
* lisp/treesit.el (treesit-font-lock-rules): Update docstring.
(treesit-fontify-with-override): New function.
(treesit-font-lock-fontify-region): Extract out into
treesit-fontify-with-override.
| -rw-r--r-- | doc/lispref/modes.texi | 22 | ||||
| -rw-r--r-- | lisp/progmodes/js.el | 2 | ||||
| -rw-r--r-- | lisp/progmodes/python.el | 2 | ||||
| -rw-r--r-- | lisp/treesit.el | 54 |
4 files changed, 49 insertions, 31 deletions
diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi index d778636d6d3..40d966ef17a 100644 --- a/doc/lispref/modes.texi +++ b/doc/lispref/modes.texi | |||
| @@ -3975,12 +3975,22 @@ that starts with @code{@@}), and tree-sitter will return matched nodes | |||
| 3975 | tagged with those same capture names. For the purpose of | 3975 | tagged with those same capture names. For the purpose of |
| 3976 | fontification, capture names in @var{query} should be face names like | 3976 | fontification, capture names in @var{query} should be face names like |
| 3977 | @code{font-lock-keyword-face}. The captured node will be fontified | 3977 | @code{font-lock-keyword-face}. The captured node will be fontified |
| 3978 | with that face. Capture names can also be function names, in which | 3978 | with that face. |
| 3979 | case the function is called with 3 arguments: @var{start}, @var{end}, | 3979 | |
| 3980 | and @var{node}, where @var{start} and @var{end} are the start and end | 3980 | @findex treesit-fontify-with-override |
| 3981 | position of the node in buffer, and @var{node} is the node itself. If | 3981 | Capture names can also be function names, in which case the function |
| 3982 | a capture name is both a face and a function, the face takes priority. | 3982 | is called with 4 arguments: @var{start}, @var{end}, @var{node}, and |
| 3983 | If a capture name is neither a face nor a function, it is ignored. | 3983 | @var{override}, where @var{start} and @var{end} are the start and end |
| 3984 | position of the node in buffer, @var{node} is the node itself, and | ||
| 3985 | @var{override} is the override property of the rule which captured | ||
| 3986 | this node. (If this function wants to respect the @var{override} | ||
| 3987 | argument, it can use @code{treesit-fontify-with-override}.) Beyond | ||
| 3988 | the 4 arguments presented, this function should accept more arguments | ||
| 3989 | as optional arguments for future extensibility. | ||
| 3990 | |||
| 3991 | If a capture name is both a face and a function, the face takes | ||
| 3992 | priority. If a capture name is neither a face nor a function, it is | ||
| 3993 | ignored. | ||
| 3984 | @end defun | 3994 | @end defun |
| 3985 | 3995 | ||
| 3986 | @defvar treesit-font-lock-feature-list | 3996 | @defvar treesit-font-lock-feature-list |
diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el index 8d1cfbd3c0e..2801a729ebd 100644 --- a/lisp/progmodes/js.el +++ b/lisp/progmodes/js.el | |||
| @@ -3573,7 +3573,7 @@ This function is intended for use in `after-change-functions'." | |||
| 3573 | @font-lock-constant-face))) | 3573 | @font-lock-constant-face))) |
| 3574 | "Tree-sitter font-lock settings.") | 3574 | "Tree-sitter font-lock settings.") |
| 3575 | 3575 | ||
| 3576 | (defun js--fontify-template-string (beg end node) | 3576 | (defun js--fontify-template-string (beg end node _override &rest _) |
| 3577 | "Fontify template string but not substitution inside it. | 3577 | "Fontify template string but not substitution inside it. |
| 3578 | BEG, END, NODE refers to the template_string node." | 3578 | BEG, END, NODE refers to the template_string node." |
| 3579 | (ignore end) | 3579 | (ignore end) |
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index a9aff167767..0b10058eebe 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el | |||
| @@ -1015,7 +1015,7 @@ It makes underscores and dots word constituent chars.") | |||
| 1015 | "VMSError" "WindowsError" | 1015 | "VMSError" "WindowsError" |
| 1016 | )) | 1016 | )) |
| 1017 | 1017 | ||
| 1018 | (defun python--treesit-fontify-string (_beg _end node) | 1018 | (defun python--treesit-fontify-string (_beg _end node _override &rest _) |
| 1019 | "Fontify string. | 1019 | "Fontify string. |
| 1020 | NODE is the last quote in the string. Do not fontify the initial | 1020 | NODE is the last quote in the string. Do not fontify the initial |
| 1021 | f for f-strings." | 1021 | f for f-strings." |
diff --git a/lisp/treesit.el b/lisp/treesit.el index 2bd71cdf5d5..72c8186044f 100644 --- a/lisp/treesit.el +++ b/lisp/treesit.el | |||
| @@ -410,7 +410,7 @@ omitted, default END to BEG." | |||
| 410 | return rng | 410 | return rng |
| 411 | finally return nil)))) | 411 | finally return nil)))) |
| 412 | 412 | ||
| 413 | ;;; Font-lock | 413 | ;;; Fontification |
| 414 | 414 | ||
| 415 | (define-error 'treesit-font-lock-error | 415 | (define-error 'treesit-font-lock-error |
| 416 | "Generic tree-sitter font-lock error" | 416 | "Generic tree-sitter font-lock error" |
| @@ -500,12 +500,14 @@ Other keywords include: | |||
| 500 | Capture names in QUERY should be face names like | 500 | Capture names in QUERY should be face names like |
| 501 | `font-lock-keyword-face'. The captured node will be fontified | 501 | `font-lock-keyword-face'. The captured node will be fontified |
| 502 | with that face. Capture names can also be function names, in | 502 | with that face. Capture names can also be function names, in |
| 503 | which case the function is called with (START END NODE), where | 503 | which case the function is called with (START END NODE OVERRIDE), |
| 504 | START and END are the start and end position of the node in | 504 | where START and END are the start and end position of the node in |
| 505 | buffer, and NODE is the tree-sitter node object. If a capture | 505 | buffer, NODE is the tree-sitter node object, and OVERRIDE is the |
| 506 | name is both a face and a function, the face takes priority. If | 506 | override option of that rule. This function should accept more |
| 507 | a capture name is not a face name nor a function name, it is | 507 | arguments as optional arguments for future extensibility. If a |
| 508 | ignored. | 508 | capture name is both a face and a function, the face takes |
| 509 | priority. If a capture name is not a face name nor a function | ||
| 510 | name, it is ignored. | ||
| 509 | 511 | ||
| 510 | \(fn :KEYWORD VALUE QUERY...)" | 512 | \(fn :KEYWORD VALUE QUERY...)" |
| 511 | ;; Other tree-sitter function don't tend to be called unless | 513 | ;; Other tree-sitter function don't tend to be called unless |
| @@ -600,6 +602,26 @@ Set the ENABLE flag for each setting in | |||
| 600 | do (setf (nth 1 (nth idx treesit-font-lock-settings)) | 602 | do (setf (nth 1 (nth idx treesit-font-lock-settings)) |
| 601 | (if (memq feature features) t nil))))) | 603 | (if (memq feature features) t nil))))) |
| 602 | 604 | ||
| 605 | (defun treesit-fontify-with-override (start end face override) | ||
| 606 | "Apply FACE to the region between START and END. | ||
| 607 | OVERRIDE can be nil, t, `append', `prepend', or `keep'. | ||
| 608 | See `treesit-font-lock-rules' for their semantic." | ||
| 609 | (pcase override | ||
| 610 | ('nil (unless (text-property-not-all | ||
| 611 | start end 'face nil) | ||
| 612 | (put-text-property start end 'face face))) | ||
| 613 | ('t (put-text-property start end 'face face)) | ||
| 614 | ('append (font-lock-append-text-property | ||
| 615 | start end 'face face)) | ||
| 616 | ('prepend (font-lock-prepend-text-property | ||
| 617 | start end 'face face)) | ||
| 618 | ('keep (font-lock-fillin-text-property | ||
| 619 | start end 'face face)) | ||
| 620 | (_ (signal 'treesit-font-lock-error | ||
| 621 | (list | ||
| 622 | "Unrecognized value of :override option" | ||
| 623 | override))))) | ||
| 624 | |||
| 603 | (defun treesit-font-lock-fontify-region | 625 | (defun treesit-font-lock-fontify-region |
| 604 | (start end &optional loudly) | 626 | (start end &optional loudly) |
| 605 | "Fontify the region between START and END. | 627 | "Fontify the region between START and END. |
| @@ -633,23 +655,9 @@ If LOUDLY is non-nil, display some debugging information." | |||
| 633 | (end (treesit-node-end node))) | 655 | (end (treesit-node-end node))) |
| 634 | (cond | 656 | (cond |
| 635 | ((facep face) | 657 | ((facep face) |
| 636 | (pcase override | 658 | (treesit-fontify-with-override start end face override)) |
| 637 | ('nil (unless (text-property-not-all | ||
| 638 | start end 'face nil) | ||
| 639 | (put-text-property start end 'face face))) | ||
| 640 | ('t (put-text-property start end 'face face)) | ||
| 641 | ('append (font-lock-append-text-property | ||
| 642 | start end 'face face)) | ||
| 643 | ('prepend (font-lock-prepend-text-property | ||
| 644 | start end 'face face)) | ||
| 645 | ('keep (font-lock-fillin-text-property | ||
| 646 | start end 'face face)) | ||
| 647 | (_ (signal 'treesit-font-lock-error | ||
| 648 | (list | ||
| 649 | "Unrecognized value of :override option" | ||
| 650 | override))))) | ||
| 651 | ((functionp face) | 659 | ((functionp face) |
| 652 | (funcall face start end node))) | 660 | (funcall face start end node override))) |
| 653 | ;; Don't raise an error if FACE is neither a face nor | 661 | ;; Don't raise an error if FACE is neither a face nor |
| 654 | ;; a function. This is to allow intermediate capture | 662 | ;; a function. This is to allow intermediate capture |
| 655 | ;; names used for #match and #eq. | 663 | ;; names used for #match and #eq. |