From 08ac036011559ba2416f935181a30cfd02083688 Mon Sep 17 00:00:00 2001 From: Jamie Schembri Date: Wed, 4 Feb 2026 10:25:01 +0100 Subject: [PATCH] Fix terminal cleanup when Claude process exits When the Claude process exits (via ctrl-c, ctrl-d, or pressing Enter after "Process exited"), the plugin now properly cleans up: 1. In toggle(): When detecting a dead terminal buffer, close any windows showing it and delete the buffer before creating a new instance. This fixes "E95: Buffer with this name already exists" error. 2. In TermClose autocmd: Clean up instance tracking, close the floating window, and delete the buffer. This prevents an empty floating window from lingering after the terminal exits. --- lua/claude-code/file_refresh.lua | 25 ++++++++++++++++++++----- lua/claude-code/terminal.lua | 9 ++++++++- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/lua/claude-code/file_refresh.lua b/lua/claude-code/file_refresh.lua index 9bbb0854..e3ae64ef 100644 --- a/lua/claude-code/file_refresh.lua +++ b/lua/claude-code/file_refresh.lua @@ -96,17 +96,32 @@ function M.setup(claude_code, config) desc = 'Set shorter updatetime when Claude Code is open', }) - -- When Claude Code closes, restore normal updatetime + -- When Claude Code closes, restore normal updatetime and clean up vim.api.nvim_create_autocmd('TermClose', { group = augroup, pattern = '*', - callback = function() - local buf_name = vim.api.nvim_buf_get_name(0) - if buf_name:match('claude%-code$') then + callback = function(args) + local buf_name = vim.api.nvim_buf_get_name(args.buf) + if buf_name:match('claude%-code') then vim.o.updatetime = claude_code.claude_code.saved_updatetime + -- Clean up instance tracking and close window + for instance_id, bufnr in pairs(claude_code.claude_code.instances) do + if bufnr == args.buf then + claude_code.claude_code.instances[instance_id] = nil + break + end + end + -- Close windows and delete buffer after a short delay to allow TermClose to complete + vim.schedule(function() + local win_ids = vim.fn.win_findbuf(args.buf) + for _, win_id in ipairs(win_ids) do + pcall(vim.api.nvim_win_close, win_id, true) + end + pcall(vim.api.nvim_buf_delete, args.buf, { force = true }) + end) end end, - desc = 'Restore normal updatetime when Claude Code is closed', + desc = 'Restore normal updatetime and clean up when Claude Code is closed', }) end diff --git a/lua/claude-code/terminal.lua b/lua/claude-code/terminal.lua index e2fd6430..0be3df12 100644 --- a/lua/claude-code/terminal.lua +++ b/lua/claude-code/terminal.lua @@ -394,7 +394,14 @@ function M.toggle(claude_code, config, git) -- Validate existing buffer if bufnr and not is_valid_terminal_buffer(bufnr) then - -- Buffer is no longer a valid terminal, reset + -- Buffer is no longer a valid terminal, clean up and reset + -- Close any windows showing this buffer + local win_ids = vim.fn.win_findbuf(bufnr) + for _, win_id in ipairs(win_ids) do + pcall(vim.api.nvim_win_close, win_id, true) + end + -- Delete the old buffer to free up the name + pcall(vim.api.nvim_buf_delete, bufnr, { force = true }) claude_code.claude_code.instances[instance_id] = nil bufnr = nil end