aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/plugins.txt14
-rw-r--r--runtime/lua/nvim/dir.lua48
-rw-r--r--runtime/lua/nvim/dir/fs.lua9
-rw-r--r--test/functional/plugin/dir_spec.lua32
4 files changed, 76 insertions, 27 deletions
diff --git a/runtime/doc/plugins.txt b/runtime/doc/plugins.txt
index 9f10625251..5a68e732a6 100644
--- a/runtime/doc/plugins.txt
+++ b/runtime/doc/plugins.txt
@@ -70,13 +70,19 @@ GLOBAL MAPPINGS *dir-mappings*
BUFFER-LOCAL MAPPINGS *dir-buffer-mappings*
• <CR> opens the file or directory under the cursor.
+• a opens the file or directory under the cursor in a vertical split.
+• o opens the file or directory under the cursor in a horizontal split.
• - opens the parent directory.
• R reloads the directory listing.
-These keys map to <Plug>(nvim-dir-open), <Plug>(nvim-dir-up), and
-<Plug>(nvim-dir-reload); map those to use different keys. Default mappings are
-skipped when the target <Plug> mapping is already mapped. The default global and
-directory-buffer "-" mappings are also skipped when "-" is already mapped.
+a and o are available for local directories and keep focus in the listing.
+'splitright' and 'splitbelow' control where the new window appears.
+
+These keys map to <Plug>(nvim-dir-open), <Plug>(nvim-dir-vsplit),
+<Plug>(nvim-dir-split), <Plug>(nvim-dir-up), and <Plug>(nvim-dir-reload); map those
+to use different keys. Default mappings are skipped when the target <Plug>
+mapping is already mapped. The default "-", "a", and "o" mappings are also
+skipped when their keys are already mapped.
*dir-config*
Directory buffers follow the global 'hidden' option by default. To delete them
diff --git a/runtime/lua/nvim/dir.lua b/runtime/lua/nvim/dir.lua
index ccce98e98c..c72d4d3b27 100644
--- a/runtime/lua/nvim/dir.lua
+++ b/runtime/lua/nvim/dir.lua
@@ -167,24 +167,15 @@ local function reload(buf, provider)
end
---@param buf integer
-local function set_maps(buf)
- ---@param lhs string
- ---@param plug string
- local function map(lhs, plug)
- if vim.fn.hasmapto(plug, 'n') == 0 then
- vim.keymap.set('n', lhs, plug, { buffer = buf, silent = true })
- end
- end
- ---@param lhs string
- ---@param plug string
- local function default_map(lhs, plug)
- if vim.fn.mapcheck(lhs, 'n') == '' and vim.fn.hasmapto(plug, 'n') == 0 then
+---@param lhs string
+---@param plug string
+---@param force? boolean
+function M._map(buf, lhs, plug, force)
+ api.nvim_buf_call(buf, function()
+ if (force or vim.fn.mapcheck(lhs, 'n') == '') and vim.fn.hasmapto(plug, 'n') == 0 then
vim.keymap.set('n', lhs, plug, { buffer = buf, silent = true })
end
- end
- map('<CR>', '<Plug>(nvim-dir-open)')
- default_map('-', '<Plug>(nvim-dir-up)')
- map('R', '<Plug>(nvim-dir-reload)')
+ end)
end
--- Let handlers reshape the rendered listing. Unlocks the buffer for the duration and
@@ -286,7 +277,9 @@ function load(buf, name, provider, restore_view, setup, select)
end
setup_render_autocmds(buf)
- set_maps(buf)
+ M._map(buf, '<CR>', '<Plug>(nvim-dir-open)', true)
+ M._map(buf, '-', '<Plug>(nvim-dir-up)')
+ M._map(buf, 'R', '<Plug>(nvim-dir-reload)', true)
if provider.init then
provider.init(buf, name)
end
@@ -326,12 +319,27 @@ local function get_provider(buf)
return state and state.provider or nil
end
-function M._open_entry()
+---@param cmd? 'split'|'vsplit'
+function M._open_entry(cmd)
local buf = api.nvim_get_current_buf()
local provider = get_provider(buf)
local entry = current_entry(buf)
- if provider and entry then
- provider.open(buf, api.nvim_buf_get_name(buf), entry)
+ if not provider or not entry then
+ return
+ end
+ local name = api.nvim_buf_get_name(buf)
+ local win = cmd and api.nvim_get_current_win()
+ local ok, err = pcall(function()
+ if cmd then
+ api.nvim_cmd({ cmd = cmd }, {})
+ end
+ provider.open(buf, name, entry)
+ end)
+ if win and api.nvim_win_is_valid(win) then
+ api.nvim_set_current_win(win)
+ end
+ if not ok then
+ error(err, 0)
end
end
diff --git a/runtime/lua/nvim/dir/fs.lua b/runtime/lua/nvim/dir/fs.lua
index 0af9d3229f..9ff95ce8ad 100644
--- a/runtime/lua/nvim/dir/fs.lua
+++ b/runtime/lua/nvim/dir/fs.lua
@@ -102,6 +102,15 @@ function M.init(buf, path)
if api.nvim_get_option_value('filetype', { buf = buf }) ~= 'directory' then
api.nvim_set_option_value('filetype', 'directory', { buf = buf })
end
+ local dir = require('nvim.dir')
+ vim.keymap.set('n', '<Plug>(nvim-dir-vsplit)', function()
+ dir._open_entry('vsplit')
+ end, { buffer = buf, silent = true, desc = 'Open directory entry in a vertical split' })
+ vim.keymap.set('n', '<Plug>(nvim-dir-split)', function()
+ dir._open_entry('split')
+ end, { buffer = buf, silent = true, desc = 'Open directory entry in a horizontal split' })
+ dir._map(buf, 'a', '<Plug>(nvim-dir-vsplit)')
+ dir._map(buf, 'o', '<Plug>(nvim-dir-split)')
api.nvim_buf_call(buf, function()
pcall(api.nvim_cmd, {
cmd = 'bcd',
diff --git a/test/functional/plugin/dir_spec.lua b/test/functional/plugin/dir_spec.lua
index b7318473c3..67cbb5ddd3 100644
--- a/test/functional/plugin/dir_spec.lua
+++ b/test/functional/plugin/dir_spec.lua
@@ -572,7 +572,7 @@ describe('nvim.dir', function()
eq({ 'unsaved' }, api.nvim_buf_get_lines(old_buf, 0, -1, false))
end)
- it('does not shadow startup plugin `-` mappings in directory buffers', function()
+ it('does not shadow startup plugin mappings in directory buffers', function()
make_fixture()
write_config_plugin(
'plugin/dirvish.lua',
@@ -581,6 +581,8 @@ describe('nvim.dir', function()
vim.keymap.set('n', '-', function()
vim.g.dirvish_up = vim.g.dirvish_up + 1
end)
+ vim.keymap.set('n', 'a', '<Nop>')
+ vim.keymap.set('n', 's', '<Plug>(nvim-dir-split)')
]]
)
@@ -591,12 +593,17 @@ describe('nvim.dir', function()
edit(root)
assert_directory(root)
eq(0, fn.maparg('-', 'n', false, true).buffer)
+ eq('<Nop>', fn.maparg('a', 'n'))
+ eq('', fn.maparg('o', 'n'))
- feed('-')
+ feed('-as')
poke_eventloop()
eq(1, exec_lua('return vim.g.dirvish_up'))
assert_directory(root)
+ eq(2, #api.nvim_list_wins())
+ feed('<C-W>p')
+ assert_directory(subdir)
end)
it('preserves alternate buffer when opening a parent directory', function()
@@ -669,6 +676,22 @@ describe('nvim.dir', function()
eq(vim.uv.fs_realpath(root), vim.uv.fs_realpath(fn.getcwd()))
eq('alpha.txt', fn.findfile('alpha.txt'))
+ local win = api.nvim_get_current_win()
+ for key, entry in pairs({ a = 'alpha.txt', o = 'subdir/' }) do
+ local cursor = { line_of(entry), 0 }
+ api.nvim_win_set_cursor(0, cursor)
+ feed(key)
+ poke_eventloop()
+ eq(win, api.nvim_get_current_win())
+ assert_directory(root)
+ eq(cursor, api.nvim_win_get_cursor(0))
+ eq(2, #api.nvim_list_wins())
+ eq(key == 'a' and 'row' or 'col', fn.winlayout()[1])
+ feed('<C-W>p')
+ eq(root .. '/' .. entry, api.nvim_buf_get_name(0))
+ command('close')
+ end
+
api.nvim_win_set_cursor(0, { line_of('alpha.txt'), 0 })
feed('<CR>')
poke_eventloop()
@@ -680,6 +703,9 @@ describe('nvim.dir', function()
assert_directory(subdir)
eq({ '' }, lines())
eq(vim.uv.fs_realpath(subdir), vim.uv.fs_realpath(fn.getcwd()))
+ feed('ao')
+ poke_eventloop()
+ eq(1, #api.nvim_list_wins())
feed('-')
poke_eventloop()
@@ -824,7 +850,7 @@ describe('nvim.dir', function()
line_of(raw_name)
end
api.nvim_win_set_cursor(0, { line_of('line\0break.txt'), 0 })
- feed('<CR>')
+ feed('a<C-W>p')
poke_eventloop()
eq(root .. '/' .. name, api.nvim_buf_get_name(0))