@@ -354,36 +354,6 @@ local function get_claude_command_and_env()
354
354
return cmd_string , env_table
355
355
end
356
356
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
387
357
388
358
--- Opens or focuses the Claude terminal.
389
359
-- @param opts_override table (optional) Overrides for terminal appearance (split_side, split_width_percentage).
@@ -516,26 +486,15 @@ function M.toggle(opts_override)
516
486
local current_neovim_win_id = vim .api .nvim_get_current_win ()
517
487
518
488
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 )
520
490
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" )
522
493
end
523
494
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 )
539
498
else
540
499
if not open_fallback_terminal (cmd_string , claude_env_table , effective_config ) then
541
500
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()
570
529
return nil
571
530
end
572
531
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
+
573
564
return 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