5

I have mapped my arrows keys to move in a visual-line mode, leaving the hjkl keys for normal, logic line movement:

" Visual movement with the arrows and End-Home 
nnoremap <Down> gj
nnoremap <Up> gk
vnoremap <Down> gj
vnoremap <Up> gk
inoremap <Down> <C-o>gj
inoremap <Up> <C-o>gk
inoremap <Home> <C-o>g<Home>
inoremap <End>  <C-o>g<End>

This works, but for a minor problem. I have a bit of code in my status line to change color between input mode and normal mode, like this:

if version >= 700
  highlight statusLine cterm=bold ctermfg=black ctermbg=red
  au InsertLeave * highlight StatusLine cterm=bold ctermfg=black ctermbg=red gui=bold guifg=black guibg=red
  au InsertEnter * highlight StatusLine cterm=bold ctermfg=black ctermbg=green   gui=bold guifg=black guibg=green
endif

...and I noticed now (on a machine slower than the one I have at home) that every time I press one of the arrows, the temporary mode switch of <ctrl>o (at least, I think) make the status line flash rapidly red then green again.

It is possible to redefine the keys to avoid the temporary jump to normal mode?

2 Answers 2

1

I have two ideas, but both are quite complex:

  1. Use :inoremap <expr> and perform the cursor repositioning with :call cursor() yourself. The downside is that you have to do the calculation which wrapped column is directly over / under the cursor.
  2. Use :inoremap <expr> to wrap the <C-o>gj command in :set eventignore+=InsertLeave,InsertEnter before and option restore afterwards, like this:
function! IgnoreOn( motion )
    set eventignore+=InsertLeave,InsertEnter
    return "\<C-o>" . a:motion
endfunction
function! IgnoreOff()
    set eventignore-=InsertLeave,InsertEnter
    return "\<Left>\<Right>" | " Workaround for missing screen update.
endfunction
inoremap <expr> <SID>IgnoreOff IgnoreOff()
inoremap <expr> <SID>IgnoredDown IgnoreOn('gj')
inoremap <script> <Down> <SID>IgnoredDown<SID>IgnoreOff
4
  • Tried, seems to work but the first Down after entering input mode is ignored. The problem is that I do not understand it ... could you point me to somewhere when to learn about <SID> stuff? Or (if you have time) comment the code? Thanks!
    – Rmano
    Apr 29, 2014 at 16:40
  • Actually, the cursor also moves the first time, just the screen isn't updated until another cursor move or char insertion. I've added a workaround to my answer. Apr 30, 2014 at 6:29
  • The <SID> just makes the mappings local; you could have used <Plug>, too. And see :h :map-expr for details. Apr 30, 2014 at 6:30
  • Sorry for the delay --- it works like a charm. Thanks, marked solved.
    – Rmano
    May 7, 2014 at 14:39
0

My solution is based on Igno's suggestions, but does not require excessive mouse movement.

autocmd! InsertEnter * set eventignore-=InsertLeave
function! s:UpDown(keys)
  set eventignore+=InsertLeave
  return "\<C-O>".a:keys
endfunction
inoremap <expr> <DOWN> <SID>UpDown('gj')
inoremap <expr> <Up> <SID>UpDown('gk')

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.