NoVIMber 08, 2014 - Introduction to Buffers

I got this out a little later than I had anticipated! Hopefully I'll have time to finish up my next post by the end of the day. I'd hate to perpetually be a day behind going forward! This is going to cover the very basics of buffers. Buffers can be a difficult concept to explain. A buffer is defined as the text of a file that is currently in memory. Think of it like this: when you open a file in Vim, it loads the contents of that file into memory and then displays that file to your current "window". A buffer does not have to be attached to a window though. We'll touch on windows a bit more in another post. For now we'll focus on buffers and the default single window that gets created when Vim starts.

Buffer Types

There are 3 different buffer types:

Active    Is displayed to a window and file contents have been loaded into the buffer
Hidden    Is not displayed to a window but file contents have been loaded into the buffer
Inactive  Is not displayed and does not contain any text

Buffer Basics

You can open a file in a new buffer with:

:edit /path/to/file

By default this will open /path/to/file into a new buffer and attach that buffer to your active window. If your current active buffer has been modified, you might see "E37: No write since last change (add ! to override)". By default an active buffer cannot become a hidden buffer if it has unsaved modifications. If you give it the ! to override, it will revert all of your modifications in the buffer. If you want to keep your modifications, you can do so with:

:set hidden  Allows a buffer to become hidden when on

It's useful to be able to see what buffers currently exist and to be able to switch between them at will. The next couple of commands will help with that:

:buffers  Displays a list of current buffers
:ls       Same as :buffers

Let's look at some example output of that:

  1 #h   "file1"                        line 1
  2      "file2"                        line 0
  3 %a + "file3"                        line 2

Each buffer is assigned a unique number that will not change - the number in the first column. The values in the second column are "indicators". Here are a few of the indicators that are relevant to this example:

#  Alternate buffer (more on that below)
h  Hidden buffer
%  Buffer that is in the current window
a  Active buffer
+  Modified buffer
=  Readonly buffer

All of those are self-explanatory except for the alternate buffer.

The Alternate Buffer

The alternate buffer provides an easy way to flip between two buffers in Vim. In the above example, file3 is our active buffer attached to our current window. file1 is our alternate buffer. We can switch to the alternate buffer with:

:edit #  Edit the alternate buffer
CTRL-^   Same as :e #. On most keyboards ^ is on the 6 key, in that case this command would be CTRL-6

Once I've flipped to the alternate buffer, my previous buffer will become the new alternate buffer. I can get back to it by flipping a second time.

Moving Between Buffers

If you're editing more than two buffers, things get a little more complicated. There are several ways to switch between multiple buffers.

:buffer [N]  Edit buffer N
:bnext       Edit next buffer
:bNext       Edit previous buffer
:bprevious   Same as :bNext

All of these commands are referencing the buffer number. If you're on buffer 2 and you use :bn, that will put you on the next highest numbered buffer. If 2 is the highest numbered buffer, it will wrap you around to the lowest numbered buffer. As you'd imagine, :bp/:bN works the same way.


That's about all I'm going to cover in today's post. We'll cover more buffer related stuff after we've covered the basics of windows in Vim. Happy Viming!

Reference Material

Vim documentation: windows

NoVIMber 07, 2014 - Advanced searching

It's Friday night, I've got a glass of wine, an episode of Stargate SG-1 is playing in the background, and I'm ready to type some words about Vim! This little project has been way more rewarding than I could have expected!

Searching in an open file is an important aspect of efficiently editing in Vim. I briefly mentioned the basics of searching (forward and backward) in yesterday's post but let's see it again:

/searchstring  Forward search
?searchstring  Backward search

If you reach the end/beginning of a file, the default behavior is to "wrap" to the top/bottom of the file and start again. Sometimes this is really useful but sometimes it's annoying. Fortunately, it's easy to enable/disable:

:set nowrapscan  Disable search wrapping in a file
:set wrapscan    Enable search wrapping in a file

Case Sensitive Searching:

By default, search is case-sensitive. Searching for "thing" will not match "Thing", "THING", or "thinG". If you'd like to ignore casing you can do:

:set ignorecase            Ignore case when searching
:set ignorecase smartcase  Ignores case if pattern is all lower-case. Conforms to case if pattern contains any upper-case letters

Regex Searching:

You can also do some regex style searching, you just need to remember to escape certain things such as (), +, |, etc... For example:

/\(dog\)*        Matches empty string, dog, dogdog, dogdogdog, etc...
/dog\+           Matches dog, dogg, doggg, etc...
/dog\|cat        Matches dog or cat
/dogg\(y\|ies\)  Matches doggy and doggies
/[0-9]           Matches a number
/[^0-9]          Matches any non-number

There are also "predefined ranges" that you can use to match certain types of characters:

\a  Matches an alpha character [a-zA-z]
\d  Matches a digit
\D  Matches a non-digit
\s  Matches whitespace
\S  Matches non-whitespace

There are more of these predefined ranges that could be useful. I just found these to be the most useful!

Hopefully this will help you when you're searching for that special thing inside of a file! For more information and a more thorough explanation of the topics I mentioned here, check out the reference material below! Happy Viming!

Reference Material: Vim documentation: usr_27

NoVIMber 06, 2014 - The much neglected Command-line mode

Command-line mode allows you to execute "Ex" commands, searches, and filters. Ex is a line editor. Vi was originally written as a visual interface for Ex. I know a lot of people that use command-line mode exclusively for a few common things:

:w   Write a file
:q   Quit a file without saving (append ! if you have made changes)

