Old blazingJJ instance linger in the background #1

Open
opened 2026-07-14 10:04:15 +02:00 by dotdash · 1 comment

When the floating window loses focus, the term buffer is set to hidden, but the next time a new blazingjj instance is started, so instances start to pile up.

I'm currently not at a box where I could create a PR, so here's a patch instead:

diff --git lua/blazingjj/init.lua lua/blazingjj/init.lua
index 1d819d9..70bf2c7 100644
--- lua/blazingjj/init.lua
+++ lua/blazingjj/init.lua
@@ -2,12 +2,19 @@
 
 local M = {}
 
-local function open_floating_window()
+-- Terminal buffer from a previous invocation, reused across opens
+local term_buf = nil
+-- Window to return to when blazingjj exits, updated on each open
+local prev_win = nil
+
+local function open_floating_window(bufnr)
 	-- Get plenary's float window module which handles window creation
 	local plenary = require("plenary.window.float")
 
-	-- Create centered floating window at 90% of screen size with rounded borders
+	-- Create centered floating window at 90% of screen size with rounded borders,
+	-- showing the given buffer (plenary creates a fresh one if nil)
 	local win = plenary.percentage_range_window(0.9, 0.8, {
+		bufnr = bufnr,
 		border = {
 			"╭",
 			"─",
@@ -20,24 +27,9 @@ local function open_floating_window()
 		},
 	})
 
-	-- Set buffer filetype for syntax highlighting
-	vim.bo[win.bufnr].filetype = "blazingjj"
-
 	-- Ensure window is completely opaque
 	vim.wo[win.win_id].winblend = 0
 
-	-- Hide buffer when window closes rather than delete it
-	vim.cmd("setlocal bufhidden=hide")
-
-	-- Automatically hide window when focus is lost
-	vim.api.nvim_create_autocmd("WinLeave", {
-		buffer = win.bufnr,
-		callback = function()
-			vim.cmd("hide")
-		end,
-		once = true,
-	})
-
 	-- Return window and buffer handles for further manipulation if needed
 	return win.win_id, win.bufnr
 end
@@ -73,27 +65,59 @@ function M.open()
 		return
 	end
 
-	local prev_win = vim.api.nvim_get_current_win()
+	prev_win = vim.api.nvim_get_current_win()
 
-	-- Create floating window
-	open_floating_window()
+	-- Filetype check guards against buffer number reuse: the counter resets
+	-- when the buffer list becomes empty (e.g. %bwipeout!), so a stale handle
+	-- could otherwise point at an unrelated buffer
+	if term_buf and not (vim.api.nvim_buf_is_valid(term_buf) and vim.bo[term_buf].filetype == "blazingjj") then
+		term_buf = nil
+	end
 
