@@ -42,19 +42,8 @@ function T.run_in_betterterm(config, is_windows, cmd, notify_warn, notify_err, o
4242 local want_focus = (focus == true ) and (opts .focus ~= false )
4343 local prev = vim .api .nvim_get_current_win ()
4444 local prev_mode = (vim .api .nvim_get_mode and vim .api .nvim_get_mode ().mode ) or ' n'
45- -- Open terminal if requested by config (open_if_closed) or when focusing is desired.
46- -- Even when we don't want to steal focus, we still open the terminal to ensure the session exists,
47- -- then immediately restore previous window to avoid key leakage and focus steal.
48- if (open_first or focus ) then
49- pcall (betterTerm .open , idx )
50- end
51- if not want_focus then
52- -- Restore immediately to avoid stealing focus
53- pcall (vim .api .nvim_set_current_win , prev )
54- if prev_mode :sub (1 , 1 ) == ' n' then
55- pcall (vim .cmd , ' stopinsert' )
56- end
57- end
45+ -- Do not pre-open to avoid toggle-closing an already visible terminal window.
46+ -- We will try to send first; if it fails, we may open; if focusing is desired, we'll try to focus an existing window.
5847 vim .defer_fn (function ()
5948 local ok_send , err = pcall (betterTerm .send , cmd .. (is_windows () and ' \r ' or ' \n ' ), idx )
6049 if not ok_send then
@@ -64,8 +53,34 @@ function T.run_in_betterterm(config, is_windows, cmd, notify_warn, notify_err, o
6453 end
6554 return
6655 end
67- -- Some versions of betterTerm may re-focus after open/send; if we don't want focus, restore again after send
68- if not want_focus then
56+ -- Focus behavior after successful send
57+ if want_focus then
58+ -- Prefer focusing an existing terminal window to avoid toggle-close behavior
59+ local terms = T .list_open_builtin_terminals ()
60+ if terms and # terms > 0 then
61+ local last = terms [# terms ]
62+ pcall (vim .api .nvim_set_current_win , prev ) -- ensure we have valid window context
63+ vim .defer_fn (function ()
64+ pcall (function ()
65+ -- try to focus existing terminal window displaying this buffer
66+ for _ , win in ipairs (vim .api .nvim_list_wins ()) do
67+ if vim .api .nvim_win_is_valid (win ) and vim .api .nvim_win_get_buf (win ) == last .bufnr then
68+ pcall (vim .api .nvim_set_current_win , win )
69+ return
70+ end
71+ end
72+ -- not found: as a fallback, open via betterTerm (may create or bring to front)
73+ pcall (betterTerm .open , idx )
74+ end )
75+ end , 60 )
76+ else
77+ -- No terminal windows: open one now to show output
78+ vim .defer_fn (function ()
79+ pcall (betterTerm .open , idx )
80+ end , 60 )
81+ end
82+ else
83+ -- If not focusing, restore previous window to avoid stealing focus
6984 vim .defer_fn (function ()
7085 pcall (vim .api .nvim_set_current_win , prev )
7186 if prev_mode :sub (1 , 1 ) == ' n' then
@@ -78,9 +93,14 @@ function T.run_in_betterterm(config, is_windows, cmd, notify_warn, notify_err, o
7893end
7994
8095function T .run_make_in_terminal (config , is_windows , cmdline , notify_warn , notify_err )
81- -- Auto-focus terminal when none is currently open; otherwise do not steal focus.
96+ -- Decide focus policy:
97+ -- - If betterTerm is enabled and focus_on_run ~= false, prefer focusing (honor user config).
98+ -- - Otherwise fallback to legacy behavior: focus only when no builtin terminal is open.
8299 local open_terms = T .list_open_builtin_terminals ()
83- local want_focus = (# open_terms == 0 )
100+ local bt_cfg = config .betterterm or {}
101+ local prefer_bt = (bt_cfg .enabled ~= false )
102+ local cfg_focus = (bt_cfg .focus_on_run ~= false )
103+ local want_focus = (prefer_bt and cfg_focus ) or (# open_terms == 0 )
84104 if not T .run_in_betterterm (config , is_windows , cmdline , notify_warn , notify_err , { focus = want_focus }) then
85105 if not T .run_in_native_terminal (config , is_windows , cmdline , { focus = want_focus }) then
86106 notify_err ' Unable to run make: cannot open terminal'
@@ -170,52 +190,18 @@ function T.select_or_run_in_terminal(config, is_windows, cmdline, notify_warn, n
170190 actions .close (bufnr )
171191 local v = entry .value
172192 if v .kind == ' default' then
193+ -- Use unified focusing/selection policy inside run_make_in_terminal
173194 T .run_make_in_terminal (config , is_windows , cmdline , notify_warn , notify_err )
174- do
175- local ok_bt , betterTerm = pcall (require , ' betterTerm' )
176- if ok_bt and (config .betterterm and config .betterterm .enabled ~= false ) then
177- local idx = (config .betterterm and config .betterterm .index ) or 0
178- local focus_on_run = (config .betterterm and config .betterterm .focus_on_run ) ~= false
179- if focus_on_run then
180- vim .defer_fn (function ()
181- pcall (betterTerm .open , idx )
182- end , 120 )
183- end
184- else
185- -- Focus a builtin terminal window after sending, to honor explicit user choice
186- vim .defer_fn (function ()
187- local terms = T .list_open_builtin_terminals ()
188- if terms and # terms > 0 then
189- -- pick the last one (most recently opened)
190- local last = terms [# terms ]
191- pcall (open_builtin_terminal_window , config , last .bufnr )
192- end
193- end , 120 )
194- end
195- end
196195 else
197196 local ok = T .send_to_builtin_terminal (is_windows , v .job , cmdline , { bufnr = v .bufnr , config = config })
198197 if not ok then
199198 notify_warn ' Failed to send to selected terminal, using default strategy'
200199 T .run_make_in_terminal (config , is_windows , cmdline , notify_warn , notify_err )
201- do
202- local ok_bt , betterTerm = pcall (require , ' betterTerm' )
203- if ok_bt and (config .betterterm and config .betterterm .enabled ~= false ) then
204- local idx = (config .betterterm and config .betterterm .index ) or 0
205- local focus_on_run = (config .betterterm and config .betterterm .focus_on_run ) ~= false
206- if focus_on_run then
207- vim .defer_fn (function ()
208- pcall (betterTerm .open , idx )
209- end , 120 )
210- end
211- end
212- end
213- end
214- if ok then
215- vim .defer_fn (function ()
216- pcall (open_builtin_terminal_window , config , v .bufnr )
217- end , 120 )
200+ return
218201 end
202+ vim .defer_fn (function ()
203+ pcall (open_builtin_terminal_window , config , v .bufnr )
204+ end , 120 )
219205 end
220206 end
221207 map (' i' , ' <CR>' , choose )
0 commit comments