camspiers / snap

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

Is there a way to change cwd before select? #37

Open zetashift opened 3 years ago

zetashift commented 3 years ago

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?

saadparwaiz1 commented 3 years ago

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')

zetashift commented 3 years ago

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 :(.

saadparwaiz1 commented 3 years ago

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

zetashift commented 3 years ago

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.

saadparwaiz1 commented 3 years ago

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

zetashift commented 3 years ago
  ;; 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

saadparwaiz1 commented 3 years ago

Does it work it you hardcode the cwd?

zetashift commented 3 years ago

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

saadparwaiz1 commented 3 years ago

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

zetashift commented 3 years ago

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

zetashift commented 3 years ago

@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

saadparwaiz1 commented 3 years ago

@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

ahmedelgabri commented 3 years ago

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

general(request, {absolute = true, args = {'--type=file', '--hidden', '--no-ignore'}, cwd = cwd})
zetashift commented 3 years ago

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 })
ahmedelgabri commented 3 years ago

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

alxndr commented 3 years ago

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

ahmedelgabri commented 3 years ago

This is how I have a custom producer with a custom cwd https://github.com/ahmedelgabri/dotfiles/blob/cc1fa6f24a2f5eebfaf9c41248ef1db5a05cd59e/config/.vim/plugin/snap.lua#L48-L67

And here is how I'm using it https://github.com/ahmedelgabri/dotfiles/blob/cc1fa6f24a2f5eebfaf9c41248ef1db5a05cd59e/config/.vim/plugin/snap.lua#L139-L154

zetashift commented 3 years ago

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 :(

zetashift commented 3 years ago

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