Articles

NoVIMber 04, 2014 - Yanking, Putting, and Registers

It's November 4th which means it is time for my 4th NoVIMber blog post! Before I get into that, I wanted to throw out my plan for the next couple of weeks. So far, I've been covering fairly basic (but useful) topics. I plan on continuing that trend for the rest of the first week. Next week I'll be covering windows & buffers in a reasonable amount of detail: The week of windows & buffers! While using Emacs, I loved that I could have multiple files open in different buffers and flip through them without needing to drop back into a shell. Unfortunately I never put the time into learning this as a Vim user. Hopefully we'll all be proficient at windows & buffers next week! Onto the main course of this post!

Yanking & Putting

I'm primarily covering yanking & putting as a prerequisite to registers - the primary focus of this post. Registers are a very powerful feature of Vim that I didn't even know existed until yesterday. Think of a register as a variable inside of vim. If I delete or yank a word, that goes into a register which I can easily use to "put" the word later. Before we get into that too much, let's look at some basic yank and put commands:

d  The delete operator is essentially equivalent to "cut" unless the "null register" is used
y  The yank operator is basically equivalent to "copy"
p  The put operator "puts" the contents of a register after your cursor (for a value less than a line) or after your current line.
P  Same as "p" except the contents of a register are "put" before your cursor (for a value less than a line) or before your current line.

You can use these commands in combinaton with a "count" and a "motion". For example:

d2w  deletes the following 2 "words"
y5j  yanks the following 5 lines
dd   deletes the current line
5dd  deletes the current line and four more below it (for a total of 5 lines)
yy   yanks the current line
5yy  yanks the current line and four more below it (for a total of 5 lines)

Registers

Now that we've reviewed deleting & yanking a bit, let's talk about registers! Registers are accessed using the '"' (double-quote) command. For example, if you wanted to access register 0, you could use '"0'. There are 9 different types of registers but I'm only going to cover a few in this post.

Unnamed Register - "" If you've done something like "dd" or "yy" and then performed a put with "p", you've been using the unnamed register. This register is almost always filled with the values from delete, change, substitute, and yank commands regardless of whether a different register is specified. If you perform a put command with no specified register, the unnamed register is used by default.

Numbered Registers - "0 through "9 Register 0 will always contain text from the most recent yank command unless another register is specified. Register 1 contains text from the most recent delete/change command unless another register is specified or the deleted/changed data is less than a line.

Registers 1 through 9 are basically "rotating" registers. Register 1 contains data from your most current delete/change, register 2 contains data from the previous delete/change, etc... When a new "non-small" delete/change takes place, the data from register 9 is dropped, the data from register 8 is moved to register 9, etc...

Small delete Register - "- The small delete register holds data from the most recent delete/change operation that is smaller than a full line unless a different register is specified.

Named Register - "a though "z or "A through "Z The named registers can be used as you see fit. Specifying a lowercase named register, "a for example, will replace the current value of the register with the text from your current yank/delete/change operation. Specifying an uppercase named register, "A, will append the text from your current yank/delete/change operation to any text that currently resides in that register.

Now how can we specify a register?

"zdd    deletes your current line and puts its contents into register "z
"Z10dd  deletes 10 lines (starting at current line) and appends their contents in register "z
"zp     puts the data from register "z below current line

So what if we want to see the contents of our registers? Glad you asked! There's a command for that too!

:registers  Displays the current contents of your registers

Now that we've covered the concept of registers, I'm sure your head is spinning with ideas that will help you use Vim more efficiently. I know mine was! There is a lot of ground to cover on this topic - I've only hit 4 of the 9 register types in this post. I'll probably cover the remaining registers and some other cool features in a later post.

Until tomorrow, Happy Viming!

Reference Material: Vim documentation: change - registers


NoVIMber 03, 2014 - Dealing with tabs and indentation

If you're tasked with maintaining scripts written by other people (including your past self), consistent indentation is a problem. I can't count how many times I've opened a script and found it littered with tab characters and varying numbers of spaces. Before I can even attempt to fix a bug or add a feature, I have to clean it up and, depending on the length of the script, this can be a very time consuming endeavour. There has to be a better way!

First let's tackle some vim config options to set your preferred method of indentation. My preference is to use 4 spaces so my config would look something like this (keep in mind that a single double quote indicates that the remainder of a line is a comment):

set tabstop=4     " Width of a tab character
set shiftwidth=4  " Affects how automatic indentation occurs as well as the <<, >>, and == commands (see below)
set expandtab     " Changes intepretation of the <TAB> key. If set, <TAB> will insert 'softtabstop' spaces
" If softtabstop is unset, its default value will be tabstop

Note: For more details, the "Identing source code" post on the Vim Wiki (linked in the reference material below) has some useful information.

Now it's time to get rid of those tab characters. Sure you could write up a little regex to do this (think :%s/\t/ /g) but let's take a look at some built-in commands for easily displaying & replacing tab characters.

