feat(buffer): open as bottom-drawer split like fugitive (#23)
* feat(buffer): open as bottom-drawer split like fugitive Problem: :Pending replaced the current buffer, making it impossible to view tasks alongside the file being edited. No way to close the drawer without :q or switching buffers manually. Solution: open the task buffer in a botright horizontal split instead of replacing the current buffer. Track the drawer window ID so re-opening focuses it rather than creating a second split. Set winfixheight so the drawer keeps its height when other windows open or close. Add q/<Esc> mappings to close the drawer, and a WinClosed autocmd to clear the tracked window ID when the user closes it manually. Add drawer_height config option (default 15). * fix(buffer): default to natural split height like fugitive Problem: hardcoded drawer_height=15 was too small and diverged from fugitive's model. Fugitive issues a plain botright split and lets Vim's own split rules (equalalways, winheight) divide the available space. Solution: remove the default height so the split sizes naturally. Only call nvim_win_set_height when the user sets drawer_height to a positive value, preserving the opt-in customization path.
This commit is contained in:
parent
5db242a9cf
commit
fbeb0e2bee
3 changed files with 49 additions and 14 deletions
|
|
@ -7,6 +7,8 @@ local M = {}
|
||||||
|
|
||||||
---@type integer?
|
---@type integer?
|
||||||
local task_bufnr = nil
|
local task_bufnr = nil
|
||||||
|
---@type integer?
|
||||||
|
local task_winid = nil
|
||||||
local task_ns = vim.api.nvim_create_namespace('pending')
|
local task_ns = vim.api.nvim_create_namespace('pending')
|
||||||
---@type 'category'|'priority'|nil
|
---@type 'category'|'priority'|nil
|
||||||
local current_view = nil
|
local current_view = nil
|
||||||
|
|
@ -25,11 +27,27 @@ function M.bufnr()
|
||||||
return task_bufnr
|
return task_bufnr
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@return integer?
|
||||||
|
function M.winid()
|
||||||
|
return task_winid
|
||||||
|
end
|
||||||
|
|
||||||
---@return string?
|
---@return string?
|
||||||
function M.current_view_name()
|
function M.current_view_name()
|
||||||
return current_view
|
return current_view
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function M.clear_winid()
|
||||||
|
task_winid = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.close()
|
||||||
|
if task_winid and vim.api.nvim_win_is_valid(task_winid) then
|
||||||
|
vim.api.nvim_win_close(task_winid, false)
|
||||||
|
end
|
||||||
|
task_winid = nil
|
||||||
|
end
|
||||||
|
|
||||||
---@param bufnr integer
|
---@param bufnr integer
|
||||||
local function set_buf_options(bufnr)
|
local function set_buf_options(bufnr)
|
||||||
vim.bo[bufnr].buftype = 'acwrite'
|
vim.bo[bufnr].buftype = 'acwrite'
|
||||||
|
|
@ -50,6 +68,7 @@ local function set_win_options(winid)
|
||||||
vim.wo[winid].foldcolumn = '0'
|
vim.wo[winid].foldcolumn = '0'
|
||||||
vim.wo[winid].spell = false
|
vim.wo[winid].spell = false
|
||||||
vim.wo[winid].cursorline = true
|
vim.wo[winid].cursorline = true
|
||||||
|
vim.wo[winid].winfixheight = true
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param bufnr integer
|
---@param bufnr integer
|
||||||
|
|
@ -251,24 +270,25 @@ function M.open()
|
||||||
setup_highlights()
|
setup_highlights()
|
||||||
store.load()
|
store.load()
|
||||||
|
|
||||||
if task_bufnr and vim.api.nvim_buf_is_valid(task_bufnr) then
|
if task_winid and vim.api.nvim_win_is_valid(task_winid) then
|
||||||
local wins = vim.fn.win_findbuf(task_bufnr)
|
vim.api.nvim_set_current_win(task_winid)
|
||||||
if #wins > 0 then
|
|
||||||
vim.api.nvim_set_current_win(wins[1])
|
|
||||||
M.render(task_bufnr)
|
M.render(task_bufnr)
|
||||||
return task_bufnr
|
return task_bufnr --[[@as integer]]
|
||||||
end
|
|
||||||
vim.api.nvim_set_current_buf(task_bufnr)
|
|
||||||
set_win_options(vim.api.nvim_get_current_win())
|
|
||||||
M.render(task_bufnr)
|
|
||||||
return task_bufnr
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if not (task_bufnr and vim.api.nvim_buf_is_valid(task_bufnr)) then
|
||||||
task_bufnr = vim.api.nvim_create_buf(true, false)
|
task_bufnr = vim.api.nvim_create_buf(true, false)
|
||||||
|
|
||||||
set_buf_options(task_bufnr)
|
set_buf_options(task_bufnr)
|
||||||
vim.api.nvim_set_current_buf(task_bufnr)
|
end
|
||||||
set_win_options(vim.api.nvim_get_current_win())
|
|
||||||
|
vim.cmd('botright new')
|
||||||
|
task_winid = vim.api.nvim_get_current_win()
|
||||||
|
vim.api.nvim_win_set_buf(task_winid, task_bufnr)
|
||||||
|
local h = config.get().drawer_height
|
||||||
|
if h and h > 0 then
|
||||||
|
vim.api.nvim_win_set_height(task_winid, h)
|
||||||
|
end
|
||||||
|
set_win_options(task_winid)
|
||||||
|
|
||||||
M.render(task_bufnr)
|
M.render(task_bufnr)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
---@field date_format string
|
---@field date_format string
|
||||||
---@field date_syntax string
|
---@field date_syntax string
|
||||||
---@field category_order? string[]
|
---@field category_order? string[]
|
||||||
|
---@field drawer_height? integer
|
||||||
---@field gcal? pending.GcalConfig
|
---@field gcal? pending.GcalConfig
|
||||||
|
|
||||||
---@class pending.config
|
---@class pending.config
|
||||||
|
|
|
||||||
|
|
@ -38,11 +38,25 @@ function M._setup_autocmds(bufnr)
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
vim.api.nvim_create_autocmd('WinClosed', {
|
||||||
|
group = group,
|
||||||
|
callback = function(ev)
|
||||||
|
if tonumber(ev.match) == buffer.winid() then
|
||||||
|
buffer.clear_winid()
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param bufnr integer
|
---@param bufnr integer
|
||||||
function M._setup_buf_mappings(bufnr)
|
function M._setup_buf_mappings(bufnr)
|
||||||
local opts = { buffer = bufnr, silent = true }
|
local opts = { buffer = bufnr, silent = true }
|
||||||
|
vim.keymap.set('n', 'q', function()
|
||||||
|
buffer.close()
|
||||||
|
end, opts)
|
||||||
|
vim.keymap.set('n', '<Esc>', function()
|
||||||
|
buffer.close()
|
||||||
|
end, opts)
|
||||||
vim.keymap.set('n', '<CR>', function()
|
vim.keymap.set('n', '<CR>', function()
|
||||||
M.toggle_complete()
|
M.toggle_complete()
|
||||||
end, opts)
|
end, opts)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue