More Gems of Vim: Tabs, Maps, and Tips, Oh my!

More Gems of Vim: Tabs, Maps, and Tips, Oh my!

Last year, I wrote a blog on some things that made using Vim much easier for development. A year is a long time to learn new things, and boy have I have learned a lot. Here are some cool takeaways from what I learned, and hopefully it will make using Vim much more powerful for you.

Tiny Tips

These are a handful of things that make using Vim a lot easier and quicker. They have small benefits that add up quickly and reduce the mental load an editor can add.

Better search with *

If your cursor is on a word, and you want to find its next occurrence, You can use *. It will instantly take you the next occurrence of the word by running a search for it. You can use n and N to go through all of its occurrences as a normal search would.

Auto indent with =

You can use = to automatically indent the current line to where it should be indented. I was a big fan of > and < until I found =, and now I have mostly abandoned those. This can be used like y,d, and the others: Type == to automatically indent the current line, highlight a section in Visual mode and press = to automatically indent it, or even =j will properly indent the line and the line below. Note: The command :normal gg=G will automatically indent a file from Top to Bottom. :normal is a way of running Normal mode commands in Ex mode(colon commands).

Easily spot extra whitespace

Put this in your .vimrc file to easily spot tabs and whitespace in your files:

set list listchars=tab:»·,trail:·,nbsp:·

Use recent changes to your .vimrc

Did you make an update to your .vimrc and want to use it without closing and reopening Vim? Run :source $MYVIMRC to re-source your .vimrc file. $MYVIMRC is an environment variable that stores the filepath to your .vimrc.

Case Insensitive Search in Vim

There are times when you need to do case insensitive search in Vim. Type :set noic to put search in case-insensitive mode. To put it back, type :set ic.

See the name of the file you’re in

Type :echo @% to see the current file’s name. It looks cryptic, but @ is how you reference a register(:help registers) in Vim, and Vim stores the filename in a register labeled %.

If you type vim ., it will put you in the directory Explorer. Explorer is very handy to move around in, but for a long time, I did not know how to get back to it after entering a file. It turns out that it’s easy to get back. If you’re already in a file, you can type :Ex to go into the directory that the file is in. Tada!

Change everything in quotes

Often I need to change a whole string or something in parenthesis. Typing ci', ci", or ci) will change everything within each of the respective boundaries.

Change ‘til something

To highlight or change everything until a specific character in the line, say “-“, type vt- or ct-. Think of it as “Change til -“.

Back to the basics

With the amount of possible commands in Vim, it’s easy to forget a handful of them. This is a refresher on helpful Vim commands that I use all of the time:

  • Go to a specific line - In normal mode, type :{number} to go to that line. For example, :10 will go to line ten.
  • Go to the end of the line - $
  • Go to the beginning of a line - ^
  • Go to the top of the file - gg
  • Go to the bottom of the file - G
  • Do something to a whole line:
    • Copy it - yy
    • Delete it - dd
    • Change it(Delete it and go into insert mode) - cc
  • Start a line below the cursor - o
  • Start a line above the cursor - O
  • Start at the end of a line - A
  • Start at the beginning of a line - I

Tabs

I have seen people use windows in Vim a lot, but I never felt comfortable with it. I found more preferrable way of opening multiple files: tabs.

“A tab page holds one or more windows. You can easily switch between tab pages, so that you have several collections of windows to work on different things.” - :help tabpage

To open a new tab, type :tabedit filename.rb. You can move around tabs with gt to go to the right and gT to go to the left. Closing and saving in a tab work the same as if you were in one file. In Explorer, you can open a tab of the file your cursor is highlighting with t.

Lastly, you can move tabs left and right with :tabm -1 and :tabm +1 respectively. Type :help tabpage to learn more about tabs.

Mappings Galore!

Now, that’s a lot of commands to remember. Wouldn’t it be nice if you could create shortcuts for them? That’s where mappings come in.

Vim allows you to map shortcuts for commands, and the ability to map is powerful. Here is a mapping that I use often to get a file’s name(one of the commands above):

map <leader>e :echo @%<cr>

This mapping allows me to press the leader key(see below) + e to see the name of the file. Note: <cr> stands for Carriage Return, aka Enter.