:set list  Displays white characters in a file. Tab characters display "^I" by default and end-line
:retab     Converts all tab characters to the number of spaces set in tabstop if expandtab is set

So we've got our tab characters out of the way. What about lines that are indented with more/less than 4 spaces? We've got some nifty commands for that as well:

<<  Shift current line left by "shiftwidth"
>>  Shift current line right by "shiftwidth"
==  Trigger auto-indent on current line

So if I've got a line that's indented 2 spaces, I can use "==" to autoindent it. If that's not where I want it, I can use "<<" or ">>" to shift it (using spaces) in my desired direction. I don't know about you, but I think that's definitely more efficient than hopping into insert mode and adding slapping the space bar.

Until next time, Happy Viming!

Reference Material: Beautiful Vim Cheat-Sheet Poster

Reference Material: Vim Wiki - Indenting source code


NoVIMber 02, 2014 - Screen alignment based on cursor position

The ideas are flowing in! I think I've already come up with enough ideas for NoVIMber posts to last me a week or so!

Far too often I find myself typing on the top or bottom line of my window and wanting to reference lines above or below that are no longer visible. In emacs, C-l would make your current cursor line the center line in the buffer. Pressing C-l again would make your current cursor line the top line of the buffer. Pressing C-l a third time would make your current cursor line the bottom line of the buffer. This is very handy but how can we do it in Vim? Easy!

Bringing your cursor line to the top of the window:

zt - Redraw cursor line at the top of the window

Alternatively, you can do z<CR> (<CR> represents "carriage return" or "enter" on your keyboard). The primary difference between z<CR> and zt is that zt will maintain your cursor's position (column) on the cursor line whereas z<CR> will bring your cursor to the beginning of the first non-whitespace character on the cursor line once redrawn.

Bringing your cursor line to the middle of the window:

zz - Redraw cursor line at the center of the window

As with zt & z<CR>, we have a second command that can perform a similar operation. "z." will redraw the cursor line at the center of the window but will not preserve your cursor's position (column) on the line. It should also be noted that you'll want to be careful using zz if you're also a regular caps lock user. zz and ZZ (write & exit) are two VERY different commands.

Bringing your cursor line to the bottom of the window:

zb - Redraw cursor line at the bottom of the window

Just like the previous examples, there is a second command that performs similarly to zb: "z-". Again, "z-" will not preserve your cursor's position (column) on the line.

That's all for today! Happy Viming!

Reference Material: Beautiful Vim Cheat-Sheet Poster

Reference Material: Vim documentation: scroll - Scrolling relative to cursor


NoVIMber 01, 2014 - Moving through large files in VIM

Let's get this NoVIMber 2014 movement under way with some simple movement shortcuts that I hadn't memorized previously. While using emacs, I really liked using C-v and M-v instead of having to move my hand and hit Page Up/Down. I've never put the time into learning the equivalent shortcuts in Vim until now. Vim actually has a couple of ways to navigate large files.

Moving halfway through pages:

^u - Half Page Up
^d - Half Page Down

Pretty self-explanatory. I'm commiting this to memory by remembering that "u" corresponds to "up" and "d" corresponds to "down".

Moving through full pages:

^b - Back a full page
^f - Forward a full page

Also self-explanatory. I'm remembery this as "b" for "Back" and "f" for "Forward".

One more thing I'd like to cover in this NoVIMber update - Moving to the first and last line of a file. Typically if I wanted to get to the first line in a file, I would just do ":1". That's not a bad way to do it but the recommended way is...

Moving to the beginning and end of a file:

gg - First line of file
G - Last line of file

For "gg", I'm remembering it as "go go" (yes, Inspector Gadget reference). It actually refers to the "goto line" command. If you provide a number to "gg" (ex: 5gg) you'll go to the nth line (line 5 in our example). If you provide no number, it defaults to line 1. "G" actually refers to the same command ("goto line") but defaults to the last line in a file rather than the first. "5gg" and "5G" would give you the same result.

That's all for this first NoVIMber 2014 update! I'll hopefully have another before the end of the day! Happy Viming!

Reference Material: Beautiful Vim Cheat-Sheet Poster

Reference Material: Vim documentation: motion - Up-down motions


NoVIMber 2014

Now let's talk about the reason that I REALLY wanted to get this site up quickly. For quite a while I've been wanting to dedicate a month to learning something new about Vim daily. Actually this idea dated back to a darker time in my life - when I used emacs as my primary development editor (just kidding, emacs is fine). What better month to do this in than November!

And thus NoVIMber was born! I'm going to make a solid effort to look at Vim cheat sheets, read Vim blog posts, and thumb through my "Learning the Vi and Vim Editors" book to find a useful feature every single day of NoVIMber! I'll try to make time to post them here daily but there will probably be some days where I'll be playing catch-up. Since today (well, Nov 1st) was "wasted" getting this new site up and running, I'll be learning & posting about 2 new things on the 2nd.

Happy Viming!