Skip to content

Commit 1c27903

Browse files
committed
feat(misc)!: update setup_termbg_sync() to use OSC 111 sequence
Details: - Using "set color explicitly" doesn't work with transparent background in `tmux`. Resolve #1128 Resolve nvim-mini/MiniMax#25
1 parent 6229e38 commit 1c27903

File tree

4 files changed

+63
-13
lines changed

4 files changed

+63
-13
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,14 @@ There are following change types:
88

99
# Version 0.18.0-dev
1010

11+
## mini.misc
12+
13+
### Evolve
14+
15+
- Update `setup_termbg_sync()` to use OSC 111 control sequence to reset terminal emulator's background color. This provides a more robust behavior across platforms (like `tmux`).
16+
17+
The previous "reset by explicitly setting initial background color" behavior is available by setting the new `opts.explicit_reset` option to `true`.
18+
1119

1220
# Version 0.17.0
1321

doc/mini-misc.txt

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ Parameters ~
238238

239239
------------------------------------------------------------------------------
240240
*MiniMisc.setup_termbg_sync()*
241-
`MiniMisc.setup_termbg_sync`()
241+
`MiniMisc.setup_termbg_sync`({opts})
242242
Set up terminal background synchronization
243243

244244
What it does:
@@ -247,8 +247,7 @@ What it does:
247247
- Creates autocommands for |ColorScheme| and |VimResume| events, which
248248
change terminal background to have same color as |guibg| of |hl-Normal|.
249249
- Creates autocommands for |VimLeavePre| and |VimSuspend| events which set
250-
terminal background back to the color at the time this function was
251-
called first time in current session.
250+
terminal background back to its original color.
252251
- Synchronizes background immediately to allow not depend on loading order.
253252

254253
Primary use case is to remove possible "frame" around current Neovim instance
@@ -257,6 +256,13 @@ used by terminal emulator itself.
257256

258257
Works only on Neovim>=0.10.
259258

259+
Parameters ~
260+
{opts} `(table|nil)` Options. Possible fields:
261+
- <explicit_reset> `(boolean)` - whether to reset terminal background by
262+
explicitly setting it to the color it had when this function was called.
263+
Set to `true` if terminal emulator doesn't support OSC 111 control sequence.
264+
Default: `false`.
265+
260266
------------------------------------------------------------------------------
261267
*MiniMisc.setup_restore_cursor()*
262268
`MiniMisc.setup_restore_cursor`({opts})

lua/mini/misc.lua

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -370,16 +370,21 @@ H.root_cache = {}
370370
--- - Creates autocommands for |ColorScheme| and |VimResume| events, which
371371
--- change terminal background to have same color as |guibg| of |hl-Normal|.
372372
--- - Creates autocommands for |VimLeavePre| and |VimSuspend| events which set
373-
--- terminal background back to the color at the time this function was
374-
--- called first time in current session.
373+
--- terminal background back to its original color.
375374
--- - Synchronizes background immediately to allow not depend on loading order.
376375
---
377376
--- Primary use case is to remove possible "frame" around current Neovim instance
378377
--- which appears if Neovim's |hl-Normal| background color differs from what is
379378
--- used by terminal emulator itself.
380379
---
381380
--- Works only on Neovim>=0.10.
382-
MiniMisc.setup_termbg_sync = function()
381+
---
382+
---@param opts table|nil Options. Possible fields:
383+
--- - <explicit_reset> `(boolean)` - whether to reset terminal background by
384+
--- explicitly setting it to the color it had when this function was called.
385+
--- Set to `true` if terminal emulator doesn't support OSC 111 control sequence.
386+
--- Default: `false`.
387+
MiniMisc.setup_termbg_sync = function(opts)
383388
-- Handling `'\027]11;?\007'` response was added in Neovim 0.10
384389
if vim.fn.has('nvim-0.10') == 0 then return H.notify('`setup_termbg_sync()` requires Neovim>=0.10', 'WARN') end
385390

@@ -390,6 +395,12 @@ MiniMisc.setup_termbg_sync = function()
390395
end
391396
if not has_stdout_tty then return end
392397

398+
opts = vim.tbl_extend('force', { explicit_reset = false }, opts or {})
399+
400+
-- Choose a method for how terminal emulator background is reset
401+
local reset = function() io.stdout:write('\027]111\027\\') end
402+
if opts.explicit_reset then reset = function() io.stdout:write('\027]11;' .. H.termbg_init .. '\007') end end
403+
393404
local augroup = vim.api.nvim_create_augroup('MiniMiscTermbgSync', { clear = true })
394405
local track_au_id, bad_responses, had_proper_response = nil, {}, false
395406
local f = function(args)
@@ -406,7 +417,6 @@ MiniMisc.setup_termbg_sync = function()
406417

