diff --git a/README.md b/README.md index 4aa44f3..f1e5fef 100644 --- a/README.md +++ b/README.md @@ -173,6 +173,11 @@ let g:Context_border_indent = function('indent') ``` When using popup windows we indent the border line to be aligned with the context base line. You can use this setting to use a different function to control that indent. Similar to `g:Context_indent` this function also takes a line number and returns an indentation number. For example you can disable that indentation at all to always show a full width border line like this: `let g:Context_border_indent = { -> [0, 0] }` +```vim +let g:context_delayed_update = 20 +``` +If you are using a plugin that redraws windows, such as the language server plugin, updates to **context.vim** and screen updates from other plugins can affect each other and cause problems. To solve this, you can delay the update of **context.vim** via `g:context_delayed_update`. The default value is 0, in milliseconds. + [indent-example]: https://github.com/wellle/context.vim/pull/45#issuecomment-582654810 diff --git a/autoload/context.vim b/autoload/context.vim index 990ef9a..d329f2f 100644 --- a/autoload/context.vim +++ b/autoload/context.vim @@ -55,6 +55,37 @@ function! context#peek() abort let w:context.peek = w:context.enabled endfunction +function! context#update_context() abort + if g:context.presenter == 'preview' + let s:ignore_update = 1 + + if w:context.needs_update + let w:context.needs_update = 0 + call context#preview#update_context() + endif + + let s:ignore_update = 0 + + else " popup + if w:context.needs_update + let w:context.needs_update = 0 + call context#popup#update_context() + endif + + if w:context.needs_layout + let w:context.needs_layout = 0 + call context#popup#layout() + endif + endif +endfunction + +function! context#update_context_callback(timer) abort + if w:update_timer != a:timer + return + endif + call context#update_context() +endfunction + function! context#update(...) abort " NOTE: this function used to have two arguments, but now it's only one " for compatibility reasons we still allow multiple arguments @@ -129,26 +160,10 @@ function! context#update(...) abort call context#util#echof('> context#update', source) call context#util#log_indent(2) - if g:context.presenter == 'preview' - let s:ignore_update = 1 - - if w:context.needs_update - let w:context.needs_update = 0 - call context#preview#update_context() - endif - - let s:ignore_update = 0 - - else " popup - if w:context.needs_update - let w:context.needs_update = 0 - call context#popup#update_context() - endif - - if w:context.needs_layout - let w:context.needs_layout = 0 - call context#popup#layout() - endif + if g:context.delayed_update != 0 + let w:update_timer = timer_start(g:context.delayed_update, 'context#update_context_callback') + else + call context#update_context() endif call context#util#log_indent(-2) diff --git a/autoload/context/settings.vim b/autoload/context/settings.vim index 7892d44..0b72957 100644 --- a/autoload/context/settings.vim +++ b/autoload/context/settings.vim @@ -120,6 +120,9 @@ function! context#settings#parse() abort let buftype_dict[buftype] = 1 endfor + " delayed time by milliseconds for update + let delayed_update = get(g:, 'context_delayed_update', 0) + let g:context = { \ 'presenter': presenter, \ 'enabled': enabled, @@ -148,6 +151,7 @@ function! context#settings#parse() abort \ 'Border_indent': Border_indent, \ 'popups': {}, \ 'windows': {}, + \ 'delayed_update': delayed_update, \ } endfunction diff --git a/doc/context.vim.txt b/doc/context.vim.txt index 9056eee..9e54db1 100644 --- a/doc/context.vim.txt +++ b/doc/context.vim.txt @@ -172,7 +172,12 @@ Here's an example that considers Markdown headers for the context: #45 (https:// When using popup windows we indent the border line to be aligned with the context base line. You can use this setting to use a different function to control that indent. Similar to `g:Context_indent` this function also takes a line number and returns an indentation number. For example you can disable that indentation at all to always show a full width border line like this: > let g:context_nvim_no_redraw = 0 + + +If you use other plugins that redraw the window, they can update each other, resulting in infinite updates. To solve the problem, delay the update of the context by a certain amount of time. The default value is 0, in milliseconds. < + let g:context_delayed_update = 0 + There's an issue in Neovim which leads to some artefacts. To avoid those we manually refresh the screen after every context update. This can lead to screen flickering, see #23 (https://github.com/wellle/context.vim/pull/23). You disable those redraws (at the cost of visual artefacts) like this: