Skip to content

Commit f5f38bd

Browse files
committed
make contexts area handle logic use extmarks
1 parent 3868642 commit f5f38bd

File tree

1 file changed

+70
-31
lines changed

1 file changed

+70
-31
lines changed

lua/eca/sidebar.lua

Lines changed: 70 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -388,28 +388,50 @@ function M:_setup_input_events(container)
388388
return
389389
end
390390

391-
local lines = vim.api.nvim_buf_get_lines(buf, 0, -1, false)
391+
vim.schedule(function()
392+
local lines = vim.api.nvim_buf_get_lines(buf, 0, -1, false)
392393

393-
-- restore input line if deleted
394-
if first == 1 and #lines < 2 then
395-
self:_update_input_display()
396-
return
397-
end
394+
-- handle empty buffer
395+
if not lines or #lines < 1 then
396+
self:_update_input_display()
397+
return
398+
end
399+
400+
local prefix_extmark = self.extmarks.prefix or nil
401+
local contexts_extmark = self.extmarks.contexts or nil
398402

399-
-- first line (contexts) was changed
400-
if first == 0 then
401-
local contexts_line = lines[1]
403+
if not prefix_extmark or not contexts_extmark then
404+
return
405+
end
402406

403-
-- if contexts line is deleted, clear all contexts
404-
if not contexts_line or contexts_line == "" then
407+
local prefix_ns = prefix_extmark._ns or nil
408+
local prefix_id = prefix_extmark._id and prefix_extmark._id[1] or nil
409+
410+
if not prefix_ns or not prefix_id then
411+
return
412+
end
413+
414+
local prefix_row = unpack(vim.api.nvim_buf_get_extmark_by_id(buf, prefix_ns, prefix_id, {}))
415+
local contexts_row = 0
416+
417+
-- If both are in the same row, contexts_row was deleted
418+
if prefix_row == contexts_row then
405419
self.mediator:clear_contexts()
406420
return
407421
end
408422

409-
-- contexts line was modified
410-
if contexts_line ~= self._contexts_placeholder_line then
423+
local prefix_line = lines[prefix_row + 1] or nil
424+
local contexts_line = lines[contexts_row + 1] or nil
425+
local contexts_placeholder_line = self._contexts_placeholder_line or ""
411426

412-
-- if contexts line is shorter than placeholder, a context was removed
427+
-- prefix line missing, restore
428+
if not prefix_line and contexts_line == contexts_placeholder_line then
429+
self:_update_input_display()
430+
return
431+
end
432+
433+
if contexts_line ~= contexts_placeholder_line then
434+
-- a context was removed
413435
if #contexts_line < #self._contexts_placeholder_line then
414436
local contexts = self.mediator:contexts()
415437

@@ -425,7 +447,7 @@ function M:_setup_input_events(container)
425447
self:_update_input_display()
426448
return
427449
end
428-
end
450+
end)
429451
end
430452
})
431453
end
@@ -654,14 +676,20 @@ function M:_update_input_display(opts)
654676
self._contexts_placeholder_line = self._contexts_placeholder_line .. "@"
655677
end
656678

657-
-- Get existing lines to preserve user input (lines after the header)
658-
local existing_lines = vim.api.nvim_buf_get_lines(input.bufnr, 0, -1, false)
659679

660-
-- If first line is the contexts placeholder, remove it from existing lines
661-
if existing_lines and #existing_lines > 1 and (existing_lines[1] == "" or existing_lines[1] == old_contexts_placeholder_line or existing_lines[1] == self._contexts_placeholder_line) then
662-
table.remove(existing_lines, 1)
680+
local prefix_extmark = self.extmarks.prefix or nil
681+
local prefix_ns = prefix_extmark and prefix_extmark._ns or nil
682+
local prefix_id = prefix_extmark and prefix_extmark._id and prefix_extmark._id[1] or nil
683+
local prefix_row = 1
684+
685+
if prefix_ns and prefix_id then
686+
local prefix_mark = vim.api.nvim_buf_get_extmark_by_id(input.bufnr, prefix_ns, prefix_id, {})
687+
prefix_row = prefix_mark and #prefix_mark > 0 and prefix_mark[1] or 1
663688
end
664689

690+
-- Get existing lines to preserve user input (lines after the header)
691+
local existing_lines = vim.api.nvim_buf_get_lines(input.bufnr, prefix_row, -1, false)
692+
665693
vim.api.nvim_buf_set_lines(input.bufnr, 0, -1, false, { self._contexts_placeholder_line, "" })
666694

667695
if not self.extmarks.contexts then
@@ -698,14 +726,22 @@ function M:_update_input_display(opts)
698726
vim.api.nvim_buf_set_lines(input.bufnr, 1, 1 + #existing_lines, false, existing_lines)
699727
end
700728

701-
self.extmarks.prefix._id = vim.api.nvim_buf_set_extmark(
729+
if not self.extmarks.prefix._id then
730+
self.extmarks.prefix._id = {}
731+
end
732+
733+
self.extmarks.prefix._id[1] = vim.api.nvim_buf_set_extmark(
702734
input.bufnr,
703735
self.extmarks.prefix._ns,
704736
1,
705737
0,
706-
vim.tbl_extend("force", { virt_text = { { prefix, "Normal" } }, virt_text_pos = "inline", right_gravity = false }, { id = self.extmarks.prefix._id })
738+
vim.tbl_extend("force", { virt_text = { { prefix, "Normal" } }, virt_text_pos = "inline", right_gravity = false }, { id = self.extmarks.prefix._id[1] })
707739
)
708740

741+
-- local prefix_mark = vim.api.nvim_buf_get_extmark_by_id(input.bufnr, self.extmarks.prefix._ns, self.extmarks.prefix._id[1], { details = true })
742+
-- local prefix_mark = opts and opts.prefix_mark or {}
743+
-- vim.notify(vim.inspect(prefix_mark), vim.log.levels.DEBUG)
744+
709745
-- Set cursor to end of input line
710746
if vim.api.nvim_win_is_valid(input.winid) then
711747
local row = 1 + (not clear and existing_lines and #existing_lines > 0 and #existing_lines or 1)
@@ -730,23 +766,26 @@ function M:_focus_input()
730766
local lines = vim.api.nvim_buf_get_lines(input.bufnr, 0, -1, false)
731767
local prefix = Config.windows.input.prefix or "> "
732768

769+
local row = 2
770+
local col = #prefix
771+
733772
-- Ensure there is at least a header and a prefix line
734773
if #lines < 2 then
735-
self:_update_input_display()
736-
lines = vim.api.nvim_buf_get_lines(input.bufnr, 0, -1, false)
774+
row = 1
775+
col = 0
737776
end
738777

739-
-- Place cursor on the prefix line (line 2), after the prefix
740-
local cursor_col = #prefix
741-
vim.api.nvim_win_set_cursor(input.winid, { 2, cursor_col })
778+
vim.api.nvim_win_set_cursor(input.winid, { row, col })
742779

743780
-- Enter insert mode
744-
local mode = vim.api.nvim_get_mode().mode
745-
if mode == "n" then
746-
vim.cmd("startinsert!")
781+
if Config.windows and Config.windows.edit and Config.windows.edit.start_insert then
782+
local mode = vim.api.nvim_get_mode().mode
783+
if mode == "n" then
784+
vim.cmd("startinsert!")
785+
end
747786
end
748787
end
749-
end, 50)
788+
end, 100)
750789
end
751790

752791
function M:_handle_input()

0 commit comments

Comments
 (0)