Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Syntax highlighting only applied after edit #572

Open
ben-cellfield opened this issue Sep 3, 2021 · 20 comments
Open

Syntax highlighting only applied after edit #572

ben-cellfield opened this issue Sep 3, 2021 · 20 comments

Comments

@ben-cellfield
Copy link

When I first open a js file, no highlighting is applied. As soon as I edit a single character, suddenly the highlighting is applied.

This behaviour seems to interact with rainbow-identifiers-mode and becomes even worse. The rainbow identifiers highlighting is applied to every word in the file on open, with no javascript syntax highlighting. Editing a single character then applies syntax highlighting (overriding much of the rainbow identifiers highlighting that was applied to keywords, etc), but only to the line with the edit and following lines; unless I scroll to the top of the file and edit something in the first line, I don't get syntax highlighting for the whole file.

@dgutov
Copy link
Collaborator

dgutov commented Sep 18, 2021

Does that happen with any file, or only specific ones?

Does it happen in a new file where you write 1-2 lines of code (then save, kill the buffer and re-visit)?

Does it happen with rainbow-identifiers-mode disabled?

@ben-cellfield
Copy link
Author

ben-cellfield commented Sep 20, 2021

It happens with any file. No difference in behaviour between a small or a large file, or between an existing or a new file.

As I mentioned, it does happen without rainbow-identifiers-mode, it just gets worse with that mode. Without rainbow identifiers the highlighting is still delayed until I make an edit, but then the whole file is properly highlighted. When using rainbow identifiers syntax highlighting is delayed until I make an edit, and then it only applies from the cursor onwards.

I did just find a difference in behaviour between editing a file inside my project work tree and one outside (even if it's a copy of a file from my project, so it's not about the contents), but only without rainbow identifiers. In that case, when outside my project just moving the cursor (with the mouse or keyboard) is enough to trigger full syntax highlighting. With rainbow identifiers, it requires an actual edit to the file to trigger highlighting.

Initial load Move cursor Any edit
Inside project with rainbow-identifiers rainbow only rainbow only highlighting from cursor onwards; rainbow only before cursor
Outside project with rainbow-identifiers rainbow only rainbow only highlighting from cursor onwards; rainbow only before cursor
Inside project without rainbow identifiers no highlighting no highlighting full highlighting
Outside project without rainbow identifiers no highlighting full highlighting full highlighting

(In all of these cases I am completely killing emacs between loads)

@dgutov
Copy link
Collaborator

dgutov commented Sep 20, 2021

Can you try emacs -Q with only js2-mode loaded and no other packages?

emacs -Q -L ~/.emacs.d/elpa/js2-mode-* -l js2-mode should do that.

And evaluate (add-to-list 'auto-mode-alist '("\\.js\\'" . js2-mode)) before visiting .js files.

@ben-cellfield
Copy link
Author

Okay, that difference between "inside project" and "outside project" seems to be caused by tide and the presence/absence of a jsconfig.json file. If I touch jsconfig.json I get the same "inside project" behaviour in my new temp folder. And if I uninstall tide then it doesn't seem to matter; I get the same "inside project" behaviour (moving cursor isn't enough to trigger highlighting) regardless of whether I have a jsconfig.json file.

@ben-cellfield
Copy link
Author

My packages aren't installed in ~/.emacs.d/elpa/ because I'm using nix, but I uninstalled all custom packages and cleared my init.el. Now syntax highlighting works immediately.

Is there a better way to figure out what's interacting with js2-mode than just adding/removing packages and customizations and seeing what happens?

@dgutov
Copy link
Collaborator

dgutov commented Sep 20, 2021

Bisecting your init script is the usual approach (e.g. cut it in half, comment out the second part, try reproducing, repeat).

You can also visit a .js file, type C-h v font-lock-keywords RET, then scroll to the bottom and see whether there are any symbolic names there that you can track down to the packages they're defined in. And try disabling those packages specifically.

@ben-cellfield
Copy link
Author

Thanks.

Should we close this then? Or when I track down the interaction do you want to see if it's something that can be addressed on the js2-mode side?

@dgutov
Copy link
Collaborator

dgutov commented Sep 20, 2021

Or when I track down the interaction do you want to see if it's something that can be addressed on the js2-mode side?

Sure. Or simply knowing about the offending mode should be useful anyway.

@ben-cellfield
Copy link
Author

Okay this is getting really weird.

