I'm trying to make my own snippets in pure vimscript using autocommands. I want to make it so that after I type a specific character sequence, it is replaced by another character sequence. I made one like this, that replaces "hello" with "bye" when you type it.
function F()
if (strpart (getline('.'), 0, col('.')-1) =~ 'hello$')
execute "normal 5i\<Backspace>"
normal! abye
normal! l
endif
endfunction
autocmd TextChangedI *.tex call F()
And it works fine if there are characters after the cursor. However, if I am writing at the end of the line, after the change the cursor is between 'y' and 'e', because the autocommand calls the function, the cursor is at the end of the line, and then it enters insert mode which starts inserting before the last character.
How can I make it so that the cursor is always left after 'bye'? I don't want to use iabbrev for a couple of reasons, one being that it doesn't expand as soon as I type.
I can do it with the option
set ve+=onemore
but I don't like it's effects on normal writing.
How about the following, which uses setline
and cursor
functions rather than normal keymaps:
function! F() abort
let [l:line, l:col] = [getline('.'), col('.')]
if strpart(l:line, 0, l:col-1) =~ 'hello$'
let l:left = strpart(l:line, 0, l:col-6)
let l:right = strpart(l:line, l:col-1)
call setline('.', l:left . 'bye' . l:right)
call cursor('.', l:col-2) " 2 = length diff between hello and bye
endif
endfunction
This seems working for me (on Neovim 0.6).