From 0af3b9827bc3c45b315e5ede3f358b4ced678ea3 Mon Sep 17 00:00:00 2001 From: Barrett Ruth <62671086+barrettruth@users.noreply.github.com> Date: Fri, 14 Aug 2026 11:25:31 -0500 Subject: feat(dir): user can sort/filter listings, DirReadPost event #41138 Problem: Directory listing entries cannot be customized (filtered, reordered). Listings are read by a BufReadCmd, which suppresses BufReadPost, so they are the only buffers with no post-read event to hook. Solution: Introduce a post-render User autocmd `DirReadPost`, marking the dir buffer writable for the duration and before the cursor is placed, so handlers can sort or filter it with ordinary commands. Document common recipes --- runtime/lua/nvim/dir.lua | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) (limited to 'runtime/lua/nvim/dir.lua') diff --git a/runtime/lua/nvim/dir.lua b/runtime/lua/nvim/dir.lua index 79145525d2..c3de19396d 100644 --- a/runtime/lua/nvim/dir.lua +++ b/runtime/lua/nvim/dir.lua @@ -187,6 +187,27 @@ local function set_maps(buf) map('R', '(nvim-dir-reload)') end +--- Let handlers reshape the rendered listing. Unlocks the buffer for the duration and +--- restores it afterwards, so a handler can sort, filter, or delete lines with ordinary +--- commands. +---@param buf integer +---@return boolean +local function exec_render_autocmd(buf) + if not set_buf_options(buf, { { 'readonly', false }, { 'modifiable', true } }) then + return false + end + -- Errors in handlers are reported by the autocmd machinery; swallow them here so the + -- buffer is never left writable. + pcall(api.nvim_buf_call, buf, function() + api.nvim_exec_autocmds('User', { pattern = 'DirReadPost', modeline = false }) + end) + return set_buf_options(buf, { + { 'modified', false }, + { 'readonly', true }, + { 'modifiable', false }, + }) +end + ---@param buf integer local function setup_render_autocmds(buf) api.nvim_clear_autocmds({ group = listing_group, buffer = buf }) @@ -246,14 +267,19 @@ function load(buf, name, provider, restore_view, setup, select) end return end + current_state.err, current_state.provider = err, provider + vim.b[buf].nvim_dir = current_state + + -- Runs before the cursor is placed, so handlers may reorder entries. + if not exec_render_autocmd(buf) then + return + end if restore_view and api.nvim_get_current_buf() == buf then vim.fn.winrestview(restore_view) end if select and api.nvim_get_current_buf() == buf then select_entry(select) end - current_state.err, current_state.provider = err, provider - vim.b[buf].nvim_dir = current_state if not setup then return -- cgit