DEV Community

khalil chermiti
khalil chermiti

Posted on

Neovim Grepping and File Search Without Plugins

Neovim already has powerful built-in tools for searching text and files.
You don't need Telescope or any plugin for basic workflow.


Grepping Text with :grep

Neovim can use any external search tool through :grep.

Check the current grep program:

:set grepprg?
Enter fullscreen mode Exit fullscreen mode

Most setups will show something like:

grepprg=rg --vimgrep -uu
Enter fullscreen mode Exit fullscreen mode

This means Neovim uses ripgrep (rg) for searching.


Better grepprg Configuration

A good default setup:

vim.opt.grepprg = "rg --vimgrep --smart-case --hidden"
Enter fullscreen mode Exit fullscreen mode

What these flags do

Flag Description
--vimgrep Output format compatible with quickfix
--smart-case Ignore case unless uppercase is used
--hidden Search hidden files too

You can also exclude useless folders:

vim.opt.grepprg =
    "rg --vimgrep --smart-case --hidden " ..
    "--glob '!node_modules' " ..
    "--glob '!.git' " ..
    "--glob '!dist' " ..
    "--glob '!build'"
Enter fullscreen mode Exit fullscreen mode

Using :grep

Basic usage:

:grep pattern
Enter fullscreen mode Exit fullscreen mode

Example:

:grep useState
Enter fullscreen mode Exit fullscreen mode

This searches inside the current working directory.

Results are added to the quickfix list.

Open it with:

:copen
Enter fullscreen mode Exit fullscreen mode

Useful Quickfix Commands

Command Description
:copen Open quickfix list
:cclose Close quickfix
:cnext Next result
:cprev Previous result
:cfirst First result
:clast Last result

Filtering Results

You can filter quickfix entries:

:Cfilter keyword
Enter fullscreen mode Exit fullscreen mode

Example:

:Cfilter test
Enter fullscreen mode Exit fullscreen mode

Only entries containing test stay visible.


Replace Across Search Results

One of the best things about quickfix:

:cdo s/old/new/g | update
Enter fullscreen mode Exit fullscreen mode

Example:

:cdo s/console.log/logger.info/g | update
Enter fullscreen mode Exit fullscreen mode

This updates every matched file.


Better Grep Keymap

A clean keymap:

vim.keymap.set("n", "<leader>g", function()
    vim.cmd("silent grep! " .. vim.fn.input("Grep > "))
    vim.cmd("copen")
end)
Enter fullscreen mode Exit fullscreen mode

Why this is better

  • asks for input
  • prevents jumping to first result
  • automatically opens quickfix
  • cleaner than command chaining

Usage:

<leader>g
Enter fullscreen mode Exit fullscreen mode

Then type:

keymap
Enter fullscreen mode Exit fullscreen mode

searching for text with :grep

qflist with results

You instantly get all matches.


Searching Files with :find

Neovim also has built-in file search.

Basic usage:

:find filename
Enter fullscreen mode Exit fullscreen mode

Out of the box it's limited, so we improve it.


Configure Search Paths

Add recursive search:

vim.opt.path:append("**")
Enter fullscreen mode Exit fullscreen mode

Now :find searches inside subdirectories.


Ignore Large Folders

Without ignores, search becomes slow.

vim.opt.wildignore:append({
    "*/node_modules/*",
    "*/dist/*",
    "*/build/*",
    "*/target/*",
    "*/.git/*",
})
Enter fullscreen mode Exit fullscreen mode

Better Completion

Enable menu completion:

vim.opt.wildmenu = true
vim.opt.wildmode = "longest:full,full"
Enter fullscreen mode Exit fullscreen mode

Now tab completion becomes much better.

Example:

:find keymaps
Enter fullscreen mode Exit fullscreen mode

Neovim autocompletes matching files.

Searching with :find


Add File Extensions Automatically

Useful when working with specific languages:

vim.opt.suffixesadd:append({
    ".lua",
    ".ts",
    ".tsx",
    ".js",
})
Enter fullscreen mode Exit fullscreen mode

Now you can do:

:find init
Enter fullscreen mode Exit fullscreen mode

Instead of:

:find init.lua
Enter fullscreen mode Exit fullscreen mode

Example Workflow

Search for text:

:grep TODO
Enter fullscreen mode Exit fullscreen mode

Open results:

:copen
Enter fullscreen mode Exit fullscreen mode

Replace text in all results:

:cdo s/TODO/DONE/g | update
Enter fullscreen mode Exit fullscreen mode

Find a file:

:find config
Enter fullscreen mode Exit fullscreen mode

Jump between results:

:cnext
:cprev
Enter fullscreen mode Exit fullscreen mode

Full Minimal Config

-- grep
vim.opt.grepprg =
    "rg --vimgrep --smart-case --hidden " ..
    "--glob '!node_modules' " ..
    "--glob '!.git' " ..
    "--glob '!dist' " ..
    "--glob '!build'"

-- recursive file search
vim.opt.path:append("**")

-- ignored folders
vim.opt.wildignore:append({
    "*/node_modules/*",
    "*/dist/*",
    "*/build/*",
    "*/target/*",
    "*/.git/*",
})

-- better completion
vim.opt.wildmenu = true
vim.opt.wildmode = "longest:full,full"

-- auto extensions
vim.opt.suffixesadd:append({
    ".lua",
    ".ts",
    ".tsx",
    ".js",
})

-- grep keymap
vim.keymap.set("n", "<leader>g", function()
    vim.cmd("silent grep! " .. vim.fn.input("Grep > "))
    vim.cmd("copen")
end)
Enter fullscreen mode Exit fullscreen mode

Top comments (0)