In most editors searching is just a way to ask your editor where you can find something. In Vim it’s also a tool for extending your selection, deleting chunks, and more. That probably sounds weird, and slow, but trust me. Once you get the used to it, it’s spectacular, and well cover it in the sections on Cut, Copy, Paste and visual mode.
Vim’s default search behavior is, in my opinion, excessively restrictive, and unhelpful. It is case sensitive, doesn’t highlight the matches, and doesn’t start finding results until you hit enter. All of this is easily changed, but I’d like you to be able to see the effects as you make them, and to do that you need to be able to search.
How to search
To search forward (down) in your text enter command mode and type a forward slash followed by your search term.
<ESC>
/some search term<RETURN>
To search backwards in your text enter command mode and type a question mark followed by your search term.
?some search term<RETURN>
If you’ve got something on the clipboard you can type the slash (or ?
) and then
paste in the bit you want to search for before hitting enter.
Vim has its own regular expressions syntax which its searches use.
It is a lot like Perl’s, but you don’t need to worry about that now. The
only notable thing that might raise an eyebrow right now is that the period
character is a wildcard in regular expressions. So, if you absolutely need it
to match a period, you escape it with a backslash. To find the end of the
previous sentence I might search for /backslash\.
Going to the next match
In command mode type n
for “next”. Each n
will jump you to the next match in
whatever direction you’re searching in. If you’ve gone past something and want
to go in the other direction type N
. This is a common convention with Vim
commands. Changing the case of a command frequently changes the direction the
command works in.
There are more cool things you can do with search, like using regular expressions, finding other occurrences of the current word, listing all the matching lines in your file, and more.
Customizing Search
As I mentioned, the default configuration for search kind-of sucks. To customize
the way your searching works by default we need to edit your vimrc
file. That’s where all your custom configurations will live. After each section
you add run :source %
and then try some searches in the file to test the effect of adding it. Sourcing is explained in the vimrc section.
Note: because we’re customizing your vimrc I won’t be including the
colon before the following set
commands. When you’re not adding a command to a
config file you typically will run it with the preceeding colon. I.e. set foo
in a config, and :set foo
when you just want to modify behavior in the current
window.
$ mvim ~/.vimrc
Let’s start by blocking off a section of the file for tweaks to how searching
works. Add the following comment lines to the bottom of your ~/.vimrc
As we
go, you can add your customizations in the middle.
"------------------------------------------------
" BEGIN SEARCH MODIFICATIONS
" END SEARCH MODIFICATIONS
"------------------------------------------------
Now, let’s make searching work the way you want it to. Read the following and add the commands that sound good to you.
Every time you add one type :source %
from within your vimrc to test
it out. If you don’t like it. Get rid of it. You’ll need to restart to make some
things go away, but not to add things.
Case Sensitivity
My personal preference is for case _in_sensitive searches by default. To get that you’d add the following to your search modifications section.
set ignorecase
Sometimes though, you want case sensitive searches. If you’ve added
set ignorecase
to your ~/.vimrc
you have two options. You can explicitly
tell it to be case sensitive by typing :set noignorecase
(:set noic
for
short). I’m not really a fan of that option though. Instead I prefer to have
on-demand case sensitivity by combining set ignorecase
with set smartcase
set ignorecase
set smartcase
If you have both turned on then searches will be case sensitive whenever your
search term includes a capital letter. For example, searching for set
will
find “set”, “Set”, and “sEt” but searching for Set
will only find “Set”.
Highlighting
Most people like their editors to highlight the things the searches find.
set hlsearch " hlsearch means highlight search
The search results continue to be highlighted until you search for something
else, or you turn off the highlights from the last search. To turn off the
highlighting (until you search again) use :nohl
(no highlight).
Turning off higlights
Many people just search for gibberish to turn them off. E.g. /sthsth
I
suggest not doing that. The problem is that it fills your search history
with garbage. Vim remembers everything you’ve searched for in the current
session, and it’s just as useful as your bash history. Type /
or ?
and
use the arrow up/down keys to recall previous search patterns. Hit enter to
choose one. You can also edit a pattern, and press Enter to search for
something different.
Immediate results
Some people like it to highlight search results immediately, as they are still typing in the search term. This is like Google giving you results before you finish typing your question. Vim can do this too. It’s called “incremental search”.
set incsearch
There is an odd quirk to Vim’s incremental search. A search isn’t complete until you hit enter. If you start typing, and it jumps to the next result, you may think “Perfect, I want to start typing there!” but you can’t, because you’re still commanding it to search. Hit enter to complete the search and stay on the current result. You can also hit escape to cancel the search and jump back to where you were before you started searching.
Aside:
I sometimes search for a thing with no intention of moving my cursor to it. “What was that method signature again?” I’ll start the search, see the result, then hit escape to jump back.
Stopping at the end (or start)
By default searches in vim wrap. E.g. if you hit the last match in the file and
hit n
(for next) it will wrap around and jump to the first match from the top,
and vice-versa when searching backwards. When your search hits the bottom Vim
will display a message in the bottom left of your screen “search hit BOTTOM,
continuing at TOP” or the opposite if searching backwards.
I like this behavior, but maybe you’d like to turn it off. Vim calls this feature “wrapscan” so…
set nowrapscan " do not wrap around
Again, I don’t recommend this, but this is your editor, so I wanted to give you the option.
Searching Multiple Files
Vim’s built in tool for searching multiple files is called vimgrep
. I highly
recommend you check out the Vimcast on “Searching Multiple Files With
Vimgrep”
There is a ton of functionality in vimgrep
and it’s something you learn more
about in the future. For now, I’ll give you the quick and dirty version.
Just like normal /
and ?
searches Vimgrep takes a regular expression.
Vimgrep takes a regular expression.
Normally a search starts with a slash (or question mark)
and ends with hitting return. With vimgrep you want to bound the start and end
of your search with slashes /my search term/
and then you follow it with the
files you want to search. The file part works pretty much like you’d expect. It
can take a list of files (yuck!) or wildcards (yay!). I’ll cover the
wildcards in a second.
I’m going to assume you would like a nice little window with a nice clickable list of all your results in it. Yeah? Ok. Well, add this little snippet to your vimrc.
augroup vimgreplaunchesquickfix
autocmd!
autocmd QuickFixCmdPost [^l]* cwindow
autocmd QuickFixCmdPost l* lwindow
augroup END
When vimgrep searches it puts all its results in a special buffer called Quickfix. Normally that’s hidden away. This code tells Vim that whenever you execute a Quickfix command it should display the results, which look like this:
My window has been split, and the bottom half is filled with the results.
They’re grouped alphabetically by file. If I double-click on any of the
lines, the top half of my window will jump to that search result. Putting your
cursor on a line and hitting enter will also jump to that search result. I can
click into the results pane and scroll to see more. I can search in it to
find things in my results. When you’re done with the results pane click into it
and tell vim to :quit
Well cover split windows later. For now know that if you’re on
the terminal (mouse input doesn’t work there) you can type <CTRL>ww
to switch
what pane currently has focus.
Let’s say I wanted to search for “wildcard” everywhere in my project.
:vimgrep /wildcard/ **
Vimgrep will jump to the first match (maybe in another file). At the bottom of my screen it will show me something like (1 of 7):
followed by the line that matched.
T> You might have noticed in the screenshot that my regexp ended with
T> /j
. Adding that j
(for jump) tells vimgrep to not jump you to the
T> first result. Personally I hate the jumping so I always use it. There are
T> other modifiers you can apply to the regexp just like in most programming
T> languages.
Going to the next vimgrep result.
If you want to “next” through the results like a normal search you, sadly,
don’t just type n
like normal searches. Instead you type :cnext
and
:cprevious
to go to the next or previous match. The shorter versions are
:cn
and :cp
which is… slightly better.
Wildcard notes
*.md
means all files in the current directory ending with “.md”**
means all files in this directory and all the subdirectory**/*.md
means all files in the current and subdirectories that end with “.md”