aboutsummaryrefslogtreecommitdiff
path: root/test/functional/plugin/dir_spec.lua
diff options
context:
space:
mode:
authorBarrett Ruth <62671086+barrettruth@users.noreply.github.com>2026-07-22 10:21:39 -0700
committerGitHub <noreply@github.com>2026-07-22 13:21:39 -0400
commitada20074535c253fe31ef5c6a927f9c38367fa8f (patch)
tree6d4290c4abc58096de00959ac10b9e023b8b4af1 /test/functional/plugin/dir_spec.lua
parent8b6bdb79e6340b74f2c66c57ebbfac09cafde5c8 (diff)
downloadrneovim-ada20074535c253fe31ef5c6a927f9c38367fa8f.tar.gz
rneovim-ada20074535c253fe31ef5c6a927f9c38367fa8f.tar.bz2
rneovim-ada20074535c253fe31ef5c6a927f9c38367fa8f.zip
feat(dir): provider framework #40738
Problem: The core behaviors of `nvim.dir` cannot be reused by consumers such as the archive plugin, ssh browser, etc. Solution: - Define a basic "provider" shape. - Extract the filesystem provider.
Diffstat (limited to 'test/functional/plugin/dir_spec.lua')
-rw-r--r--test/functional/plugin/dir_spec.lua158
1 files changed, 158 insertions, 0 deletions
diff --git a/test/functional/plugin/dir_spec.lua b/test/functional/plugin/dir_spec.lua
index 5cc9e7fef8..339ebefda0 100644
--- a/test/functional/plugin/dir_spec.lua
+++ b/test/functional/plugin/dir_spec.lua
@@ -190,6 +190,164 @@ describe('nvim.dir', function()
assert_directory(root)
end)
+ it('opens a custom listing provider', function()
+ n.clear({ args_rm = { '-u' } })
+
+ exec_lua(function()
+ require('nvim.dir').open(0, 'custom://root', {
+ list = function(_, name, cb)
+ vim.g.nvim_dir_list_name = name
+ cb(nil, {
+ { name = 'child', dir = true },
+ { name = 'file.txt', dir = false },
+ })
+ end,
+ open = function(_, name, entry)
+ vim.g.nvim_dir_opened = entry.name .. ':' .. name
+ end,
+ open_parent = function(_, name)
+ vim.g.nvim_dir_parent = name
+ end,
+ init = function(buf)
+ vim.bo[buf].filetype = 'customdir'
+ end,
+ })
+ end)
+
+ eq('custom://root', api.nvim_buf_get_name(0))
+ eq('customdir', bufopt('filetype'))
+ eq({ 'child/', 'file.txt' }, lines())
+ eq('custom://root', exec_lua('return vim.g.nvim_dir_list_name'))
+
+ api.nvim_win_set_cursor(0, { 2, 0 })
+ api.nvim_set_option_value('modifiable', true, { buf = 0 })
+ api.nvim_set_current_line('renamed.txt')
+ feed('<CR>')
+ poke_eventloop()
+ eq('renamed.txt:custom://root', exec_lua('return vim.g.nvim_dir_opened'))
+
+ feed('-')
+ poke_eventloop()
+ eq('custom://root', exec_lua('return vim.g.nvim_dir_parent'))
+ end)
+
+ it('reports custom listing provider errors', function()
+ n.clear({ args_rm = { '-u' } })
+
+ exec_lua(function()
+ require('nvim.dir').open(0, 'custom://error', {
+ list = function(_, _, cb)
+ cb('simulated error')
+ end,
+ open = function() end,
+ open_parent = function() end,
+ })
+ end)
+
+ ok(exec_capture('messages'):find('simulated error', 1, true) ~= nil)
+ eq(false, exec_lua([[return vim.b.nvim_dir ~= nil]]))
+ end)
+
+ it('reloads custom listing providers', function()
+ n.clear({ args_rm = { '-u' } })
+
+ exec_lua(function()
+ require('nvim.dir').open(0, 'custom://root', {
+ list = function(buf, _, cb)
+ vim.b[buf].custom_count = (vim.b[buf].custom_count or 0) + 1
+ cb(nil, { { name = 'file' .. vim.b[buf].custom_count .. '.txt', dir = false } })
+ end,
+ open = function() end,
+ open_parent = function() end,
+ })
+ end)
+
+ eq({ 'file1.txt' }, lines())
+ feed('R')
+ poke_eventloop()
+ eq({ 'file2.txt' }, lines())
+ end)
+
+ it('ignores callbacks from replaced listings', function()
+ n.clear({ args_rm = { '-u' } })
+
+ exec_lua(function()
+ local dir = require('nvim.dir')
+ dir.open(0, 'custom://old', {
+ list = function(_, _, cb)
+ _G.nvim_dir_stale_callback = cb
+ end,
+ open = function() end,
+ open_parent = function() end,
+ })
+ dir.open(0, 'custom://new', {
+ list = function(_, _, cb)
+ cb(nil, { { name = 'current.txt', dir = false } })
+ end,
+ open = function() end,
+ open_parent = function() end,
+ })
+ end)
+
+ eq('custom://new', api.nvim_buf_get_name(0))
+ eq({ 'current.txt' }, lines())
+
+ exec_lua(function()
+ _G.nvim_dir_stale_callback(nil, { { name = 'stale.txt', dir = false } })
+ end)
+
+ eq('custom://new', api.nvim_buf_get_name(0))
+ eq({ 'current.txt' }, lines())
+ end)
+
+ it('replaces listing providers', function()
+ n.clear({ args_rm = { '-u' } })
+
+ exec_lua(function()
+ local dir = require('nvim.dir')
+ local function provider(label)
+ return {
+ list = function(buf, _, cb)
+ local key = 'nvim_dir_' .. label .. '_lists'
+ vim.b[buf][key] = (vim.b[buf][key] or 0) + 1
+ vim.g.nvim_dir_provider_list = label .. ':' .. vim.b[buf][key]
+ cb(nil, { { name = label .. '.txt', dir = false } })
+ end,
+ open = function(_, _, entry)
+ vim.g.nvim_dir_provider_open = label .. ':' .. entry.name
+ end,
+ open_parent = function()
+ vim.g.nvim_dir_provider_parent = label
+ end,
+ }
+ end
+ dir.open(0, 'custom://old', provider('old'))
+ dir.open(0, 'custom://new', provider('new'))
+ end)
+
+ eq({ 'new.txt' }, lines())
+ eq('new:1', exec_lua('return vim.g.nvim_dir_provider_list'))
+ for _, plug in ipairs({
+ '<Plug>(nvim-dir-open)',
+ '<Plug>(nvim-dir-up)',
+ '<Plug>(nvim-dir-reload)',
+ }) do
+ eq(0, fn.maparg(plug, 'n', false, true).buffer)
+ end
+
+ feed('<CR>')
+ poke_eventloop()
+ eq('new:new.txt', exec_lua('return vim.g.nvim_dir_provider_open'))
+
+ feed('-')
+ poke_eventloop()
+ eq('new', exec_lua('return vim.g.nvim_dir_provider_parent'))
+
+ feed('R')
+ poke_eventloop()
+ eq('new:2', exec_lua('return vim.g.nvim_dir_provider_list'))
+ end)
+
it('maps - to open parent directories', function()
make_fixture()
n.clear({ args_rm = { '-u', '--cmd' } })