I often open the results of an external project-wide find | xargs grep command into a new tab like this :tabnew|read !find . -iname \*.py | xargs grep -n 'pattern'

I then use gf to open the matching files and perform edits. While this is handy, the file opens with the cursor on the top-most line of the file.

I want to be able to jump directly to the exact line as indicated by the results (note the use of grep -n to include line numbers in the results).

Is it possible to "promote" or "convert" the results of the command to a quickfix or location list?

Or, conversely, is there a command other than gf that will jump to not only the file but the exact line in the file as indicated by the results?

[Edit: I know of :vimgrep /pattern/ **/*.py but I don't know how to tell it not to follow symlinks (whereas find won't follow links unless -L is specified). There's also the problem of ** exhausting the command buffer if there are too many files... hence why I use find | xargs grep.]


3 Answers 3


The gF command is jumping at a specific line within the file.

It open the file at the number specified after the file name where the file name and the line number are separated by a non isfname character.

Your grep result need to be adapted accordingly.

  • 1
    ah... so simple! thank you :) [btw, the filepath:line notation seems to be supported just fine out of the box]
    – textral
    Commented Dec 16, 2022 at 4:10

To answer your question more directly, you can use :help :cexpr or :help :cgetexpr in combination with :help system() to populate the quickfix:

:cexpr system("find . -iname \*.py | xargs grep -n 'pattern'")

Once the quickfix is populated, you can use :help :cn, :help :cp, :help :cc, etc. to move around and/or open the quickfix window with :help :cwindow:


  • 1
    that's awesome! even better than using tabnew|read + gF because I don't have to move the cursor over the file name at the beginning of a line in the results list. Thanks!
    – textral
    Commented Dec 17, 2022 at 14:54

Here's a simple Neovim/Lua example, for inspiration:

        print('🐰 torgling the flidgets ...')
        local out = vim.fn.systemlist("torgle ./flidgets.txt")
        if vim.v.shell_error == 0 then
            print('nothing to see here')
        local files = {}
        for _, file in pairs(out) do
            local parts = {}
            for part in string.gmatch(file, "%S+") do
                table.insert(parts, part)
            table.insert(files, {filename = parts[1], lnum = parts[2], col = parts[3]})
    {nargs = 0}
  • Your answer could be improved if it explained how this function addresses the question.
    – Friedrich
    Commented Mar 23 at 9:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.