Today I Learned

A Hashrocket project

210 posts about #vim

Re-mark a Word as Bad

Vim's spell checking feature is pretty great. I use it as a default for .md and .rdoc files on my machine.

Sometimes it incorrectly marks technical words like 'ExUnit' as bad (misspelled). To fix this, I type zg over the word in normal mode, which adds it to a list of white-listed words that are no longer considered bad.

The opposite of that command is zw, which comments out the line in the dictionary file. Run :runtime spell/cleanadd.vim to clean up those comments.

Determine the type of buffer

The :set <option> command will show the value of an option. In the case of :set buftype this is generally set to nothing. It's empty. This is because we're usually working with a normal buffer. The exception is the quick window. Generally, the buftype of the quick window is quickwindow. The help window also has its own buftype, help.

These values are used programmatically to help create features with vimscript.

See more with: :help buftype

Making your JS files prettier on Vim

We all use VIM at Hashrocket and we can run prettier everytime we save a JS file:

yarn global add prettier
autocmd FileType javascript set formatprg=prettier\ --single-quote\ --trailing-comma\ es5\ --stdin
autocmd BufWritePre *.js :normal gggqG
autocmd BufWritePre *.js exe "normal! gggqG\<C-o>\<C-o>"

And yes. I like trailing comma,

**** Update: There is an open issue on Github when prettier fails to parse the JS file but there is a workaround for it.

Turn off folds in my vim buffer!

Sometimes, a co-worker will come over to your vim session and just start folding things.

In these cases, turn off folds with the ever valuable :set nofoldenable.

If all the buffers have been folded then consider, :bufdo nofoldenable.

yank full line without new line character

I am often in a scenario where I want to take all the contents of the current line and paste them into the middle of another line, perhaps into some parentheses or quotation marks.

If I'm in the middle of a line I can type ^y$ which will goto the first character of the line and then yank to the end without the newline.

This is the rare palindramic vim command. It works the same backwards as it does forwards ($y^).

There is also a plugin that treats the line as a vim object called vim-textobj-line. Check it out!

Matching on directories for vim's autocmd

Generally, vim users use the autocmd command to set specific options for filetypes. Like, if you want all Ruby files to have the shiftwidth option set to 2 then you would include an autocmd line like this in your ~/.vimrc file:

autocmd BufRead *.rb set shiftwidth=2

I wanted to do something a bit different. I wanted to set the color scheme for each file in a directory rather than for a file type, and I tried this:

autocmd BufRead *writing* color shine

Nothing happened.

Via :help autocmd-patterns I was able to learn that if there isn't a slash char (/) anywhere in the pattern then it just tries to match on the filename. If a slash is included however, the whole path for that file is matched. All I needed was to add a slash:

autocmd BufRead */writing* color shine

Shine On.

Selected Text Character Count

When highlighting a word in vim (Visual Mode), type:

g<CTRL-g>

In the command section of vim you'll see something like this:

Selected 1 of 90 Lines; 2 of 715 Words; 15 of 4171 Chars; 15 of 4173 Bytes

In this case, 15 of 4171 Chars is the number of total characters and the number of characters selected.

Its not as straight forward or as easy to parse as you might expect, but when you know what to look for it becomes easy to read.

Get The pid Of The Session

Your current Vim session is a process running on your machine. That means that this session is tied to a particular process id, pid.

Want to know what the pid is?

:echo getpid()

This will echo the pid of your current Vim session.

See :h getpid() for more details.

Default netrw To Tree Liststyle

The built-in netrw plugin is a great way to browse files and directories within a Vim session. netrw supports four ways of displaying files and directories. That is, there are four liststyles. You can toggle through these by hitting i.

I prefer the tree liststyle, which is not the default. I can set the tree liststyle as the default by adding the following line to my .vimrc file.

let g:netrw_liststyle = 3

Now, every time I visit or revisit a netrw window, I'll see everything nicely displayed as a tree.

Use Mkdir! to create dir of present file in vim

In vim its easy to :edit, :write, or :saveas a file to a path that doesn't yet exist. Such as:

:edit non/existant/path/file.txt

Vim will let you have a buffer with that path, but when you try to write the file vim will throw an error:

E212: Can't open file for writing

Enter the Mkdir! command. The Mkdir command has been added by the eunuch.vim plugin to make creating directories easier from vim. The bang (!) variant takes the path of the current buffer and creates the directory from that path.

When we get the E212 error we can type:

:Mkdir!

And walla! The path will be created. No more errors when writing the file.

Change Time to UTC or Local

Today I discovered yet another cool feature from the vim-speeddating plugin.

To change a time in a Vim buffer to UTC, type d<C-A> with the cursor over the word. For local time, d<C-X>.

A use case would be setting a created_at time in a test, or time-stamping a manual log entry.

Break Up Lines with Splitjoin

One style-guide idea I try to maintain is sticking to a reasonable line length. 72 characters, 80 characters, whatever your preference; long lines are hard to read. They're a code smell. They need to have a reason for existing.

A task I find myself repeating a lot to achieve this is breaking apart Ruby blocks and hashes into multiple lines, with a combination of jumping forward, entering insert mode, and hitting enter. Turning this:

FactoryGirl.create(:developer, username: 'jake_skid', superpower: 'technical writing and style-guide compliance')

into this:

FactoryGirl.create(:developer, {
  username: 'jake_skid',
  superpower: 'technical writing and style-guide compliance'
})

