225225--- `source.items` defines items to choose from. It should be one of the following:
226226--- - Array of objects which can have different types. Any type is allowed.
227227--- - `nil`. Picker waits for explicit |MiniPick.set_picker_items()| call.
228- --- - Callable returning any of the previous types. Will be called once on start.
228+ --- - Callable returning any of the previous types. Will be called once on start
229+ --- with source's `cwd` set as |current-directory|.
229230---
230231--- *MiniPick-source.items-stritems*
231232--- Matching is done for items array based on the string representation of its
299300--- i.e. not depend on current directory being constant after picker start.
300301--- It also makes the |MiniPick.builtin.resume()| picker more robust.
301302---
303+ --- It will be set as local |current-directory| (|:lcd|) of picker's main window
304+ --- to allow simpler code for "in window" functions (choose/preview/custom/etc.).
305+ ---
302306--- Default value is |current-directory|.
303307---
304308--- *MiniPick-source.match*
@@ -1276,7 +1280,8 @@ MiniPick.builtin.files = function(local_opts, opts)
12761280 opts = vim .tbl_deep_extend (' force' , default_opts , opts or {})
12771281
12781282 if tool == ' fallback' then
1279- opts .source .items = function () H .files_fallback_items (opts .source .cwd ) end
1283+ local cwd = H .full_path (opts .source .cwd or vim .fn .getcwd ())
1284+ opts .source .items = function () H .files_fallback_items (cwd ) end
12801285 return MiniPick .start (opts )
12811286 end
12821287
@@ -1312,7 +1317,8 @@ MiniPick.builtin.grep = function(local_opts, opts)
13121317
13131318 local pattern = type (local_opts .pattern ) == ' string' and local_opts .pattern or vim .fn .input (' Grep pattern: ' )
13141319 if tool == ' fallback' then
1315- opts .source .items = function () H .grep_fallback_items (pattern , opts .source .cwd ) end
1320+ local cwd = H .full_path (opts .source .cwd or vim .fn .getcwd ())
1321+ opts .source .items = function () H .grep_fallback_items (pattern , cwd ) end
13161322 return MiniPick .start (opts )
13171323 end
13181324
@@ -1347,7 +1353,8 @@ MiniPick.builtin.grep_live = function(local_opts, opts)
13471353 local default_source = { name = string.format (' Grep live (%s%s)' , tool , name_suffix ), show = show }
13481354 opts = vim .tbl_deep_extend (' force' , { source = default_source }, opts or {})
13491355
1350- local set_items_opts , spawn_opts = { do_match = false , querytick = H .querytick }, { cwd = opts .source .cwd }
1356+ local cwd = H .full_path (opts .source .cwd or vim .fn .getcwd ())
1357+ local set_items_opts , spawn_opts = { do_match = false , querytick = H .querytick }, { cwd = cwd }
13511358 local process
13521359 local match = function (_ , _ , query )
13531360 pcall (vim .loop .process_kill , process )
@@ -1499,7 +1506,9 @@ MiniPick.builtin.cli = function(local_opts, opts)
14991506 local_opts = vim .tbl_deep_extend (' force' , { command = {}, postprocess = nil , spawn_opts = {} }, local_opts or {})
15001507 local name = string.format (' CLI (%s)' , tostring (local_opts .command [1 ] or ' ' ))
15011508 opts = vim .tbl_deep_extend (' force' , { source = { name = name } }, opts or {})
1502- local_opts .spawn_opts .cwd = local_opts .spawn_opts .cwd or opts .source .cwd
1509+ -- Explicitly use full path to not conflict with `set_picker_items_from_cli`
1510+ -- behavior of treating `spawn_opts.cwd` relative to source's cwd
1511+ local_opts .spawn_opts .cwd = H .full_path (local_opts .spawn_opts .cwd or opts .source .cwd or vim .fn .getcwd ())
15031512
15041513 local command = local_opts .command
15051514 local set_from_cli_opts = { postprocess = local_opts .postprocess , spawn_opts = local_opts .spawn_opts }
@@ -1515,7 +1524,7 @@ MiniPick.builtin.resume = function()
15151524 H .cache = {}
15161525 local buf_id = H .picker_new_buf ()
15171526 local win_target = vim .api .nvim_get_current_win ()
1518- local win_id = H .picker_new_win (buf_id , picker .opts .window .config )
1527+ local win_id = H .picker_new_win (buf_id , picker .opts .window .config , picker . opts . source . cwd )
15191528 picker .buffers = { main = buf_id }
15201529 picker .windows = { main = win_id , target = win_target }
15211530 picker .view_state = ' main'
@@ -1673,6 +1682,7 @@ end
16731682--- Will be called with array of lines as input, should return array of items.
16741683--- Default: removes trailing empty lines and uses rest as string items.
16751684--- - <spawn_opts> `(table)` - `options` for |uv.spawn|, except `args` and `stdio` fields.
1685+ --- Note: relative `cwd` path is resolved against active picker's `cwd`.
16761686--- - <set_items_opts> `(table)` - table forwarded to |MiniPick.set_picker_items()|.
16771687---
16781688--- @see also |MiniPick.get_picker_items ()| and |MiniPick.get_picker_stritems ()|
@@ -1732,9 +1742,11 @@ end
17321742--- @see also |MiniPick.get_picker_opts ()|
17331743MiniPick .set_picker_opts = function (opts )
17341744 if not MiniPick .is_picker_active () then return end
1735- H .pickers .active .opts = vim .tbl_deep_extend (' force' , H .pickers .active .opts , opts or {})
1736- H .pickers .active .action_keys = H .normalize_mappings (H .pickers .active .opts .mappings )
1737- H .picker_update (H .pickers .active , true , true )
1745+ local picker , cur_cwd = H .pickers .active , H .pickers .active .opts .source .cwd
1746+ picker .opts = vim .tbl_deep_extend (' force' , picker .opts , opts or {})
1747+ picker .action_keys = H .normalize_mappings (picker .opts .mappings )
1748+ if cur_cwd ~= picker .opts .source .cwd then H .win_set_cwd (picker .windows .main , picker .opts .source .cwd ) end
1749+ H .picker_update (picker , true , true )
17381750end
17391751
17401752--- Set target window for active picker
@@ -2076,7 +2088,7 @@ H.picker_new = function(opts)
20762088
20772089 -- Create window
20782090 local win_target = vim .api .nvim_get_current_win ()
2079- local win_id = H .picker_new_win (buf_id , opts .window .config )
2091+ local win_id = H .picker_new_win (buf_id , opts .window .config , opts . source . cwd )
20802092
20812093 -- Construct and return object
20822094 local picker = {
@@ -2178,7 +2190,7 @@ H.picker_new_buf = function()
21782190 return buf_id
21792191end
21802192
2181- H .picker_new_win = function (buf_id , win_config )
2193+ H .picker_new_win = function (buf_id , win_config , cwd )
21822194 -- Hide cursor while picker is active (to not be visible in the window)
21832195 -- This mostly follows a hack from 'folke/noice.nvim'
21842196 H .cache .guicursor = vim .o .guicursor
@@ -2198,6 +2210,9 @@ H.picker_new_win = function(buf_id, win_config)
21982210 H .win_update_hl (win_id , ' FloatBorder' , ' MiniPickBorder' )
21992211 vim .fn .clearmatches (win_id )
22002212
2213+ -- Set window's local "current directory" for easier choose/preview/etc.
2214+ H .win_set_cwd (nil , cwd )
2215+
22012216 return win_id
22022217end
22032218
@@ -3267,7 +3282,6 @@ end
32673282
32683283H .files_fallback_items = function (cwd )
32693284 if vim .fn .has (' nvim-0.9' ) == 0 then H .error (' Tool "fallback" of `files` builtin needs Neovim>=0.9.' ) end
3270- cwd = cwd or ' .'
32713285 local poke_picker = H .poke_picker_throttle ()
32723286 local f = function ()
32733287 local items = {}
@@ -3311,7 +3325,6 @@ end
33113325
33123326H .grep_fallback_items = function (pattern , cwd )
33133327 if vim .fn .has (' nvim-0.9' ) == 0 then H .error (' Tool "fallback" of `grep` builtin needs Neovim>=0.9.' ) end
3314- cwd = cwd or ' .'
33153328 local poke_picker = H .poke_picker_throttle ()
33163329 local f = function ()
33173330 local files , files_full = {}, {}
@@ -3478,6 +3491,14 @@ H.win_get_bottom_border = function(win_id)
34783491 return res or ' '
34793492end
34803493
3494+ H .win_set_cwd = function (win_id , cwd )
3495+ -- Avoid needlessly setting cwd as it has side effects (like for `:buffers`)
3496+ if cwd == nil or vim .fn .getcwd (win_id or 0 ) == cwd then return end
3497+ local f = function () vim .cmd (' lcd ' .. vim .fn .fnameescape (cwd )) end
3498+ if win_id == nil or win_id == vim .api .nvim_get_current_win () then return f () end
3499+ vim .api .nvim_win_call (f , win_id )
3500+ end
3501+
34813502H .seq_along = function (arr )
34823503 if arr == nil then return nil end
34833504 local res = {}
0 commit comments