Textmate to VIM

Where I explain how to reproduce over 110 commands from Textmate in VIM.

When I switched from Textmate to VIM I felt like a tourist lost on a Japanese subway without a guide, translator or hope. I was unable to find in VIM the features I’d come to love and rely on in Textmate. I yearned for ⌘ + T to summon my models, a project drawer to manage my files, and snippets to save my fingers.

Instead of accommodating my needs, VIM sat firm and unresponsive, save for a judgemental beep. Even though I was supposed to go cold turkey on Textmate, I met her by night for a guilty after-hours edit.

With time I learned to mimic nearly every Textmate feature in VIM, and then some. This guide isn’t about the powerful functionality VIM has over-and-above Textmate; you’ll figure this out with time. This guide is to help you do in VIM what you already can using Textmate, only with considerably less pain than I underwent.

This guide makes a few assumptions:

  1. 1.You are using a Mac.
  2. 2.You’ve installed Mac VIM. The easiest way is using Home Brew. brew install macvim
  3. 3.You’ve installed Janus, the community-maintained VIM distro with plugins and configurations useful to Rails programmers accustomed to Textmate.
  4. 4.You’ve created a ~/.vimrc.local file (for core VIM configurations), ~/.gvimrc.local (for configuring the graphics in VIM) and ~/.janus.rake (for adding or removing plugins in VIM). See my dotfiles for some commented examples. Better yet, use them as sensible defaults.
  5. 5.You’ve already learned the basics of VIM. If you haven’t type vimtutor in your terminal for a 20 minute tutorial. Advanced training can be found be referring to the vim training resources below.
  6. 6.You were a power user of Textmate.
  7. 7.You are a Rails programmer switching from Textmate to VIM. About 30% of this guide is Rails specific.

This guide may only be reproduced with the express permission of Jack Kinsella - Rails Developer, Berlin

Some Preliminary Notes (Do Not Skip)

Command Shortcut in Textmate Shortcut in Vim
  • In general the keyboard shortcuts in Textmate require you to press the keys at the same time. Below, this is symbolised by a +. VIM’s shortcuts, by contrast, typically require you to press the keys in quick succession, rather than at the same time. If you see ‘dd’ this means type d twice.

  • Whilst commands in Textmate are case insensitive, or rather the shift key is specified in the commands below, the commands in VIM are case sensitive. If I tell you to type Y then typing y will not suffice.

  • Unless otherwise specified, all the VIM commands assume you are in normal mode, the mode where you cannot type text into the file.

  • If I instruct you to add something to your vimrc.local or gvimrc.local files you will need to type :source ~/.vimrc.local or :source .gvimrc.local to reload VIM with your changes.

  • If I instruct you to add code to your .janus.rake file, you must cd into your ~/.vim directory and run rake for these changes to be installed.

  • Regular expressions in VIM differ from those in Textmate, and these are outside the scope of this guide. 90% of these differences will be alleviated if you add this to your .vimrc.local:
    nnoremap / /\v
    vnoremap / /\v

This automaticaly prefixes your search commands with \v (Technically, the commands map the key /, symbolising search, to /\v, meaning search with ‘very magic’ regex syntax. There are two entries since the remapping happens in two modes.). ‘Very magic’ regex syntax means that all ASCII characters except ‘0’-‘9’, ‘a’-‘z’, ‘A’-‘Z’ and ‘’ have a special meaning. Without this you would need to escape many characters which are standard regex syntax in, say, Ruby._

Opening, Closing and Creating Files

Open a file ⌘ + 0 :e FILENAME Use Tab completion after typing the first few letters. You may need to save your current file first.
Create new file File > new ⌘ + T (new tab) You will be in a new file on a separate tab. Type something and then save with: :w newfilename :e new_filename Opens a new file in the current window.
Quit ⌘ + q :q This throws an error if you have not saved. use :wq to save and quit or :q! to quit without saving.
Open project from command line [cd to folder] mate . [cd to folder] mvim .

Saving Files

Save file ⌘ + S :w
Save file as ⌘ + ⇧ + S :w NEWFILENAME

Undo / Redo

Undo ⌘ + Z u
Redo ⇧ + ⌘ + Z ⌃ + R

File Renaming

Rename a file Focus on the project drawer and select a file. Press spacebar. Type a new name. Start by “focusing on the NERDTree”:#nerd_tree. Select the file you wish to rename (however you want: e.g. with a search or plain old jklh). Type ‘m’ to bring up a menu. Type ‘m’ again to chose to modify the file name. Type the new name of file and press enter.

