Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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?

share|improve this question

1 Answer 1

up vote 1 down vote accepted

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
share|improve this answer
    
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 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. –  Ingo Karkat Apr 30 at 6:29
    
The <SID> just makes the mappings local; you could have used <Plug>, too. And see :h :map-expr for details. –  Ingo Karkat Apr 30 at 6:30
    
Sorry for the delay --- it works like a charm. Thanks, marked solved. –  Rmano May 7 at 14:39

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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