407418
-- Set up reset to the color returned from the very first call
408419
H.termbg_init = H.termbg_init or termbg
409-
local reset = function() io.stdout:write('\027]11;' .. H.termbg_init .. '\007') end
410420
vim.api.nvim_create_autocmd({ 'VimLeavePre', 'VimSuspend' }, { group = augroup, callback = reset })
411421

412422
-- Set up sync

tests/test_misc.lua

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -711,8 +711,8 @@ T['setup_termbg_sync()']['works'] = new_set(
711711
end
712712
validate_event('VimResume', '\027]11;#dddddd\007')
713713
validate_event('ColorScheme', '\027]11;#dddddd\007')
714-
validate_event('VimLeavePre', '\027]11;#11262d\007')
715-
validate_event('VimSuspend', '\027]11;#11262d\007')
714+
validate_event('VimLeavePre', '\027]111\027\\')
715+
validate_event('VimSuspend', '\027]111\027\\')
716716
end,
717717
}
718718
)
@@ -734,7 +734,7 @@ T['setup_termbg_sync()']['can be called multiple times'] = function()
734734

735735
-- Should reset to the color from the very first call
736736
child.api.nvim_exec_autocmds('VimLeavePre', {})
737-
eq(child.lua_get('_G.log'), { { '\27]11;#11262d\a' } })
737+
eq(child.lua_get('_G.log'), { { '\027]111\027\\' } })
738738
end
739739

740740
T['setup_termbg_sync()']['does nothing if there is no proper stdout'] = function()
@@ -831,7 +831,7 @@ end
831831
T['setup_termbg_sync()']['handles different color formats'] = function()
832832
skip_if_no_010()
833833

834-
local validate = function(term_response_color, ref_color)
834+
local validate = function(term_response_color)
835835
-- Mock clean start to overcome that color is parsed only once per session
836836
child.lua('package.loaded["mini.misc"] = nil')
837837
child.lua('require("mini.misc").setup_termbg_sync()')
@@ -840,7 +840,7 @@ T['setup_termbg_sync()']['handles different color formats'] = function()
840840
-- Should properly parse initial background and use it to reset on exit
841841
child.lua('_G.log = {}')
842842
child.api.nvim_exec_autocmds('VimLeavePre', {})
843-
eq(child.lua_get('_G.log'), { { '\027]11;' .. ref_color .. '\007' } })
843+
eq(child.lua_get('_G.log'), { { '\027]111\027\\' } })
844844

845845
-- Clean up
846846
child.lua('_G.log = {}')
@@ -872,7 +872,33 @@ T['setup_termbg_sync()']['handles transparent `Normal` background'] = function()
872872
-- terminal background
873873
child.cmd('hi Normal guifg=#222222 guibg=NONE')
874874
child.api.nvim_exec_autocmds('ColorScheme', {})
875-
eq(child.lua_get('_G.log'), { { '\27]11;#11262d\a' } })
875+
eq(child.lua_get('_G.log'), { { '\027]111\027\\' } })
876+
end
877+
878+
T['setup_termbg_sync()']['respects `opts.explicit_reset`'] = function()
879+
skip_if_no_010()
880+
881+
child.cmd('hi Normal guifg=#222222 guibg=#dddddd')
882+
child.lua('MiniMisc.setup_termbg_sync({ explicit_reset = true })')
883+
child.api.nvim_exec_autocmds('TermResponse', { data = '\027]11;rgb:1111/2626/2d2d' })
884+
child.lua('_G.log = {}')
885+
886+
-- Should still sync on appropriate events
887+
local validate_event = function(event, log_entry)
888+
child.api.nvim_exec_autocmds(event, {})
889+
eq(child.lua_get('_G.log'), { { log_entry } })
890+
child.lua('_G.log = {}')
891+
end
892+
validate_event('VimResume', '\027]11;#dddddd\007')
893+
validate_event('ColorScheme', '\027]11;#dddddd\007')
894+
-- - Should reset by setting initial color explicitly
895+
validate_event('VimLeavePre', '\027]11;#11262d\007')
896+
validate_event('VimSuspend', '\027]11;#11262d\007')
897+
898+
-- Should reset with explicit bg color on transparent `Normal` background
899+
child.cmd('hi Normal guifg=#222222 guibg=NONE')
900+
child.api.nvim_exec_autocmds('ColorScheme', {})
901+
eq(child.lua_get('_G.log'), { { '\027]11;#11262d\a' } })
876902
end
877903

878904
local restore_cursor_test_file = make_path(dir_misc_path, 'restore-cursor.lua')

0 commit comments

Comments
 (0)