This task has been automated for me by the Splitjoin plugin for Vim, which is included in the Hashrocket dotfiles. Typing gS in normal mode over the first example turns it into the second example. It's opinionated, and probably won't satisfy every tangent of your personal style (I'd leave off the curly braces and add a trailing comma, for instance). But it's already saved me a lot of time.

h/t Dorian Karter

Open images in vim with iTerm 🖼

iTerm 3 has a built in shell script called imgcat for displaying images in the terminal. With one simple autocmd in my vim configuration I can open images*:

:autocmd BufEnter *.png,*.jpg,*gif exec "! ~/.iterm2/imgcat ".expand("%") | :bw

In my command I wipe the image buffer(:bw) because I don't want large images sitting around in buffers, but this is easy to change.

imgcat

*imgcat does not work with tmux

Vimscript String Coercion

An unique feature of Vimscript is coercion of strings into integers.

Here's an example:

:echom "six" + 6
:echom "6six" + 6
:messages
6
12

Our messages show that the first string was coerced to 0 (0 + 6 = 6), and the second string was coerced to 6 (6 + 6 = 12).

Following this logic a little further, because 0 is falsey and 1 (or greater than 1) is truthy, our first string is falsey and our second string is truthy.

Spellcheck Certain Filetypes

I don't like misspellings in my documentation, yet make a lot of them. Spelling is disabled in all my buffers by default; I turn it on when reading or editing docs. When I forget to do so, it's easy to miss typos.

While reading Learn VimScript The Hard Way I figured out a better solution to this problem. This now lives in my ~/.vimrc.local:

augroup spellcheck_documentation
  autocmd BufNewFile,BufRead *.md setlocal spell
  autocmd BufNewFile,BufRead *.rdoc setlocal spell
augroup END

Anytime a markdown or RDoc file is created or read, I set a local configuration to turn spelling on. This has already proved invaluable after only a day or two.

Exclamation Point Toggles Vim Booleans

I have Vim line numbers turned on as a default, but sometimes I turn them off for better reading.

Today I learned that instead of :set nonumber (and the corresponding :set number) we can toggle any Vim boolean option with an exclamation point.

So, if line numbers are 'on', :set number! (or the even shorter :set nu!) turns them off, and vice versa.

Exit BufExplorer with `q`

One of my favorite Vim plugins is BufExplorer. It's indespensible if buffers are part of your Vim workflow.

Today I was reminded that you can exit your BufExplorer window with just q; no :q required. One keystroke instead of four; enjoy your extra free time.

h/t Josh Branchaud

See :help BufExplorer for more information.

Close All Other Splits

If you have a couple other splits open, but you only want the window in focus, you may find yourself doing some finger gymnastics to navigate to those other split windows to close out of them.

There is an easier way.

The Ex command :only will close all other splits, excluding the window that is currently in focus.

See :h :only for more details.

Set persistent font in MacVim

Like many, I have MacVim installed through Homebrew Cask. When I first started using MacVim, I had to change the font to a powerline supported font so that my Airline looks spiffy.

To do that I went to Edit -> Font -> Show Fonts and selected a font.

Unfortunately this setting gets wiped out with each update of MacVim, and since it updates often, which is great, having to set the font over and over is not.

To have your font setting persisted in MacVim add this to your .gvimrc:

set guifont=Source\ Code\ Pro\ for\ Powerline:h24

You can set what ever font you like, just make sure to escape the spaces with a slash.

To get powerline (and Airline) patched fonts go here: https://github.com/powerline/fonts

List Your Leader Vim Mappings

Mapping your Vim leader is a great way to customize Vim without clobbering keys that are already mapped. By default your Vim leader is \, but you can change it to another key - many people suggest , since it's so easy to type but I just use the default.

In any event, if you want to add a leader mapping how can you be sure that it's not already taken??

Easy, try this:

:map <leader>

Behold - a list of all mappings that involve your leader key.

Vim Asterisk Search 🔎

My favorite thing about Vim is how deep it goes. I learn new things every day, even after several years of daily use. Asterisk (*) search was one such example from this week.

Typing * over any word initiates a search of the current buffer for the next instance of that word. It actually transfers the folllowing into the command bar, with word boundaries included (hovering over the word foo):

/\<foo\>

This is vanilla Vim, from the patterns library.

Chaining Vim Commands ⛓

You can chain Vim commands together using |. Here's an example:

:help fugitive | resize 10

This will open the help page for Vim-Fugitive, and then resize the current window.

Here's some real-life code I execute frequently:

:Gread | w

This empties the buffer and reads it at the last git revision, then writes the file. Very useful for rapid experimentation.

See :help :bar for more information.

Move to column in Vim

Jumping to a specific line in Vim is something I do all the time:

10G
# move to line number 10

In the last couple days I've wanted to jump to a specific character in a line. I did a quick Google search and found that you use pipe:

10|
# move to character number 10 in your current line

I wondered if there was anything else to know, so I hit the help file:

:he |

Which gives you:

To screen column [count] in the current line. exclusive motion. Ceci n'est pas une pipe.

And I was like, whaaa? A little more Googling and I found this:

https://en.wikipedia.org/wiki/The_Treachery_of_Images

And that there is a list of Vim help easter eggs:

http://vim.wikia.com/wiki/Best_Vim_Tips#Easter_eggs

It was like a TIL three-for-one!!

From VIM to Tmux

There's a really good plugin tslime for sending text from VIM to another Tmux session/window/pane. In addition, sometimes it's super useful to map short cuts like this:

:vmap <buffer> \t <Plug>SendSelectionToTmux

In this example I'm mapping \t for sending all visual selected text in VIM to Tmux.

Check this out:

tmux

h/t @joshuadavey

Vim collapse/expand code

Today I learned to collapse/expand code in VIM using the indent fold strategy.

To enable that we need to set foldmethod:

set foldmethod=indent
set foldlevel=5

To toggle code collapse/expand just use: za.

Disable a pathogen plugin

Let's say I got this plugin that's just messing my editor up all day and I want to disable it. Because pathogen just looks at the plugins dir and loads whatever is there I can't just remove it from a manifest (or something similar).

There IS though a cool global vimscript var called g:pathogen_disabled that can be populated with all the vimscripts you'd like to disable.

It must be declared and populated before the call to pathogen#infect

let g:pathogen_disabled = []
call add(g:pathogen_disabled, 'vim-badplugin')
call pathogen#infect()

There ya go! Now vim-badplugin will not be included by pathogen!

Project Specific VIM Configuration

I learned that if you want to have a project specific .vimrc file you first need to enable it:

" ~/.vimrc
set exrc

And then you can create your specific project .vimrc file configuration in the root of your project folder.

When enabling exrc you should also consider to set secure flag as well (h/t @ali_aliev).

Vim undo tree

Vim has an undo tree and there's two different ways to iterate with your changes.

One way to undo/redo changes is with: u and <Ctrl>r. This moves the current state based on the current branch in the tree.

The other way is using g- and g+. In this case it moves based on the timestamp of that change.

So here's an example to follow:

  1. add a line: added_line_1
  2. update this line: updated_line_1
  3. undo this change: u
  4. add another line: added_line_2

If you run through these steps your undo tree will be something like:

 o  [3] "added_line_2" <= "current_state"
 | *  [2] "updated_line_1"
 |/
 *  [1] "added_line_1"
 *  [0] "empty_file"

Now, if you undo with u will be in this state:

 *  [3] "added_line_2"
 | *  [2] "updated_line_1"
 |/
 o  [1] "added_line_1" <= "current_state"
 *  [0] "empty_file"

Otherwise if you undo with g- will be in this part of the tree:

 *  [3] "added_line_2"
 | o  [2] "updated_line_1" <= "current_state"
 |/
 *  [1] "added_line_1"
 *  [0] "empty_file"

You can check gundo vim plugin for tree visualization.

Vim Regex Word Boundaries

Today while writing a Vim regex to change every instance of it (ignoring larger matches like itemized), we stumbled upon Vim regex word boundary matching.

Given this file:

foo
foobar

The following Vim regex will match on both the first and second line:

:%s/foo/baz/g

But with word boundaries, we'll only match (and change) the first line, because only the first foo is a standalone word:

:%s/\<foo\>/baz/g

Remove both scrollbars from MacVim

If you use MacVim you may encounter the gray Mac OS scrollbar on the right side.

When you split the window you may encounter two scrollbars, one on each side.

I find that to ruin the look of MacVim, especially with a dark colorscheme (I use Dracula).

example

To remove only the left one use

set guioptions=r

This will tell vim to always show the right scrollbar only. To remove only the right one use

set guioptions=l

To remove all scrollbars, remove everything after the equal sign viml set guioptions=

example

Add this to your vimrc for a consistent experience.

Turn on mouse in newer versions of Vim

In newer versions of Vim, set mouse=a lets you use the mouse for moving the cursor, copy/paste, etc.

Toggle CursorLine, CursorColumn w/Vim Unimpaired

Vim Unimpaired plugin by Tim Pope ships with a shortcut for quickly toggling CursorLine and CursorColumn. This is particularly useful on large files with plenty of syntax highlighting.

Turning CursorLine/CursorColumn off can speed buffer navigation by reducing the blocks being re-rendered on the screen, making Vim snappy again.

To use this shortcut type cox from NORMAL mode and Vim will toggle CursorLine and CursorColumn on and off.

h/t Chris Erin

DEMO: demo

Non-Greedy Vim Regex

Regex is by default greedy, meaning, if you used this regex /.*, on the following line:

a123,b123,c123,d123

You'd match everything up to the last comma a123,b123,c123. If you just want everything to the first comma you need to use a non-greedy matcher. In posix regex you could modify the * operator (match 0 or more) with the ? operator, like this: /.*?,/.

Vim however is a bit weird and doesn't support making the * operator non-greedy in this manner. You can however use curly braces to tell vim to match 0 or more, but as few as possible like this: /.\{-}, which will match just a123,.

Remember, the leading curly needs to be escaped with a slash \.

See :help pattern-overview for more!

Rotate Everything By 13 Letters

For some inane reason, Vim comes with a ROT-13 feature. So, if you are ever in need of rotating the letters of some portion of the file by 13, you can do that with the simple g? binding.

For example, if you hit g?? on the following line:

Six dollar eggs

you will get

Fvk qbyyne rttf

As you can see, casing is preserved.

The only practical uses of this are Vimgolf and convincing people at coffee shops that you are a hacker.

See :h g? for more details.

Show Matching Entries For Help

Looking up things with Vim's :help command can be error prone if you don't know exactly how to format what you are looking up. Bypass some of the guesswork by hitting Ctrl-d after writing part of the :help command. This will populate a wildmenu of possible matches.

For instance, if you know there is a command containing ?, but you aren't sure how to look it up, try the following:

:help ?<Ctrl-d>

You can tab through to the one you want and hit enter to read up on it. Who knew there were so many Vim bindings involving a ?.

See :h help-context for more details.

Reset Target tslime Pane

The combination of tslime and turbux makes running tests from Vim in a tmux session as easy as a single key binding. One problem that can arise from time to time is having tslime focused on an undesired tmux window/pane combination. There is no binding to tell tslime that you'd like to re-select the target window and pane.

I've often resorted to closing out of Vim in order to reset the prompt. There is a better way and it doesn't require you to wipe out your Vim session.

Just unlet the global Vim variable for the tslime plugin like so:

:unlet g:tslime

The next time you invoke turbux it will see that g:tslime isn't set and will prompt you for a new window and pane combination.

h/t Josh Davey

Open Multiple Tabs with Vim

I like to use Vim to open many files at once. Today I discovered the -p flag to help with this process.

To open all the files in a directory in tab mode, use this command:

$ vim -p path/to/files/*

-o does the same thing in horizontal splits; -O in vertical splits.

When you're finished reading, :qall is a nice way to close the book.

Share Highlighted Code

Today I learned a cool trick.

Select a range of code, enter command mode, and type Gbrowse:

:'<,'>Gbrowse

This opens Github in your browser with the range of code highlighted. Github support seems to be standard; I believe you can add other code hosting providers.

Here's a link I made with this command:

https://github.com/hashrocket/hr-til/blob/1bc38b724bb620b1672a9f525a4450f6d4f68b3c/app/controllers/sessions_controller.rb#L15-L18

This also accepts a line number:

:10 Gbrowse

Window to Tab

Sometimes I like to use Windows in Vim, and sometimes tabs. But switching from windows to tabs? That's pretty smooth.

If you have a bunch of windows open, CTRL-W_T moves the current window to a new tab.

Check out :help CTRL-W for a crazy list of similar Vim power tools.

h/t Brian Dunn

Open a URL from Vim

If you have Vim and Netrw, you can open a URL in your browser of choice, right from the editor.

Place the cursor on the URL and type gx.

This will invoke your file handler; open for OSX. As a result, it also works with file types such as images, GIFs, and videos.

Move a File with Netrw

Today I tried to move a file into a subdirectory using only Netrw commands, and it kind of worked.

Here's my abridged Netrw window as an example:

ilike-for-case-insensitive-data/
intro-to-hstore/
lateral-joins/
lateral_joins.md

My goal was to move the lateral_joins.md file into the lateral-joins/ directory.

First, I placed the cursor over the target directory and entered mt. This makes that directory the 'markfile target'.

Next, I moved the cursor over the markdown file, and entered mf to mark the file, followed by mc to copy the file to the marked target directory.

Finally, I deleted the original file with D.

Since this was a little confusing, I tracked my changes with watch git status running in a separate Tmux window. I haven't found a way to do this as a straight-up move.

Read command line output into buffer

Sometimes you need some information from outside of vim in your vim buffer. A list of all the models in rails perhaps?

:read !ls app/models

Anything to the right of the bang(!) will be executed via the shell and everything given to standard out by the program will be read into the buffer.

Your own vim <leader> key in a pairing situation

Leader keys in Vim let you set up powerful and easy to access shortcuts for commands you use often.

For example I use <leader>vr to open my .vimrc in a split. That looks something like this:

nnoremap <leader>vr :vsp $MYVIMRC<cr>

I also use it to edit my vim bundles which are managed using the amazing vim-plug:

nnoremap <leader>vb :vsp ~/.vimrc.bundles<cr>

Finally, after making changes to both I need to source my vimrc:

nnoremap <leader>so :source $MYVIMRC<cr>

This allows for quick iteration on my vim configuration.

In a pair scenario though I cannot use my own configuration and more often than not the differences can be problematic for my muscle memory. For example at Hashrocket we use the \ key as leader.

In my personal vim setup I have <space> setup as the leader key. I find it to be more ergonomic and easier to access since I can slam it with either thumb.

Since there can only be one leader key you might need to add a leader alias. That can be done simply by adding this:

nmap <space> \

Remember not to use nnoremap if you wan this to work.

Blank Lines Above And Below

Generally when I want to add a line above or below the line that the cursor is on, I use O and o, respectively. This has a couple potential drawbacks. First and most prominent, the cursor is moved to the new line and left in insert mode. Usually, I'd like to remain in normal mode and stay on the current line. Second, these commands will emulate indentation and other formatting rules. This is either exactly what you want or a bit of an annoyance.

The vim-unimpaired plugin provides an alternative worth adding to your toolbelt. By hitting [<space> and ]<space>, a new line will be opened above and below the current line, respectively. Additionally, it leaves you in normal mode, keeps the cursor on the current line, and moves the cursor to the first non-indented character. In the case of performing this command in the midst of a comment in a source code file, neither the indentation nor the comment character will be propagated onto the new line.

Hold on to O/o and [<space>/]<space> and know the difference. You'll likely need each of them from time to time.

h/t Josh Davey

Use !! to quickly insert result of a bash command

Vim has the ability to read a result of a bash command into the current buffer. This can be done in many ways:

:read !echo "hello world"

To replace the content of the whole file with the result of a command use %!:

:%!cat file_to_copy_from.c

Similarly to replace the current line use . instead of %:

:.!cal

The command above will insert an ascii calendar into your buffer.

Last night I was testing to see what each of the keys in the number row do when used with the Shift key in Vim. One of the most interesting NORMAL mode mappings I found was the bangbang (!!). If pressed it opens the command line with .! and places your cursor right after that.

This allows for quickly bringing in data such as the date when you are working on a blog post.

:.!date

Please tweet at me @dorian_escplan and @hashrockettil if you find other interesting uses for it.

Access Last Executed Vim Macro

I love Vim macros. They can be a huge time-saver.

Today I learned a new way to access them: @@.

We can access any macro with @<letter>, where <letter> is the macro you've assigned.

@@ accesses your last executed macro. This is useful when you have assigned multiple macros.

h/t David Colgan

Setting Filetype With Modelines

Vim and various plugins generally use known file extensions to determine the filetype of a file. This is important because it is how Vim decides which filetype-specific settings to enable, such as syntax highlighting.

If I am editing a file such as build.boot, Vim is not going to know that its filetype should be set to clojure. The build.boot file is full of clojure code though, so I'm losing out on syntax highlighting and so forth. I can settle for manually setting the filetype to clojure (e.g. :set ft=clojure) each time I open up the file.

Or I can use a modeline setting. By including a comment at the top or bottom of the file specifying the filetype setting, I can ensure that each time I go to edit the file, the appropriate filetype will be set.

That modeline comment will look something like:

; vim: set ft=clojure:

See :h modeline for more details.

h/t Brian Dunn

Vim Spelling Suggestions

Vim makes finding misspellings easy, with this command:

:set spell

You may need to adjust your color scheme to read the highlighted words. I like 'ron' for this purpose.

Once Vim has highlighted a typo, what then? What is the correct spelling?

Put your cursor over the word, and type z= for a list of suggestions. You can replace the word with the index number of your choice:

Change "tryin" to:
 1 "Tryin"
 2 "Trying"
 3 "Train"
 4 "Try in"
 5 "Tr yin"

h/t Dorian Karter

Allow j and k to work on visual lines

Wrapped lines in Vim can be challenging at times. Try to move up or down in a perceived paragraph and instead of moving one line down/up you move to one of the ends of the paragraph.

To solve this you might be using gj and gk, but that slows your navigation considerably.

To allow vim to navigate between wrapped lines (visual lines) more naturally, as if they where hard lines, you can add the following mappings to your vimrc:

nnoremap k gk
nnoremap j gj

Now when you press j or k the cursor will move where you really intended for it to move. Normal j and k will still work as intended.

Write into a protected file without reopening Vim

If you ever worked on an SSH session on a remote machine and tried to edit a file that requires super user permissions you might be familiar with the following scenario:

  1. You open the file in vim (e.g. nginx.conf)
  2. You make a few changes, potentially many
  3. You are happy with the result and run the write command :w
  4. You get an error saying that the file is readonly or that you don't have permissions to write to it
  5. Now you are scrambling to copy all your changes and save them somewhere else
  6. Then you re-open the file with sudo vim ... paste your changes and save. Hopefully everything went smoothly and you did not lose your changes.

No more! Next time this happens try this:

:w !sudo tee %

I hope it saves you some frustration.

Vim tree view mode

In folder/file structure if you type i you'll change the way you see the folders and files.

There are 4 different view modes and one of them is something like that:

../
my-app/
| app/
| bin/
| config/
| | environments/
| | | development.rb
| | | production.rb
| | | test.rb
| | initializers/
| | locales/
| | application.rb
| | boot.rb
| | database.yml
| | environment.rb
| | routes.rb
| db/

So yes, We don't need nerdtree

Vim add text surrounding

So you have in vim one line with: Hello World!.

You can add <b> and </b> surrounding Hello by typing on normal mode:

ysiw<b>
# from: Hello World!
#   to: <b>Hello</b> World!

For the whole line:

yss<b>
# from: Hello World!
#   to: <b>Hello World!</b>

You'll need vim-surround plugin

Move current VIM pane to a new tab

To move the current a VIM pane to a new tab:

<Ctrl>wT

Indent and de-indent line in INSERT MODE

While in insert mode it is possible to indent the current line while maintaining cursor position:

Ctrl+t - will indent the line in
Ctrl-d - will de-indent the line

Super useful.

Read In The Contents Of A Rails File

The rails.vim plugin allows you to quickly navigate to specific types of files with the E prefix. For instance, :Emodel will scope you to just the models directory.

You can use this same approach with the D prefix. Instead of navigating to the specified file though, this will read in the contents of that file into the current buffer.

Do you need to copy and tweak the contents of a similar view? Open up your new view file (e.g. :Eview posts/edit.html.erb) and then enter :Dview posts/new to quickly copy in its contents.

h/t Josh Davey

App-Wide Search-Replace in Vim

1) In command-line mode, load all desired files into your argument list (arglist)

:args `git grep -l <string>`

where <string> is the string you want to replace.

2) Run a global search-replace across all the files in your arglist

:argdo %s/<string>/<replacement>/gce | update

Note:

  • Search-replace flags:

    • g[lobal]: replace all matches
    • c[onfirm]: ask for confirmation before replacing
    • e[rror]: don't halt operation at errors
  • update saves each file after the replacement is made.

  • The search-replace will only apply to files checked into your git history. Be sure to commit the files you want searched before attempting this.

Vim Configuration Files by Directory

I have Vim line numbers enabled (:set nu) as a default, but I was working on a project recently where the line numbers weren't helpful. I wanted to disable them in that directory only, without changing my default setting.

One way to do this is to enable a local Vim configuration file. Here's how you do that:

" ~/.vimrc
set exrc

This enables the reading of .vimrc in the current directory.

Caveat: you should also add the following:

" ~/.vimrc
set secure

When this setting is enabled, :autocmd, shell, and write commands are not allowed in your local .vimrc.

Enabling local Vim configurations give a lot of power to any local configuration file. For instance, you could clone a Git repo with a checked-in .vimrc, and if you open Vim in that directory, any commands in that configuration will be executed. Use with caution.

More info:

:help 'exrc'
:help 'secure'

h/t Josh Branchaud

Auto Complete with vim snippets

There is a vim plugin called vim-snipmate that lets to auto complete a bunch of code for you. So you type some snippet trigger and hit <tab> and that's it.

Also there is another vim plugin vim-snippets with a lot of snippets for a lot of languages or file types.

For example this snippet for if in shell files:

snippet if
    if [[ ${1:condition} ]]; then
        ${0:#statements}
    fi

reference

Repeatable operations on search matches with gn

When you find yourself having to operate on a certain string, you may first search for it:

:/ReentrantLock

To change it you will usually use a repeatable operation such as ciw followed by whatever you are changing it to.

Now to repeat that change you will first jump to the next search result using n then press the . operator to repeat the change. But if you know that you are going to do that there's an easier way:

Instead of ciw use cgn. Then just press the . and Vim will jump to the next match and change it for you.

According to Vim's help:

gn - Searches forward for the last used search pattern, like with n, and starts Visual mode to select the match.

for more info:

:h gn
or 
:h gN (for searching backwards)

Note: this also works with * which searches for the word currently under the cursor.

Get Vim Help for Current Word

Some Vim users may be familiar with K, which runs a program to lookup the keyword under the cursor. If not, try typing K over puts and watch the magic happen.

I wanted the same functionality for Vimscript keywords, so I added this mapping to my ~/.vimrc:

nnoremap <F1> :help <C-r><C-w><CR>

This maps F1 (or your key of choice) to, basically, run 'help' followed by whatever word is under the cursor, in normal mode. After sourcing your configuration file, you can try it on nnoremap— you should see the corresponding help page from map.txt.

Vim Cursorline

Yesterday I learned that Vim has a feature called the Cursorline.

Cursorline highlights the screen column of the cursor. It's useful for reading dense code like raw SQL or minified anything. It will also make screen redrawing slower.

Activate this feature with :set cursorline or :set cul. Deactivate with :set nocursorline or :set nocul. As with anything Vim, you can add it to your ~/.vimrc if you want to have it on by default.

vim-unimpaired gives us a mapping for this. [oc turns it on; ]oc turns it off.

See :help cul for the Vim feature, and :help [oc for the plugin.

Copy some line at current position

Say I want to paste line 20 onto my current cursor position: :20co.

Say I'm on line 10 and I want to paste 20 UNDER line 10 :20co10

Choose Your Own RSpec Command

We use vim-turbux to quickly iterate on Ruby tests. But we hit an issue setting up a project on Ubuntu 14.014 that had not been developed in a Linux environment before— Webkit tests there require the Xvfb library. Leaving out the xvfb-run wrapper raises a connection error in test.

Luckily, you can customize vim-turbux commands for each test framework.

Add this to your ~/.vimrc.local:

" ~/.vimrc.local
let g:turbux_command_rspec  = 'xvfb-run -a rspec'

Any RSpec test sent to the terminal window now includes the wrapper library.

Documentation

h/t Dorian Karter, Chris Erin, and Josh Davey

Vim arglist => replace text to multiple files

  • :arg => list files in arglist
  • :argdelete * => clean arglist
  • :argadd **/*.rb => add files to arglist
  • :argdo %s/foo/bar/gc => replace foo by bar in arglist
  • :argdo update => save changes to arglist
  • :argdo undo => undo changes to arglist

Navigation in arglist

  • [a => go to the previous file in arglist
  • ]a => go to the next file in arglist
  • [A => go to the first file in arglist
  • ]A => go to the last file in arglist

Vim Registers and Macros

Vim Macros and yanked texts are actually stored in the same Vim Registers.

So you can do crazy things like record a macro and paste it. Or copy (yank) a piece of code and play it as a macro.

It seems that this does not ever makes sense to mix them, but it's crazy!

Toggle Vim Syntax Highlighting

Something I found memorable about Steve Klabnik's Ancient City Ruby 2016 talk was the Vim slides. He did something on-the-fly that caught my attention: disabling Vim syntax highlighting.

Syntax highlighting is useful. As Vim users we try to always have it— when I'm learning a new programming language, one of the first things I do is install the corresponding Vim plugin. It makes my code easier to read and write.

But sometimes it works against you. Code on a projector, code in certain languages, or code that exposes a highlighting edge case or bug in your Vim plugin, may require a different (monochrome) perspective.

:syntax off and :syntax on is all it takes.

See :help syntax for more information.

Vim registers

When copy/cut some code you are already using registers. To see them:

:registers

Or simply :reg

You can also define which one to use, including any letter.

For example, to copy the current line and store it into the register T:

"Tyy

in order to paste it:

"Tp

Use Active Window With BufExplorer

I often use BufExplorer within long-running Vim sessions as a way of quickly jumping between the various buffers in my buffer list. After working with one buffer, I use <leader>bs to open BufExplorer, move my cursor to the next buffer of interest, and hit enter to open it in place of the current buffer. This is the default behavior at least.

With this setting toggled on, BufExplorer will open buffers in the active window. The active window is the window that was active before BufExplorer was opened. If this setting is toggled off, BufExplorer doesn't bother finding the active window, it just opens the buffer up in place of itself in whatever split window was created for itself.

This setting can be toggled within the BufExplorer window by hitting f. It will toggle between Locate Buffer and Don't Locate Buffer. I prefer the default of Locate Buffer.

h/t Vidal Ekechukwu

Load A Directory Of Files Into The Buffer List

Consider the scenario where I want to go through all files in a directory to make a series of minor, related changes. After editing each file, I can type something like :e path/to/next/file.md to bring up the next file. That can get a bit tedious though. Instead, I can load up all the files in the directory with the args command:

:args path/to/files/*.md

From there, I can use :bnext (or :bn) and:bprev` to more quickly jump through those files I want to edit.

I can also run :ls to see all the files loaded in to the buffer list at that point.

source

Vim increment time

<C-a> and <C-x> will increase and decrease a digit, but it will also do the same for a time string. Using <C-a> on "11:00 AM" will change it to "12:00 PM".

Edit: This is actually a feature of @tpope 's speeddating plugin.

View a File In Another Git Snapshot

Have you ever wondered: 'what does this file look like on the master branch?' vim-fugitive to the rescue.

This command will open our Gemfile as it exists on the master branch:

:Gedit master:Gemfile

And the same file, in the HR-TIL repo, initial commit:

:Gedit b4da33:Gemfile

This also works with tags, and includes split, vertical split, and tab variations— I like :Gsplit the best.

Install vim-fugitive and see :help Gedit for more information.

Word Count in Vim

Vim has a built in shortcut for counting words. To see the word count for the whole buffer type:

g<CTRL-g>

You will see something like:

Col 11 of 54; Line 12 of 24; Word 39 of 68; Byte 360 of 727

Meaning we are currently at word 39 and the whole buffer contains 68 words.

To see the word count for a selection, first select and type the same shortcut g<CTRL-g> the result should look something like this:

Selected 7 of 24 Lines; 23 of 68 Words; 234 of 727 Bytes

in this case I have selected 23 words.

Jump to cucumber step definitions in VIM

There is an amazing vim plugin vim-cucumber that allows you to jump from step (.feature file) to its definition (_steps.rb file).

In vim normal mode put the cursor on any step inside a .feature file and:

  • [d or ]d => split pane
  • <CTRL-w><CTRL-d> => split pane and change cursor focus
  • [<CTRL-d> or ]<CTRL-d> => replace pane

h/t @mrmicahcooper

Vim writethrough

R in normal mode lets you write through existing text, so you don't have to delete it first.

VIM Insert in paste mode

We can copy a text from anywhere and paste into vim using the insert mode with the paste option by just typing: yo or yO:

yo
<paste>

this is equivalent to:

:set paste
o
<paste>
:set nopaste

Next/Previous item in quick fix list

Use [q to go to the previous file in the quickfix list, ]q for the next

Vim next/previous file

You can go to the next file in vim with ]f, or [f for the previous.

Use colorcolumn to visualize maximum line length

With the large screen real estate we get nowadays, its hard to recognize when your code's line length is getting out of control. You can use auto word wrapping (:set textwidth=n) or some other restrictive method. However I just want to visually see where the break is:

:set colorcolumn=80

This adds a nifty highlight line at 80 characters that I can use as a reference.

h/t Vinicius Negrisolo

Rails Server in Vim

With the help of Rails.vim, we can start a Rails server without leaving our Vim session.

This starts a server, with the standard optional arguments:

:Rserver {options}

Adding a ! will kill the pid found in 'tmp/pids/server.pid', and then invoke :Rserver. Powerful!

See :help Rserver with Rails.vim installed for more information.

h/t Paul Haddad

Open Vim To A Tag Definition

If you are using ctags with Vim, you can provide a tag name when opening Vim. This signals to Vim that it should open to the file and location of the tag's definition. For instance, if you have a Rails project going and you provide Vim with the UsersController tag name, it will open the app/controllers/users_controller.rb. Just use the -t flag like so:

$ vim -t UsersController

See man vim for more details.

Replace text in VIM and keep the case

If you use the vim plugin vim-abolish you can replace some text keeping the original case. You just need to use S instead of s in find/replace vim command.

In order to change foo to bar and keep the case use:

:%S/foo/bar/gi

This will apply the following changes:

FOO => BAR
foo => bar
Foo => Bar

Open The Latest Rails Migration

The rails.vim plugin comes with a lot of handy helpers for quickly navigating to many parts of a Rails project. Among these helpers is the :Emigration command that makes it easy to tab complete and navigate to Rails migration files. Often times the migration you want is the latest migration. There is no need for tab complete here, just type:

:Emigration

By default this command opens the latest migration in a new buffer.

See :h rails-:Emigration for more details.

Use Vim counts for small arithematic calculations

In CSS land you often need to increment/decrement a pixel value. You can use <C-a> for incrementing and <C-x> for decrementing value but what if you want to move faster or increment by a specific number?

Counts for the rescue!

Every motion in vim can be preceded by a count, and as it turns out so does increment/decrement:

body {
  height: 1827px;
}

Say I want to increment the padding by 344. I can either:

  • replace the 1827 with 2171 after using my calculator.
  • Press <C-a> 344 times
  • Or alternatively 344<C-a>

You can also set a mapping to increment/decrement by 10.

Credit: Practical Vim by Drew Neil

Open A Tag In A Split Window

Using tags and ctrl-] is a quick way to jump from the use of a keyword to the declaration or definition whether in the same file or another file. Sometimes what you really want is that tag definition opened up in a (horizontal) split window. That way you can see the definition without losing context. This can be accomplished with ctrl-w ].

The Vim help file gives the following definition of this command:

Use identifier under cursor as a tag and jump to it in the new upper window.

See :h CTRL-W_] for more details.

h/t Dorian Karter

Add highlighted code from #Vim to #Apple #Keynote

Giving a talk with keynote? If you're like me and you love Vim and Apple Keynote you might struggle with getting your highlighted, indented code over to Keynote and making it look as good as it looks in Vim.

Fret no more - vim-copy-as-rtf is a plugin that will let you do that without installing any additional libraries on your mac.

Simply select the code snippet, type :CopyRTF and the highlighted code will be copied to your clipboard ready to be pasted into Keynote. That simple.

Get it here: https://github.com/zerowidth/vim-copy-as-rtf

Next file or next search result in Vim

We can jump to next file just typing:

  • ]f => go to next file in the same folder, or next folder
  • [f => go to previous file in the same folder, or previous folder

We can also jump to next search results, for example after a :grep my-search-text .

  • ]q => go to next search result
  • [q => go to previous search result

Running same Vim command into multiple lines

We can run the same vim command for multiple lines using the norm, like:

:%norm cs'"

This will replace every single quote with double quote:

  • % => for every line
  • norm => repeat the following command in normal mode
  • c => change
  • s => surround
  • ' => delimiter char, in this case single quote
  • " => replaced char, in this case double quote

Interact With The Alternate File

If you have a couple buffers going in a Vim session and you check out the buffer list with :ls, you'll notice that one of those buffers has a # indicator next to it. That means the file for this buffer is considered the alternate file of the current, visible buffer. In addition to hitting CTRL-^ to switch to that buffer, you can reference it in other commands with #. This means you can quickly :edit, :split, :vsplit, and so forth the alternate file by just giving # as the argument to those commands.

Quickly open the alternate file in a vertical split with:

:vsp #

See :h alternate-file for more details.

Close All Other Windows

Opening split windows can be useful in a number of circumstances. Eventually though, you are going to want to go back to just one window. Generally when this happens to me, I navigate to each of the other split windows that I don't want and execute :q. What I want to do is essentially close all the other split windows except for my current one. Vim provides a single command for doing this. By hitting

<CTRL>w <CTRL>o

all other windows are closed leaving the current window as the only one on the screen.

If you want this command to be able to work with windows containing modified buffers, you are going to want to have the hidden option turned on.

See :h CTRL-W_CTRL-O for more details.

Delete To The End Of The Line

There are a number of ways to delete from the cursor position to the end of the line. Generally when I am doing this, I want delete to the end of the line and then start typing something different. Perhaps the best way to do this is by hitting C. It deletes to the end of the line and then leaves you in insert mode. This also makes for easier repetition with the dot command.

This is synonymous with hitting c$.

See :h C for more details.

h/t Dorian Karter

Tabularize in VIM - changing whitespaces count

In order to tabularize texts based on comma character use the tabular vim plugin:

:Tabularize /,

This will by default add at least 1 whitespace to the left and exactly 1 whitespace to the right.

You can change this adding /l<NUM>r<NUM> to the end of command.

For 0 to the left and 1 to the right:

:Tabularize /,/l0r1

example:

# original
resources :posts, path: 'blog_posts', only: [:index, :show, :create]
resources :comments, path: 'user_comments', only: [:index, :show]

# :Tabularize /,
resources :posts    , path: 'blog_posts'    , only: [:index , :show  , :create]
resources :comments , path: 'user_comments' , only: [:index , :show]

# :Tabularize /,/l0r1
resources :posts   , path: 'blog_posts'   , only: [:index, :show , :create]
resources :comments, path: 'user_comments', only: [:index, :show]

reference

gcc comments the code

I've been using the vim-commentary plugin for years but always by selecting a line and THEN using gc to turn the line into a language specific comment. Selecting the line isn't necessary though, you can just use gcc and the line the cursor is on will either be turned into a comment or if its a comment already it'll be uncommented.

Rails vim navigation for lib

Y'all might be familiar with :Emodel, :Econtroller, and :Eview but today I learned that there is a vim rails navigation for :Elib.

The command :Elib xyz! creates a vim buffer and file at path lib/xyz.rb.

Almost The End Of The Line

If you are visually selecting from the cursor to the end of the line, you will probably hit:

v$

This isn't always ideal though because the visual selection includes the newline character at the end of the line. If instead you'd like to motion to the last non-blank character on the line you can use the g_ motion. This is great for deleting to the end of the line.

dg_

See :h g_ for more details.

h/t Dorian Karter

Persistent folds between Vim sessions

Folds are great. They help you when you have to deal with big files where compartmentalizing the logic might be of help.

The problem is that when you close Vim, your artfully folded code returns to its unfolded state.

The solution is quite simple - when you are ready to save your folds run the :mkview command. This will save your folds in the current buffer to your viewdir (:h viewdir) depending on your environment.

To load your folds use :loadview.

To automate this process add the following to your vimrc:

augroup AutoSaveFolds
  autocmd!
  autocmd BufWinLeave * mkview
  autocmd BufWinEnter * silent loadview
augroup END

The folds will be local to your machine, but if you want you can configure mkview to save folds to a file in your project directory and share them with your team.

Deleting Buffers In BufExplorer

The BufExplorer plugin makes it easy to browse and navigate to the various buffers open in a Vim session. It is based on your buffer list. After a bit of coding, your buffer list can start to get a bit out of control. There are surely going to be buffers that you want to close out, delete if you will.

Within the BufExplorer browser you can move your cursor onto a buffer and delete it.

To delete it by unloading the buffer (see :h bd), you can hit d.

To delete it by wiping out the buffer (see :h bw), you can hit D.

If you already have the plugin installed, see :h bufexplorer for more details.

Switch direction of selection in Vim

Switch the free end of the cursor in Vim's VISUAL MODE.

Simply press o while selecting and the free end will go to the beginning of your selection.

screenshot

Go to file under the cursor in Vim

Let's say in a file you reference another one, requiring that code. Vim has an very easy way to open the required (imported, loaded, etc) file. Great tip for adding external dependencies code.

Put the cursor in the file name you want to open and:

gf

If you want to go back: <Ctrl> o.

To find the file Vim uses an option called path, and you can check your current path with:

:set path

So if you expect a file is not being found you can check the path and add values to it.

:set path+=some_special_folder/

Finally, as Vim looks for a lot of paths, it may find more than one, and gf will bring the first one. To get the second match, type g2f, for the third g3f and so on.

Also, check this article to restrict Vim options by file extensions and to add file suffixes.

Use suffixadd to save yourself some life

I've been wasting a lot of my time trying to find certain backbone files lately (yes I know, coffeescript blehg).

define [
  'hbs!templates/my_template'
  'views/my_view'
], (
  Template
  MyView
) ->

I'd like to just go to the template line and type gf

So vfnegrisolo helped me out and added the following to my .vimrc.local:

autocmd BufRead,BufNewFile *.coffee set path+=app/assets/javascripts/app/

Which in coffeescript files adds the location of my backbone app. Which is great, but for some reason it wasn't working on one of our dev machines. Luckily, with some quick googling, we were able to get to the bottom of it with suffixadd!

autocmd BufRead,BufNewFile *.coffee set suffixesadd+=.coffee,.hbs

Which searches the path with the suffix added to the search criteria as well. Which has already saved me soooo much time! Yay!!!

Quick Pane Splitting

Usually I type :split or :vsplit to split my panes in Vim.

Little did I know before now; you can use Ctrl-w s and Ctrl-w v respectively.

Saves a few keystrokes :)

Vim macro is amazing!

If you want to repeat a bunch of vim commands for running multiple times, record them in a macro and run wherever you want.

To record a macro you need:

  1. type q followed by any char: [a-z]
  2. type your vim commands
  3. type q again to finish recording

Finally, to run the macro that you just created type:

@ followed by the same char you chose to store the macro.

Vim change case of words

If you want to switch the case in Vim:

gu => lowercase

gU => uppercase

g~ => toogle case

You can also combine with Vim motions like:

g~ip => toogle case for the current paragraph.

Find where anything is defined in Vim config

When your vim bundle and vimrc become a plugin soup you often need to debug where an autocmd, command, map or function are coming from.

The :verbose command can come in handy in this scenario. Here are some examples:

See where a mapping was set from:

:verbose map gY

See what happens when you enter a buffer:

:verbose autocmd BufEnter

See which file defined a command:

:verbose command Explore

Where is the abbreviation coming from:

:verbose abbrev bpry

etc...

Example output:

    Name        Args       Address   Complete  Definition
!   Explore     *    0c              dir           call netrw#Explore(<count>,0,0+<bang>0,<q-args>)
        Last set from /usr/local/Cellar/vim/7.4.1190/share/vim/vim74/plugin/netrwPlugin.vim

Happy hunting! 🔫

Browse and repeat Vim commands

If you typed a command in Vim's command line and want to repeat it you can open the command-line window and browse through past commands. There are two ways two do that:

  1. From Normal mode type q:
  2. From the command line after typing a colon press CTRL-f

In the command window you can browse up and down with HJKL and hit return to re-run the command.

Missed an alert message in vim?

If you ever missed an alert message in Vim, you know the ones that show up at the bottom in the command line, you can easily view a list of all past messages by running the :messages command.

You can also add your own using :echom, which adds a persistent message.

Try it now.

NOTE this will only show persistent messages (echom), and not momentary messages set using echo.

Build And Install A Go Program

With the vim-go plugin, Vim gets all kinds of support for working with a Go project. Generally, with a Go project, you have to run go build to compile the project and if that is successful, you can run go install to put the executable binary on the $GOPATH.

This plugin allows you to tighten the feedback loop. You can build right within your Vim session using

:GoBuild

which will alert you to any compilation errors.

You can then install the program using

:GoInstall

Your program is now ready to run.

It's worth noting that this plugin will also notify you about syntax errors when you save, if they exist.

Highlight #markdown fenced code syntax in #Vim

Up until now I was editing all my blog posts in Atom for lack of markdown fenced code block highlighting in Vim. Atom supported it out of the box. As it turns out Vim can do that too, out of the box!

If you are running a recent version of Vim (mine at time of writing 7.4.9910) you can setup highlighting for fenced code blocks in markdown.

Open your .vimrc and add the following line:

let g:markdown_fenced_languages = ['html', 'vim', 'ruby', 'python', 'bash=sh']

You can customize it to your liking and add more languages.

Note: Not all languages are supported but you can try and see if they work. To see a list of languages you have installed on Mac (with Vim installed by Homebrew) run ls -l /usr/local/Cellar/vim/7.4.1190/share/vim/vim74/syntax

screenshot

This is a game changer.

Ruby Text Objects

Today I discovered the amazing Ruby text objects feature of the plugin Vim-ruby.

Vim-ruby give us these four objects:

  • am ('a method')
  • im ('inner method')
  • aM ('a class')
  • iM ('inner class')

These can be composed with d, c, and v to build great editing tools like cim (change inner method) or vaM (select a class).

Breezy copy to system clipboard in Vim

When it's time to get text processed in Vim out of your editor and onto a shiny blog post many Vim Warriors reach for the awkward copy to system register keyboard chord.

"*y[motion]

Worse is trying to copy the whole file:

gg"*yG

This feat of keyboard heroism has crushed many heroes and inflicted countless RSI wounds.

It's time to slay the dragon 🐲 by adding these to your .vimrc:

" copy to system clipboard
map gy "*y
" copy whole file to system clipboard
nmap gY gg"*yG

Pretty Print JSON/HTML in Vim

When working with external APIs often you will get a highly netsted json, like this one, all in one line, with no spaces:

{"batters":{"batter":[{"id":"1003","type":"Blueberry"},{"id":"1004","type":"Devil's Food"}]},"id":"0001","name":"Cake","ppu":0.55,"topping":[{"id":"5002","type":"Glazed"},{"id":"5007","type":"Powdered Sugar"}],"type":"donut"}

The horror. You are not a network cable! You deserve better!

Add the following to your .vimrc file:

command! PrettyPrintJSON %!python -m json.tool
command! PrettyPrintHTML !tidy -mi -html -wrap 0 %
command! PrettyPrintXML !tidy -mi -xml -wrap 0 %

Now you can paste the json into your Vim buffer and run the :PrettyPrintJSON command.

{
    "batters": {
        "batter": [
            {
                "id": "1003",
                "type": "Blueberry"
            },
            {
                "id": "1004",
                "type": "Devil's Food"
            }
        ]
    },
    "id": "0001",
    "name": "Cake",
    "ppu": 0.55,
    "topping": [
        {
            "id": "5002",
            "type": "Glazed"
        },
        {
            "id": "5007",
            "type": "Powdered Sugar"
        }
    ],
    "type": "donut"
}

Magic.

Same goes for HTML, just run :PrettyPrintHTML.

NOTE: For these to work you need to have python and tidy installed on your machine.

Highlighting Search Matches

Want to see all the places in the buffer that match a search pattern? Turn on hlsearch and Vim will highlight all the matches of the previous search.

Try turning it on with :set hlsearch and then search for some pattern using /.

If you no longer want to see all the highlighted matches, turn it off with :set nohlsearch.

See :h hlsearch for more details.

Paste A Register From Insert Mode

Generally pasting a register is done from Normal mode using p or something like '1p (the former pasting from the default register, 0, and the latter pasting from register 1). Vim also allows you to paste from a register without leaving Insert mode. By hitting CTRL-R and then the name of the register, Vim will insert the contents of the register in front of the cursor.

For example, to paste from the default register from Insert mode, hit CTRL-R 0.

Note, mappings and abbreviations will not be applied to the inserted text.

See :h i_CTRL-R for more details.

h/t Chris Erin

Backspace Options

The backspace option determines the behavior of pressing the backspace key (<BS>). By default, Vim's backspace option is set to an empty list. There are three values that can be added that each independently alter the behavior of the backspace key. These are indent, eol, and start.

When indent is included, you can backspace over indentation from autoindent. Without it, Vim will not allow you to backspace over indentation.

When eol is included, you can backspace over an end of line (eol) character. If the cursor is at the first position of a line and you hit backspace, it will essentially be joined with the line above it. Without eol, this won't happen.

When start is included, you can backspace past the position where you started Insert mode. Without start, you can enter Insert mode, type a bit, and then when backspacing, only delete back as far as the start of Insert mode.

The backspace default is absurd, you are going to want to add all of the above to your Vim settings.

See :h 'backspace' for more details.

Breaking The Undo Sequence

Generally, the sequence of undo-able actions is segmented by command. When entering Insert mode, everything typed until exiting Insert mode is part of a single undo-able segment. If you are going to be typing in Insert mode for a while though, you may want to break it up a bit. Without leaving Insert mode, hit ctrl-g u to mark a break in the sequence of undos.

For example, starting in Normal mode and then typing iabc<CTRL-G>udef<CTRL-G>ughi<ESC> will leave the buffer with:

abcdefghi

Hitting u once will leave the buffer with:

abcdef

Hitting u again:

abc

Hitting ctrl-r:

abcdef

See :h i_CTRL-G_u for more details.

Difference Between :wq and :x

The :wq command is used in Vim to write and quit. The contents of the buffer are written to disk for the associated file and then the Vim session is terminated. So, what is the difference between this and the :x command. The Vim help files give the following description of the :x command:

Like :wq, but write only when changes have been made.

So, :wq writes the buffer to disk either way, whereas :x just exits if the buffer hasn't changed. Either way the contents of the resulting file are going to be the same. So what's the difference?

Modification time.

If you :x a buffer that hasn't changed, the modification time will be untouched because the file isn't re-saved. The :wq command will alter the modification time no matter what.

This matters if the modification time is used by anything. For instance, a background process that monitors a directory for changed files based on modification times will get some false positives if you use :wq too liberally.

source

Get help with Pathogen

Today I found a great command in Pathogen.vim, :Helptags. This is a riff off :helptags {dir}, a Vim feature that builds helptags for directory {dir}.

:Helptags does the same for all the directories in your runtimepath, which defaults on Unix and Mac OS X to:

"$HOME/.vim,
$VIM/vimfiles,
$VIMRUNTIME,
$VIM/vimfiles/after,
$HOME/.vim/after"

The use case here is when you've just loaded a new plugin into your Vim bundle, you open up Vim, and :h {my_new_plugin} isn't 'helping' you out.

Change Inner Tag Block

Vim has excellent commands for changing the contents of parentheses (ci(), brackets (ci[), and squiggly braces (ci{) (as well as single quotes, double quotes, backticks, etc.). But what about tags?

Place your cursor anywhere inside the tags, type cit in Visual mode, and this:

<div>Begone</div>

Becomes:

<div></div>

d works too, but I prefer c because it puts you in Insert mode at the end of the opening tag, ready to type.

Check out :h v_it for more information.

h/t Josh Branchaud

Increment and Decrement Numbers

Vim has commands built-in to increment and decrement numbers: CTRL-A and CTRL-X, respectively.

Combining this with a macro was a technique we tried today to build a large database migration. We ended up finding a more efficient solution, but it's still a very magical key combination.

Check out :help CTRL-A for more info.

h/t Josh Branchaud

Override Vim's Filetype

Vim's filetype auto-detection is great for effortless syntax highlighting, but what if a certain kind of file (i.e. Ruby) contains lots of another kind of code (i.e. SQL)? The Ruby code will be highlighted and readable, the SQL a large monochrome blob. Hard to read and reason about. We can do better!

Override the automatic assignment with:

:set ft=sql

This command with no assignment returns the current setting:

:set ft
=> filetype=lua

We can easily revert to the auto-detected extension as needed.

h/t Josh Branchaud

Running Bundle With vim-bundler

The vim-bundler plugin is a companion of the rake.vim and rails.vim plugins. It is a lightweight plugin that exposes some bundler-related convenience methods.

The Vim :Bundle command exposes the bundle command. To install the latest changes to the Gemfile, you can invoke :Bundle or :Bundle install from inside of Vim.

Grepping Through The Vim Help Files

Trying to look up the help file for a Vim feature, but you cannot quite remember the right keyword? Use :helpgrep. With :helpgrep, you can search across all of the Vim help files for not just the specific keywords, but any pattern of text. For instance, if you want to find where substitution is mentioned in the help files, try:

:helpgrep substitution

It makes a list of all occurrences in the quick fix window and then opens up a split with the cursor on the line of the first occurrence. You can then hit :copen to see the rest of the entries.

See :h helpgrep for more details.

Increment All The Numbers

Vim's substitution feature can be used for more than simple static text replacement. Each replacement can be the result of some operation on the original text. For instance, what if we'd like to increment all numbers in the buffer? We can achieve this by searching for all numbers and then using \= with submatch. Whenever the replacement string of a substitution starts with \=, the remainder of the string is evaluated as an expression.

Given the following text in our buffer:

1 2 a b c 45 123 1982

We can run the following substitution command:

:%s/\d\+/\=submatch(0)+1/g

This will transform all digits in the buffer, resulting in:

2 3 a b c 46 124 1983

Want to decrement all the numbers instead?

:%s/\d\+/\=submatch(0)-1/g

See :h sub-replace-expression for more details.

Read a File Into Vim

In a Hashrocket blog post earlier this year I wrote about a command to read a file into your current Vim window:

:.! cat [filename]

A similar idea, from the command line:

$ cat [source_file] >> [target_file]

But with Vim there's always a better way:

:r[ead] [filename]

This command reads [filename] (defaulting to the current file) into in your window.

h/t Dorian Karter

Tmux Copy Mode

Last week we encountered a breaking change in our Tmux configuration, and briefly lost the ability to scroll with the mouse. It became an opportunity to re-learn Tmux's copy mode, and liberate ourselves from the mouse a little more.

Enter copy mode with <prefix> [. From here, you can navigate with standard Vim commands.

ctrl-u moves you a half-page up, perfect for wading through test failure backtraces.

Coercing Casing With vim-abolish

The vim-abolish plugin provides a couple handy shortcuts for quickly coercing the casing of a variable.

For instance, if you have a variable in camel case and you want to change it snake case, you can navigate over the variable and hit crs (e.g. myFavoriteVariable -> my_favorite_variable).

Similarly, you can hit crc to change a variable to camel case.

It even has support for mixed case (crm) and uppercase (cru).

h/t Jake Worth

Make directories with Vim Eunuch

Vim Eunuch has been my go-to Vim plugin this week.

The :Mkdir command is awesome. It's the mkdir you know and love, inside Vim. I find it useful when building a set of Rails views for a brand new controller. No more shelling out to make a directory, just to write my file.

:Mkdir! is even better because it adds the -p flag, creating all intermediate directories as well.

Move a File with Vim Eunuch

Among the many useful commands provided by Vim Eunuch is :Move.

:Move <new directory> renames a buffer and the file on disk simultaneously. It's the mv you know and love, right inside Vim.

Change Vim cursor in different modes

Vim's NORMAL mode and VISUAL mode are complemented perfectly by the block cursor. When in INSERT mode however, you might want a little more precision. That's why changing the cursor to a slim pipe shape is beneficial (you know, like in any textbox on your OS). It is also a nice reminder that you are in VISUAL mode, without having to stare at the bottom of the screen.

While we are at it, you might also want REPLACE mode to have a cursor of it's own, for that an underscore style looks great.

To accomplish this customization add the following to your .vimrc

iTerm2 + Tmux on OS

let &t_SI = "\<Esc>Ptmux;\<Esc>\<Esc>]50;CursorShape=1\x7\<Esc>\\"
let &t_SR = "\<Esc>Ptmux;\<Esc>\<Esc>]50;CursorShape=2\x7\<Esc>\\"
let &t_EI = "\<Esc>Ptmux;\<Esc>\<Esc>]50;CursorShape=0\x7\<Esc>\\" 

iTerm2 on OS

let &t_SI = "\<Esc>]50;CursorShape=1\x7"
let &t_SR = "\<Esc>]50;CursorShape=2\x7"
let &t_EI = "\<Esc>]50;CursorShape=0\x7"

Delete All Lines with Vim

I have a Vim pane I've been filling with throwaway code lately, and wanted to find the most efficient way to wipe it clean from inside Vim:

This is an option I've seen on message boards:

:1,$d

At seven keystrokes, it's pretty good. This is what I've been doing with five keystrokes:

ggdG

Starting on the first line (Vim's default) would make the gg redundant, bringing it down to three keystrokes. That might be the lower limit to how concise this can be, though I'd be glad to see someone do it with less.

Opening Man Pages In Vim

In Quick Man Pages, I explained how you can quickly open man pages with K. For times when the particular command isn't in the buffer or the command contains a hyphen, you can instead use :Man. With the ft-man-plugin enabled, you can use :Man with the name of any command that has a manual page and the respective man page will be opened in a split buffer. For example, check out git log with:

:Man git-log

If you don't want the first manual entry, provide a specific number. For instance, you can open the echo(3) man page with:

:Man 3 echo

See :h :Man for more details.

Creating Non-Existent Directories

When creating new files from within vim, using :e, you may find yourself creating that file in a directory that doesn't yet exist. Vim will tell you as much if you then try to save that file. To get around this, I have often shelled out with :!mkdir %:h. This is a bit awkward to type though.

The vim-eunuch plugin comes with a handy command for this. :Mkdir will create the parent directory for the current buffer. If you're in a situation where multiple levels of the buffer's directory don't exist, you can use :Mkdir! which will invoke mkdir with the -p flag.

Vim startup time profiling

If you want to see why vim is taking so long, you can get a breakdown of how long each plugin took to load:

vim --startuptime startup.log

To make things a little easier, I created the following bash command, which will create the startup log, open it in vim and delete it when done.

vim --startuptime startup.log +qall && vim startup.log && rm startup.log

Graphing the data

You can use vim-plugins-profile shell script to get a better sense of which plugins are causing the biggest slowdown: https://github.com/hyiltiz/vim-plugins-profile

It will create a graph resembling the DevTools network tab: graph

and provide a summary similar to this one:

Generating vim startup profile...    
Parsing vim startup profile...     
Crunching data and generating profile plot ...    

Your plugins startup profile graph is saved     
as `profile.png` under current directory.    

==========================================    
Top 10 Plugins That Slows Down Vim Startup    
==========================================    
   1    105.13  "vim-colorschemes"    
   2    42.661  "vim-easytags"    
   3    31.173  "vim-vendetta"    
   4    22.02   "syntastic"    
   5    13.362  "vim-online-thesaurus"    
   6    7.888   "vim-easymotion"    
   7    6.931   "vim-airline"    
   8    6.608   "YankRing.vim"    
   9    5.266   "nerdcommenter"    
  10    5.017   "delimitMate"    
==========================================    
Done!

Profiling Vim

To find which plugins may be causing certain actions in vim run slowly try using the built in profiler:

:profile start profile.log
:profile func *
:profile file *

Then perform the slow action, when done run:

:profile pause
:q

You can then open the profile.log file and look at the bottom to see summary, sorted by run time, of which functions took the most time, the function name may give away which plugin/core function is causing the issue. The top of the file will contain each line of code that was run in vim during the profiling session and how long it took.

Add A File Without Loading It

Generally, when you interact with files (e.g. :e some-file.txt), you are both adding it to the buffer list and loading the contents of the file as a separate buffer. The :bad command allows you to add a file to the buffer list without loading it. For instance, you can add your README.md to the buffer list and leave the current buffer in focus with:

:bad README.md

This command seems particularly useful for scripting the setup of an initial vim environment or preparing for a :bufdo command.

Reverse A Group Of Lines

The following command can be used to reverse the order of all lines in a file by doing a global move on all lines that match the beginning of line character starting at the theoretical 0th character:

:g/^/m 0

Reversing a range of lines is a little more work. Just as the previous example needs to be anchored against the 0th character, a specific range of lines needs to be anchored at the line just before the range. Thus reversing the lines 5 to 10 requires being anchored at line 4, like so:

:4,10g/^/m 4

See :h 12.4 for more details on how this works.

source

Delete a Line From Another Line

Today I was cleaning up a test with an extra empty line at the top of the file, away from my Vim cursor. I wanted to delete it... without moving the cursor.

It seems like Vim almost lets you do this, with :[range]d. But it leaves the cursor on the deleted line, which isn't very magical.

This is the hack we found:

:[range]d

Then:

''

'' returns the cursor to the last jump point.

h/t Josh Branchaud

Beginning And End Of Previous Change

You can jump to the beginning of the previous change with the [ mark by hitting '[ from normal mode. Similarly, you can jump to the end of the previous change with the ] mark by hitting '].

Text that was just pasted is also considered a change. Thus, hitting '[ and '] will jump to the beginning and end, respectively, of the text that was just pasted into the buffer.

See :h '[ and :h '] for more details.

Center The Cursor

If you've moved the cursor to a particular line towards the top or bottom of the screen, you may want to center the screen on that line. This can be achieved by hitting zz. It is a quick way to center the cursor and ensure that you have an equal amount of context on either side of the line of interest.

Take care to not mistake this for ZZ which will save and quit the buffer.

See :h zz and :h z. for more details.

h/t Chris Erin

Jump To The Next Misspelling

If spelling is turned on (:set spell), you can jump back and forth between words that are misspelled. To jump to the next misspelling, hit ]s. To jump to the previous misspelling, hit [s.

See :h ]s and :h [s for more details.

Add Custom Dictionary Words

When editing a file with spell turned on, you may find vim highlighting some of your content in red. This red highlighting indicates a misspelling. Sure, these words technically aren't going to show up in something like the Merriam-Webster dictionary, but as far as you are concerned, they are words. They are part of your internal, shared language. The word admin is a great example. Why not just tell vim once and for all that such words are valid.

You can do just that by moving your cursor over the misspelled word and hitting zg. That will add it to the spellfile, a list of words, which vim includes in its spell checking. This means vim will no longer highlight that word red.

vim-surround is different for selected text

If you tried using vim-surround after selecting text in visual mode, just to get your text deselected and have nothing happen, it's because visual mode uses a different trigger for vim-surround:

In visual mode use S, followed by your surrounding character (e.g. S)).

This is different from the normal mode way of doing it ys[text-object] (e.g. ysap{)

I like thinking of this one as yes, surround! [my text object] and prefer it to selecting, but some cases require visually selecting.

Delete Every Other Line

You can delete every other line in the current buffer using the following command.

There is a fairly elegant way in vim to delete every other line in the current buffer. Why would you want to do that? I don't know. Nevertheless, here it is:

:g/^/+d

This will essentially delete all even numbered lines. If you'd like to delete all odd numbered lines, delete the first line in the file (ggdd) and then run the same command as above.

This syntax is a bit awkward, so you may be better off going straight for a macro (e.g. qqjddq5@q or qqddjq5@q).

source

Spell check in vim

Don't let typos sneak into production, you can use a spell checker right from Vim. Here's how:

:set spell

To navigate between spelling mistakes use ]s and [s.

To correct spelling mistakes, go to the mistake and use z= to see suggestions.

P.S. if the spelling errors don't show up, make sure to check two things:

  1. That you are not a fantastic speller and a true scholar
  2. That the file type you are checking spell on is allowed (you can test it by setting your syntax to txt :set syntax=txt)

Move Pane to Tab

If you want to close the pane you're working in and open it in a new tab, <ctrl-w>T while in that pane.

Navigating By Blank Lines

Use vim to open a file full of code (or text) that has some blank lines. Move the cursor to the middle of the file. Then start hitting { or }. You'll see that the cursor jumps from blank line to blank line.

Use { to jump to the closest blank line behind the cursor. Use } to jump to the closest blank line ahead of the cursor.

This may not seem like the most practical or obvious way to navigate, but it can help move you around a bit quicker than just tapping k and j.

Browse ruby gem source inside of a vim tab

When you are working with gems you often need to jump to the gem's source. Vim has a really neat trick for that.

First make sure you have the vim-bundler plugin by Tim Pope installed: https://github.com/tpope/vim-bundler. Then you can use the following command:

:Btabedit name_of_gem

💥Boom.

Vim opens the gem's source starting with a netrw file list in a new tab for you.

Bonus: Vim will autocomplete the gem name for you based on your Gemfile.

Delete Lines That Match A Pattern

The :g command can be used to execute an Ex command over the entire buffer for all lines that match a given pattern. By choosing d (delete) as the Ex command, all lines that match the given pattern will be deleted. For instance, if I want to remove all lines that contain binding.pry, I can execute the following command:

:g/binding\.pry/d

See :h :g for more details.

h/t Chris Erin

Searching For Hex Digits

If you want to find sequences of hex digits (A-F, a-f and 0-9) in a search, you can hack together something like:

/[A-Fa-f0-9]\+

This is a bit verbose, though. Vim has a number of built in character classes that can be referenced in searches and substitutions. For hex digits, there is \x. Using this, the search above can be achieved with:

/\x\+

See :h \x for more details and other character classes.

Explore Buffers with BufExplorer

I'm a huge fan of Vim buffers. I try to have my buffer list roughly mirror the files I am currently holding in my brain.

The BufExplorer Vim plugin helps, and is included in the Hashrocket Dotmatrix. Today I learned to use the command \bs, which opens a colorful buffer list that you can navigate with Vim directions.

https://github.com/jlanzarotta/bufexplorer

Confirm each find replace in Vim

If you are running a find replace on the whole file, you might want to use the c flag at the end of your replace command which will make vim confirm each replace.

Example:

:s/(.*)/test/gc

h/t @joshbranchaud

Jump To Matching Pair

If you are dealing with code or data that contains parentheses or brackets that are hard to follow, you can easily jump between them with %.

For example, if you move over a [ and hit %, Vim will jump your cursor to the matching ]. Hit % one more time and it will jump back.

See :h % for more details.

h/t Jake Worth

Amend Commits With Fugitive

Let's assume you are using fugitive for Git integration with Vim. You've made a commit that you want to amend. First, stage any changes that should be included in the amend with :Gstatus or :Ge:. Then hit ca to open up the commit window for amending. Save and quit when you are finished.

Want to view the aggregate changes? Open the commit window for amending in verbose mode with cva.

See the vim-fugitive docs for more details.

Swapping Split Windows

Consider a scenario where you have a vim window that has been split horizontally into two viewports. You'd prefer the top one to be on bottom and the bottom one to be on top. You want to swap them.

If you are currently focused on the top viewport, then tell vim to move that viewport down with CTRL-w J. As you might guess, moving the bottom viewport up can be done with CTRL-w K. J and K mean down and up in other contexts; vim is consistent with their meaning here.

Viewports of a vertical split can be swapped in the same sort of way. Use CTRL-w L to move the left viewport to the right. Use CTRL-w H to move the right viewport to the left.

Pane size management in vim

Make all panes the same size: <CTRL-w>=

Resize vertical splits: <CTRL-w>< and <CTRL-w>>

Resize horizontal splits: <CTRL-w>+ and <CTRL-w>-

Auto remove trailing whitespace

Copy this in your .vimrc.local, and any trailing whitespace will be highlighted, and automatically removed when you write the file.

"highlight trailing whitespace
match ErrorMsg '\s\+$'
" kill trailing whitespaces automatically
autocmd BufWritePre * :%s/\s\+$//e

Yes, I totally stole this from someone else's vimrc on github. https://github.com/rwz/dotfiles/blob/master/vim/vimrc

Just another operator

For some reason it never occurred to me that in vim, = is just another operator like d,c, etc, and I could chain it. When I would indent a whole document, I would do ggVG= to highlight the whole file and indent, when gg=G accomplishes the same thing.

Repeating Characters

It's not common to need to type 39 space characters in a row, but when the moment arises, you don't want to be caught hitting the space bar 39 times. Vim makes it easy. From normal mode, type the number, then i, and then the character to be repeated followed by an escape.

For instance, for 39 spaces, hit:

39i <esc>

or for 80 dashes, hit:

80i-<esc>

Vim Sort and Remove Duplicates

Today while rearranging a Ruby word array, I discovered this Vim command:

:sort u

This will sort all lines, or a given range, while also removing any duplicate lines.

Documentation

Deleting Directories Of Files From netrw

In netrw, you can delete files and directories by navigating over the target of deletion and hitting D.

By default, netrw will use rmdir when deleting directories. This means that if a directory has files in it, then it won't be deleted. rmdir rightly gives an error when the target directory isn't empty.

Not to worry though, netrw can be configured to use rm -r instead of rmdir when deleting directories.

:let g:netrw_localrmdir='rm -r'

source

Format Long Lines To Text Width

Vim allows you to set the maximum width for text per line in a buffer with the textwidth setting. For example, you can set the maximum text width to 80 characters like so:

:set textwidth=80

With this set, vim will automatically break on whitespace whenever you hit 80 characters. However, there are two places where this doesn't quite pan out. You will see this as soon as you open a file with lines of text that exceed 80 characters and when you paste long lines of text into your buffer. You can quickly remedy this with gw.

Make a visual selection of the lines that need formatting and then hit gw. All the lines should then we truncated to 80 or less characters.

See :h gw and :h gq for more details.

Absolute And Relative Line Numbers

By default, vim uses absolute line numbering. This can be turned off with set nonumber or more concisely set nonu. Turn it back on with set nu. Get more details at :h number.

Vim also supports relative line numbers. If you'd rather use relative line numbers, first turn off absolute line numbers (set nonu) and then turn on relative line numbers with set relativenumber. Shave off some characters with set rnu. As you might expect, you can turn off relative numbering with set nornu.

See :h relativenumber for more details.

Open Files in Vim Splits

You can open multiple files with Vim in vertical or horizontal splits. To demonstrate, I'll create some test files.

$ touch a.txt b.txt c.txt d.txt e.txt

From the command line, vim -o *.txt will open these five files in vertical splits. vim -O *.txt will open them in horizontal splits. This is great for quickly comparing two files side-by-side.

Load vimrc inside Vim

While building a .vimrc configuration file, you can test the effect of your changes by loading them up while still in the Vim session:

:so %

This is shorthand for 'source the current file'. It will raise Not an editor command: <foo> if your syntax is incorrect, a useful side effect when quickly iterating through changes to your setup.

Homerow escape

I've had this mapping forever, but Paolo was pretty stoked on it and I thought I would share in case anyone else wanted to try it. Remapping escape to 'jk' so you stay on the homerow and avoid any stretching.

inoremap jk <esc>`^

Quick .vimrc editing and sourcing

Vim will set the MYVIMRC environment variable to the path of your vimrc on startup. You can verify this by running

:! env | grep VIM

This gives us the ability to do quick vimrc editing after adding something like this in your vimrc.

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

You could change the to horizontal split if want with :sp, but you get the idea. Don't forget to source!

Case-Aware Substitution With vim-abolish

Substitution in vim is, by default, case-sensitive. Adding the i s-flag makes it case-insensitive. vim-abolish, on the other hand, lets you perform a case-insensitive substitution that preserves three case variants (foo, Foo, and FOO). Substitution with vim-abolish can be performed with Subvert or S.

For instance, :%S/blog/article/g will turn

blog Blog bLOg BLOG

into

article Article bLOg ARTICLE

Install vim-abolish and see :h Subvert for more details.

Case-Insensitive Substitution

Use the i s-flag to perform a case-insensitive substitution (search and replace).

For instance, :%s/blog/article/gi will turn

blog bLOg BLOG Blog

into

article article article article

See :h s_flags for more details.

:vglobal helps you find all the other lines

Given a file like:

cat
dog
elephant
dog
mouse

You may want to delete all lines that are not 'dog'

:v/dog/d.

Will find all the lines that are NOT dog, and delete them.

:v is short for :vglobal, also equivalent to :g!

Create A New Directory In netrw

With netrw open (try vi .), navigate to the parent directory you want to create a new directory in and then hit d. Type the name of the new directory in the provided prompt and then hit enter.

Inspired by Micah Woods' TIL from earlier today.

Create new file in Vim's file explorer

If you want to create a new file when you are viewing vim's file explorer (netrw), simply hit the %. Vim will ask you for a file name, create that file in the currently viewed directory and open a buffer.

Alternate Files With vim-rails

If you are doing a good job of testing all the code you write in a rails project, then most of your code files should be paired with test (or spec) files. You can think of these as alternate files. The alternate file of user.rb is user_spec.rb and vice versa.

The vim-rails plugin makes it easy to jump back and forth between alternate files. Enter :A and you will go to the alternate file of the current file. This makes a common navigation path for rails projects all the more efficient.

Filter Lines Through An External Program

Vim allows you to filter lines from your current buffer through an external program. For instance, if you have some ugly looking json that you'd like to format in a readable way, you might want to filter it through an external json pretty printer program.

To filter the entire file through an external program, use

:%!! <external-program>

Or you can make a visual selection and just filter that

:'<,'>!! <external-program>

See :h !! for more details.

Next Modified Buffer

After working for a while on a feature that involves looking at a number of files, I end up with a decent buffer list. I will have inevitably edited a few of those files and occasionally I'll inadvertently leave one of the buffers modified. Instead of opening the buffer list (:ls), finding the modified buffer, and navigating to it, I can just jump straight to it. I can do this with :bmodified or just :bm. This jumps straight to the next modified buffer. If there is no modified buffer, it tells me No modified buffer found.

See :h bmodified for more details.

Find & replace newlines or whitespace with Vim

If you're looking to collapse lines via a find/replace in Vim, you probably need to kill both whitespace and newlines. Use \_s to match against both. Here's the situation where I just now made use of this:

        %dt
          %label Name

To remove the %label here, select the range in visual mode, type s/\_s*%label//g, and you'll get:

        %dt Name

Edges Of The Selection

When you make a visual selection, Vim stores the position of the first character of the selection in the < mark and the position of the last character of the selection in the > mark.

Thus moving to the edges of your previous selection is easy. To move to the beginning of the selection, press

`<

To move to the end, press

`>

Vim Range Copy And Move

Today I used the Vim command :88t143 to copy a let block from one unit test to another. Vim has a few terse commands that work on whole lines like this. Here are two:

:[range]co[py] {address}        :co :copy
:[range]m[ove] {address}        :m :mo :move

:t is an alias for :copy, so the command I used copied line 88 and pasted it below line 143. It's all about saving those keystrokes!

h/t Josh Davey & Josh Branchaud

Comment with Commentary

Commenting out a range of code is easy with the plugin commentary.vim.

Simply highlight the range of code in visual mode and type gc.

Undo the action with u, or by repeating the same gc command on your range.

h/t Josh Branchaud

List Of Plugins

Get a list of all your plugins (and other sourced scripts) with

:scriptnames

See :h scriptnames for more details.

Swapping Letters With Vim

Imagine you've typed 'recieve' instead of 'receive' in an RSpec test. This is will break things. I use this example because it's a typo I make frequently.

To swap the letters, move to the first letter ('i') and type xp. This will swap that letter with the next letter. It's Vim for 'cut what's under the cursor, then paste it after the cursor.'

There are more complex ways to do this; this is the simplest I know of.

h/t Matt Polito

Save your vim sessions for later

Create a new session in vim:

:mksession ~/session_file_name.vim

Open it up later in terminal:

$ vim -S ~/session_file_name.vim

Or from vim:

:source ~/session_file_name.vim

I learned this from @hogihung. Full post

`gf` go-to-file mapping goes-to-gem-source

Everyone knows (or does not know) that gf when the cursor is over a word in vim will try to find a file on the system to navigate to that matches that word or path.

Rails overrides this to be used on constants and to navigate to the file where a constant is defined if the constant name matches the file name (matches in the rails sense).

When you're in the Gemfile, gf on a gem will take you to that gem, just like bundle open. Brilliant!

View Vim Mappings

Somehow the Vim :map command eluded me until today. :map with no arguments lists you all your Vim mappings. If you have a lot of plugins, you have a lot of mappings.

Explore them and reap the benefits!

Code to HTML

The vim 'syntax.txt' plugin includes an awesome command called :TOhtml.

Highlight a range of code in Vim and run the command. Default range is the entire buffer.

You'll get an HTML document based on the code and its highlighting. Write the file and it is ready for a browser, a presentation, or anyplace else.

Swap Occurrences Of Two Words

Imagine I have a file with foo and bar all over the place. The tables have turned and now I want all occurrences of foo to be bar and all occurrences of bar to be foo.

Reaching for a simple substitution won't work because after flipping all the occurrences of foo to bar. I will no longer be able to distinguish between the new bars and the bars that need to be flipped.

Abolish.vim enhances Vim's substitution capabilities making it easy to flip these strings in one relatively simple command.

:%S/{foo,bar}/{bar,foo}/g

Notice the uppercase S as well as the ordering of foo and bar in the before and after sequences.

Close All Windows

The Vim command :only, or :on, closes all windows except the one you are currently in.

End Of The Word

Word-based movement can serve as a quick way to get around locally in Vim. I most often use w and b for this kind of movement. While w and b move me to the beginning of the next and previous word, respectively, I find that sometimes it would be more convenient if I were at the end of a word.

The e and ge commands serve this purpose well. e will move me to the end of the next word and ge will move me to the end of the previous word.

Change to snake, pascal, or camel case in vim

Abolish brings us some outlandish powers. Change snake_case to snakeCase by putting your cursor on it in normal mode and entering crc. The pneumonic here is CoeRce Camel. Stupid potent.

The 0 Buffer

Here's a Vim 101 thing that I went without knowing for far too long, so maybe it'll help you as well:

Say you have 3 lines of code ...

T-2000
John Connor's Foster Mom
Random Policeman

And you want to replace the second two lines with the first. You might type yy to yank T-2000, then type shift-v and p on line 2 to replace John Connor's Foster Mom with T-2000:

T-2000
T-2000
Random Policeman

But if you go to line 3 and type shift-v and p again, you'll paste John Connor's Foster Mom, because Vim replaces the default buffer with the previously removed line.

Fortunately, T-2000 is still available in that scenario – it's automatically placed into the 0 buffer. To continue to paste T-2000, just type:

"0 p

to paste from the 0 buffer instead of the default buffer.

Set Syntax Highlighting Manually

If you've opened a file with Vim and it has a weird extension (or you've just pasted code into a new file with no extension yet), you might need to set your highlighting manually. Just use :set syntax:[language], for example:

:set syntax:javascript

Set Your Color Scheme

Vim ships with a number of standard color schemes for both light and dark backgrounds. You can also find and install many others. To set your color scheme, you can use the :colorscheme command. You can quickly see what color schemes are available by typing :colorscheme and then tabbing for completion. For instance, you can set the delek color scheme by entering

:colorscheme delek

See :h colorscheme for more details.

Check Your Current Color Scheme

Vim ships with a number of different color schemes. There is also a plethora of color schemes built by the open source community. If you'd like to know what color scheme you are currently using, you can check with

:echo g:colors_name

So more details at both :h g:colors_name and :h colorscheme.

Incremental Searching

You can do a text-based search on the contents of your current buffer by hitting / and then beginning to type a pattern (including regex). The incsearch feature makes searching for text even easier. As you type your pattern, the first valid match will be located and highlighted. As you continue to type the pattern, it will continue to update the highlighted match. Incremental searching makes it easy to see when you've made a typo in your pattern. By default incsearch is turned off in Vim. You can enable it with :set incsearch.

See :h incsearch for more details.

Edit the Current File Always

The Vim command :e edits a file. Add a bang, :e!, to edit the current file 'always', discarding any changes to the current buffer.

This is useful if you rename a file with a new file extension (i.e. .txt to .rb). :e! reloads the file in Vim, picking up any customizations you have in your configuration files such as syntax highlighting.

Find and Replace Across Files

Vim can find and replace strings across files, just like other text editors. It's really (sort of) easy.

First, load all the files you want to change into the Vim buffer with a splatted directory.

:args path/to/files/*/*

Then, execute the substitution.

:argdo %s/old_string/new_string/ge | update

The e flag is important; it tells Vim not to issue an error if the search pattern fails. This will prevent No Match errors from breaking the chain.

Re-indenting Your Code

If you have pasted some poorly formatted code or you've written a portion of code in a way that mangled the indentation, you can quickly re-indent that code for you. Or at least do its best to try and indent it correctly.

Make a visual selection of the code that you want to re-indent and then hit =.

For instance, this ruby code

if this_thing
p something
else
p nothing
end

will be indented by Vim as

if this_thing
  p something
else
  p nothing
end

See :h = for more details on how vim decides what formatting and indenting it will do.

h/t Chris Erin

Vim Without The Extras

If you want to start up vim without loading all the usual plugins, you can supply the --noplugin flag

$ vim --noplugin coffee.rb

You can take things even further by instead telling vim to open without loading any plugins or configuration files. That is, you can tell vim to skip all initializations.

$ vim -u NONE coffee.rb

If you are used to lots of syntax highlighting, custom bindings, and other niceties, this may feel rather foreign.

h/t Jake Worth

Viewing Man Pages with man.vim

In Quick Man Pages, I introduced K which shells out to the man page for the unix command under the cursor. It gets better though. Vim has a built-in plugin, man.vim, that you can enable which allows you to view man pages without shelling out.

Add the following to your .vimrc file

runtime! ftplugin/man.vim
" grep

Then save it and re-source the configuration with :source %.

With the man.vim plugin enabled, you can now move your cursor over the word grep and hit <leader>K which will pop open the man page for grep in a unnamed, split buffer.

Not only does this prevent context-switching when viewing a man page, but it also gives you the full power of vim over the content of the man page. You can search, you can yank text, or you can even pop open the man page for another command.

See :h ft-man-plugin for more details.

Current Value of a Setting

Check the value of any Vim setting by adding a ? to the end of its name.

# Validate spelling is turned off
:set spell?
=> nospell

# Validate incremental search is turned on
:set incsearch?
=> :incsearch

The Black Hole Register

Vim has a variety of registers for storing and moving around text. Vim also has a special register called the black hole register. This black hole register is associated with the _ character.

When writing to this register, nothing happens. This can be used to delete text without affecting the normal registers. When reading from this register, nothing is returned.

As stated in the docs, if you don't want to overwrite the unnamed register or some other register when deleting text, you can use the black hole register. For instance, deleting the current line without any register side-effects looks like this:

"_dd

See :h registers for more info on Vim's registers.

Vim Tips

Get some Vim tips with:

:h tips

Create A New File In A New Directory

From within a vim session, if you create a buffer for a new file in a directory that doesn't exist. For instance, let's say that /features doesn't exist and the new file is my_latest_feature_spec.rb:

:e spec/features/my_latest_feature_spec.rb

Vim's command line will inform you that this is a buffer for a [New DIRECTORY]. If you then make some changes and subsequently try to save the file, Vim will present you with:

"spec/features/my_latest_feature_spec.rb" E212: Can't open file for writing

This is because the containing directory doesn't exist. You can quickly create that directory with a combination of Vim filename shorthands and shelling out to the mkdir command.

:!mkdir -p %:h

The % is shorthand for the qualified path of the current file. The :h is a filename modifier that returns the head of the filename, that is, it resolves to the path with everything except the name of the file.

Thus, this command is essentially resolving to:

:!mkdir -p spec/features/

Vim will shell out with this command making directories for all non-existent directories in the given path. Now you can happily save your new file.

Count number of matches

You can use the search and replace functionality in vim to count the number of matches for that search like so:

:%s/transaction_id//n

You will see the result in the command tray like so:

8 matches on 8 lines

If you want to find matches global (that is, counting multiples per line), you can add the g flag:

:%s/transaction_id//gn

for a response like:

13 matches on 8 lines

Moving To A Specific Line

Often times when I open a new buffer, it is with the intention of moving to a particular line. For example, if I am trying to move to line 55 in the file, then I will hit 55j*. This works fine when I am dealing with a freshly opened buffer. That is, this works fine if I am starting from the top of the buffer.

In general, there is a better approach. I can move to an exact line number from normal mode with :{N} where {N} is the line number. So, if I want to get to line 55 regardless of where I am currently positioned in the buffer, I can simply hit :55<cr>.

* This actually is slightly inaccurate, it moves me to line 56, not 55. If I need to be precise, this doesn't cut it.

** Also, 55G apparently does the same thing.

Whole Line Auto-Completion

To get whole line auto-completion in Vim, you don't need a fancy plugin. It is built right in. There is a sub-mode of insert mode called X mode that allows you to do various kinds of special insertions. The ctrl-x ctrl-l binding corresponds to whole line completion. So, if you start typing a few characters and then (while still in insert mode) hit ctrl-x ctrl-l you will see a completed line that matches the initial characters you typed as well as a list of subsequent matches. You can cycle through the matches using ctrl-n and ctrl-p (going forward and backward, respectively).

The completion is done based on the configured completion sources. Generally, the completion sources will include the current buffer, other loaded and unloaded buffers, plus others. You can see which sources are configured with :set complete? and read more about the completion configuration at :h 'complete'.

Help For Non-Normal Mode Features

The majority of your time in vim will be spent in normal mode. You will often look to the documentation for help on any number of commands and bindings available in normal mode. For instance, to find out more about goto file, you may do :h gf. And if you want to read more about yanking lines of code, you may do :h y.

But what about commands and bindings that aren't found in normal mode? What if you want to read about yanking text from visual mode? What if you want to get more details on insert's x-mode? Doing :h y and :h ctrl-x, respectively, won't do the trick because vim thinks you are talking about normal mode bindings.

The docs for these and other non-normal mode features can be found by prepending i_ and v_ to the binding in question.

To get at the docs for yanking from visual mode:

:h v_y

And to read up on insert's x-mode:

:h i_ctrl-x

Delete comments with Vim

:g/^\s*#/d will remove comment lines from a file with Vim.

Marks Across Vim Sessions

Any mark set with a capital letter (that is, A-Z) is called a file mark. File marks can be used to move from file to file. File marks will also be written to the Vim Info file (~/.viminfo) which means that if you close Vim and open it again, it will still know about those file marks. This means that your file marks are persisted across vim sessions which will save you the trouble of having to redefine them each time.

A more detailed description of marks is at :help marks.

Buffer Wipe

If you use buffers to navigate Vim, and you open a file you didn't mean to edit or won't need later, wipe it from the buffer with :bw.

This will prevent that file from showing up in your buffers list. It will also delete any changes to the file; use with caution.

Previous Visual Select

Typing gv in normal mode will re-select the previous visual selection. This is great for when you are doing a search and replace on a visual selection and don't get the regex quite right on the first try.

Retab

:retab resets the tabs dependent on shift width and tab stop.