From 01bd19d9fe19277861188d51443cd163fd9ab6bf Mon Sep 17 00:00:00 2001 From: Christophe Troestler Date: Fri, 18 Oct 2024 23:50:06 +0200 Subject: [PATCH] Rust ts: fontify as type the possible suffix of number literals * lisp/progmodes/rust-ts-mode.el (rust-ts-mode--fontify-number-literal): Perform the improved fontification of numbers. (Bug#73877) * test/lisp/progmodes/rust-ts-mode-tests.el: * test/lisp/progmodes/rust-ts-mode-resources/font-lock.rs: * test/lisp/progmodes/rust-ts-mode-resources/font-lock-number.rs: Add tests for the new optional fontification of the possible type suffix of numbers. (cherry picked from commit 902696c3ae3ed046208c57de923362bb609da6df) --- etc/NEWS | 7 ++++ lisp/progmodes/rust-ts-mode.el | 37 ++++++++++++++++++- .../font-lock-number.rs | 17 +++++++++ .../rust-ts-mode-resources/font-lock.rs | 18 +++++++++ test/lisp/progmodes/rust-ts-mode-tests.el | 14 ++++++- 5 files changed, 90 insertions(+), 3 deletions(-) create mode 100644 test/lisp/progmodes/rust-ts-mode-resources/font-lock-number.rs diff --git a/etc/NEWS b/etc/NEWS index e89133fec03..37964bbd178 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -497,6 +497,13 @@ the built-in Web server. Interactively, when invoked with a prefix argument, 'php-ts-mode-run-php-webserver' prompts for the config file as well as for other connection parameters. +** Rust-ts mode + +--- +*** New user option 'rust-ts-mode-fontify-number-suffix-as-type'. +Rust number literals may have an optional type suffix. When this option +is non-nil, this suffix is fontified using 'font-lock-type-face'. + ** Ediff +++ diff --git a/lisp/progmodes/rust-ts-mode.el b/lisp/progmodes/rust-ts-mode.el index e52ea3b125a..7a421eb506b 100644 --- a/lisp/progmodes/rust-ts-mode.el +++ b/lisp/progmodes/rust-ts-mode.el @@ -62,6 +62,15 @@ to be checked as its standard input." (repeat :tag "Custom command" string)) :group 'rust) +(defcustom rust-ts-mode-fontify-number-suffix-as-type nil + "If non-nil, suffixes of number literals are fontified as types. +In Rust, number literals can possess an optional type suffix. When this +variable is non-nil, these suffixes are fontified using +`font-lock-type-face' instead of `font-lock-number-face'." + :version "31.1" + :type 'boolean + :group 'rust) + (defvar rust-ts-mode-prettify-symbols-alist '(("&&" . ?∧) ("||" . ?∨) ("<=" . ?≤) (">=" . ?≥) ("!=" . ?≠) @@ -116,6 +125,12 @@ to be checked as its standard input." ((parent-is "use_list") parent-bol rust-ts-mode-indent-offset))) "Tree-sitter indent rules for `rust-ts-mode'.") +(defconst rust-ts-mode--number-types + (regexp-opt '("u8" "i8" "u16" "i16" "u32" "i32" "u64" + "i64" "u128" "i128" "usize" "isize" "f32" "f64")) + "Regexp matching type suffixes of number literals. +See https://doc.rust-lang.org/reference/tokens.html#suffixes.") + (defvar rust-ts-mode--builtin-macros '("concat_bytes" "concat_idents" "const_format_args" "format_args_nl" "log_syntax" "trace_macros" "assert" "assert_eq" @@ -221,7 +236,8 @@ to be checked as its standard input." :language 'rust :feature 'number - '([(float_literal) (integer_literal)] @font-lock-number-face) + '([(float_literal) (integer_literal)] + @rust-ts-mode--fontify-number-literal) :language 'rust :feature 'operator @@ -369,6 +385,25 @@ to be checked as its standard input." (treesit-node-start id) (treesit-node-end id) 'font-lock-variable-name-face override start end))))))) +(defun rust-ts-mode--fontify-number-literal (node override start stop &rest _) + "Fontify number literals, highlighting the optional type suffix. +If `rust-ts-mode-fontify-number-suffix-as-type' is non-nil, use +`font-lock-type-face' to highlight the suffix." + (let* ((beg (treesit-node-start node)) + (end (treesit-node-end node))) + (save-excursion + (goto-char end) + (if (and rust-ts-mode-fontify-number-suffix-as-type + (looking-back rust-ts-mode--number-types beg)) + (let* ((ty (match-beginning 0)) + (nb (if (eq (char-before ty) ?_) (1- ty) ty))) + (treesit-fontify-with-override + ty end 'font-lock-type-face override start stop) + (treesit-fontify-with-override + beg nb 'font-lock-number-face override start stop)) + (treesit-fontify-with-override + beg end 'font-lock-number-face override start stop))))) + (defun rust-ts-mode--defun-name (node) "Return the defun name of NODE. Return nil if there is no name or if NODE is not a defun node." diff --git a/test/lisp/progmodes/rust-ts-mode-resources/font-lock-number.rs b/test/lisp/progmodes/rust-ts-mode-resources/font-lock-number.rs new file mode 100644 index 00000000000..ed5b222d5ff --- /dev/null +++ b/test/lisp/progmodes/rust-ts-mode-resources/font-lock-number.rs @@ -0,0 +1,17 @@ +fn main() { + let x = 1usize; +// ^ font-lock-number-face +// ^ font-lock-type-face + let x = 1_usize; +// ^ font-lock-number-face +// ^ font-lock-type-face + let x = 1_f64; +// ^ font-lock-number-face +// ^ font-lock-type-face + let x = 1.0f64; +// ^ font-lock-number-face +// ^ font-lock-type-face + let x = 1.0_f64; +// ^ font-lock-number-face +// ^ font-lock-type-face +} diff --git a/test/lisp/progmodes/rust-ts-mode-resources/font-lock.rs b/test/lisp/progmodes/rust-ts-mode-resources/font-lock.rs index 377cda0e3b9..1f549085e3f 100644 --- a/test/lisp/progmodes/rust-ts-mode-resources/font-lock.rs +++ b/test/lisp/progmodes/rust-ts-mode-resources/font-lock.rs @@ -23,3 +23,21 @@ macro_rules! unsafe_foo { // ^ font-lock-operator-face } }; + +fn main() { + let x = 1usize; +// ^ font-lock-number-face +// ^ font-lock-number-face + let x = 1_usize; +// ^ font-lock-number-face +// ^ font-lock-number-face + let x = 1_f64; +// ^ font-lock-number-face +// ^ font-lock-number-face + let x = 1.0f64; +// ^ font-lock-number-face +// ^ font-lock-number-face + let x = 1.0_f64; +// ^ font-lock-number-face +// ^ font-lock-number-face +} diff --git a/test/lisp/progmodes/rust-ts-mode-tests.el b/test/lisp/progmodes/rust-ts-mode-tests.el index f718a57fc9e..3a710b3af3b 100644 --- a/test/lisp/progmodes/rust-ts-mode-tests.el +++ b/test/lisp/progmodes/rust-ts-mode-tests.el @@ -23,11 +23,21 @@ (require 'ert-font-lock) (require 'ert-x) (require 'treesit) +(require 'rust-ts-mode) (ert-deftest rust-ts-test-font-lock () (skip-unless (treesit-ready-p 'rust)) - (let ((treesit-font-lock-level 4)) - (ert-font-lock-test-file (ert-resource-file "font-lock.rs") 'rust-ts-mode))) + (let ((treesit-font-lock-level 4) + (rust-ts-mode-fontify-number-suffix-as-type nil)) + (ert-font-lock-test-file (ert-resource-file "font-lock.rs") + 'rust-ts-mode))) + +(ert-deftest rust-ts-test-font-lock-number () + (skip-unless (treesit-ready-p 'rust)) + (let ((treesit-font-lock-level 4) + (rust-ts-mode-fontify-number-suffix-as-type t)) + (ert-font-lock-test-file (ert-resource-file "font-lock-number.rs") + 'rust-ts-mode))) (provide 'rust-ts-mode-tests) -- 2.39.2