camspiers/snap

Is there a way to change cwd before select?

zetashift opened this issue · 19 comments

For searching through my dotfiles I currently have:

  ;; Search through dotfiles
  (local config (vim.fn.stdpath :config))
  (snap.register.map [:n]
                     [:<Leader>fP]
                     (fn []
                       (snap.run {:prompt "Config files"
                                  :producer (fzf (producer-file.args {} (.. config "/fnl/magic")))
                                  :select select-file.select
                                  :multiselect select-file.multiselect
                                  :views [preview-file]})))

But it the path shows up in full like this:
image

For Telescope I had this configured:

M.search_dotfiles = function()
  require("telescope.builtin").find_files({
    prompt_title = "NeoVim Config",
    cwd = vim.fn.stdpath("config"),
  })
end

Is there anyway to change the cwd so I see the relative path from config rather than the full path?

maybe you can use something like this

  local general = snap.get('producer.fd.general')
  snap.run {
    producer = snap.get'consumer.fzy'(
    function(request)
      local cwd = vim.loop.cwd() 
      return general(request, {args = {'--type=file', '--hidden', '-no-ignore'}, cwd = cwd})
    end
    ),
    select = snap.get'select.file'.select,
    multiselect = snap.get'select.file'.multiselect,
    views = {snap.get'preview.file'}
  }

replace vim.loop.cwd() in the above example with vim.fn.stdpath('config')

Thanks @saadparwaiz1 ! I tried translating it to fennel and I currently have this:

  ;; Search through dotfiles
  (local config (.. (vim.fn.stdpath :config) "/fnl/magic" ))
  (snap.register.map [:n]
                     [:<Leader>fP]
                     (fn []
                       (snap.run {:prompt "Config files"
                                  :producer (fzf (fn [request]
                                                    (general request { :args ["--type=file" "--hidden" "-no-ignore"] :cwd config })))
                                  :select select-file.select
                                  :multiselect select-file.multiselect
                                  :views [preview-file]})))

But the result list shows up empty :(.

You need to wrap vim.fn.stdpath with a snap.sync command.

Is there a way to pass arguments to (snap.sync vim.fn.stdpath)? Looking at the function signature of snap.sync I can't figure it out :S.

try doing this: snap.sync(function() return vim.fn.stdpath("config") end)

  ;; Search through dotfiles
  (snap.register.map [:n]
                     [:<Leader>fP]
                     (fn []
                       (snap.run {:prompt "Config"
                                  :producer (fzf (fn [request]
                                                    (local config (snap.sync (fn [] (vim.fn.stdpath :config))))
                                                    (general request { :args ["--type=file" "--hidden" "-no-ignore"] 
                                                                       :cwd  config})))
                                  :select select-file.select
                                  :multiselect select-file.multiselect
                                  :views [preview-file]})))

Thank you! But still an empty result list :(.
image

Does it work it you hardcode the cwd?

Does it work it you hardcode the cwd?

 (general request { :args ["--type=file" "--hidden" "-no-ignore"]
                              :cwd  "/home/rishi/.config/nvim/fnl/magic"})

So with this it still doesn't work(and config up to evaluated to the correct directory too), maybe I'm using general wrong mhmhm

I made a mistake in the args, change your snippet as follows:

 (general request { :args ["--type=file" "--hidden" "--no-ignore"]
                              :cwd  "/home/rishi/.config/nvim/fnl/magic"})

This works for me

local function config()
  return vim.fn.stdpath('config')
end

local snap = require('snap')
local general = snap.get('producer.fd.general')
snap.register.map('n', '<leader>fP', snap.create(function ()
  return {
    prompt = 'Config'
    producer = snap.get'consumer.fzy'(
    function(request)
      local cwd = snap.sync(config)
      return general(request, {args = {'--type=file', '--hidden', '--no-ignore'}, cwd = cwd})
    end
    ),
    select = snap.get'select.file'.select,
    multiselect = snap.get'select.file'.multiselect,
    views = {snap.get'preview.file'}
  }
end))

Screenshot 2021-06-25 at 15 12 31

I made a mistake in the args, change your snippet as follows:

 (general request { :args ["--type=file" "--hidden" "--no-ignore"]
                              :cwd  "/home/rishi/.config/nvim/fnl/magic"})

Yup, that works! Thanks a lot, I wish I saw the double dash sooner too

@saadparwaiz1 well there is one hiccup only this is my code:

  (snap.register.map [:n]
                     [:<Leader>fP] 
                     (fn [] (snap.run {:prompt "Config"
                                       :producer (fzf (fn [request]
                                                        (local cwd (snap.sync (fn [] (.. (vim.fn.stdpath :config) "/fnl/magic"))))
                                                        (general request { :args ["--type=file" "--hidden" "--no-ignore"]
                                                                           :cwd  "/home/rishi/.config/nvim/fnl/magic" })))
                                       :select select-file.select
                                       :multiselect select-file.multiselect
                                       :views [preview-file]})))

So when I'm in my config folder <leader>fP works fine, but whenever I'm in a different folder I get this error:
image

@zetashift Ah it seems that the files are being opened relative to the current directory instead of the cwd being passed. You'll have to make similar changes to view and select to get it working properly

@zetashift @saadparwaiz1 you need to pass absolute = true & that should work.

general(request, {absolute = true, args = {'--type=file', '--hidden', '--no-ignore'}, cwd = cwd})

Trying to get this working with the newly map API, I'm not sure how to pass this along tho. This is what I currently have.

(snap.map :<leader>fP
          (file { :prompt "Neovim Config"
                  :producer :ripgrep.file
                  :args [ (config) ]})
          { :command :find-config })

edit: or is it more like this?

(snap.map :<leader>fP
          (file { :prompt "Neovim Config"
                  :producer "fd.file"
                  :args [ :cwd (config) ]})
          { :command :find-config })

@zetashift I think if you want to change cwd you have to create a custom producer using the general ripgrep.general or fd.general.

Or look at the example called "Search files in multiple paths" (sorry I'm on my phone and I can't link to it directly)

Also not all APIs are currently supporter with snap.map so not sure if that example will work with snap.map or not but the custom producer will work.

I think I'm having a similar issue. When looking at a file in a subdirectory of a git repo, using fzf and ripgrep or git to find a filename will only find files in the file's directory or subdirs. (May be based on the cwd of the first file to be opened?)

Error executing luv callback:
...re/nvim/site/pack/paqs/start/snap/lua/snap/common/io.lua:136: ENOENT: no such file or directory: [...filepath...]
Press ENTER or type command to continue

The mapping, the function

Looking at your example

I've came up with:

(local fzf (snap.get :consumer.fzf))

(local general (snap.get :producer.ripgrep.general))
(local config-producer (fzf (fn [request]
                                (general request { :absolute true
                                                   :args ["--vimgrep"]
                                                   :cwd  (snap.sync (fn [] (.. (vim.fn.stdpath :config) "/fnl/magic" )))
                                })
)))

;; and then use it like this

(snap.register.map [:n]
                   [:<leader>fP]
                   (fn []
                     (snap.run {
                              :prompt :Config
                              :producer config-producer
                              :select (. (snap.get :select.vimgrep) :select)
                              :multiselect (. (snap.get :select.vimgrep) :multiselect)
                              :views [(snap.get :preview.vimgrep)]
                     })
))

However an empty floating window is the only thing that shows up :(

This is what happens if I replace :producer.ripgrep.general with :producer.fd.general
image