Monday, June 16, 2008

Smart case-insensitive, incremental search using vim

My previous article describes my top annoyance with the vim text editor, namely, its syntax highlighting. In this article, I will tell on a close second annoyance, and what to do about it.

vim, by default, searches case sensitively. If you search for apple, you will find exactly that, but not Apple or APPLE.

In most situations, I want my searches to be case insensitive. To make search case sensitive, set the corresponding vim option by typing :set ignorecase (and press the return key).

ignorecase has a shorter alias called ic. You can type :set ic and it will have the same effect.

Now searching for apple will give you Apple, APPLE as well as apple.

But, what about the situations where you DO want case-sensitive searching?

You can always disable the ignorecase search, by typing the following and hit return:
:set noignorecase

Flipping between ignorecase and ignorecase can be tiresome for even the most patient. Luckily, vim has the smartcase option that you can use TOGETHER with ignorecase.

Type the following:
:set ignorecase (and hit return)
:set smartcase (and hit return)

With both ignorecase and smartcase turned on, a search is case-insensitive if you enter the search string in ALL lower case. For example, searching for apple will find Apple and APPLE.

However, if your search string has one or more characters in upper case, it will assume that you want a case-sensitive search. So, searching for Apple will only give you Apple but not apple or APPLE. It turns out to be quite satisfactory for most people (including yours truly).

While we are on the topic of vim search options, there is a third option that you should know:
:set incsearch (and hit return)

incsearch stands for incremental search. It means that you will see what vim matches as you type in each letter of your search string (without having to hit return before search is even attempted).

For example, you type / to initiate search, and right after you type the letter a, vim will highlight the a in apple. As you type the next letter p, vim will highlight ap in the word apple.

You can often find what you are looking for before you finish typing in the entire search string. It is also helpful if you are not quite sure of what you are searching for, and depending on the instant feedback as you type, you can make corrections to the search string by backspacing.

If you want to enable those options permanently, insert the following lines into your ~/.vimrc file.
set ignorecase
set smartcase
set incsearch

Happy searching!


Anonymous said...

Thanks! Very useful settings. -noob

Anonymous said...

Very useful, now i put it as my default settings for vi!

Anonymous said...

Thanks, useful tip
I suggest add them to vim tip wiki.

Anonymous said...

Very cool stuff,
I have added them all to my .vimrc.


Unknown said...

nice indeed

Anonymous said...

You can also insert a \c (case insensitive) or \C (case sensitive) metacharacter at the head of your search string. When you use one of these, all text that follows them, until the next case sensitivity metacharacter is encountered, is bound by that case sensitivity metacharacter.

For example, the following:

:/\capple\C Apple/

will find "apple Apple", "Apple Apple", "ApPlE Apple", but not "apple apple" or "apple ApPlE".

Using \c and \C means you can mix types of sensitivity in one search, whereas smartcase does not. Also, smartcase may be problematic when you really do want your search all lowercase, and not erroneously match similar uppercase strings.

If you can think in regex no problem (as I can), this may be a better option for you. If you prefer a more intuitive, do-what-I-mean interface, using smartcase etc. is probably better for you.

Anonymous said...

Error in the above: you can't mix case sensitivity in the way described; the first case sensitivity metacharacter in the pattern, \c or \C, decides what sensitivity the entire pattern follows, even the part of the pattern before the \c or \C. So inserting any \c or \C metacharacters later in the pattern doesn't change case sensitivity. You can still choose to be case sensitive on all-lowercase search patterns, though.

E Both said...

\c and \C was exactly what I was after, thanks Anonymous.