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')

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .