Making a Window Submode in Vim¶

I found a plugin that is changing my Vim-tire life! This plugin is so awesome it should be built into default Vim. What does the plugin do? It enables the creation of new submodes. Why would a person want more modes?!? Isn't dealing with modes the main deterrent for new Vim users? Isn't Normal, Insert, Command-line, Visual, Select, and Operator-pending enough? (Did I miss one?) Let's try out a new submode and see what happens.

Window commands are prefixed with <C-w> . Want to create a horizontal split? Try <C-w>s , didn't mean to do that and want to do vertical split? <C-w>q<C-w>v . Want to resize the vertical split 50<C-w>> ? Too wide? Narrow it with 5<C-w>< . Move back to the other window? <C-w>p or <C-w>w .

Are your fingers getting tired? After I get the windows just right using default mappings my fingers are crying for mercy.

Here's a short list of common default window commands:

" Change window focus { n } < C - w > h move cursor left { n } window { n } < C - w > l move cursor right { n } window { n } < C - w > j move cursor down { n } window { n } < C - w > k move cursor up { n } window " Move window < C - w > H move window far left < C - w > L move window far right < C - w > J move window far bottom < C - w > K move window far top " Change size { n } < C - w >+ increase height by { n } rows { n } < C - w >- decrease height by { n } rows { n } < C - w >< decrease width by { n } columns { n } < C - w >> increase width by { n } columns < C - w >| maximize width < C - w > _ maximize height < C - w >= equalize sizes

For a comprehensive list of window commands try :help windows.txt .

Solution A¶

The most common solution to window-command-itis is to map other keys to these common actions so to include the <C-w> prefix.

From spf13-vim:

map < C - J > < C - W > j < C - W > _ map < C - K > < C - W > k < C - W > _ map < C - L > < C - W > l < C - W > _ map < C - H > < C - W > h < C - W > _ " Note: They go one extra by maximizing the height after entering the split.

From Thoughbot:

nnoremap < C - J > < C - W >< C - J > nnoremap < C - K > < C - W >< C - K > nnoremap < C - L > < C - W >< C - L > nnoremap < C - H > < C - W >< C - H >

This has been the accepted solution for most, but it takes away so many convenient keys. And in some cases, it even overrides default behaviour. <C-L> , I miss you. C-H , isn't that also <BS> ? Guess I won't be using you either.

Solution B - Submode to the Rescue¶

This entire solution depends on kana/vim-submode, I consider it one of Japan's national treasures along with ninjas and ramen. Unfortunately, Kana's example use of submodes is a little underwhelming: undo/redo using g- and g+ . I agree with the author that using g- and g+ is not convenient, and using g++++-++-+ is easier, but the solution for that was simply u and <C-R> . I feel a better application for a new submode is window management. Imagine if resizing a split was <C-w>++++++++ or <C-w>------=->>>>>>>><> or changing cursor location was <C-w>hjlll or moving was <C-w>HjKLkjh . Imagine no more!

First, install the plugin. If you're not sure how to install a plugin, try junegunn/vim-plug. Next, add the following to your $MYVIMRC .

" A message will appear in the message line when you're in a submode " and stay there until the mode has existed. let g :submode_always_show_submode = 1 " We're taking over the default <C-w> setting. Don't worry we'll do " our best to put back the default functionality. call submode#enter_with ( 'window' , 'n' , '' , '<C-w>' ) " Note: <C-c> will also get you out to the mode without this mapping. " Note: <C-[> also behaves as <ESC> call submode#leave_with ( 'window' , 'n' , '' , '<ESC>' ) " Go through every letter for key in [ 'a' , 'b' , 'c' , 'd' , 'e' , 'f' , 'g' , 'h' , 'i' , 'j' , 'k' , 'l' , 'm' , \ 'n' , 'o' , 'p' , 'q' , 'r' , 's' , 't' , 'u' , 'v' , 'w' , 'x' , 'y' , 'z' ] " maps lowercase, uppercase and <C-key> call submode#map ( 'window' , 'n' , '' , key , '<C-w>' . key ) call submode#map ( 'window' , 'n' , '' , toupper ( key ), '<C-w>' . toupper ( key )) call submode#map ( 'window' , 'n' , '' , '<C-' . key . '>' , '<C-w>' . '<C-' . key . '>' ) endfor " Go through symbols. Sadly, '|', not supported in submode plugin. for key in [ '=' , '_' , '+' , '-' , '<' , '>' ] call submode#map ( 'window' , 'n' , '' , key , '<C-w>' . key ) endfor " Old way, just in case. nnoremap < Leader > w < C - w >

After :source $MYVIMRC , you'll have a glorious new submode in Vim. You can see I named it window mode. Can you guess how to get into window mode? <C-w> , the normal prefix used to do any wincmd . If this is too drastic, feel free to change line #7 to something else. Just replace <C-w> with a different normal mapping.

Let's give it a test drive. I know you can't see what keys I'm pressing, but I guarantee I only pressed <C-w> once. I also didn't have to remember any new key bindings. The hesitation in the demo is the resistance to hitting <C-w> every time, which I'll get over soon enough.

Bonus Mappings¶

But wait there's more! In case I haven't provided enough tips for one post, here's the overrides I have in $MYVIMRC to make windowing even better.

" I don't like <C-w>q, <C-w>c won't exit Vim when it's the last window. call submode#map ( 'window' , 'n' , '' , 'q' , '<C-w>c' ) call submode#map ( 'window' , 'n' , '' , '<C-q>' , '<C-w>c' ) " <lowercase-pipe> sets the width to 80 columns, pipe (<S-\>) by default " maximizes the width. call submode#map ( 'window' , 'n' , '' , '\' , ':vertical resize 80<CR>' ) " Resize faster call submode#map ( 'window' , 'n' , '' , '+' , '3<C-w>+' ) call submode#map ( 'window' , 'n' , '' , '-' , '3<C-w>-' ) call submode#map ( 'window' , 'n' , '' , '<' , '10<C-w><' ) call submode#map ( 'window' , 'n' , '' , '>' , '10<C-w>>' )

Rainbows without Unicorns¶

While learning this new way of windowing, there have been a few negatives:

I forget that I'm in window mode and get disoriented when I think I'm moving the cursor within a buffer, but it jumps around to other splits. For one off window commands, I have to hit an extra key to get out of window mode or wait for the timeout. When I use some one else's computer, I'm useless.

I think most of these annoyances will go away with time, and the benefits overtime in keystroke savings are non-trivial. As for #3, regardless of submodes, the brain freeze will never go away, because no one thinks as strangely as me, and that's a Good Thing™.

Shout-out to Kana Natsuno, @kana1, http://whileimautomaton.net/, https://github.com/kana . None of this awesomeness would be possible without https://github.com/kana/vim-submode . She makes some totally sweet plug-ins. Check out her stuff. You won't regret it!

Let me know what you think. Am I crazy? What other things deserve a submode? Hit me up in the comments below! Thanks for reading!