map and noremap

map has several different flavors. You can create mappings specific to the mode you’re in: nmap for Normal Mode, vmap for Visual Mode, etc. There’s a potential side effect with mappings of unexpectedy calling other mappings, and you can read more about it here. The remedy is to use noremap which does not take other mappings into account. The modes can also be used with noremap: nnoremap, etc.

See :help mapping to learn more about mapping functions.

Leader

I like to write most of my maps starting with a Leader key.

Vim defaults to using \ as the leader key, and when adding mappings in your .vimrc, <leader> is used to reference the leader key. Because \ is less convenient, I have remapped leader to the spacebar:

let mapleader = " "

Below are several mappings that I use daily.

Easier Navigation & Editing

These are a major time saver. They allow me to move in and out of files easily and indent a whole file in two button presses.

noremap <leader>e :echo @%<cr>
noremap <leader>z  :Ex<cr> " Return to explorer mode
noremap <leader>x :q<cr>   " Close a file
nnoremap <leader>= :normal gg=G<cr> " Indent a whole file

Note: Ctags

CTags is an external tool that builds tags for each function in a repository. Vim has functionality to navigate through a ctag file, and you can visit a method’s declaration using <leader>]. It keeps track of where you came from in a stack, and you can return to your original spot with :pop. I map pop to p for efficiency, and I also created a mapping for opening a declaration in a new tab using \.

noremap <leader>p  :pop<cr> " Return to the file that you came from
nnoremap <leader>\  <C-w><C-]><C-w>T "

Easier Tabs

I have a few mappings that make using tabs much easier.

noremap <leader>te :tabedit
noremap <leader>t. :tabedit .<cr>
noremap <leader>h  :tabm -1<cr>
noremap <leader>l  :tabm +1<cr>

Easier Customization

Because I rely on mappings more now, I like having the ability to create/edit mappings and use them immediately. I have two mappings that give me this functionality: <leader>ev and <leader>sv. ev splits the window, opening the .vimrc file to the left. I can make changes and close it, then run sv to re-source the file, and the changes are immediately available.

nnoremap <leader>ev :vsplit $MYVIMRC<cr>
nnoremap <leader>sv :source $MYVIMRC<cr>

Note: I have similar functions for my .bashrc file as well: al, short for aliases, opens my .bashrc, and sal re-sources it.

al() {
  vim ~/.bashrc
}

sal () {
  source ~/.bashrc
}

Custom Functions

I have a few custom functions in vim that I created to use for mappings. One opens the current tab in another tab. I can’t give functions justice yet, but if you want to learn more, here is the source that I learned about them from.

:function! OpenCurrentTab()
: let current = @%
: exec "tabedit ".current
:endfunction

noremap <leader>tt :call OpenCurrentTab()<cr>
nnoremap <leader>f :call RunFile()<cr>

Ruby & Rails in Vim

The ability to create custom functions opens a whole new world in Vim. I have only started to dabble in functions, but here are a few that I’ve been using with Rails development.

:function! RunReek()
: let current = @%
: exec "!reek ".current
:endfunction

:function! RunFile() " I use this one when running tests submitted with Rails Github Issues
: let current = @%
: exec "!bundle exec ruby ".current
:endfunction

:function! RunCucumberOnFile()
: let file_path = @%
: execute "!bundle exec cucumber ".file_path
:endfunction

function! Rubocop()
: let current = @%
: exec "!rubocop -E -F ".current
:endfunction

Final Thoughts

A lot of what I learned this year came from Learn Vimscript the Hard Way and Practical Vim. I highly recommend checking them both out. Also, there are many great plugins out there that I’ve only started to use recently, but they are worth checking out. Tim Pope seems to be the creator of all the great ones out there. I don’t know how he does it.

I plan to dig into Vim scripting more this year, and hopefully I’ll have a new blog for you with brand new tricks! If you have some favorites that I didn’t mention, let me know in the comments. Happy Vimming!

alex

About Alex Kitchens

I am a principal software engineer at Stitch Fix working remotely from Amarillo, TX. Talk to me about anything Rails, Ruby, Rust, or coffee.