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

Feature Request: cache syntax highlighting to improve 'relativenumber' scroll performance #1735

Closed
bluz71 opened this issue May 30, 2017 · 9 comments

Comments

@bluz71
Copy link

bluz71 commented May 30, 2017

Hello Vim team,

Spawning a new feature request from the existing Ruby high CPU usage #282 issue. Note, the vim-ruby #243 issue is fundamentally the same issue as well.

Basically the issue boils down to syntax highlighting needing to be calculated for every visible line when scrolling up or down with relativenumber enabled. The more lines visible and the slower the host CPU the worse the performance hit especially for languages with complex syntax highlighters such as Ruby.

In issue #282 Bram said this (Dec 2015):

When moving the cursor around, with 'relativenumber' or 'cursorcolumn'
set, cause a full redraw, because every line changes. I'm wondering if
it is possible to cache the result of syntax highlighting. It would
require storing the "attr" value, before it's mixed with other
attributes, such as from 'cursorcolumn'. So long as we don't scroll the
screen update would be much faster. These days memory is plenty, thus
that isn't a problem.

As soon as you page forward it's just as slow, of course, thus making
the syntax highlighting faster is still desired.

I suspect, if implemented, that this suggestion indeed would greatly help scroll performance for those of us who enable relativenumber. A new setting possibly? cachesyntax?

I leave it to the Vim masters to either: do this, or not do this, or schedule later, or close if too hard.

Thank you.

@mgraham
Copy link

mgraham commented Aug 24, 2017

Ok, I don't know the internals of cursorline or vim's syntax highlighting, but it seems to me that it should be possible to completely separate cursorline highlighting from syntax highlighting?

Usually, the cursorline just changes the background colour for the current line. So...

  • when drawing the line the cursor is on, set the background colour to the highlight colour.
  • when drawing any other line set the background colour to the regular background colour.

I don't understand why the entire screen's syntax highlighting needs to be recalculated because the background colour of one line gets toggled.

@mgraham
Copy link

mgraham commented Sep 8, 2017

For instance, the screen's syntax highlighting does not seem to need to be recalculated every time a visual text selection changes.

@neoadventist
Copy link

Awesome! I've been wondering why my screen has been flickering every time I go to the next line. I would love to know how to fix this! @mgraham @bluz71

@bluz71
Copy link
Author

bluz71 commented Jan 8, 2018

@neoadventist,

The enhancement needs to happen inside Vim & Neovim, so for now there is not much you can do except disable relativenumber.

Inglorion-G added a commit to Inglorion-G/dotfiles that referenced this issue Jan 18, 2018
Having relative line numbers enabled and using regex engine 0 or 2
causes high latency in ruby files. There is an open issue to track this:
vim/vim#1735.

This sets the regex engine to 1, which allows for relative line numbers.
@her
Copy link

her commented Apr 21, 2018

If you comb through the various postings about this issue across the internet these suggestions come up frequently as a fix:

set ttyfast
set lazyredraw
set regexpengine=1

However these I suspect are actually just fixing people's issues with 3rd party plugins.

The real fix for this is:

set norelativenumber

I think this feature is simply broken when applied to ruby filetypes due to what @bluz71 and @brammool already mentioned.

Hopefully this helps others as it took me some time to find the culprit. Cheers.

@bluz71
Copy link
Author

bluz71 commented Apr 22, 2018

@her,

I agree with:

set ttyfast
set regexpengine=1

However, enabling lazyredraw has lead to weird redraw and slow character deletion issues in my experience. I experimented with it quite a bit and in the end concluded that it is best left disabled.

I also recommend this setting:

set synmaxcol=200

Only syntax highlight the first 200 chars of a line. Very long lines are a killer with relativenumber.

The Ruby syntax highlighter contains hundreds of regexps, multiple by the number of visible lines can equal very bad scroll performance with relativenumber. Caching syntax highlighting is my number one most wanted Vim enhancement. Good to see the first post of this issue now with 62 likes (and slowly growing).

@folofjc
Copy link

folofjc commented Jul 26, 2018

I have this issue and do not do pgp or ruby syntax highlighting. It also just started happening recently, so might have come from an update.

@bluz71
Copy link
Author

bluz71 commented Dec 1, 2018

I noticed that #282 has been closed due to patches 8.1.0372 - 8.1.0374

Commit bd9a53c (patch 8.1.0374) implements a relativenumber optimisation, only redraw the number column, not all lines.

I have updated and tested, and indeed when scrolling within a page, with relativenumber enabled, navigating the cursor seems much smoother.

Note, scrolling off the top or bottom of the page, via long-pressing j or k may still be slow sometimes, but in that case every line on the page is changing AND syntax highlighting will be applied to lines coming into view. That was never the crux of this issue which was only about scrolling within a single static screen.

Thanks to the Vim maintainers, very much appreciate the enhancement.

Resolving.

@bluz71 bluz71 closed this as completed Dec 1, 2018
@her
Copy link

her commented Dec 1, 2018

Oh that’s awesome @bluz71, thanks for the update!

