Want to see the full-length video right now for free?Sign In with GitHub for Free Access
Here's a typical ruby file. It contains a module, class, and several method definitions. These are some of the main building blocks that we use to create ruby programs, and Vim provides motions that let us jump quickly between them.
We can jump forward and back between method definitions using the
Notice how these two commands always position the cursor on the
Now, suppose that we're working somewhere in the middle of this function and we decide that we need to change its arguments.
def group(name, &block) group = Group.new(name) group.run(&block) @groups << group end def group(*names, &block) group = Group.new(names) group.run(&block) @groups << group end
We can easily manoeuvre our cursor to where we need it:
Vim also provides a variant that lets us jump to the end of a method definition, by using
]M (there's also
[M, which lets us jump to the end of the previous method's definition).
]M comes in handy if we need to change the return value of the current method.
]M - jump to the end of the current method definition O - and open a new line
I don't actually want to keep that change, so let's undo it.
We can also jump between module and class definitions using the double-square-bracket motions.
]] - double-close-bracket jumps to the start of the *next* class or module definition [[ - double-open-bracket jumps to the start of the *previous* class or module definition
I use these motions less frequently than the ones for jumping between methods, because the class and module keywords tend to only appear a couple of times in each ruby file. But it's good to know that they're there.
Also, there are corresponding motions that jump to end of a class or module, but I find that reading them makes my eyes go crossed, so I'm not going to dwell on them for long!
These motions are provided by the
vim-ruby bundle. You should already have this installed, because it's included in the Vim distribution. But I'd recommend installing it manually to ensure you have the latest and greatest version.
You probably already know about Vim's built-in percent command, which moves the cursor between matching parentheses, brackets, and braces. There's a plugin called
matchit.vim, which enhances the percent command by making it jump between keyword pairs.
The matchit plugin actually ships with Vim, but you have to enable it by adding this line to your vimrc file:
With matchit enabled, I can now use the percent command to jump between the opening and closing keywords of certain ruby constructs. It works on
do, and the corresponding
end keyword for each of them.
I expect that you can think of many uses for this feature, but let me just demonstrate one place where I've found it to be especially useful.
Here's a test file written using RSpec. Note the nested
context blocks, which group together the specs defined within. The descriptive strings make it easy to see what's going on at the top of these blocks, but if we jump to the end it's less clear what's going on. Here, we have a series of consecutive
end keywords, each of which might be closing an
We can find out which is which by placing the cursor on an
end keyword, then pressing the percent command and seeing where we end up.
That's so much quicker than scrolling the page while scanning the indentation with your eyes.
Learn to trust this feature and it will serve you well.
Text objects are one of my favourite features in Vim. With only a couple of keystrokes, they allow us to select a range of text that matches a particular pattern. In this section, I'll introduce a few text objects that can help when working with Ruby files in Vim.
Suppose that we wanted to select this entire spec. We already know that the percent command gives us a shortcut for jumping between the
end keywords. We can use that!
These steps should work just as well if the cursor starts off inside a three-line spec or a ten-line spec. You might consider creating a mapping, so that you can select a spec with fewer keystrokes.
Let me save you the trouble. The
textobj-rubyblock plugin provides a couple of mappings that you can use in this scenario. With this plugin installed, we can select the current ruby block by pressing
r stands for rubyblock and
a stands for around, so you can read
select around the current rubyblock
Alternatively, you can use
vir, which reads as:
select inside the current rubyblock
Under the hood, the
textobj-rubyblock plugin invokes matchit.vim, so you can use the
ar mappings to select all sorts of ruby constructs, including
if blocks. Also, once you've started visual mode, you can repeat the
ir mapping to contract your selection to the inner block, or repeat the
ar mapping to expand the selection outwards. That's quite handy!
Suppose that we're working on this method and we wanted to select everything inside its body. We could do so combining the
ir mappings supplied by the rubyblock plugin. But watch this: With our cursor positioned deep within the innermost block, we'd have to make several repetitions of these commands to select the target range of text.
It would be handy if there were a dedicated mapping for selecting a ruby method, for this scenario. Check this out:
Just as the
vim-ruby bundle supplies motions for jumping between module, class, and method definitions, it also supplies text objects for operating on these constructs. The
im object selects inside of a method definition.
That's exactly the command we were looking for! If we use
am instead, it selects all of the method, not just the method body. If your code includes docstring-style comments, then these are also selected by the
vam text object. How cool is that?
im selects inside the current method, while
am selects around the current method. If we use an uppercase
M, then we can operate on classes and modules instead of methods. And to complete the table:
ar operate on rubyblocks.
These mappings are all text objects.
So far, I've demonstrated how they can be used with visual mode to quickly make a selection. But text objects are versatile and they can be used with other operations such as
d to delete,
c to change, and
y to yank.
For example, suppose that we wanted to change the code inside this RSpec test. We could use
vir to select the range, then use
c to delete the selection and switch to insert mode. But there's a quicker way. [Let's undo that]. Instead, we could simply use
cir - to change inside the rubyblock.
Here's another example. Suppose that we wanted to delete this method. We could use
vam to select all of the method, then
d to delete the selection. Or we could simply press
dam to delete around the method.
One more! Suppose we want to yank the contents of this class, so that we can use it as a template for another class. I won't show you the visual mode workflow this time, I'll go straight to the shortcut:
yiM wye-eye-big-EM, yanks inside of the class definition. Now I can jump to the other class
]]p and paste the text. Boom!
These text objects enable you to operate with precision on ruby constructs using only a couple of keystrokes. I'd recommend using them with visual mode initially, as you get used to them. But once you've got the hang of how they work, try and stay out of visual mode. It's more efficient, and it makes you look badass.