@@ -291,18 +291,9 @@ export async function exec(
291291 lnum : divider ,
292292 } ) ) ,
293293 ) ;
294- // Store buffer names for cleanup
295- await vars . b . set ( denops , "gin_blame_paired_buffers" , [
296- bufnameNav ,
297- bufnameDetail ,
298- ] ) ;
299294 // Close all paired buffers when this buffer is unloaded
300295 await denops . cmd (
301- `autocmd BufUnload <buffer> ++once call timer_start(0, { -> execute('silent! bwipeout ' . bufnr('${
302- bufnameNav . replaceAll ( "'" , "''" )
303- } ') . ' | silent! bwipeout ' . bufnr('${
304- bufnameDetail . replaceAll ( "'" , "''" )
305- } ')) })`,
296+ `autocmd BufUnload <buffer> ++once call timer_start(0, { -> execute('silent! bwipeout ' . getbufvar(str2nr(expand('<abuf>')), 'gin_blame_paired_bufnr_nav') . ' | silent! bwipeout ' . getbufvar(str2nr(expand('<abuf>')), 'gin_blame_paired_bufnr_detail')) })` ,
306297 ) ;
307298 } ) ;
308299 } ) ;
@@ -325,6 +316,17 @@ export async function exec(
325316 await fn . win_gotoid ( denops , winidNav ) ;
326317 }
327318 const bufnrNav = await fn . bufnr ( denops , bufnameNav ) ;
319+ const bufnrDetail = await fn . bufnr ( denops , bufnameDetail ) ;
320+
321+ // Store buffer numbers in ginblame buffer for cleanup autocmd
322+ await fn . setbufvar ( denops , bufnr , "gin_blame_paired_bufnr_nav" , bufnrNav ) ;
323+ await fn . setbufvar (
324+ denops ,
325+ bufnr ,
326+ "gin_blame_paired_bufnr_detail" ,
327+ bufnrDetail ,
328+ ) ;
329+
328330 await buffer . replace ( denops , bufnrNav , navContent , {
329331 fileformat,
330332 fileencoding,
@@ -355,6 +357,9 @@ export async function exec(
355357 await vars . b . set ( denops , "gin_blame_file_bufname" , bufnameFile ) ;
356358 await vars . b . set ( denops , "gin_blame_file_fragment" , relpath ) ;
357359 await vars . b . set ( denops , "gin_blame_detail_bufname" , bufnameDetail ) ;
360+ // Store buffer numbers for cleanup
361+ await vars . b . set ( denops , "gin_blame_paired_bufnr_file" , bufnr ) ;
362+ await vars . b . set ( denops , "gin_blame_paired_bufnr_detail" , bufnrDetail ) ;
358363 // Initialize history as empty - will be populated on first Enter
359364 await vars . b . set ( denops , "gin_blame_history" , [ ] ) ;
360365 await vars . b . set ( denops , "gin_blame_history_index" , - 1 ) ;
@@ -374,17 +379,12 @@ export async function exec(
374379 ) ;
375380 // Close all paired buffers when this navigation buffer is unloaded
376381 await denops . cmd (
377- `autocmd BufUnload <buffer> ++once call timer_start(0, { -> execute('silent! bwipeout ' . bufnr('${
378- bufnameFile . replaceAll ( "'" , "''" )
379- } ') . ' | silent! bwipeout ' . bufnr('${
380- bufnameDetail . replaceAll ( "'" , "''" )
381- } ')) })`,
382+ `autocmd BufUnload <buffer> ++once call timer_start(0, { -> execute('silent! bwipeout ' . getbufvar(str2nr(expand('<abuf>')), 'gin_blame_paired_bufnr_file') . ' | silent! bwipeout ' . getbufvar(str2nr(expand('<abuf>')), 'gin_blame_paired_bufnr_detail')) })` ,
382383 ) ;
383384 } ) ;
384385 } ) ;
385386
386387 // Setup commit detail buffer
387- const bufnrDetail = await fn . bufnr ( denops , bufnameDetail ) ;
388388 // Initial commit detail will be set by the first CursorMoved event
389389 await buffer . ensure ( denops , bufnrDetail , async ( ) => {
390390 await batch . batch ( denops , async ( denops ) => {
@@ -398,13 +398,12 @@ export async function exec(
398398 await option . bufhidden . setLocal ( denops , "unload" ) ;
399399 await option . buftype . setLocal ( denops , "nowrite" ) ;
400400 await option . modifiable . setLocal ( denops , false ) ;
401+ // Store buffer numbers for cleanup
402+ await vars . b . set ( denops , "gin_blame_paired_bufnr_file" , bufnr ) ;
403+ await vars . b . set ( denops , "gin_blame_paired_bufnr_nav" , bufnrNav ) ;
401404 // Close all paired buffers when detail buffer is unloaded
402405 await denops . cmd (
403- `autocmd BufUnload <buffer> ++once call timer_start(0, { -> execute('silent! bwipeout ' . bufnr('${
404- bufnameFile . replaceAll ( "'" , "''" )
405- } ') . ' | silent! bwipeout ' . bufnr('${
406- bufnameNav . replaceAll ( "'" , "''" )
407- } ')) })`,
406+ `autocmd BufUnload <buffer> ++once call timer_start(0, { -> execute('silent! bwipeout ' . getbufvar(str2nr(expand('<abuf>')), 'gin_blame_paired_bufnr_file') . ' | silent! bwipeout ' . getbufvar(str2nr(expand('<abuf>')), 'gin_blame_paired_bufnr_nav')) })` ,
408407 ) ;
409408 } ) ;
410409 } ) ;
@@ -595,13 +594,9 @@ async function updateBlameBuffers(
595594 fileencoding,
596595 } ) ;
597596
598- // Rename ginblame buffer using nvim_buf_set_name
599- const oldBufnrBlame = bufnrBlame ;
600- await denops . call ( "nvim_buf_set_name" , bufnrBlame , newBufnameBlame ) ;
601-
602- // Get the new buffer number after rename (nvim_buf_set_name may create a new buffer)
603- const actualBufnrBlame = await fn . bufnr ( denops , newBufnameBlame ) ;
604- bufnrBlame = actualBufnrBlame ;
597+ // Rename ginblame buffer using :file command (Vim/Neovim compatible)
598+ const escapedBlame = await fn . fnameescape ( denops , newBufnameBlame ) ;
599+ await fn . win_execute ( denops , winidBlame , `noautocmd file ${ escapedBlame } ` ) ;
605600
606601 // Get detail bufname before batch (to avoid issues with vars.b.get in batch)
607602 const detailBufname = await vars . b . get (
@@ -662,27 +657,17 @@ async function updateBlameBuffers(
662657 ) ;
663658 } ) ;
664659
665- // If buffer number changed, switch the window to the new buffer and delete old one
666- if ( actualBufnrBlame !== oldBufnrBlame && winidBlame !== - 1 ) {
667- await fn . win_execute ( denops , winidBlame , `buffer ${ actualBufnrBlame } ` ) ;
668- await denops . cmd ( `silent! bwipeout ${ oldBufnrBlame } ` ) ;
669- }
670-
671660 // Update ginblamenav buffer content
672661 await buffer . replace ( denops , bufnrNav , navContent , {
673662 fileformat,
674663 fileencoding,
675664 } ) ;
676665
677- // Rename ginblamenav buffer using nvim_buf_set_name
678- const oldBufnrNav = bufnrNav ;
679- await denops . call ( "nvim_buf_set_name" , bufnrNav , newBufnameNav ) ;
680-
681- // Get the new buffer number after rename (nvim_buf_set_name may create a new buffer)
682- const actualBufnrNav = await fn . bufnr ( denops , newBufnameNav ) ;
683- bufnrNav = actualBufnrNav ;
666+ // Rename ginblamenav buffer using :file command (Vim/Neovim compatible)
667+ const escapedNav = await fn . fnameescape ( denops , newBufnameNav ) ;
668+ await fn . win_execute ( denops , winidNav , `noautocmd file ${ escapedNav } ` ) ;
684669
685- // Update ginblamenav buffer variables and signs (use the actual buffer number)
670+ // Update ginblamenav buffer variables and signs
686671 await batch . batch ( denops , async ( denops ) => {
687672 await fn . setbufvar ( denops , bufnrNav , "gin_blame_result" , newBlameResult ) ;
688673 await fn . setbufvar ( denops , bufnrNav , "gin_blame_line_map" , lineMap ) ;
@@ -710,12 +695,6 @@ async function updateBlameBuffers(
710695 ) ;
711696 } ) ;
712697
713- // If buffer number changed, switch the window to the new buffer and delete old one
714- if ( actualBufnrNav !== oldBufnrNav && winidNav !== - 1 ) {
715- await fn . win_execute ( denops , winidNav , `buffer ${ actualBufnrNav } ` ) ;
716- await denops . cmd ( `silent! bwipeout ${ oldBufnrNav } ` ) ;
717- }
718-
719698 return { newBufnrNav : bufnrNav , newBufnrBlame : bufnrBlame } ;
720699 } finally {
721700 // Re-enable winfixbuf in both windows
@@ -960,6 +939,9 @@ export async function switchToCommit(denops: Denops): Promise<void> {
960939 await fn . win_gotoid ( denops , winidCurrent ) ;
961940 }
962941 }
942+
943+ // Redraw to ensure display is updated after buffer/cursor changes
944+ await denops . cmd ( "redraw" ) ;
963945}
964946
965947/**
@@ -1098,4 +1080,7 @@ export async function navigateHistory(
10981080 if ( scheme === "ginblame" ) {
10991081 await fn . win_gotoid ( denops , winidCurrent ) ;
11001082 }
1083+
1084+ // Redraw to ensure display is updated after buffer/cursor changes
1085+ await denops . cmd ( "redraw" ) ;
11011086}
0 commit comments