:[range]s/search/replace/  Basic search & replace

/searchstring  Forward search
?searchstring  Backward search

Until recently, I was also one of those people. In previous posts we've touched on a few specific Ex commands (:retab, :set list, and :reg come to mind). For today's post, I'd like to cover a few additional commands that could be useful.


For starters, let's cover a very useful and surprisingly underused/under-known command:

:help  Display Vim's help documentation in a new window

:help {command/subject}  Same as :help except jump to relevant section in documentation. Can include wildcards *, ?, and [a-z].

You'd be surprised how often this could come in handy... but I know very few people (myself included) that actually use it with any regularity. If you're not exactly sure what you're searching for, just try searching for something. I have had good success with finding information this way.


:history  Display the history of ":" Ex commands

: + CTRL-P/CTRL-N  Scroll through your history (CTRL-P is "previous" line and CTRL-N is "next" line... like Emacs!)

This one is a no-brainer as well but is very underused. Let's say that you've executed several search & replace commands but you're missing more data than you thought. The first place you should look is at the :history of your search & replace commands to make sure you typed them correctly. It's also really useful to be able to scroll through your history and execute Ex commands again (by pressing once you've selected your desired command).

Text Manipulation:

The next few commands are going to kinda be lumped together since they're mostly dealing with the processing of text. Most of these commands follow the same syntax pattern:

:[range] command [arguments ...]

Before we get into commands that follow this syntax pattern, let's see how we can represent different ranges:

.  The current line
$  The last line of your file
%  Every line of your file
7  Line 7 of your file

You can also represent ranges and do basic math in these ranges:

1,5  Every line from line 1 to line 5 including lines 1 and 5
+10  10th line below current line (. is assumed in this case)
$-8  8th line from the bottom

Global Actions

Global actions are so powerful! Let's look at the syntax and a few examples.

:[range]g/pattern/command  Find *pattern* within *range* and execute *command* on that line

:g/redhat/p  Print lines matching "redhat"
:g/suse/d    Delete all lines matching "suse" (no bias here at all)

Fun fact: this is where the command line utility "grep" got its name (:g/re/p). I can't count the number of times that I've (incorrectly) used the search & replace command to remove entire lines that match a pattern. This is so much easier! I've linked the Vim Wiki page for Global actions below in the reference material. Check it out to see more of the cool stuff you can do.

Filter Command

If search & replace and global actions aren't powerful enough, you can even leverage external command line utilities to help you out.

:range!command  Execute *command* on *range* lines

:%!sort  Uses the "sort" command line utility to sort all lines in your file

If you do not specify a range, the command will just be executed and the results will temporarily be displayed on your window. You could also see why it's a bad idea to grant users sudo access to Vim haha!

Well that about covers it for today! We're almost a week into NoVIMber and there's still so much to cover. I might eventually double-back and pull from previous posts to elaborate on certain subjects since a few things have been skimmed.

Until next time, Happy Viming!

Reference Material: Vim documentation: helphelp - :help

Reference Material: Vim Wiki - Power of g

Reference Material: Vim documentation: usr_20

Reference Material: Vim documentation: cmdline

NoVIMber 05, 2014 - Commands in insert mode

This post is going to cover commands that can be executed while in insert mode. There are a lot of these commands but I only plan on touching a few that were interesting to me.

First let's take a look at how you can get out of insert mode:

Getting out of Insert mode
<Esc>   End insert or replace mode finishing abbreviation
CTRL-[  Same as <Esc>
CTRL-C  Quit insert mode without checking for abbreviations. Does not trigger the "InsertLeave" autocommand.

If you don't like moving your hand to the key, you could use CTRL-[ as a replacement. CTRL-C would probably work just as well in most cases but if you have anything that depends on the InsertLeave autocmd, that will not trigger with CTRL-C. If CTRL-C (or any other sequence) is easier for you, you could always map that to . I personally map ndc> so that I can just mash the two together (in any order) and hop out of insert mode:

inoremap jk <esc>
inoremap kj <esc>

What if we want to delete some text without leaving insert mode?

Deleting text in Insert mode
CTRL-W  Deletes the word before your cursor
CTRL-U  Deletes all characters in the current line before your cursor

We can also insert the contents of a register without leaving insert mode!

Inserting text from a register in Insert mode
CTRL-R {register}         Insert the contents of a register. Once you press CTRL-R, a " (double quote) will appear under your cursor. Text is inserted as if you typed it with your keyboard.
CTRL-R CTRL-R {register}  Same as CTRL-R except the text will be inserted literally rather than as if you had typed it.

There are a couple of other CTRL-R variants. Check out the Vim documentation linked below for more details on those.

You can also manage line indentation without needing to go to command mode! I've already started using this one and it has made my life a lot better!

Managing indentation in Insert mode
CTRL-T    Insert a single "shiftwidth" size indent at the beginning of the current line
CTRL-D    Delete a single "shiftwidth" size indent from the beginning of the current line
0 CTRL-D  Delete all indentation in the current line

The last thing I'd like to cover is the ability to "literally" insert a character. For example, let's say that you have expandtab set but you want to insert a real tab character:

Inserting a "literal" character in Insert mode
CTRL-V  Insert follwing character literally
Example: CTRL-V <TAB> would insert a tab character at cursor location

There's a lot more that you can do inside of insert mode. I intentionally wanted to keep this post brief. I may touch on more of these commands in a later post.

Happy Viming!

Reference Material: Beautiful Vim Cheat-Sheet Poster

Reference Material: Vim Documentation: insert - Special keys

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)


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