##(#nerd_tree). Project Drawer/ NERDTree

Focus on project drawer ⌃ + “Switch tabs until selected”:#switch_tabs
Close/Open project drawer ⌃ + ⌥ + ⌘ + D \n
Change size of project drawer Use mouse to adjust size [add this to your .vimrc] let NERDTreeWinSize=16
Create new in Project Drawer ⌘ + ⇧ + N Select Project Drawer. Highlight parent folder you’d like file to appear in. Type m the choose a from select menu and type desired filename
Delete a file Click on file and select “remove file” Highlight undesired file file in Project Drawer. Type m then choose d from drop down menu.
Opening a sub-folder   Enter to open/close a directory
Refresh project tree to reflect newly added files Automatic Nearly always automatic. Otherwise press r


Copy ⌘ + C yy Copies the current selection, or, if there is no selection, the current line
Cut ⌘ + X d Technically this deletes the selection, but deleting in VIM saves the deleted text to a register where it can be now be pasted with p
Paste ⌘ + V p Pastes below the current line P pastes above the current line “0p this pastes the last *explicitly copied* text. This is important since many commands, such as deleting text, override the paste buffer
Paste from system clipboard As above. “*p VIM distinguishes between its internal clipboards (buffers) and the system’s clipboard.
Clipboard history ⌘ + ⇧ + V :reg Show a list of registers each of which can be pasted e.g. “8p pastes the contents of the register 8

##(#switch_tabs). Tabs

New tab Click on file in project drawer ⌘ + ⇧ + T
Drop tab ⌃ + w ⌃ + w
Switch tabs left ⇧ + ⌘ + ← gT
Switch tabs right ⇧ + ⌘ + → gt
Go to tab ⌘[1-9] ⌘[1-9]

Moving Around A File

Go to beginning of line ⌃ + A ^
Go to end of line ⌃ + E $
Go to top of file ⌘ + ↑ gg
Go to bottom of file ⌘ + ↓ G
Move up one line (with caret at same position) ⌃ + P k
Move down one line (with caret at same position) ⌃ + N j
Go to line 20 ⌘ + L [type a line - e.g. 20] :20
Jump between words left ⌥ + ← w b or B Lowercase b goes back one word, where puntuation marks count as word separators. B is back one word where only spaces count as word separators.
Jump between words right ⌥ + → w or W same distinction as above

Selecting Text

Begin selection ⇧ [then use arrows to drag over desired text] v [enters visual mode. use w to move forward one word. ) to move forward one sentence and % to move to next bracket close. also /apple to move forward to next occurrence of apple]
Select all ⌘ + A ggVG
Increase selection left one word ⇧ + ⌥ + ← then alt + ← for each additional word v(select)w then w for each additional word
Select a vertical block ⌥ + drag mouse ⌃ + v

Deleting Text

Delete line ⌘ + ⇧ + k dd
Delete character Backspace Erases character to the left of the caret x Erases character under caret
Delete selected text Backspace d

Moving Text Around

Move selected text up ⌃ + ⌘ + ↑ (or ↓) :m 22 moves current line to line 22. Easier if line numbers are on with :set number. Alternatively :m+ or :m+N or :m-N for moving 1 or N lines up or down
Merge current line With Next Line ⌃ + ⇧ +J J
Sort lines ⌥ + ⌘ + R > sort in dialogue box Where you have previously selected text !:sort Where you have nothing selecting and want to act on whole file :%!sort (% is a symbol representing the whole file)

Searching Files

Search file downwards for TOM ⌃ + S TOM /Tom Then press they enter key and then you can press n or N repeatedly to continue searching up or down
Search file upwards for TOM ⇧ + ⌃ + S TOM ?TOM As above, n or N continue searching up or down
Full screen (Lion Only) ⌘ + Enter
Search entire project ⌘ + ⇧ + F ,a THING_SEARCHING_FOR (ack)
Find a specific method ⌘ + ⇧ + t /def foo then use * to cycle through instances of the method name under the caret. This will not necessarily by definition # does the same but in the oppose direction

Replacing Text in Files and in Entire Project

