So far there is no native way of moving the cursor up or down a display line in insert mode.
Allow cursor to be moved one display line up or down natively in insert mode. Using either a new command or a new keybind like i_ctrl-g g j, i_ctrl-g g k that can be mapped to.
<c-o>gk, it works properly, but it triggers ModeChange and invokes other auto commands.<cmd>normal gk<cr>, it works most of the time but not when the cursor is on the last char of the line.—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
Vim is a modal editor, you can use a mapping.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
Vim is a modal editor, you can use a mapping.
Map to what?
Maybe I wasn't being clear. The goal is to be able to move the cursor without triggering any auto commands. I am not aware of any solution without the usage of either :normal or <c-o> but those do trigger other events.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
pleaes use cursor keys or map to them.
imap <c-b><c-j> <down>
imap <c-b><c-k> <up>
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
You might like sub-mode mapping
imap <C-b>j <down><SID>im
imap <C-b>k <up><SID>im
inoremap <script> <SID>imj <down><SID>im
inoremap <script> <SID>imk <up><SID>im
imap <SID>im <Nop>
This enable moving with prefix <c-b> key. Try typing like <c-b>jjjjjkkkkkkjjjkjkkkkjj
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
If you have an autocommand triggering, you should ask, why do you have such an autocommand in the first place?
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.![]()
You might like sub-mode mapping
imap <C-b>j <down><SID>im imap <C-b>k <up><SID>im inoremap <script> <SID>imj <down><SID>im inoremap <script> <SID>imk <up><SID>im imap <SID>im <Nop>This enable moving with prefix
<c-b>key. Try typing like<c-b>jjjjjkkkkkkjjjkjkkkkjj
I don't think this solves the problem.
To clarify. I have the following config to remap arrow keys to display line moves:
inoremap <up> <c-o>gk inoremap <down> <c-o>gj
The issue I'm facing with this approach is it will trigger InsertLeave and InsertEnter in addition to just CursorMovedI.
I have lsp plugins that perform expensive operations on those two triggers as the plugin assumes no one should rapidly leave and reenter insert mode.
After setting set verbose=9 verbosefile=/dev/pts/1, I can see that InsertLeave and InsertEnter would be triggered for the above script as well.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
You can try this script as a workaround. It moves the cursor by display line in insert mode without triggering InsertLeave/InsertEnter:
let s:curswant = 0 let s:prev = [0, 0] function! s:textwidth() abort return winwidth(0) - getwininfo(win_getid())[0].textoff endfunction function! s:move(dir) abort let tw = s:textwidth() let vcol = virtcol('.') if s:prev[0] == 0 let s:curswant = (vcol - 1) % tw endif let screen_line = (vcol - 1) / tw let target_screen = screen_line + a:dir if target_screen >= 0 && (target_screen + 1) * tw < virtcol([line('.'), '$']) " Move within the same logical line let lnum = line('.') let target = target_screen * tw + 1 + s:curswant else " Move to adjacent logical line let lnum = line('.') + a:dir if lnum < 1 || lnum > line('$') return endif if a:dir > 0 let target_screen = 0 else let last = max([virtcol([lnum, '$']) - 1, 1]) let target_screen = (last - 1) / tw endif let target = target_screen * tw + 1 + s:curswant endif let last = max([virtcol([lnum, '$']) - 1, 1]) call cursor(lnum, virtcol2col(0, lnum, min([target, last]))) endfunction function! s:on_move() abort let cur = [line('.'), virtcol('.')] if cur[0] == s:prev[0] || s:prev[0] == 0 " Horizontal move, text input, or first move: update curswant let s:curswant = (cur[1] - 1) % s:textwidth() endif let s:prev = cur endfunction augroup insmode_gjgk autocmd! autocmd CursorMovedI * call <SID>on_move() augroup END inoremap <Down> <Cmd>call <SID>move(1)<CR> inoremap <Up> <Cmd>call <SID>move(-1)<CR>
Save this as a file and :source it, or paste into your vimrc.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()
Thank you for your hard work. It is indeed not triggering any auto command other than cursor move.
It works 95% of time. But sometimes it would jump from the second last display line right to the next line, or jumping to a different column.
I will keep this as a workaround and improve upon it for now. Though I really believe something fundamental like moving cursor around should be a built in feature instead of having to write a such complicated workaround script. We have gk for normal mode, so it would make sense to have an equivalent of that for insert mode.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.![]()