I’ve been trying to write a bit of Vimscript to call a function when I insert the same character twice, in my particular case I wanted that if you inserted semi colon twice for it to actually move the semi colon to the end of the line.
command! Semi call Semi()
inoremap ; <C-O>:Semi2<CR>
function! Semi()
let x = getpos(".")
" If we are in the last column..
if col(".")+1 == col("$")
let insert_semi = getline(".") . ";"
call setline(".", insert_semi)
let x[2] += 1
call setpos(".", x)
return
endif
let char = getline(".")[x[2] - 2]
if char == ";"
" if prev char was a semicolon also, remove and append to the end
else
" insert semicolon normally...
endif
endfunction
The problem I am having is when calling this function on the last column, you have to exit insert mode to call this function the cursor will go into normal mode and move the cursor to the last column. Is there any way to tell whether the cursor was appending to the end of the line or inserting before the last column and when function call is finished return it to the same position?
I am well aware that I could use an insert mapping on ;; however I dislike this behaviour, where Vim goes into a waiting for next key mode and does not display what you have written. This issue is not only to do with my problem listed but a more general problem which also occurs in the first column.
I would advise against using
i_CTRL-O, it triggersInsertLeaveandInsertEnterevents, which may affect other plugins. I would use:inoremap <expr> ;here. See:help :map-expr. Inside that expression (i.e. your function), record the current cursor position and compare it with the last recorded one. If it’s next to it, return the keys to undo the inserts and redo at the end (<BS><BS><End>;), else just return;.