rust-lang / rust-mode

Emacs configuration for Rust
Apache License 2.0
1.1k stars 176 forks source link

Behavior with enum variants, using treesitter #518

Open sebastiencs opened 4 months ago

sebastiencs commented 4 months ago

Hello

I just tested the new rust-ts-mode with emacs 29, and it seems to be working well. I can already see some improvements, compared to some cases where rust-mode was having some issues, both in fontifications and identations. Thanks to everyone who worked on that integration.

However I've noticed an issue with enum variants:

This is my buffer using the legacy rust-mode: Screenshot from 2024-02-26 23-23-04

The same buffer using rust-ts-mode, with treesit-font-lock-level set to 3: Notice the variants are using white color.

Screenshot from 2024-02-26 23-22-26

Same buffer using rust-ts-mode, with treesit-font-lock-level set to 4: Here we have 3 different colors, for variants Screenshot from 2024-02-26 23-22-43

Ideally I would like to get the same colors/fontification than rust-mode (variants in green). What would be the correct way to customize that ?

Thanks cc @casouri @psibi

psibi commented 4 months ago

Thanks for the clear description of the issue!

I tried your code block in my rust setup (which uses my fork of rustic) and here is the snapshot of the same code:

rustic

The reason I'm getting a consistent look is because I have enabled semantic tokens in lsp-mode and that's what my buffer is using: https://github.com/psibi/dotfiles/blob/8f491d47846683860a9605a4e4b9ce9c45644e32/.emacs.d/init.el#L154

casouri commented 4 months ago

Assuming you want to use font lock level 3, this should do the trick:

(defun rust-ts-add-enum-rules ()
  "Add a rule that fontifies Capitalized identifiers as types."
  (setq treesit-font-lock-settings
        (append
         treesit-font-lock-settings
         (treesit-font-lock-rules
          :language 'rust
          :feature 'enum-supplement
          '(((identifier) @font-lock-type-face
             (:match "\\`[A-Z]" @font-lock-type-face)))))))

(add-hook 'rust-ts-mode-hook #'rust-ts-add-enum-rules)
sebastiencs commented 3 months ago

@casouri Thanks, I have added :override t to cover more cases, and it's working now.

I might have found a bug with indentation:

fn my_fun<F>(_: F)
          where
      F: Clone
       {
           // abc
       }

When I open an empty main.rs buffer and insert the block above, indentation doesn't work. I put the cursor anywhere on line 2 or below, and I press TAB, it just doesn't indent the line. Same when I call manually (treesit-indent)

I have tested with an empty init.el, using emacs master branch.

Not sure if I should report to bug-gnu-emacs@gnu.org, it seems to be a bug in treesit.el, not rust-ts-mode

casouri commented 2 months ago

That's because it's rare for the where keyword to be on its own line and therefore rust-ts-mode didn't and an indentation rule for it. You can open a bug report if you think this is a valid use-case. (And as a rule-of-thumb, open a bug report if you don't know if you should open a bug report ;-)