Vim Toggle Movement: I Just Want to Go Home¶
I have a problem with the
^ key. I need its functionality, but its proximity is
too far for either of my stubby index fingers. No vimrc change can physically move it
closer to me, but I have found a way to move its funtionality to another a key.
A key which already knows how to go home. An alternate home. A home where my
heart isn't. Enough drama, what's the problem?!?
In my daily coding, I have a deep seeded need to go to the first non-blank
character of a line. The only key that Vim provides for that functionality is
the hardest key to reach from the home row. A much more comfortable key to reach
0, but that shoots us past the first non-blank character all the way to
the left edge of the window.
<Home> is the ugly step child of either option
since it's even harder to reach and takes us to the first column, too.
In case you don't believe me. Here's what the Vim document says:
0 To the first character of the line. |exclusive| motion. *<Home>* *<kHome>* <Home> To the first character of the line. |exclusive| motion. When moving up or down next, stay in same TEXT column (if possible). Most other commands stay in the same SCREEN column. <Home> works like "1|", which differs from "0" when the line starts with a <Tab>. *^* ^ To the first non-blank character of the line. |exclusive| motion.
Why can't I have a key that is easy to reach and takes me to the first non-blank?!?
I could swap the functionality of
nnoremap 0 ^ nnoremap ^ 0
This still forces me to reach for
^ when I need to need to get to that left
edge. There must be a better way!
0 some super toggling powers. When I hit it the first time, I want it be
^. If I hit it again, I want it to finish its travels and go to the
function! ToggleHomeZero() let pos = getpos('.') execute "normal! ^" if pos == getpos('.') execute "normal! 0" endif endfunction nnoremap 0 :call ToggleHome()<CR>
This gets us exactly to the center of Venn diagrams heart:
Easy to reach + First non-blank character + First column = Rainbow Colored Unicorn!
After enjoying staring at the function for a while, I realized we could add
super toggling powers to other movements. Lets extract the
into arguments and share the love with other keys!
function! ToggleMovement(firstOp, thenOp) let pos = getpos('.') execute "normal! " . a:firstOp if pos == getpos('.') execute "normal! " . a:thenOp endif endfunction " The original carat 0 swap nnoremap <silent> 0 :call ToggleMovement('^', '0')<CR> " How about ; and , nnoremap <silent> ; :call ToggleMovement(';', ',')<CR> nnoremap <silent> , :call ToggleMovement(',', ';')<CR> " How about H and L nnoremap <silent> H :call ToggleMovement('H', 'L')<CR> nnoremap <silent> L :call ToggleMovement('L', 'H')<CR> " How about G and gg nnoremap <silent> G :call ToggleMovement('G', 'gg')<CR> nnoremap <silent> gg :call ToggleMovement('gg', 'G')<CR>
ToggleMovement is the gift that keeps on giving!
What other movement can we add to the list? Let me know in the comments below.