Replace all “donut” with “eclair” in file ⌘ F Find and replace box where you select ‘Replace All’. :%s/donut/eclair/g
Replace all “donut” with “eclair” in file, ignoring case ⌘ F Find and replace dialogue where you then select ‘Ignore Case’and then ‘Replace All’. :%s/donut/eclair/gi
Replace all “donut” with “eclair” in file, confirming each time ⌘ F Find and replace box where you select ‘Replace Next’. :%s/donut/eclair/gc
Replace “donut” with “eclair” in entire project ⌘ + ⇧ + F :Ack donut[Enter]. A window pops up with all instances of the term. into the ack search window. Type :bufdo %s/donut/eclair/gce. :q the ack search window once down to close it. _Save current file first if VIM throws an error_
Replace “donut” with “eclair” in entire project ⌘ + ⇧ + F ,a donut[Enter]

Ruby On Rails

Nearly all of this functionality is thanks to Tpope’s Rails.vim plugin.

Call Ruby On Rails generate script “⌃ + Pipe [1..8]== :Rgenerate [controller model scaffold] Blog
Go To Last Migration None :Rmig
Run migrations ⌃ + ⇧ + Pipe [when in a migration] :Rake
Switch focus to project drawer ⌘ + ⌥ + ` (check) ⌃ + w ⌃ + w _A good key remapping is to map this onto tab by adding this to your vimrc: noremap _
Insert erb’s <%= ⌃ + ⇧ + . Type text you want to surround first and place caret some inside. yss=
Insert erb’s <% ⌃ + ⇧ + . yss-
Run unit test caret inside of ⇧ + ⌘ + R :.Rake . here represents the current line. You can substitute this for other lines e.g. :40Rake TEST
Go to test file (e.g. from user.rb to user_spec.rb) ⌥ + ⇧ + ⌘ + ↓ :A (:AV in a new split, :AT new tab)
Find related file ⌥ + ⌘ + ↓ :R If typed within the Controller you’ll be brought to the View corresponding to the method selected; If typed in view -> Controller; Migrations -> Next Migration; Typed in Model -> Schema. For something more precise see the following VIM only commands
Go to related controller ⌥ + ⇧ + ⌘ + ↓ :Rco
Go to related helper As above :Rhe
Go to model under cursor No equivalent gf [e.g. you see Pos*t.first -> brought to #post.rb
Go to stylesheet under cursor No equivalent gf [e.g. you see<%= stylesheet_link_tag ‘scaf*fold’ %>-> brought to scaffold.css
View Rails logs No equivalent :Rlogs :Rake logs:clear if takes too long to load
Go to layout under cursor No equivalent gf e.g. you see layout :print -> brought to #print.html.erb
Go to application.rb No equivalent :Renv
Go to test.rb No equivalent :Renv t[tab to autofill out to test]
Go to controller from link under cursor No equivalent gf e.g. you see <%= link_to “New”, new_comme*nt_path %> -> brought to #comments_controller.rb
Create a posts controller No equivalent :Rco posts! Note the exclamation mark which distinguishes this create command from the find command.
Extract to partial [Select text] ⌃ + H [Select text] :Rextract PARTIAL_NAME


Automatically indent code beautifully on whole file ⌥ + ⌘ + B (Code Beautifier Plugin) gg=G
Fix indentation on selected area No equivalent =
Fix indentation on a single line No equivalent == Compare with the above to note a pattern. Type a command once to apply it to visually selected areas. Type it twice to apply to the current line, which need not be selected. See also d and dd, y and yy
Indent ⌘ + [ >
Unindent ⌘ + ] <

Font Size, Line Numberings

Bigger/Smaller Font ⌘ +/- [~/gvimrc.local] set guifont=Monaco:h18 You can replace 18 here with your desired font-size [Note that you can try this command out by typing it into a live VIM session just by preceding it with a :, e.g. :set….. Using ⌘ +/- in VIM makes the screen scale disproportionately
Line numbering ⌘ + ⇧ + L :set number Turn on :set nonumber Turn off. Note the symmetry between turning the number on and off, the only different being the preceded “no”. This is the same for all VIM set commands. As with other preferences this may be placed in vimrc.local

Spell Checking

Highlight incorrect spellings ⌥ + ⌘ + ; :set spell
Next incorrect spelling ⌘ + : [Assuming you’ve enabled spell checking and can see highlighter errors] ] s Go to previous spelling error with [s
Suggest correct spelling Double click and select best spelling z= Then choose the correct spelling from drop down menu


Add bookmark ⌘ + F2 (Never worked on my mac) m[a-z] The letter in the range refers to this bookmark
Jump to bookmark F2 (next) + F2 (previous) ‘a Where a is a bookmark previously set. Type :marks to see all bookmarks


Upcase selected text ⌃ + ⇧ + U u
Downcase selected text ⌃ + ⇧ + U U
Switchcase of selected text ⌃ + g ~
Titlecase current text ⌃ + ⌥ + U No exact equivalent To titlecase the current line you can use :s :s/<(\w)(\w*)>/\u\1\L\2/g


All of the following commands assume you are in insert mode

Auto-complete method ⎋ after typing first few letters Tab after typing first few letters
Auto-complete filename No equivalent ⌃ + X ⌃ + F Only fills one directory at a time so you’ll need to repeat for each additional one
Auto-complete full line of code No equivalent ⌃ + X + l

Commenting Code

Comment Line or Selection ⌘ + / ⌘ + /

Syntax Errors

Check for syntax errors on saving (*life saver) Validate On Save Plugin Built In A grey bar appears right of the number column with an > beside the error

Auto-closing Quotes, Html Tags, Brackets.

All of the following commands assume you are in insert mode

Add opposing bracket or quotation mark Typing a “ will automatically add in closing. Add this gist
Close current html tag ⌘ + ⌥ + . ⌃ + x + / Also you have auto tag creation. To create <p></p> type p then ⌃ + X Spacebar _Assumes you have the following in your ~/.janus.rake file: _ vim_plugin_task “ragtag”, “git://github.com/tpope/vim-ragtag.git” _

CSS Colours

View CSS colour wheel ⌘ + ⇧ + C No exact equivalent. vim_plugin_task “vim-css-color”, ‘git://github.com/skammer/vim-css-color.git’ turns #acbdef into its correct colour

Running Tests and Files

Run tests for given file ⌘ + r :Rake
Run current file ⌘ + R :!ruby % Explanation: :! means execute what follows as if in shell. % expands to the current_file_name so you are executing `ruby current_file_name. This runs in a buffer in VIM making you unable to continue editing.