-	-- Execute blazingjj in the floating window
-	vim.fn.termopen(cmd, {
-		-- Return to previous window on exit
-		on_exit = function()
-			if vim.api.nvim_win_is_valid(prev_win) then
-				vim.api.nvim_set_current_win(prev_win)
-			end
-		end,
-		-- Handle potential errors
-		on_stderr = function(_, data)
-			for _, line in ipairs(data) do
-				if line:match("^Error:.*") then
-					vim.notify("blazingjj error: " .. line, vim.log.levels.ERROR)
+	-- Create floating window, reusing the hidden terminal buffer from a
+	-- previous invocation if there is one
+	local reused = term_buf ~= nil
+	local _, bufnr = open_floating_window(term_buf)
+
+	if not reused then
+		term_buf = bufnr
+
+		-- Set buffer filetype for syntax highlighting
+		vim.bo[bufnr].filetype = "blazingjj"
+
+		-- Hide buffer when window closes rather than delete it
+		vim.bo[bufnr].bufhidden = "hide"
+
+		-- Execute blazingjj in the floating window
+		vim.fn.termopen(cmd, {
+			-- Drop the buffer and return to previous window on exit
+			on_exit = function()
+				if term_buf and vim.api.nvim_buf_is_valid(term_buf) then
+					vim.api.nvim_buf_delete(term_buf, { force = true })
+				end
+				term_buf = nil
+				if prev_win and vim.api.nvim_win_is_valid(prev_win) then
+					vim.api.nvim_set_current_win(prev_win)
 				end
-			end
+			end,
+			-- Handle potential errors
+			on_stderr = function(_, data)
+				for _, line in ipairs(data) do
+					if line:match("^Error:.*") then
+						vim.notify("blazingjj error: " .. line, vim.log.levels.ERROR)
+					end
+				end
+			end,
+		})
+	end
+
+	-- Automatically hide window when focus is lost
+	vim.api.nvim_create_autocmd("WinLeave", {
+		buffer = bufnr,
+		callback = function()
+			vim.cmd("hide")
 		end,
+		once = true,
 	})
 
 	-- Enter insert mode to allow immediate interaction
When the floating window loses focus, the term buffer is set to hidden, but the next time a new blazingjj instance is started, so instances start to pile up. I'm currently not at a box where I could create a PR, so here's a patch instead: ```diff diff --git lua/blazingjj/init.lua lua/blazingjj/init.lua index 1d819d9..70bf2c7 100644 --- lua/blazingjj/init.lua +++ lua/blazingjj/init.lua @@ -2,12 +2,19 @@ local M = {} -local function open_floating_window() +-- Terminal buffer from a previous invocation, reused across opens +local term_buf = nil +-- Window to return to when blazingjj exits, updated on each open +local prev_win = nil + +local function open_floating_window(bufnr) -- Get plenary's float window module which handles window creation local plenary = require("plenary.window.float") - -- Create centered floating window at 90% of screen size with rounded borders + -- Create centered floating window at 90% of screen size with rounded borders, + -- showing the given buffer (plenary creates a fresh one if nil) local win = plenary.percentage_range_window(0.9, 0.8, { + bufnr = bufnr, border = { "╭", "─", @@ -20,24 +27,9 @@ local function open_floating_window() }, }) - -- Set buffer filetype for syntax highlighting - vim.bo[win.bufnr].filetype = "blazingjj" - -- Ensure window is completely opaque vim.wo[win.win_id].winblend = 0 - -- Hide buffer when window closes rather than delete it - vim.cmd("setlocal bufhidden=hide") - - -- Automatically hide window when focus is lost - vim.api.nvim_create_autocmd("WinLeave", { - buffer = win.bufnr, - callback = function() - vim.cmd("hide") - end, - once = true, - }) - -- Return window and buffer handles for further manipulation if needed return win.win_id, win.bufnr end @@ -73,27 +65,59 @@ function M.open() return end - local prev_win = vim.api.nvim_get_current_win() + prev_win = vim.api.nvim_get_current_win() - -- Create floating window - open_floating_window() + -- Filetype check guards against buffer number reuse: the counter resets + -- when the buffer list becomes empty (e.g. %bwipeout!), so a stale handle + -- could otherwise point at an unrelated buffer + if term_buf and not (vim.api.nvim_buf_is_valid(term_buf) and vim.bo[term_buf].filetype == "blazingjj") then + term_buf = nil + end - -- Execute blazingjj in the floating window - vim.fn.termopen(cmd, { - -- Return to previous window on exit - on_exit = function() - if vim.api.nvim_win_is_valid(prev_win) then - vim.api.nvim_set_current_win(prev_win) - end - end, - -- Handle potential errors - on_stderr = function(_, data) - for _, line in ipairs(data) do - if line:match("^Error:.*") then - vim.notify("blazingjj error: " .. line, vim.log.levels.ERROR) + -- Create floating window, reusing the hidden terminal buffer from a + -- previous invocation if there is one + local reused = term_buf ~= nil + local _, bufnr = open_floating_window(term_buf) + + if not reused then + term_buf = bufnr + + -- Set buffer filetype for syntax highlighting + vim.bo[bufnr].filetype = "blazingjj" + + -- Hide buffer when window closes rather than delete it + vim.bo[bufnr].bufhidden = "hide" + + -- Execute blazingjj in the floating window + vim.fn.termopen(cmd, { + -- Drop the buffer and return to previous window on exit + on_exit = function() + if term_buf and vim.api.nvim_buf_is_valid(term_buf) then + vim.api.nvim_buf_delete(term_buf, { force = true }) + end + term_buf = nil + if prev_win and vim.api.nvim_win_is_valid(prev_win) then + vim.api.nvim_set_current_win(prev_win) end - end + end, + -- Handle potential errors + on_stderr = function(_, data) + for _, line in ipairs(data) do + if line:match("^Error:.*") then + vim.notify("blazingjj error: " .. line, vim.log.levels.ERROR) + end + end + end, + }) + end + + -- Automatically hide window when focus is lost + vim.api.nvim_create_autocmd("WinLeave", { + buffer = bufnr, + callback = function() + vim.cmd("hide") end, + once = true, }) -- Enter insert mode to allow immediate interaction ```
Owner

Thank you, will work on it later tonight!

Thank you, will work on it later tonight!
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
sejo/blazingjj.nvim#1
No description provided.