Follow @learnvim for more Vim tips and tricks!
You may find yourself in situation where you need to use Vim without plugins (inside a docker container or connecting to remote server for example). In that case, what will you do to search and open files quickly? You have to rely on Vim's built-in search methods. Luckily, Vim provides different ways to search and open files without plugins.
In this article, I will show different ways you can search and open files without plugins. Here are subjects I will cover:
- Opening files with
- Searching for files with
- Searching for pattern within files with
- Browsing files with
:edit is the simplest way to open a file in Vim.
fileexists, it opens that file in current buffer.
filedoesn't exist, it creates a new file in current buffer.
<tab>) works with
:e. For example, if your file is
./app/controllers/users_controllers.rb, you can do:
edit accepts wildcards. If you are only looking for
.yml files in root directory:
Post tab, Vim will list you all
.yml files in current directory to choose from.
You can also use
** to search recursively. Let's say you want to look for all
*.png files in your project:
You may get warning that there are too many file names, depending on your project size.
:e integrates well with
netrw, Vim's built-in text editor. If you pass it a directory instead of file, it will open a
netrw explorer (which I will cover later):
:e . :e test/unit/
By the way, when you opening a file with
:e, you can also pass an Ex command.
:e +EX_COMMAND /your/file
To go to line 5:
:e +5 /test/unit/helper.spec.js
To go to the first line containing
:e +/const /test/unit/helper.spec.js
To delete all empty lines:
:e +g/^$/d test/unit/helper.spec.js
Vim has a
:find method to find a file in our project. It finds a file in
:find package.json :find app/controllers/users_controller.rb
Autocomplete works with
:find p<tab> " to find package.json :find a<tab>c<tab>u<tab> " to find app/controllers/users_controller.rb
:find looks a lot like
:edit. You may wonder, "Why should I use find at all? Can't I just use edit?"
The difference is that
:find finds file in
path. Edit doesn't.
Let's learn a little about path. Once we learn how to modify our paths,
:find can become a powerful tool to search files.
To check what your paths are, do
By default, yours probably look like this:
Here is what they mean:
.means current directory
,,means anything relative to current directory
/usr/includeis a directory.
Let's assume this is our project structure:
▾ app/ ▸ assets/ ▾ controllers/ application_controller.rb comments_controller.rb users_controller.rb ...
You want to go to
users_controller without going through each directory (and doing a lot of
<tab> presses on the way). Path can shorten the journey.
controllers to your own path with:
What we just did is adding
app/controllers/ to our current path (run
:set path? again to see updated path). Now everything inside
app/controllers/ path, Vim will look when we tab.
Before we added
app/controllers/ to our path, if we type
:find u<tab>, nothing happens. That's because Vim only sees everything inside current directory
.. After adding new path, when we do:
:find u<tab> -> :find users_controller.rb
Vim finds and autocompletes it (assuming there is no other controller starting with
If you have nested directories inside
app/controllers, you might want to add
:set path+=app/controllers/** so autocomplete will find those files. The larger your directories, the slower finding each file may be.
If you're familiar with Rails, you might want to add paths for
:set path+=app/views). You can also add the entire app directory into your path (
You may be tempted to do something like:
To add everything in your project to your path so you can tab to any file quickly. While this may work for small project, I suggest you don't do it on large projects. On gargantuan projects, when I typed
:find a<tab>, Vim tried to find everything starting with "a" and froze momentarily. I don't think this is how path is supposed to be used.
Adding paths for your frequently visited directories takes only a few seconds and it lets you find files quickly, saving you a lot of time. You can even make it permanent by adding it to your vimrc (ex:
If you need to find a phrase within files, you can use grep.
Vim has two different greps:
- Internal (
:vim[grep]. Yes, this command is spelled
- External (
Let's go through *Internal grep* first.
:vim has the following syntax:
:vim /pattern/ file
/pattern/is a regex pattern of what we want to search
fileis the file(s) we pass. It accepts
For example, to look for all occurrences of
"before_action" inside all ruby files within
:vim /before_action/ app/controllers/**/*.rb
You'll notice that once Vim is done, you don't immediately see all results. This is because the search result is inside quickfix (
:h quickfix). To see the search result, type
I won't go over quickfix here. But here are some useful shortcuts to get started:
:cope[n] " Open the quickfix window :ccl[ose] " Close the quickfix window :cn[ext] " Go to the next error :cp[revious] " Go to the previous error :col[der] " Go to older error list :cnew[er] " Go to newer error list
You may notice that running internal grep (
:vim) can get slow if there are many matches. This is because internal grep (
:vim) reads all matches into memory. Vim loads each matching files as if they are being edited.
External grep, by default, uses shell
To search for
"require" inside a ruby file inside my controllers, I can do:
:grep require app/controllers/**/*.rb
**. It also displays via quickfix.
grepprg variable to determine which external program to run when running
:grep, so you don't have to always use shell
grep. I will not discuss how to do it here because the point is this article is to use default Vim config, but if you're interested, this article Faster Grepping in Vim shows you how to integrate with
Ag and Using ripgrep With Vim shows you how to use it with ripgrep.
netrw is Vim's built-in file explorer. In order to get started, you need two minimum settings in your
set nocp filetype plugin on
I will only cover the very basic of
netrw, but it should be enough to get started.
You can start
netrw when you launch Vim and passing it a directory instead of a file:
vim . vim src/client/ vim app/controllers/
netrw from inside Vim while editing a file, you can use
:e . :e src/client/ :e app/controllers/
netrw has its own set of commands to launch the explorer. Some of them are:
:Ex " Explore directory of current file (head) :Sex " Not kidding. It splits horizontally and start netrw on top screen :Vex " Split vertically
You can navigate with Vim motions.
hjkl and searches like
/?, work well. To go up one directory, use
netrw explorer, sometimes you need to create, delete, rename file/directory.
% " create new file d " create new directory R " rename file/directory D " delete file/directory
These should be enough to get you going.
:h netrw is very comprehensive. If you have time, I highly suggest checking it out.
Some of you may ask, "Do I need to use
netrw? Nerdtree looks much better."
It's up to you. I've used nerdtree for several years and I loved it. However, if you must use Vim without plugins and you're not used to
netrw basic navigations, you may lose some speed.
By the way, vim-vinegar is a good (lightweight) plugin to enhance
netrw if you decide to go with
Last but not least, Vim has many plugins to let you quickly search for/ within files. Here are some of them:
Plugins are awesome. I personally use
ripgrep for searching. I would recommend to learn what Vim can do without plugins before you use one. Only use the plugins you need.
I think this is a good place to stop. I've shown you different ways to search and open files in Vim with:
You don't know when you'll have to use Vim without any. Be the Vim expert in your team.
Thanks for reading. Happy coding!