mirror of
https://github.com/neovim/neovim.git
synced 2026-11-06 05:16:52 +00:00
feat(dir): open entries in splits with a, o mappings #41834
This commit is contained in:
1 parent
361191790a
commit
4ceb92cd76
4 files changed
+76
-27
No files matched your search
+10
-4
@@ -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
|
||||
|
||||
+28
-20
@@ -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
|
||||
---@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
|
||||
---@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
|
||||
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
|
||||
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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))
|
||||
|
||||
Reference in new issue
Block a user