camspiers / snap

A fast finder system for neovim.
The Unlicense
490 stars 17 forks source link

"File local" files #27

Closed TyberiusPrime closed 3 years ago

TyberiusPrime commented 3 years ago

I love snap!

With my old fzf based setup, I had a mapping to search for files starting in the directory of the current file.

I'm trying to reproduce this in snap, but I believe by the time my producer runs, I'm already in the 'snap buffer', and it's retrieving the wrong directory.

Can anybody point me into the right direction to work around this?

My current code

-- so we have something that snap.sync(vim.fn...) can call.
vim.cmd([[
    function! GetCurrentFileDir()
        let r = expand("%:p:h")
        return r 
    endfunction
]])

produce_local_files = function (request)
    local general = snap.get("producer.ripgrep.general")
    local default_args  = {"--line-buffered", "--files"}
    local tbl = snap.get('common.tbl')
    --local args  = tbl.concat(default_args, rg_args)
        local args = default_args -- of no concern for the example
    local cwd = snap.sync(vim.fn.GetCurrentFileDir)
    coroutine.yield({cwd}) -- that works out to pwd instead
    return general(request, {
            args = args,
            cwd=cwd
        })
end

snap.register.map({"n"}, {"<leader>F"}, function()
    snap.run {
      producer = snap.get'consumer.fzf'(produce_local_files),
      select = snap.get'select.file'.select,
    }
end)
camspiers commented 3 years ago

The request contains a prop called winnr, it's the id of the original window snap was launched from. You can use that to do what you want. I can help more tomorrow

TyberiusPrime commented 3 years ago

Thanks, I'm not versed enough in vimscript to find out what to do with that window number.

I've gone the other way now, I get the vaule before calling snap.run, which get's a warpped producer function:

produce_local_files = function (cwd)
    return function(request)
        local general = snap.get("producer.ripgrep.general")
        local default_args  = {"--line-buffered", "--files"}
        local tbl = snap.get('common.tbl')
        local args  = tbl.concat(default_args, rg_args)
        return general(request, {
                args = args,
                cwd=cwd
            })
    end
end

snap.register.map({"n"}, {"<leader>F"}, function()
    local cwd = vim.api.nvim_eval("expand('%:p:h')")
    snap.run {
      producer = snap.get'consumer.fzf'(produce_local_files(cwd)),
      select = snap.get'select.file'.select,
    }
end)
camspiers commented 3 years ago

I haven't tested and you need to add some vim.fn prefixes (I am on my phone), but something like this:

snap.sync(function ()
  return fnamemodify(bufname(winbufnr(request.winnr)), ":p:h")
end)
camspiers commented 3 years ago

I can help more tomorrow 😊

camspiers commented 3 years ago

This is now resolved with: https://github.com/camspiers/snap#search-files-in-multiple-paths

So with ripgrep.file.args you can now search in non-cwd's. The paths will be absolute, but I can work on making that better later.

For now the following will search in the directory of the current file:

snap.run {
  producer = snap.get'consumer.fzf'(
    snap.get'producer.ripgrep.file'.args(
      {},
      vim.fn.fnamemodify(vim.fn.bufname(), ":p:h")
    ),
  ),
  select = snap.get'select.file'.select,
  multiselect = snap.get'select.file'.multiselect,
  views = {snap.get'preview.file'}
}
TyberiusPrime commented 3 years ago

Very cool, thank you.

TyberiusPrime commented 3 years ago

For posterity, using ':p:.:h' will list the files relative to the cwd. Much better than the absolute files :p:h delivers.