Some problems in Vim8/neovim
Shougo opened this issue · comments
-
The cursor is flickered when use ddc.vim in Vim8. It seems when the popup window is displayed, the cursor will be hidden. I don't know why.
-
The mode string in the echoarea is redrawn when the popup window is displayed in both Vim8 and neovim.
Minimal vimrc
if &compatible
set nocompatible
endif
set runtimepath^=~/work/ddc.vim
set runtimepath^=~/work/ddc-around
set runtimepath^=~/work/ddc-matcher_head
set runtimepath^=~/work/ddc-sorter_rank
set runtimepath+=~/src/denops.vim
filetype plugin indent on
syntax enable
call ddc#custom#patch_global('sources', ['around'])
"call ddc#custom#patch_global('completionMode', 'inline')
"call ddc#custom#patch_global('completionMode', 'manual')
call ddc#custom#patch_global('sourceOptions', {
\ '_': {
\ 'ignoreCase': v:true,
\ 'matchers': ['matcher_head'],
\ 'sorters': ['sorter_rank'],
\ },
\ 'around': {'mark': 'A'},
\ })
call ddc#enable()
Both problems are not occurred in deoplete.
Could you make it without using ddc.vim?
It seems from complete()
call in ddc.vim.
Without the function call, it is not reporuced.
The cursor problem is reduced by below config.
let &t_SI = "\<Esc>[6 q"
let &t_EI = "\<Esc>[0 q"
Both problems are not occurred in deoplete.
In deoplete, the cursor is not hidden when input.
Could you make it without using ddc.vim?
In Vim8, denops.vim hide the cursor without popup window.
It can be reproduced without ddc.vim.
@Shougo
Sorry, cause of the problem i was recognized was different to this.
Above problem was caused by redrawing in Vim
It's more likely issues on ddc.vim so close. Please feel free to re-open or re-create once the issue can reproduced without using ddc.vim
Really? OK. I will create the minimal example. Please wait.
denops/completion/app.ts
import { Denops } from "https://deno.land/x/denops_std@v1.0.0/mod.ts#^";
import * as autocmd from "https://deno.land/x/denops_std@v1.0.0/autocmd/mod.ts#^";
export async function main(denops: Denops) {
denops.dispatcher = {
async onEvent(_arg1: unknown): Promise<void> {
denops.call("completion#complete");
},
};
await autocmd.group(denops, "completion", (helper: autocmd.GroupHelper) => {
helper.remove("*");
for (
const event of [
"TextChangedI",
"TextChangedP",
]
) {
helper.define(
event as autocmd.AutocmdEvent,
"*",
`call denops#notify('${denops.name}', 'onEvent', ["${event}"])`,
);
}
});
console.log(`${denops.name} has loaded`);
}
autoload/completion.vim
let s:root_dir = fnamemodify(expand('<sfile>'), ':h:h')
function! completion#enable() abort
autocmd User DenopsReady call denops#plugin#register('completion',
\ denops#util#join_path(s:root_dir, 'denops', 'completion', 'app.ts'))
endfunction
function! completion#complete() abort
inoremap <silent> <Plug>_ <C-r>=completion#_complete()<CR>
set completeopt-=longest
set completeopt+=menuone
set completeopt-=menu
set completeopt+=noselect
call feedkeys("\<Plug>_", 'i')
return ''
endfunction
function! completion#_complete() abort
if getline('.') =~ '\w\+$'
call complete(1, ['foo', 'bar', 'baz'])
else
call complete(1, [])
endif
return ''
endfunction
Minimal vimrc
if &compatible
set nocompatible
endif
set runtimepath+=~/src/denops.vim
set runtimepath+=~/src/denops-completion
call completion#enable()
You can reproduce the problems without ddc.vim.
I cloud reproduce 1. but 2. with above. I'll investigate 1. (but I've no idea at least for now)
The cursor is flickered when use ddc.vim in Vim8. It seems when the popup window is displayed, the cursor will be hidden. I don't know why.
The mode string in the echoarea is redrawn when the popup window is displayed in both Vim8 and neovim.
Not sure but the following fix cursor issue on my environment.
diff --git a/denops/completion/app.ts b/denops/completion/app.ts
index 5c106aa..0e0f977 100644
--- a/denops/completion/app.ts
+++ b/denops/completion/app.ts
@@ -4,7 +4,7 @@ import * as autocmd from "https://deno.land/x/denops_std@v1.0.0/autocmd/mod.ts#^
export async function main(denops: Denops) {
denops.dispatcher = {
async onEvent(_arg1: unknown): Promise<void> {
- denops.call("completion#complete");
+ await denops.call("completion#complete");
},
};
@@ -19,7 +19,7 @@ export async function main(denops: Denops) {
helper.define(
event as autocmd.AutocmdEvent,
"*",
- `call denops#notify('${denops.name}', 'onEvent', ["${event}"])`,
+ `call denops#request('${denops.name}', 'onEvent', ["${event}"])`,
);
}
});
Using denops#notify
means that you don't wait onEvent
thus I guess onEvent
calls pollute something?
import { Denops } from "https://deno.land/x/denops_std@v1.0.0/mod.ts#^";
import * as autocmd from "https://deno.land/x/denops_std@v1.0.0/autocmd/mod.ts#^";
const wait = async (ms) => {
return new Promise((resolve) => {
setTimeout(() => {
resolve();
}, ms)
});
}
export async function main(denops: Denops) {
denops.dispatcher = {
async onEvent(_arg1: unknown): Promise<void> {
await wait(1000);
await denops.call("completion#complete");
},
};
await autocmd.group(denops, "completion", (helper: autocmd.GroupHelper) => {
helper.remove("*");
for (
const event of [
"TextChangedI",
"TextChangedP",
]
) {
helper.define(
event as autocmd.AutocmdEvent,
"*",
`call denops#notify('${denops.name}', 'onEvent', ["${event}"])`,
);
}
});
console.log(`${denops.name} has loaded`);
}
Please test it.
let s:root_dir = fnamemodify(expand('<sfile>'), ':h:h')
function! completion#enable() abort
autocmd User DenopsReady call denops#plugin#register('completion',
\ denops#util#join_path(s:root_dir, 'denops', 'completion', 'app.ts'))
endfunction
function! completion#complete() abort
inoremap <silent> <Plug>_ <C-r>=completion#_complete()<CR>
set completeopt-=longest
set completeopt+=menuone
set completeopt-=menu
set completeopt+=noselect
call feedkeys("\<Plug>_", 'i')
return ''
endfunction
function! completion#_complete() abort
if getline('.') =~ '\w\+$' && getline('.') !~# 'date$'
call complete(1, map(['foo', 'bar', 'baz'], { _, v -> {'word': v, 'equal': v:true}}))
else
call complete(1, [])
endif
return ''
endfunction
Please test it and input date date date ...
quickly.
I could reproduce the issue on Vim but Neovim
Vim
I could reproduce "statusline flush" issue when I hit <Esc>
to escape from insert mode.
Kapture.2021-08-07.at.15.21.40.mp4
Neovim
I could not reproduce "statuslie flush" issue (but Shougo said it might be a performance difference of the terminal).
Kapture.2021-08-07.at.15.20.41.mp4
Using denops#notify means that you don't wait onEvent thus I guess onEvent calls pollute something?
Probably this is the reason but ddc.vim use denops#notify
on purpose. Using denops#request
blocks thus.
The cursor is flickered when use ddc.vim in Vim8. It seems when the popup window is displayed, the cursor will be hidden. I don't know why.
The problem is fixed when I use denops#request()
instead.
But
The mode string in the echoarea is redrawn when the popup window is displayed in both Vim8 and neovim.
Does not fix.
The cursor is flickered when use ddc.vim in Vim8. It seems when the popup window is displayed, the cursor will be hidden. I don't know why.
It is fixed after de-bounce.
The mode string in the echoarea is redrawn when the popup window is displayed in both Vim8 and neovim.
It is also reproduced in deoplete. It is less flicker though.
📝
This is the debounced version I suggested and solved.
let s:root_dir = fnamemodify(expand('<sfile>'), ':h:h')
let s:complete_timer = v:null
function! completion#enable() abort
autocmd User DenopsReady call denops#plugin#register('completion',
\ denops#util#join_path(s:root_dir, 'denops', 'completion', 'app.ts'))
endfunction
function! completion#complete() abort
" デバウンス
silent! call timer_stop(s:complete_timer)
let s:complete_timer = timer_start(10, { -> completion#_complete() })
endfunction
function! completion#_complete() abort
" 入力モードじゃない可能性もあるので...この辺の条件は知らないです
if mode() !=# 'i'
return
endif
set completeopt-=longest
set completeopt+=menuone
set completeopt-=menu
set completeopt+=noselect
if getline('.') =~ '\w\+$' && getline('.') !~# 'date$'
call complete(1, map(['foo', 'bar', 'baz'], { _, v -> {'word': v, 'equal': v:true}}))
else
call complete(1, [])
endif
endfunction