Skip to content

Commit

Permalink
fix: clean up buffers properly (#1428)
Browse files Browse the repository at this point in the history
* fix: preseve old visible editor if document it not closed

* fix: use wrapped function clean up windows and buffers

Looks like the atomic request is not working as expected
  • Loading branch information
xiyaowong committed Sep 7, 2023
1 parent 050be0b commit 48ef8e6
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 25 deletions.
16 changes: 16 additions & 0 deletions runtime/lua/vscode-neovim/api.lua
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,20 @@ function M.scroll_viewport(vscode_topline, vscode_endline)
end
end

---Close windows
---@param wins number[]
function M.close_windows(wins)
for _, win in ipairs(wins) do
pcall(vim.api.nvim_win_close, win, true)
end
end

---Delete buffers
---@param bufs number[]
function M.delete_buffers(bufs)
for _, buf in ipairs(bufs) do
pcall(vim.api.nvim_buf_delete, buf, { force = true })
end
end

return M
56 changes: 31 additions & 25 deletions src/buffer_manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -336,9 +336,9 @@ export class BufferManager implements Disposable, NeovimRedrawProcessable, Neovi
this.logger.debug(`${LOG_PREFIX}: syncing layout`);
// store in copy, just in case
const currentVisibleEditors = [...window.visibleTextEditors];
const preservedPrevVisibleEditors: TextEditor[] = [];
const prevVisibleEditors = this.openedEditors;

const nvimRequests: [string, unknown[]][] = [];
// Open/change neovim windows
this.logger.debug(`${LOG_PREFIX}: new/changed editors/windows`);
for (const visibleEditor of currentVisibleEditors) {
Expand Down Expand Up @@ -395,45 +395,51 @@ export class BufferManager implements Disposable, NeovimRedrawProcessable, Neovi
}

this.logger.debug(`${LOG_PREFIX}: Closing non visible editors`);
// close any non visible neovim windows
const unusedWindows: number[] = [];
const unusedBuffers: number[] = [];
for (const prevVisibleEditor of prevVisibleEditors) {
// still visible, skip
if (currentVisibleEditors.includes(prevVisibleEditor)) {
this.logger.debug(
`${LOG_PREFIX}: Editor viewColumn: ${prevVisibleEditor.viewColumn}, visibility hasn't changed, skip`,
);
continue;
}
// buffers
const document = prevVisibleEditor.document;
if (!currentVisibleEditors.find((e) => e.document === document) && document.isClosed) {
this.logger.debug(
`${LOG_PREFIX}: Document ${document.uri.toString()} is not visible and closed, unloading buffer id: ${this.textDocumentToBufferId.get(
document,
)}`,
);
const bufId = this.textDocumentToBufferId.get(document);
this.textDocumentToBufferId.delete(document);
if (bufId) {
nvimRequests.push(["nvim_command", [`bdelete! ${bufId}`]]);
if (!currentVisibleEditors.find((e) => e.document === document)) {
if (document.isClosed) {
this.logger.debug(
`${LOG_PREFIX}: Document ${document.uri.toString()} is not visible and closed, unloading buffer id: ${this.textDocumentToBufferId.get(
document,
)}`,
);
const bufId = this.textDocumentToBufferId.get(document);
this.textDocumentToBufferId.delete(document);
if (bufId) unusedBuffers.push(bufId);
} else {
if (!preservedPrevVisibleEditors.includes(prevVisibleEditor)) {
preservedPrevVisibleEditors.push(prevVisibleEditor);
}
}
}
// windows
const winId = this.textEditorToWinId.get(prevVisibleEditor);

if (!winId) {
continue;
if (winId) {
this.logger.debug(
`${LOG_PREFIX}: Editor viewColumn: ${prevVisibleEditor.viewColumn}, winId: ${winId}, closing`,
);
this.textEditorToWinId.delete(prevVisibleEditor);
this.winIdToEditor.delete(winId);
unusedWindows.push(winId);
}

this.logger.debug(
`${LOG_PREFIX}: Editor viewColumn: ${prevVisibleEditor.viewColumn}, winId: ${winId}, closing`,
);
this.textEditorToWinId.delete(prevVisibleEditor);
this.winIdToEditor.delete(winId);
nvimRequests.push(["nvim_win_close", [winId, true]]);
}
await callAtomic(this.client, nvimRequests, this.logger, LOG_PREFIX);
unusedBuffers.length &&
(await this.client.executeLua("require'vscode-neovim.api'.delete_buffers(...)", [unusedBuffers]));
unusedWindows.length &&
(await this.client.executeLua("require'vscode-neovim.api'.close_windows(...)", [unusedWindows]));

// remember new visible editors
this.openedEditors = currentVisibleEditors;
this.openedEditors = [...currentVisibleEditors, ...preservedPrevVisibleEditors];

if (cancelToken.isCancellationRequested) {
// If the visible editors has changed since we started, don't resolve the promise,
Expand Down

0 comments on commit 48ef8e6

Please sign in to comment.