Snippets (e.g. validates present of) vp + TAB vp ⌃ + ] Abbreviations same as in Textmate Non Rails snippets not working since the latest releases of snippets plugin clashes with Command-T search plugin. I’ve filed bug reports and if anyone has fixed this let me know.
See All Available Snippers Use Menu :Rabbrev

Syntax Highlighting

Set syntax highlighting to (e.g.) textile Varies depending on highlighter. Select manually at the bottom of the screen. :set syntax=textile You probably won’t need this since VIM will automatically figure out the appropriate syntax highlighter.
Turn on syntax highlighting No option to enable/disable :syntax on
Turn off syntax highlighting No option :syntax off


Reformat selection to according to wrap settings ⌃Q gq gqgq, i.e. the command twice, to reformat the current line


Duplicate line/selection ⌃ + ⇧ + D yyp y copies line then p pastes in below.
Add placeholder text lorem + tab lorem + enter Assumes you have add the following to your vimrc.local: “ anytime ‘lorem’ is typed in, replace it with placeholder text abbr lorem Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras a ornare metus. In justo metus, auctor nec semper in, laoreet porttitor augue. Maecenas tortor libero, dignissim vel placerat sit amet, malesuada ut quam. Curabitur vitae velit lacus, sed imperdiet sapien. Sed posuere, odio nec pharetra adipiscing
Overwrite Mode ⇧ + ⌥ + O Then start typing text R Then start typing text
Edit ends of selected lines ⌘ + ⌥ + a ⌃ + V to enter VISUAL-BLOCK mode, select your lines, $ to go to the end of the selection, A to enter EDIT mode at the end, ⎋ when you are finished_
Edit start of selected lines No equivalent Sane as above, except you press I instead of A
Wrap selected text in P tags ⇧ + ⌃ + W ystp


Search help for ‘grep’ Click help menu and search for help :help grep

Email Me If I Left Something Out

Or if you can find a more idiomatic way of doing any of the above commands.

Remember the key is to train your fingers. Don’t just read the text; open up a blank file and try out different commands. If you want to get good at VIM you need to have the confidence to tear a file to pieces your training sessions.

More Articles:

4 Ideas For Improving Testability in Web Apps

Backdoors, interface hooks, explanatory dry runs, and deep reachability

5 Ways URLs Go Wrong

A tour of the traps and potholes that inhibit us from getting URL naming right

Project-Level Attribute Normalisation

Why you should introduce a software layer close to your object relational mapper that formats attributes into clean, standardised forms