Subject: bug#75764: 30.0.50; [PATCH] java-ts-mode: Constant highlighting no longer captures Java annotations.

From: Yuan Fu <[email-masked]>
Date: Mon, 27 Jan 2025 17:35:30 -0800

> On Jan 25, 2025, at 2:45 AM, Eli Zaretskii <[email-masked]> wrote:
> 
>> From: Vincenzo Pupillo <[email-masked]>
>> Date: Wed, 22 Jan 2025 16:38:20 +0100
>> 
>> Ciao,
>> the attached patch fixes a problem with highlighting constants in java-ts 
>> mode. Annotations such as @GET were previously being captured by the regular 
>> expression used for constants. 
>> The patch can be safely applied to Emacs 31.
>> 
>> Thanks.
>> 
>> Vincenzo
> 
> Yuan and Theo, any comments?
> 
>>> From 82e2e6d1d8827f9ed811760e3b08fb637b33f958 Mon Sep 17 00:00:00 2001
>> From: Vincenzo Pupillo <[email-masked]>
>> Date: Wed, 22 Jan 2025 16:14:41 +0100
>> Subject: [PATCH] Constant highlighting no longer captures Java annotations.
>> 
>> * lisp/progmodes/java-ts-mode.el
>> (java-ts-mode--fontify-constant): New function.
>> (java-ts-mode--font-lock-settings): Use it.
>> ---
>> lisp/progmodes/java-ts-mode.el | 20 ++++++++++++++++++--
>> 1 file changed, 18 insertions(+), 2 deletions(-)
>> 
>> diff --git a/lisp/progmodes/java-ts-mode.el b/lisp/progmodes/java-ts-mode.el
>> index 6823cb4f38a..849ab23ef3e 100644
>> --- a/lisp/progmodes/java-ts-mode.el
>> +++ b/lisp/progmodes/java-ts-mode.el
>> @@ -164,6 +164,23 @@ java-ts-mode--string-highlight-helper
>>     (error
>>      `((string_literal) @font-lock-string-face))))
>> 
>> +(defun java-ts-mode--fontify-constant (node override start end &rest _)
>> +  "Fontify a Java constant.
>> +In Java the names of variables declared class constants and of ANSI
>> +constants should be all uppercase with words separated by underscores.
>> +This function also prevents annotations from being highlighted as if
>> +they were constants.
>> +For NODE, OVERRIDE, START, and END, see `treesit-font-lock-rules'."
>> +  (let ((node-start (treesit-node-start node))
>> + (case-fold-search nil))
>> +    (when (and
>> +   (not (equal (char-before node-start) ?@)) ;; skip annotations
>> +   (string-match "\\`[A-Z_][0-9A-Z_]*\\'" (treesit-node-text node)))
>> +      (treesit-fontify-with-override
>> +       node-start (treesit-node-end node)
>> +       'font-lock-constant-face override
>> +       start end))))
>> +
>> (defvar java-ts-mode--font-lock-settings
>>   (treesit-font-lock-rules
>>    :language 'java
>> @@ -174,8 +191,7 @@ java-ts-mode--font-lock-settings
>>    :language 'java
>>    :override t
>>    :feature 'constant
>> -   `(((identifier) @font-lock-constant-face
>> -      (:match "\\`[A-Z_][0-9A-Z_]*\\'" @font-lock-constant-face))
>> +   `((identifier) @java-ts-mode--fontify-constant
>>      [(true) (false)] @font-lock-constant-face)
>>    :language 'java
>>    :override t
>> -- 
>> 2.48.1
>> 

Seems reasonable to me. Tree-sitter’s query doesn’t support negation match, so we can’t match constants that are not annotations. But I don’t want these fixes to delay emacs 30 (they will keep coming), so perhaps we can apply this to emacs-30 after release, WDYT, Eli?

Yuan