Skip to content

Conversation

bfredl
Copy link
Member

@bfredl bfredl commented Jan 20, 2019

Extract the "compositor" layer from #6619. This allows us to draw the popupmenu on a separate grid rather than on the default grid, even for TUI use.

Attempt to eliminate flicker in all these cases:

  • The pum was filtered due to the user added a prefix char.
  • The pum is moved due to linewrap change ( i e by long inserted item at end of line)
  • The contents of the pum was changed due to complete() call or something (corresponding to vim/vim@ae65438, tested now)

Also update_screen(NOT_VALID) should never be needed to redraw the text under the pum, rather the cached contents is resent from default_grid.

Note: in principle this will enable two connected UI:s, one using ext_popupmenu and the other using the builtin popupmenu, at the same time. This will need some other refactors though.

Note 2: this should reduce the bookkeeping in edit.c for pum redraws (ideally all commented code can be removed, but needs more testing). This will lower the bar for ex_getln.c also using the pum instead of statusline wildmenu for completions. It will need to compute position differently, but apart from that it would be able to use pum_display and pum_undisplay without thinking about window redraws at all.

fixes #9542.

@bfredl
Copy link
Member Author

bfredl commented Jan 20, 2019

ping @Shougo what is the typical situation for vim/vim@ae65438, is it multiple complete() calls changing the popupmenu?

@bfredl bfredl force-pushed the pum_float branch 3 times, most recently from 42217df to a9a74d7 Compare January 20, 2019 12:44
@marvim marvim added the WIP label Jan 20, 2019
@@ -0,0 +1,369 @@
// This is an open source non-commercial project. Dear PVS-Studio, please check
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

name it ui_compositor.c , so it is grouped with ui.c and ui_bridge.c ? And the prefix could be uicomp_. This helps discover the project structure.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, lets do that.

src/nvim/ui.c Outdated
@@ -338,6 +359,18 @@ void ui_line(ScreenGrid *grid, int row, int startcol, int endcol, int clearcol,
}
}

