From a2aa35a72a11387db8f0784de1e832220c187966 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 Content-Type: text/plain; charset="utf-8" * lisp/progmodes/rust-ts-mode.el (rust-ts-mode--fontify-number-literal): perform the improved fontification of numbers. * 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. --- etc/NEWS | 7 ++++ lisp/progmodes/rust-ts-mode.el | 36 ++++++++++++++++++- .../font-lock-number.rs | 18 ++++++++++ .../rust-ts-mode-resources/font-lock.rs | 18 ++++++++++ test/lisp/progmodes/rust-ts-mode-tests.el | 16 +++++++-- 5 files changed, 92 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 d1c7303f976..4a987f11f4b 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -630,6 +630,13 @@ cloning, or prompts for that, too. When the argument is non-nil, the function switches to a buffer visiting the directory into which the repository was cloned. +** 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 as a type. + * New Modes and Packages in Emacs 31.1 diff --git a/lisp/progmodes/rust-ts-mode.el b/lisp/progmodes/rust-ts-mode.el index e52ea3b125a..4314fa9aeed 100644 --- a/lisp/progmodes/rust-ts-mode.el +++ b/lisp/progmodes/rust-ts-mode.el @@ -62,6 +62,15 @@ rust-ts-flymake-command (repeat :tag "Custom command" string)) :group 'rust) +(defcustom rust-ts-mode-fontify-number-suffix-as-type nil + "If non-nil, fontify the optional type suffix of number literals with +`font-lock-type-face' instead of `font-lock-number-face'." + :version "31.1" + :type 'boolean + :group 'rust) +(put 'rust-ts-mode-fontify-number-suffix-as-type 'safe-local-variable + 'booleanp) + (defvar rust-ts-mode-prettify-symbols-alist '(("&&" . ?∧) ("||" . ?∨) ("<=" . ?≤) (">=" . ?≥) ("!=" . ?≠) @@ -116,6 +125,12 @@ rust-ts-mode--indent-rules ((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 that matches any suffix on number literals as documented +at 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 @@ rust-ts-mode--font-lock-settings :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,24 @@ 'rust-ts-mode--fontify-pattern (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 suffix as a type +based on the value of `rust-ts-mode-highlight-number-literal-type'." + (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..1c9a38bd683 --- /dev/null +++ b/test/lisp/progmodes/rust-ts-mode-resources/font-lock-number.rs @@ -0,0 +1,18 @@ + +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..fe82ce7ad7e 100644 --- a/test/lisp/progmodes/rust-ts-mode-tests.el +++ b/test/lisp/progmodes/rust-ts-mode-tests.el @@ -26,8 +26,20 @@ (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) + (h rust-ts-mode-fontify-number-suffix-as-type)) + (setq rust-ts-mode-fontify-number-suffix-as-type nil) + (ert-font-lock-test-file (ert-resource-file "font-lock.rs") 'rust-ts-mode) + (setq rust-ts-mode-fontify-number-suffix-as-type h))) + +(ert-deftest rust-ts-test-font-lock-number () + (skip-unless (treesit-ready-p 'rust)) + (let ((treesit-font-lock-level 4) + (h rust-ts-mode-fontify-number-suffix-as-type)) + (setq rust-ts-mode-fontify-number-suffix-as-type t) + (ert-font-lock-test-file (ert-resource-file "font-lock-number.rs") + 'rust-ts-mode) + (setq rust-ts-mode-fontify-number-suffix-as-type h))) (provide 'rust-ts-mode-tests) -- 2.45.2