The minimal change I have been able to find to my init.el to cure this problem requires three separate edits:

  1. remove use-package flycheck (and configuration; but just removing the configuration doesn't help)
  2. remove use-package rainbow-identifiers
  3. remove (menu-bar-mode -1)

Adding back any one of those bits of configuration independently of the other two is enough to cause the problem. (I'm really confused by the involvement of menu-bar-mode)

Going to try from the other end and see how little I have to add to a blank configuration to start seeing it.

@ben-cellfield
Copy link
Author

ben-cellfield commented Sep 20, 2021

Going minimalist, I can reproduce the problem by having js2-mode and rainbow-identifiers as the only installed emacs packages, and the contents of my init.el being:

(add-hook 'prog-mode-hook 'rainbow-identifiers-mode)
(add-to-list 'auto-mode-alist '("\\.js\\'" . js2-mode))

With this minimal config, (menu-bar-mode -1) and flycheck don't seem to be relevant.

But removing just rainbow-identifiers-mode from my normal config doesn't help, so there seems to be something more complicated than simply an incompatibility between js2-mode and rainbow-identifiers (or there are two separate things going on, that just happen to have similar symptoms).

@ben-cellfield
Copy link
Author

Ugh, more weirdness.

Removing rainbow-identifiers-mode without also removing flycheck and (menu-bar-mode -1) does help, if I start my emacs session with emacs foo.js.

My normal workflow uses emacsclient (via a script ee), and when I start emacs with ee foo.hs that's when I get the dependency on flycheck and the menu bar.

@dgutov
Copy link
Collaborator

dgutov commented Sep 22, 2021

I'm guessing your emacsclient workflow connects to the daemon, and said daemon needs to be restarted, for certain changes for your config to be applied?

I'm seeing certain weirdness indeed when rainbow-identifiers-mode is enabled, and that's probably not surprising given that these two modes use different, competing approaches to highlight text (basically all buffer text).

But r-i-m doesn't seem to integrate with js2-mode's parser, its scopes, etc, so its usefulness seems limited here.

@ben-cellfield
Copy link
Author

ben-cellfield commented Sep 22, 2021

Yes, but I have been careful to M-x kill-emacs between each configuration change and test, so I've definitely been starting the daemon fresh every time. I'm now a bit less certain about whether I used my emacsclient script consistently or just plan emacs for some of the tests above; I wasn't keeping track at first, because how could that possibly make a difference. 🙄

I'm honestly happy to get rid of rainbow-identifiers; I've only ever been middling about whether it's actually helpful. Although it does seem to work fine with other syntax highlighting packages for every other language I use, so it obviously isn't inherently incompatible with any package that does syntax highlighting (I assumed it has some process figured out for the rainbow-identifiers highlighting to be "low-priority" so it can be overridden by whatever else the syntax highlighter wants to do).

Unfortunately that still doesn't fix my normal configuration; I still get the problem unless I also add back in the menu bar (that seems absurd) and disable flycheck (definitely not something I want to drop), or else stop using the daemon. I guess I'll remove rainbow-identifiers and go back to bisecting my config to try to find out what is breaking js2's syntax highlighting in conjunction with flycheck (since flycheck alone doesn't seem to).

@dgutov
Copy link
Collaborator

dgutov commented Sep 22, 2021

so it obviously isn't inherently incompatible with any package that does syntax highlighting

Yeah: it is js2-mode that is odd/special, since it mostly circumvents font-lock. But the conflict with rainbow-identifiers is also unusual because it's the only minor mode that basically highlights everything in the buffer.

I guess I'll remove rainbow-identifiers and go back to bisecting my config to try to find out what is breaking js2's syntax highlighting in conjunction with flycheck (since flycheck alone doesn't seem to).

Good luck! If you find some minimal configuration, maybe I could do something about it. Or it'll be just another mode to disable.

@AlexChesters
Copy link

@ben-cellfield did you ever make any progress with identifying what causes this? (or @dgutov are you aware of any other reports?) I've recently started having the same issue but I can't see what would cause it in my set up.

I don't have rainbow-delimiters-mode enabled and font-lock-keywords is (t nil).

Weirdly I find that the first JS file I open of a session everything is fine, but subsequent files don't have syntax highlighting applied until I edit them (see below gif).

js2-mode-bug

@dgutov
Copy link
Collaborator

dgutov commented May 1, 2022

Might be some other mode. If you see no errors, what would ultimately help is bisecting your config.

But try this first:

M-x toggle-debug-on-error
M-: (js2-reparse t) RET in the same JS buffer where highlighting seems broken

and see if that ends up in a backtrace.

@ben-cellfield
Copy link
Author

@AlexChesters No, I haven't dug out any more specific information about what's causing this. It's still happening, but it's a lot less annoying since I got rid of rainbow-identifiers. There's no longer a dependency on where my cursor is, so I can just space-backspace wherever it is when the I open the window and it's not highlighted.

Interestingly I'm not seeing that same behaviour you are where the first file is okay and subsequent ones are unhighlighted. Both cases are the same for me.

@AlexChesters
Copy link

hey both,

apologies for the delay - been quite busy recently.

I eventually determined by issue was caused by eglot; I'm not sure entirely how, but the offending block in my config was:

(use-package eglot
  :config
  (add-hook 'js2-mode-hook 'eglot-ensure))

@dgutov
Copy link
Collaborator

dgutov commented May 11, 2022

That's odd: Eglot doesn't seem to be doing anything with font-lock.

But if you are using LSP, maybe try js-mode instead? Syntax highlighting is similar enough, and you get syntax error annotations from Eglot anyway.

@jordigh
Copy link

jordigh commented Jun 13, 2022

I'm experiencing this problem on macOS homebrew Emacs 28.1 too with js2 version 1.8.5 (or version 20211229 according to ELPA). It seems that js2-reparse just isn't being called at the normal invocation places where it should be called (every edit?).

When upgrading to MELPA version 20220402.2211 the problem seems to have disappeared.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants