@@ -354,36 +354,6 @@ local function get_claude_command_and_env()
354354 return cmd_string , env_table
355355end
356356
357- --- Find any existing Claude Code terminal buffer by checking terminal job command
358- -- @local
359- -- @return number|nil Buffer number if found, nil otherwise
360- local function find_existing_claude_terminal ()
361- local buffers = vim .api .nvim_list_bufs ()
362- for _ , buf in ipairs (buffers ) do
363- if vim .api .nvim_buf_is_valid (buf ) and vim .api .nvim_buf_get_option (buf , " buftype" ) == " terminal" then
364- -- Check if this is a Claude Code terminal by examining the buffer name or terminal job
365- local buf_name = vim .api .nvim_buf_get_name (buf )
366- -- Terminal buffers often have names like "term://..." that include the command
367- if buf_name :match (" claude" ) then
368- -- Additional check: see if there's a window displaying this buffer
369- local windows = vim .api .nvim_list_wins ()
370- for _ , win in ipairs (windows ) do
371- if vim .api .nvim_win_get_buf (win ) == buf then
372- require (" claudecode.logger" ).debug (
373- " terminal" ,
374- " Found existing Claude terminal in buffer" ,
375- buf ,
376- " window" ,
377- win
378- )
379- return buf , win
380- end
381- end
382- end
383- end
384- end
385- return nil , nil
386- end
387357
388358--- Opens or focuses the Claude terminal.
389359-- @param opts_override table (optional) Overrides for terminal appearance (split_side, split_width_percentage).
@@ -516,26 +486,15 @@ function M.toggle(opts_override)
516486 local current_neovim_win_id = vim .api .nvim_get_current_win ()
517487
518488 if claude_term_neovim_win_id == current_neovim_win_id then
519- close_fallback_terminal ( )
489+ vim . api . nvim_win_hide ( claude_term_neovim_win_id )
520490 else
521- focus_fallback_terminal () -- This already calls startinsert
491+ vim .api .nvim_set_current_win (claude_term_neovim_win_id )
492+ vim .cmd (" startinsert" )
522493 end
523494 else
524- -- Check if there's an existing Claude terminal we lost track of
525- local existing_buf , existing_win = find_existing_claude_terminal ()
526- if existing_buf and existing_win then
527- -- Recover the existing terminal
528- managed_fallback_terminal_bufnr = existing_buf
529- managed_fallback_terminal_winid = existing_win
530- require (" claudecode.logger" ).debug (" terminal" , " Recovered existing Claude terminal in toggle" )
531-
532- -- Check if we're currently in this terminal
533- local current_neovim_win_id = vim .api .nvim_get_current_win ()
534- if existing_win == current_neovim_win_id then
535- close_fallback_terminal ()
536- else
537- focus_fallback_terminal ()
538- end
495+ local existing_buf = find_existing_terminal_buffer_by_name ()
496+ if existing_buf then
497+ open_window_for_buffer (existing_buf , effective_config )
539498 else
540499 if not open_fallback_terminal (cmd_string , claude_env_table , effective_config ) then
541500 vim .notify (" Failed to open Claude terminal using native fallback (toggle)." , vim .log .levels .ERROR )
@@ -570,4 +529,52 @@ function M.get_active_terminal_bufnr()
570529 return nil
571530end
572531
532+ --- Opens a window for an existing buffer.
533+ -- @local
534+ -- @param bufnr number The buffer number to open.
535+ -- @param effective_term_config table Configuration for split_side and split_width_percentage.
536+ local function open_window_for_buffer (bufnr , effective_term_config )
537+ local original_win = vim .api .nvim_get_current_win ()
538+
539+ local width = math.floor (vim .o .columns * effective_term_config .split_width_percentage )
540+ local full_height = vim .o .lines
541+ local placement_modifier
542+
543+ if effective_term_config .split_side == " left" then
544+ placement_modifier = " topleft "
545+ else
546+ placement_modifier = " botright "
547+ end
548+
549+ vim .cmd (placement_modifier .. width .. " vsplit" )
550+
551+ local new_winid = vim .api .nvim_get_current_win ()
552+
553+ vim .api .nvim_win_set_height (new_winid , full_height )
554+
555+ vim .api .nvim_win_set_buf (new_winid , bufnr )
556+
557+ managed_fallback_terminal_winid = new_winid
558+ managed_fallback_terminal_bufnr = bufnr
559+
560+ vim .api .nvim_set_current_win (managed_fallback_terminal_winid )
561+ vim .cmd (" startinsert" )
562+ end
563+
573564return M
565+
566+ --- Finds the existing Claude terminal buffer, even if it's not in a window.
567+ -- @local
568+ -- @return number|nil The buffer number if found, otherwise nil.
569+ local function find_existing_terminal_buffer_by_name ()
570+ local buffers = vim .api .nvim_list_bufs ()
571+ for _ , buf in ipairs (buffers ) do
572+ if vim .api .nvim_buf_is_valid (buf ) and vim .bo [buf ].buftype == ' terminal' then
573+ local buf_name = vim .api .nvim_buf_get_name (buf )
574+ if buf_name :match (" claude" ) then
575+ return buf
576+ end
577+ end
578+ end
579+ return nil
580+ end
0 commit comments