[vim/vim] Implement flicker free redraw and scroll (Issue #11718)

94 views
Skip to first unread message

Kovid Goyal

unread,
Dec 17, 2022, 6:23:39 AM12/17/22
to vim/vim, Subscribed

Currently there are various issues with screen flicker in vim. I am sure you already know about this but I can quote issue numbers for you if you want.

Modern terminals implement atomic screen updates. Emit the BSU (Begin synchronized update) escape code, emit whatever you want, emit the ESU (End synchronized update) escape code and a supporting terminal will render everything that happens in between the two in an atomic, flicker free manner. There will be no flicker caused by partial screen updates anymore.

Terminals that are known to support it: iTerm, kitty, mintty, contour, wezterm, foot, etc.

For details see: https://gist.github.com/christianparpart/d8a62cc1ab659194337d73e399004036

And before you ask, no, there is no terminfo key for it.

I am not familiar with vim's codebase so cant comment on how easy/difficult it would be, but at least for some use cases, such as :redraw! and scroll it should be easy to emit the sequences before after the functions that implement these.


Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/11718@github.com>

Bram Moolenaar

unread,
Dec 17, 2022, 7:27:55 AM12/17/22
to vim/vim, Subscribed


> Currently there are various issues with screen flicker in vim. I am
> sure you already know about this but I can quote issue numbers for you
> if you want.

I am not aware of screen flicker that can be avoided. If you have a
reproducible example, that is always good to have. Below you refer to
"flicker caused by partial screen updates", I'm not sure what that is,
thus an example for that would help understand what problem you are
trying to fix.


> Modern terminals implement atomic screen updates. Emit the BSU (Begin
> synchronized update) escape code, emit whatever you want, emit the ESU
> (End synchronized update) escape code and a supporting terminal will
> render everything that happens in between the two in an atomic,
> flicker free manner. There will be no flicker caused by partial screen
> updates anymore.
>
> Terminals that are known to support it: iTerm, kitty, mintty, contour, wezterm, foot, etc.
>
> For details see: https://gist.github.com/christianparpart/d8a62cc1ab659194337d73e399004036
>
> And before you ask, no, there is no terminfo key for it.
>
> I am not familiar with vim's codebase so cant comment on how
> easy/difficult it would be, but at least for some use cases, such as
> :redraw! and scroll it should be easy to emit the sequences before
> after the functions that implement these.

I see no point for it with ":redraw!", it would only delay seeing the
screen update. Perhaps if the text is already mostly as it should be
you would skip the state where it's cleared, but the whole reason of
using ":redraw!" is that things got messed up.

For scrolling, Vim tries to use scroll regions as much as possible.
There should be no flicker then. In some cases a scroll region can't be
used, I think in those cases the text is just overwritten, thus no
flicker. But there are many different situations, perhaps there are a
few where flicker can be visible.

Thus I can't think of a good place to use this.

--
[clop clop]
GUARD #1: Halt! Who goes there?
ARTHUR: It is I, Arthur, son of Uther Pendragon, from the castle of
Camelot. King of the Britons, defeator of the Saxons, sovereign of
all England!
GUARD #1: Pull the other one!
The Quest for the Holy Grail (Monty Python)

/// Bram Moolenaar -- ***@***.*** -- http://www.Moolenaar.net \\\
/// \\\
\\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///


Reply to this email directly, view it on GitHub.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/11718/1356235383@github.com>

Kovid Goyal

unread,
Dec 17, 2022, 7:48:44 AM12/17/22
to vim/vim, Subscribed

On Sat, Dec 17, 2022 at 04:27:33AM -0800, Bram Moolenaar wrote:
>
> > Currently there are various issues with screen flicker in vim. I am
> > sure you already know about this but I can quote issue numbers for you
> > if you want.
>
> I am not aware of screen flicker that can be avoided. If you have a
> reproducible example, that is always good to have. Below you refer to
> "flicker caused by partial screen updates", I'm not sure what that is,
> thus an example for that would help understand what problem you are
> trying to fix.

Reproducing flicker is hard, since it depends on timing which varies from
machine to machine. But here is a scenario for you. vim sends the
commands to clear the screen then the commands to draw line 1, then draw
line 2, etc. The terminal emulator reads the command to clear the
screen, and draw line 1 but does not yet receive the command to draw
line2, so it clears the screen, then draws line1 and then displays that
to the user. The user sees a partial screen drawn, then the terminal
receives line 2 through N, and draws those, the user perceives this as a
flash or "flicker".


>
> > Modern terminals implement atomic screen updates. Emit the BSU (Begin
> > synchronized update) escape code, emit whatever you want, emit the ESU
> > (End synchronized update) escape code and a supporting terminal will
> > render everything that happens in between the two in an atomic,
> > flicker free manner. There will be no flicker caused by partial screen
> > updates anymore.
> >
> > Terminals that are known to support it: iTerm, kitty, mintty, contour, wezterm, foot, etc.
> >
> > For details see: https://gist.github.com/christianparpart/d8a62cc1ab659194337d73e399004036
> >
> > And before you ask, no, there is no terminfo key for it.
> >
> > I am not familiar with vim's codebase so cant comment on how
> > easy/difficult it would be, but at least for some use cases, such as
> > :redraw! and scroll it should be easy to emit the sequences before
> > after the functions that implement these.
>
> I see no point for it with ":redraw!", it would only delay seeing the
> screen update. Perhaps if the text is already mostly as it should be
> you would skip the state where it's cleared, but the whole reason of
> using ":redraw!" is that things got messed up.

See above for why its useful for redraw!


>
> For scrolling, Vim tries to use scroll regions as much as possible.
> There should be no flicker then. In some cases a scroll region can't be
> used, I think in those cases the text is just overwritten, thus no
> flicker. But there are many different situations, perhaps there are a
> few where flicker can be visible.

You can use scroll regions when doing a vertical slit, you cant use
scroll regions when using relative line numbers in the gutter, etc.


Reply to this email directly, view it on GitHub.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/11718/1356244435@github.com>

Bram Moolenaar

unread,
Dec 17, 2022, 10:29:01 AM12/17/22
to vim/vim, Subscribed


> On Sat, Dec 17, 2022 at 04:27:33AM -0800, Bram Moolenaar wrote:
> >
> > > Currently there are various issues with screen flicker in vim. I am
> > > sure you already know about this but I can quote issue numbers for you
> > > if you want.
> >
> > I am not aware of screen flicker that can be avoided. If you have a
> > reproducible example, that is always good to have. Below you refer to
> > "flicker caused by partial screen updates", I'm not sure what that is,
> > thus an example for that would help understand what problem you are
> > trying to fix.
>
> Reproducing flicker is hard, since it depends on timing which varies from
> machine to machine. But here is a scenario for you. vim sends the
> commands to clear the screen then the commands to draw line 1, then draw
> line 2, etc. The terminal emulator reads the command to clear the
> screen, and draw line 1 but does not yet receive the command to draw
> line2, so it clears the screen, then draws line1 and then displays that
> to the user. The user sees a partial screen drawn, then the terminal
> receives line 2 through N, and draws those, the user perceives this as a
> flash or "flicker".

Hmm, I would only call that flicker if the text being displayed is
similar to what was there before clearing. But that's just what you
call it.

Depending on the speed of communication, complexity of what to draw
(especially some syntax highlighting can be slow), amount of meta data
(mainly color info), displaying lines can be faster or slower. If it's
really fast then it doesn't really matter how the displaying happens.
When it's slow enough to notice, then the question is: would the user
rather see nothing (no change) for some time and suddenly all the text,
or rather see the lines appearing as they become available? Hard to
say, but my personal preference is that I rather see something
happening, otherwise I suspect something is wrong. Or type the same
command again, because it looks like it didn't work the first time.


> > For scrolling, Vim tries to use scroll regions as much as possible.
> > There should be no flicker then. In some cases a scroll region can't be
> > used, I think in those cases the text is just overwritten, thus no
> > flicker. But there are many different situations, perhaps there are a
> > few where flicker can be visible.
>
> You can use scroll regions when doing a vertical slit, you cant use
> scroll regions when using relative line numbers in the gutter, etc.

When a scroll region is not possible then it should overwrite the text.
In some previous version it could clear the screen first, which does
cause flicker. I think I found all situations where that happens and
removed the clearing, but I may have missed one or two. If you can
reproduce, please let us know.

Relative line numbers are already updated without flicker. Not sure if
it depends on something, but for me it's easy to see:
1. Edit a file with enough lines to fill the terminal
2. :set number relativenumber wd=10
3. Move the cursor up or down with "j" or "k".

You should see the numbers being updated from top to bottom, no
clearing, no flicker, they are just overwritten with the new value.

The 'writedelay' option is a simple way to slow down the terminal
output, so you can see how the screen is updated. You may want to
adjust 'redrawtime' to avoid highlighting being disabled.


--
GUARD #1: What, ridden on a horse?
ARTHUR: Yes!
GUARD #1: You're using coconuts!
ARTHUR: What?
GUARD #1: You've got two empty halves of coconut and you're bangin' 'em
together.

The Quest for the Holy Grail (Monty Python)

/// Bram Moolenaar -- ***@***.*** -- http://www.Moolenaar.net \\\
/// \\\
\\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///


Reply to this email directly, view it on GitHub.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/11718/1356308623@github.com>

Kovid Goyal

unread,
Dec 17, 2022, 7:43:23 PM12/17/22
to vim/vim, Subscribed

Closed #11718 as completed.


Reply to this email directly, view it on GitHub.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issue/11718/issue_event/8063126094@github.com>

Kovid Goyal

unread,
Dec 17, 2022, 7:43:26 PM12/17/22
to vim/vim, Subscribed

Well, if you prefer flicker as an indication of "something happening" that's obviously your choice. I just wanted to make you aware that if you want flicker free drawing in vim the technology for it exists.


Reply to this email directly, view it on GitHub.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/11718/1356585341@github.com>

Reply all
Reply to author
Forward
0 new messages