Skip to content

Commit c165cfb

Browse files
authored
Merge pull request #167 from lambdalisue/fix/blame-buffer-cleanup
fix: improve buffer cleanup and rename in gin-blame
2 parents 353e32d + 714dc46 commit c165cfb

File tree

1 file changed

+33
-48
lines changed

1 file changed

+33
-48
lines changed

denops/gin/command/blame/edit.ts

Lines changed: 33 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)