From :h insertcharpre
:
It is not allowed to change the text |textlock|.
You need to delay the change with a one-shot autocmd, for example until the next TextChangedI
is fired:
fu! Test() abort
au TextChangedI * ++once call setline(1, getline('.'))
endfu
augroup test
au!
au InsertCharPre * call Test()
augroup END
The ++once
flag is provided by the patch 8.1.1113. If you don't have it, make the autocmd clear itself:
fu! Test() abort
augroup setline_on_textchangedi
au!
au TextChangedI * call setline(1, getline('.')) | au! setline_on_textchangedi
augroup END
endfu
augroup test
au!
au InsertCharPre * call Test()
augroup END
Note that TextChangedI
is not fired after you insert a character while the popup menu is visible.
If that's an issue, you need to also listen to TextChangedP
provided by the patch 8.0.1494:
au TextChangedI,TextChangedP * ++once call setline(1, getline('.'))
^^^^^^^^^^^^
Or just use a timer:
fu! Test() abort
call timer_start(0, {-> setline(1, getline('.'))})
endfu
augroup test
au!
au InsertCharPre * call Test()
augroup END
If you don't need to listen to InsertCharPre
, then the textlock issue disappears, and the code can be simplified:
augroup test
au!
au TextChangedI,TextChangedP * call setline(1, getline('.'))
augroup END
For more information, see:
:h textlock
:h insertcharpre
:h textchangedi
:h textchangedp
:h autocmd-once
:h timer_start(