chunkhang added a commit to chunkhang/dotfiles that referenced this issue May 16, 2019
atweiden pushed a commit to atweiden/macfiles that referenced this issue May 17, 2020
- whereas
  - `regexpengine=1`
    - is incompatible with fennel.vim
      - e.g.

```
Error detected while processing /Users/user/.vim/plugged/fennel.vim/syntax/fennel.vim:
line  241:
E945: Range too large in character class
E475: Invalid argument: FennelSymbol "\v<%([\!\$%\&\#\*\+\-./:<=>?A-Z^_a-z|\x80-\U10FFFF])%([0
&\#\*\+\-./:<=>?A-Z^_a-z|\x80-\U10FFFF])*>"
line  242:
E945: Range too large in character class
E475: Invalid argument: FennelKeyword "\v<:%([0-9\!\$%\&\#\*\+\-./:<=>?A-Z^_a-z|\x80-\U10FFFF]
```

    - is mostly obsolete
      - e.g.
        - vim 8 rendering slowness should be bearable in all but the
          most extreme cases
        - switching to neovim could solve rendering slowness otherwise
      - see
        - vim/vim#1735
        - vim-ruby/vim-ruby#243
  - unset `regexpengine=1`
  - decrease `synmaxcol`
    - for good measure
    - per @bluz71 recommendations
atweiden pushed a commit to atweiden/pacfiles that referenced this issue May 17, 2020
- whereas
  - `regexpengine=1`
    - is incompatible with fennel.vim
      - e.g.

```
Error detected while processing /Users/user/.vim/plugged/fennel.vim/syntax/fennel.vim:
line  241:
E945: Range too large in character class
E475: Invalid argument: FennelSymbol "\v<%([\!\$%\&\#\*\+\-./:<=>?A-Z^_a-z|\x80-\U10FFFF])%([0
&\#\*\+\-./:<=>?A-Z^_a-z|\x80-\U10FFFF])*>"
line  242:
E945: Range too large in character class
E475: Invalid argument: FennelKeyword "\v<:%([0-9\!\$%\&\#\*\+\-./:<=>?A-Z^_a-z|\x80-\U10FFFF]
```

    - is mostly obsolete
      - e.g.
        - vim 8 rendering slowness should be bearable in all but the
          most extreme cases
        - switching to neovim could solve rendering slowness otherwise
      - see
        - vim/vim#1735
        - vim-ruby/vim-ruby#243
  - unset `regexpengine=1`
  - decrease `synmaxcol`
    - for good measure
    - per @bluz71 recommendations
atweiden pushed a commit to atweiden/ttyfiles that referenced this issue May 17, 2020
- whereas
  - `regexpengine=1`
    - is incompatible with fennel.vim
      - e.g.

```
Error detected while processing /Users/user/.vim/plugged/fennel.vim/syntax/fennel.vim:
line  241:
E945: Range too large in character class
E475: Invalid argument: FennelSymbol "\v<%([\!\$%\&\#\*\+\-./:<=>?A-Z^_a-z|\x80-\U10FFFF])%([0
&\#\*\+\-./:<=>?A-Z^_a-z|\x80-\U10FFFF])*>"
line  242:
E945: Range too large in character class
E475: Invalid argument: FennelKeyword "\v<:%([0-9\!\$%\&\#\*\+\-./:<=>?A-Z^_a-z|\x80-\U10FFFF]
```

    - is mostly obsolete
      - e.g.
        - vim 8 rendering slowness should be bearable in all but the
          most extreme cases
        - switching to neovim could solve rendering slowness otherwise
      - see
        - vim/vim#1735
        - vim-ruby/vim-ruby#243
  - unset `regexpengine=1`
  - decrease `synmaxcol`
    - for good measure
    - per @bluz71 recommendations
atweiden pushed a commit to atweiden/voidfiles that referenced this issue May 17, 2020
- whereas
  - `regexpengine=1`
    - is incompatible with fennel.vim
      - e.g.

```
Error detected while processing /Users/user/.vim/plugged/fennel.vim/syntax/fennel.vim:
line  241:
E945: Range too large in character class
E475: Invalid argument: FennelSymbol "\v<%([\!\$%\&\#\*\+\-./:<=>?A-Z^_a-z|\x80-\U10FFFF])%([0
&\#\*\+\-./:<=>?A-Z^_a-z|\x80-\U10FFFF])*>"
line  242:
E945: Range too large in character class
E475: Invalid argument: FennelKeyword "\v<:%([0-9\!\$%\&\#\*\+\-./:<=>?A-Z^_a-z|\x80-\U10FFFF]
```

    - is mostly obsolete
      - e.g.
        - vim 8 rendering slowness should be bearable in all but the
          most extreme cases
        - switching to neovim could solve rendering slowness otherwise
      - see
        - vim/vim#1735
        - vim-ruby/vim-ruby#243
  - unset `regexpengine=1`
  - decrease `synmaxcol`
    - for good measure
    - per @bluz71 recommendations
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants