diff --git a/runtime/lua/vim/_core/defaults.lua b/runtime/lua/vim/_core/defaults.lua index b508827c3b..b1e705411b 100644 --- a/runtime/lua/vim/_core/defaults.lua +++ b/runtime/lua/vim/_core/defaults.lua @@ -1011,16 +1011,20 @@ do -- Neither the TUI nor $COLORTERM indicate that truecolor is supported, so query the -- terminal local caps = {} ---@type table - vim.tty.query({ 'Tc', 'RGB', 'setrgbf', 'setrgbb' }, function(cap, found) - if not found then - return - end + vim.tty.query( + { 'Tc', 'RGB', 'setrgbf', 'setrgbb' }, + { group = group, chan = ui.chan }, + function(cap, found) + if not found then + return + end - caps[cap] = true - if caps.Tc or caps.RGB or (caps.setrgbf and caps.setrgbb) then - setoption('termguicolors', true) + caps[cap] = true + if caps.Tc or caps.RGB or (caps.setrgbf and caps.setrgbb) then + setoption('termguicolors', true) + end end - end) + ) -- Arbitrary colors to set in the SGR sequence local r = 1 @@ -1035,7 +1039,7 @@ do -- Reset attributes first, as other code may have set attributes. local payload = ('\027[0m\027[48;2;%d;%d;%dm%s'):format(r, g, b, '\027P$qm\027\\') - vim.tty.request(payload, { group = group }, function(resp) + vim.tty.request(payload, { group = group, chan = ui.chan }, function(resp) local decrqss = resp:match('^\027P1%$r([%d;:]+)m$') if not decrqss then return @@ -1083,7 +1087,7 @@ do -- startup TTY (including runtime reactivity), so the UIEnter path below is -- not registered for it (avoids double-detection). if vim.o.ttyfast then - detect_background(true) + detect_background(true, tty.chan) end detect_termguicolors(tty) diff --git a/runtime/lua/vim/tty.lua b/runtime/lua/vim/tty.lua index 06b8eddcec..73de366bc1 100644 --- a/runtime/lua/vim/tty.lua +++ b/runtime/lua/vim/tty.lua @@ -80,13 +80,23 @@ end --- emulator supports the XTGETTCAP sequence. --- --- @param caps string|table A terminal capability or list of capabilities to query +--- @param opts? { timeout?: integer, on_timeout?: fun(), group?: integer|string, chan?: integer } --- @param on_response fun(cap:string, found:boolean, seq:string?) Called for each capability in --- `caps`. `found` is true if the capability was found, else false. `seq` is the control --- sequence if found, or nil for boolean capabilities. -function M.query(caps, on_response) +---@overload fun(caps:string|table, on_response:fun(cap:string, found:boolean, seq:string?)) +function M.query(caps, opts, on_response) + if type(opts) == 'function' then + on_response = opts + opts = {} + end + vim.validate('caps', caps, { 'string', 'table' }) + vim.validate('opts', opts, 'table', true) vim.validate('on_response', on_response, 'function') + opts = opts or {} + if type(caps) ~= 'table' then caps = { caps } end @@ -103,11 +113,17 @@ function M.query(caps, on_response) local payload = ('\027P+q%s\027\\'):format(table.concat(encoded, ';')) M.request(payload, { + timeout = opts.timeout, + group = opts.group, + chan = opts.chan, on_timeout = function() -- Call the callback for all capabilities that were not found. for k in pairs(pending) do on_response(k, false, nil) end + if opts.on_timeout then + opts.on_timeout() + end end, }, function(resp) local k, rest = resp:match('^\027P1%+r(%x+)(.*)$') @@ -144,7 +160,7 @@ end --- Return `true` from `on_response` to stop listening. --- ---@param payload string APC sequence to send (full escape sequence including prefix/suffix) ----@param opts {timeout?:integer} Options table (timeout in milliseconds, default 1000) +---@param opts {timeout?:integer, chan?:integer} Options table (timeout in milliseconds, default 1000) ---@param on_response fun(resp:string):boolean? Callback invoked for each APC TermResponse ---@overload fun(payload:string, on_response:fun(resp:string):boolean?) function M.query_apc(payload, opts, on_response) diff --git a/runtime/lua/vim/ui/img.lua b/runtime/lua/vim/ui/img.lua index 129917a973..59aaf868a2 100644 --- a/runtime/lua/vim/ui/img.lua +++ b/runtime/lua/vim/ui/img.lua @@ -137,7 +137,7 @@ end --- Query whether the host terminal supports displaying images. --- Blocks until the terminal responds or times out. --- ----@param opts? {timeout?: integer} timeout in milliseconds (default: 1000) +---@param opts? {timeout?: integer, chan?: integer} timeout in milliseconds (default: 1000) ---@return boolean supported true if the terminal supports image display ---@return string? msg error detail if the terminal responded but not with OK function M._supported(opts) diff --git a/runtime/lua/vim/ui/img/_kitty.lua b/runtime/lua/vim/ui/img/_kitty.lua index 33e1f4236a..9aebb7e196 100644 --- a/runtime/lua/vim/ui/img/_kitty.lua +++ b/runtime/lua/vim/ui/img/_kitty.lua @@ -160,11 +160,12 @@ end --- Query whether this terminal supports the kitty graphics protocol. --- Blocks until the terminal responds or times out. --- ----@param opts? {timeout?: integer} timeout in milliseconds (default: 1000) +---@param opts? {timeout?: integer, chan?: integer} timeout in milliseconds (default: 1000) ---@return boolean supported ---@return string? msg error detail if terminal responded but not with OK function M.supported(opts) - local timeout = opts and opts.timeout or 1000 + opts = opts or {} + local timeout = opts.timeout or 1000 -- Do not use APC on terminals that echo unknown sequences if vim.env.TERM_PROGRAM == 'Apple_Terminal' then @@ -180,7 +181,7 @@ function M.supported(opts) vim.tty.query_apc( seq({ a = 'q', i = query_id, s = 1, v = 1 }), - { timeout = timeout }, + { timeout = timeout, chan = opts.chan }, function(resp) -- kitty APC response: \027_G[,]i=[,]; -- status is "OK" or an error code+message like "ENODATA:Missing image data"