void ui_composed_call_raw_line(Integer draw_grid, Integer row,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't "composite" the more common phrasing rather than "composed"?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe, but "composed" is a passive/past tense as in "the UI is (being) composed" or "after the line was composed"

src/nvim/ui.c Outdated
@@ -85,21 +86,25 @@ static char uilog_last_event[1024] = { 0 };
//
// See http://stackoverflow.com/a/11172679 for how it works.
#ifdef _MSC_VER
# define UI_CALL(funname, ...) \
# define UI_CALL_CND(CND, funname, ...) \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does CND mean?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

condition, maybe _IF is better?

Copy link
Member

@justinmk justinmk Jan 20, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW we use cond in a few places.

# define UI_CALL_IF(cond, ...

@Shougo
Copy link
Contributor

Shougo commented Jan 20, 2019

is it multiple complete() calls changing the popupmenu?

Yes. I will test the branch later.

@bfredl
Copy link
Member Author

bfredl commented Jan 20, 2019

And another thing: using compositior for pum also make possible things like this:
screenshot from 2019-01-20 21-27-23

Probably not practially useful for anything (except I guess providing useful context once in a blue moon), but maybe it can help make up for the lack of :smile.

@bfredl bfredl mentioned this pull request Jan 20, 2019
23 tasks
@Shougo
Copy link
Contributor

Shougo commented Jan 20, 2019

@bfredl I have tested below script with the branch.

" save this as complete_flicker.vim
" vim -u complete_flicker.vim -c "startinsert"

let s:months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']

let s:last_tick = []

function! s:current_tick()
    return [b:changedtick, getcurpos()]
endfunction

function! s:check_changes(...)
    let l:current_tick = s:current_tick()
    if s:last_tick != l:current_tick
        let s:last_tick = l:current_tick
        call s:on_changed()
    endif
endfunction

function! s:start_check_changes_timer()
    let s:last_tick = []
    let s:check_change_timer = timer_start(30, function('s:check_changes'), {'repeat': -1})
endfunction

function! s:stop_check_changes_timer()
    if exists('s:check_change_timer')
        call timer_stop(s:check_change_timer)
        unlet s:check_change_timer
    endif
endfunction

function! s:on_changed()
    if mode() != 'i'
        return
    endif
    setlocal completeopt-=longest
    setlocal completeopt+=menuone
    setlocal completeopt-=menu
    setlocal completeopt+=noselect
    call complete(1, s:months)
endfunction

autocmd TextChangedI * call s:check_changes()
autocmd InsertEnter * call s:start_check_changes_timer()
autocmd InsertLeave * call s:stop_check_changes_timer()

In the branch, narrowing flicker is gone, but press backspace is more flicker than master of neovim.
Can you fix the backspace flicker?

@bfredl
Copy link
Member Author

bfredl commented Jan 21, 2019

Thanks, I will investigate.

@bfredl
Copy link
Member Author

bfredl commented Jan 21, 2019

Actually, it seems to randomly happen for both typing and backspace (but not all of either).

@bfredl
Copy link
Member Author

bfredl commented Jan 21, 2019

@Shougo I think at least some of the flicker here is fundamental, not related to this patch. Because if you press a key that changes the pum, and then 0-30ms later a timer will change the pum back again, there will be flicker for up to 30ms. Adding this line fixes it:

   autocmd TextChangedP * call s:check_changes()

Does nvim behave subtly different than vim for the behavior of autocmds, perhaps?

@bfredl
Copy link
Member Author

bfredl commented Jan 21, 2019

But I changed timer to manually invoked <cmd> command and there is still some flicker, so all was not timer related.

@bfredl
Copy link
Member Author

bfredl commented Jan 21, 2019

Hmm state management in edit.c is a bit more complicated than I thought. At several points where the pum is undisplayed, the code doesn't know if the pum is going to be displayed immediately again. (The code might say pum_undisplay(); ins_show_completion_again() but the later sometimes ends up not showing the pum again). I will try a different approach:

  • at every point pum_undisplay or pum_display is called, just store the internal state
  • do the actual pum draw or clearing in ins_redraw.

@bfredl
Copy link
Member Author

bfredl commented Jan 21, 2019

Did the defer for only undisplay for now, probably enough.

@Shougo please try it again.

@Shougo
Copy link
Contributor

Shougo commented Jan 22, 2019

I have tested the latest version.
I have confirmed the flicker problem is fixed.
Thank you.

@bfredl
Copy link
Member Author

bfredl commented Jan 22, 2019

Issue: invoke the popupmenu with lots of items so it covers the entire the height of the screen. Now do :<c-r>=<c-f>. The cmdline window is now unusable due to covered by the pum. But the same issue exists on vim master, I will report it upstream.

@bfredl
Copy link
Member Author

bfredl commented Jan 22, 2019

vim issue: vim/vim#3838

@Shougo
Copy link
Contributor

Shougo commented Jan 23, 2019

The problem is fixed in Vim.

@bfredl bfredl added build building and installing Neovim using the provided scripts display redraw, layout, presentation ui and removed build building and installing Neovim using the provided scripts labels Jan 30, 2019
@bfredl bfredl force-pushed the pum_float branch 2 times, most recently from b650143 to 6426cd1 Compare January 31, 2019 18:31
@Shougo
Copy link
Contributor

Shougo commented Feb 2, 2019

I have tested the branch, and it is faster completion than master.

@bfredl bfredl force-pushed the pum_float branch 5 times, most recently from 8f0a227 to 1a03769 Compare February 2, 2019 15:30
Initially we will use this for the popupmenu, floating windows will
follow soon

NB: writedelay + compositor is weird, we need more flexible
redraw introspection.
This makes it possible for the compositor to compare the old pum with
the new position, and only clear what is necessary.
Many of these are handled by the compositor. Check that it causes
no glitches.
@bfredl
Copy link
Member Author

bfredl commented Feb 2, 2019

Made some simplifications to the dispatching logic. A single UI_CALL macro now does all the work without a bunch of helper macros for __VA_ARGS__ shenanigans. Also internal-only events use ui_call_evname wrappers, just like internal+external and external-only events.

@bfredl bfredl merged commit 79a0ea2 into neovim:master Feb 2, 2019
@purpleP
Copy link

purpleP commented Feb 3, 2019

Seems like you have a bug. After filtering spaces between items and metadata disappear.

Nice to see this pull request. I thought it would never be fixed!

@bfredl
Copy link
Member Author

bfredl commented Feb 3, 2019

@purpleP yes, the metadata seems to be shifted to the left one cell. Thanks for noticing, I will fix it.

bfredl added a commit to bfredl/neovim that referenced this pull request Feb 3, 2019
bfredl added a commit to bfredl/neovim that referenced this pull request Feb 3, 2019
bfredl added a commit that referenced this pull request Feb 3, 2019
popupmenu: fix alignment of kind and extra after #9530
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
display redraw, layout, presentation ui
Projects
None yet
Development

Successfully merging this pull request may close these issues.

E41: Out of memory when rightleft is set and a certain plugin is used
5 participants