Did you check docs and existing issues?
Neovim version (nvim -v)
0.12.4
Operating system/version
Manjaro Linux (kernel 6.12.96)
Describe the bug
Snacks.lazygit sets terminal palette entries for numeric theme keys by writing OSC 4 escape sequences directly to stdout:
-- lua/snacks/lazygit.lua:153
pcall(io.write, ("\27]4;%d;%s\7"):format(k, color[1]))
This is only valid when the builtin TUI is attached. With a GUI frontend (Neovide, neovim-qt, any --embed client), stdout is the msgpack-RPC channel, so the raw bytes go into the protocol stream instead of a terminal. Neovide logs this on every lazygit open:
ERROR [neovide::bridge::session] ]4;241;#65bcff
The pcall does not help here because the write itself succeeds; it just writes to the wrong place.
Neovim core guards its own escape writes with a check over nvim_list_uis() (ui.chan == 1 and ui.stdout_tty, see runtime/lua/vim/_defaults.lua), and since 0.12 it provides vim.api.nvim_ui_send() for exactly this purpose (routed to the TUI host terminal, no-op for GUIs; core's OSC 52 clipboard moved to it).
Note: under Neovide the attached UI reports chan == 1, stdout_tty == false, so stdout_tty is the field that discriminates; guess_handle(1) is not reliable because UIs can attach and detach over a session.
The same adapted code in AstroNvim/astroui had the same bug and was fixed in AstroNvim/astroui#66 with:
if vim.api.nvim_ui_send then -- 0.12+
pcall(vim.api.nvim_ui_send, ("\27]4;%d;%s\7"):format(k, color[1]))
elseif tui_attached() then -- nvim_list_uis() scan: ui.chan == 1 and ui.stdout_tty
pcall(io.write, ("\27]4;%d;%s\7"):format(k, color[1]))
end
Happy to send a PR with the equivalent change if you want it.
Steps To Reproduce
- Start Neovide from a terminal with
neovide --no-fork using the repro below (forked Neovide discards stderr, so the error is invisible in a normal launch)
- Run
:lua Snacks.lazygit()
- Check the terminal's stderr:
ERROR [neovide::bridge::session] ]4;241;...
Expected Behavior
Palette escapes are only emitted when a TUI attached to a real terminal can act on them; under GUI frontends nothing is written to the RPC stream.
Repro
vim.env.LAZY_STDPATH = ".repro"
load(vim.fn.system("curl -s https://raw.githubusercontent.com/folke/lazy.nvim/main/bootstrap.lua"))()
require("lazy.minit").repro({
spec = {
{ "folke/snacks.nvim", opts = { lazygit = { enabled = true } } },
},
})
Did you check docs and existing issues?
Neovim version (nvim -v)
0.12.4
Operating system/version
Manjaro Linux (kernel 6.12.96)
Describe the bug
Snacks.lazygitsets terminal palette entries for numeric theme keys by writing OSC 4 escape sequences directly to stdout:This is only valid when the builtin TUI is attached. With a GUI frontend (Neovide, neovim-qt, any
--embedclient), stdout is the msgpack-RPC channel, so the raw bytes go into the protocol stream instead of a terminal. Neovide logs this on every lazygit open:The
pcalldoes not help here because the write itself succeeds; it just writes to the wrong place.Neovim core guards its own escape writes with a check over
nvim_list_uis()(ui.chan == 1 and ui.stdout_tty, seeruntime/lua/vim/_defaults.lua), and since 0.12 it providesvim.api.nvim_ui_send()for exactly this purpose (routed to the TUI host terminal, no-op for GUIs; core's OSC 52 clipboard moved to it).Note: under Neovide the attached UI reports
chan == 1, stdout_tty == false, sostdout_ttyis the field that discriminates;guess_handle(1)is not reliable because UIs can attach and detach over a session.The same adapted code in AstroNvim/astroui had the same bug and was fixed in AstroNvim/astroui#66 with:
Happy to send a PR with the equivalent change if you want it.
Steps To Reproduce
neovide --no-forkusing the repro below (forked Neovide discards stderr, so the error is invisible in a normal launch):lua Snacks.lazygit()ERROR [neovide::bridge::session] ]4;241;...Expected Behavior
Palette escapes are only emitted when a TUI attached to a real terminal can act on them; under GUI frontends nothing is written to the RPC stream.
Repro