irongit

My nvim configuration

fix(claude): scroll to see spinner

huncholanehuncholaneauthored
parent 9a3acb0commit 33dc5bd29200297d6fe962fe50e134fd1a1bd220Browse files

2 files changed, +37 -20

+3-2claude-nvim/lua/claude/runner.lua
@@ -240,7 +240,8 @@ function M.is_busy(sid)
240240 return st and st.job ~= nil
241241 end
242242
243-function M.send(sid, prompt_text)
243+function M.send(sid, prompt_text, opts)
244+ opts = opts or {}
244245 local st = active[sid]
245246 if not st then return false, "no session" end
246247 if st.job then return false, "previous prompt still running" end
@@ -260,7 +261,7 @@ function M.send(sid, prompt_text)
260261 table.insert(cmd, prompt_text)
261262
262263 local ok_u, ui = pcall(require, "claude.ui")
263- if ok_u then ui.append_user_prompt(sid, prompt_text) end
264+ if ok_u and not opts.skip_ui_prompt then ui.append_user_prompt(sid, prompt_text) end
264265
265266 log("CMD", table.concat(cmd, " | "))
266267
+34-18claude-nvim/lua/claude/ui.lua
@@ -8,23 +8,30 @@ local panel = {
88 }
99
1010 local spinner = {
11- ns = vim.api.nvim_create_namespace("claude_spinner"),
1211 timer = nil,
13- mark_id = nil,
12+ line = nil,
1413 frame = 1,
1514 frames = { "⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏" },
1615 }
1716
1817 local function spinner_render()
1918 if not panel.buf or not vim.api.nvim_buf_is_valid(panel.buf) then return end
20- local lc = vim.api.nvim_buf_line_count(panel.buf)
21- local line = math.max(0, lc - 1)
2219 local txt = spinner.frames[spinner.frame] .. " thinking…"
23- spinner.mark_id = vim.api.nvim_buf_set_extmark(panel.buf, spinner.ns, line, 0, {
24- id = spinner.mark_id,
25- virt_lines = { { { txt, "Comment" } } },
26- virt_lines_above = false,
27- })
20+ vim.bo[panel.buf].modifiable = true
21+ local appended = false
22+ if spinner.line ~= nil and spinner.line < vim.api.nvim_buf_line_count(panel.buf) then
23+ pcall(vim.api.nvim_buf_set_lines, panel.buf, spinner.line, spinner.line + 1, false, { txt })
24+ else
25+ local lc = vim.api.nvim_buf_line_count(panel.buf)
26+ pcall(vim.api.nvim_buf_set_lines, panel.buf, lc, lc, false, { txt })
27+ spinner.line = lc
28+ appended = true
29+ end
30+ vim.bo[panel.buf].modifiable = false
31+ if appended and panel.win and vim.api.nvim_win_is_valid(panel.win) then
32+ local lc = vim.api.nvim_buf_line_count(panel.buf)
33+ pcall(vim.api.nvim_win_set_cursor, panel.win, { lc, 0 })
34+ end
2835 end
2936
3037 local function spinner_stop()
@@ -33,10 +40,14 @@ local function spinner_stop()
3340 if not spinner.timer:is_closing() then spinner.timer:close() end
3441 spinner.timer = nil
3542 end
36- if spinner.mark_id and panel.buf and vim.api.nvim_buf_is_valid(panel.buf) then
37- pcall(vim.api.nvim_buf_del_extmark, panel.buf, spinner.ns, spinner.mark_id)
43+ if spinner.line ~= nil and panel.buf and vim.api.nvim_buf_is_valid(panel.buf) then
44+ if spinner.line < vim.api.nvim_buf_line_count(panel.buf) then
45+ vim.bo[panel.buf].modifiable = true
46+ pcall(vim.api.nvim_buf_set_lines, panel.buf, spinner.line, spinner.line + 1, false, {})
47+ vim.bo[panel.buf].modifiable = false
48+ end
3849 end
39- spinner.mark_id = nil
50+ spinner.line = nil
4051 end
4152
4253 local function spinner_start()
@@ -44,7 +55,7 @@ local function spinner_start()
4455 spinner.frame = 1
4556 spinner_render()
4657 spinner.timer = vim.uv.new_timer()
47- spinner.timer:start(0, 90, vim.schedule_wrap(function()
58+ spinner.timer:start(90, 90, vim.schedule_wrap(function()
4859 spinner.frame = (spinner.frame % #spinner.frames) + 1
4960 spinner_render()
5061 end))
@@ -307,13 +318,14 @@ function M.open_input(opts)
307318 if closed then return end
308319 local lines = vim.api.nvim_buf_get_lines(input_buf, 0, -1, false)
309320 local text = table.concat(lines, "\n")
310- close()
311- if text:match("^%s*$") then return end
321+ if text:match("^%s*$") then close(); return end
312322 if context and context ~= "" then
313323 text = context .. "\n\n" .. text
314324 end
325+ M.append_user_prompt(sid, text)
326+ close()
315327 local runner = require("claude.runner")
316- local ok, err = runner.send(sid, text)
328+ local ok, err = runner.send(sid, text, { skip_ui_prompt = true })
317329 if not ok then
318330 vim.notify("claude: " .. tostring(err), vim.log.levels.WARN)
319331 end
@@ -385,17 +397,21 @@ function M.append_user_prompt(sid, text)
385397 table.insert(lines, "")
386398 append_lines(lines)
387399 spinner_start()
388- vim.cmd("redraw")
400+ pcall(vim.cmd, "redraw!")
389401 end
390402
391403 function M.append_assistant_text(sid, text)
392404 if sid ~= panel.sid then return end
393- vim.schedule(function() append_text_streaming(text) end)
405+ vim.schedule(function()
406+ spinner_stop()
407+ append_text_streaming(text)
408+ end)
394409 end
395410
396411 function M.append_tool_use(sid, name, path)
397412 if sid ~= panel.sid then return end
398413 vim.schedule(function()
414+ spinner_stop()
399415 append_lines({ "", "> **" .. name .. "** `" .. path .. "`", "" })
400416 end)
401417 end