2

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.]

textral
  • 123
  • 4

3 Answers3

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.

Vivian De Smedt
  • 16,336
  • 3
  • 18
  • 37
  • 1
    ah... so simple! thank you :) [btw, the filepath:line notation seems to be supported just fine out of the box] – textral Dec 16 '22 at 04:10
3

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:

qf

romainl
  • 40,486
  • 5
  • 85
  • 117
  • 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 Dec 17 '22 at 14:54
0

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

vim.api.nvim_create_user_command('TorgleFlidgets',
    function()
        vim.cmd.cclose()
        print(' torgling the flidgets ...')
        local out = vim.fn.systemlist("torgle ./flidgets.txt")
        if vim.v.shell_error == 0 then
            print('nothing to see here')
            return
        end
        local files = {}
        for _, file in pairs(out) do
            local parts = {}
            for part in string.gmatch(file, "%S+") do
                table.insert(parts, part)
            end
            table.insert(files, {filename = parts[1], lnum = parts[2], col = parts[3]})
        end
        vim.fn.setqflist(files)
        vim.cmd.copen()
    end,
    {nargs = 0}
)
Sasgorilla
  • 125
  • 5