diff --git a/doc/kitty-scrollback.nvim.txt b/doc/kitty-scrollback.nvim.txt index 14abd5bd..d37180b2 100644 --- a/doc/kitty-scrollback.nvim.txt +++ b/doc/kitty-scrollback.nvim.txt @@ -1,4 +1,4 @@ -*kitty-scrollback.nvim.txt* For NVIM v0.10+ Last change: 2023 September 29 +*kitty-scrollback.nvim.txt* For NVIM v0.10+ Last change: 2023 October 01 ============================================================================== Table of Contents *kitty-scrollback.nvim-table-of-contents* diff --git a/doc/kitty-scrollback.nvim_spec.txt b/doc/kitty-scrollback.nvim_spec.txt index 6b2559da..5424ace0 100644 --- a/doc/kitty-scrollback.nvim_spec.txt +++ b/doc/kitty-scrollback.nvim_spec.txt @@ -170,4 +170,19 @@ M.generate_kittens() *kitty-scrollback.api.generate_kittens* M.checkhealth() *kitty-scrollback.api.checkhealth* + *kitty-scrollback.api.close_kitty_loading_window* +M.close_kitty_loading_window() + Try to close Kitty loading window + If the first attempt to close fails, then list all Kitty windows to see if window exists + If the window does exist, then reattempt to close the window and report error on failure + + +M.get_kitty_colors({kitty_data}) *kitty-scrollback.api.get_kitty_colors* + Try to get Kitty terminal colors + If the first attempt fails for the given window id, then reattempt without a window id + + Parameters: ~ + {kitty_data} (KsbKittyData) @return boolean, vim.SystemCompleted + + vim:tw=78:ts=8:noet:ft=help:norl: diff --git a/lua/kitty-scrollback/api.lua b/lua/kitty-scrollback/api.lua index b8d777bd..535e6edc 100644 --- a/lua/kitty-scrollback/api.lua +++ b/lua/kitty-scrollback/api.lua @@ -156,4 +156,56 @@ M.checkhealth = function() end end +--- Try to close Kitty loading window +--- If the first attempt to close fails, then list all Kitty windows to see if window exists +--- If the window does exist, then reattempt to close the window and report error on failure +M.close_kitty_loading_window = function() + local winid = p.kitty_loading_winid + local close_ok, close_result = ksb_kitty_cmds.close_kitty_loading_window(true) + if not close_ok then + if + close_result + and close_result.stderr + and close_result.stderr:match('.*No matching windows.*') + then + local ok, kitty_windows_result = ksb_kitty_cmds.list_kitty_windows() + if not ok then + return + end + local kitty_windows = vim.json.decode(kitty_windows_result.stdout) + for _, kitty_window in pairs(kitty_windows) do + for _, tab in pairs(kitty_window.tabs) do + for _, window in pairs(tab.windows) do + for env_name, env_value in pairs(window.env) do + if env_name == 'KITTY_WINDOW_ID' and tonumber(env_value) == winid then + -- the close error is valid, attempt one more time to properly display error to user + vim.defer_fn(ksb_kitty_cmds.close_kitty_loading_window, 500) + end + end + end + end + end + end + end +end + +--- Try to get Kitty terminal colors +--- If the first attempt fails for the given window id, then reattempt without a window id +---@param kitty_data KsbKittyData +---@return boolean, vim.SystemCompleted +M.get_kitty_colors = function(kitty_data) + local colors_ok, colors_result = ksb_kitty_cmds.get_kitty_colors(kitty_data, true) + if not colors_ok then + if + colors_result + and colors_result.stderr + and colors_result.stderr:match('.*No matching windows.*') + then + -- do not specify a window id + return ksb_kitty_cmds.get_kitty_colors(kitty_data, false, true) + end + end + return colors_ok, colors_result +end + return M diff --git a/lua/kitty-scrollback/highlights.lua b/lua/kitty-scrollback/highlights.lua index a3ce924e..d62d52c8 100644 --- a/lua/kitty-scrollback/highlights.lua +++ b/lua/kitty-scrollback/highlights.lua @@ -1,9 +1,11 @@ ---@mod kitty-scrollback.highlights +local ksb_api = require('kitty-scrollback.api') local ksb_kitty_cmds = require('kitty-scrollback.kitty_commands') local ksb_util = require('kitty-scrollback.util') local M = {} +---@type KsbPrivate local p local opts ---@diagnostic disable-line: unused-local @@ -84,7 +86,7 @@ end M.setup = function(private, options) p = private opts = options ---@diagnostic disable-line: unused-local - local ok, colors = ksb_kitty_cmds.get_kitty_colors(p.kitty_data) + local ok, colors = ksb_api.get_kitty_colors(p.kitty_data) if ok then p.kitty_colors = colors end diff --git a/lua/kitty-scrollback/kitty_commands.lua b/lua/kitty-scrollback/kitty_commands.lua index dfeb5873..a17192a1 100644 --- a/lua/kitty-scrollback/kitty_commands.lua +++ b/lua/kitty-scrollback/kitty_commands.lua @@ -10,7 +10,7 @@ M.setup = function(private, options) opts = options ---@diagnostic disable-line: unused-local end -local system_handle_error = function(cmd, sys_opts) +local system_handle_error = function(cmd, sys_opts, ignore_error) local proc = vim.system(cmd, sys_opts or {}) local result = proc:wait() local ok = result.code == 0 @@ -27,6 +27,7 @@ local system_handle_error = function(cmd, sys_opts) local stdout = result.stdout or '' local stderr = result.stderr or '' local err = { + '*entrypoint:* |vim.system()|', '*command:* ' .. table.concat(cmd, ' '), '*pid:* ' .. proc.pid, '*code:* ' .. result.code, @@ -53,13 +54,18 @@ local system_handle_error = function(cmd, sys_opts) buf = error_bufid, }) local prompt_msg = 'kitty-scrollback.nvim: Fatal error, see logs.' - vim.api.nvim_set_current_buf(error_bufid) if stderr:match('.*allow_remote_control.*') then vim.list_extend(msg, ksb_health.advice().allow_remote_control) + ignore_error = false -- fatal error, always report this error end if stderr:match('.*/dev/tty.*') then vim.list_extend(msg, ksb_health.advice().listen_on) + ignore_error = false -- fatal error, always report this error + end + if ignore_error then + return ok, result end + vim.api.nvim_set_current_buf(error_bufid) vim.api.nvim_buf_set_lines(error_bufid, 0, -1, false, vim.list_extend(msg, err)) vim.cmd.redraw() local response = vim.fn.confirm(prompt_msg, '&Quit\n&Continue') @@ -96,16 +102,26 @@ M.send_paste_buffer_text_to_kitty_and_quit = function(bracketed_paste_mode) M.signal_term_to_kitty_child_process() end -M.close_kitty_loading_window = function() - if p.kitty_loading_winid then - system_handle_error({ +M.list_kitty_windows = function() + return system_handle_error({ + 'kitty', + '@', + 'ls', + }) +end + +M.close_kitty_loading_window = function(ignore_error) + if p and p.kitty_loading_winid then + local winid = p.kitty_loading_winid + p.kitty_loading_winid = nil + return system_handle_error({ 'kitty', '@', 'close-window', - '--match=id:' .. p.kitty_loading_winid, - }) + '--match=id:' .. winid, + }, {}, ignore_error) end - p.kitty_loading_winid = nil + return true end M.signal_winchanged_to_kitty_child_process = function() @@ -155,15 +171,16 @@ M.open_kitty_loading_window = function(env) end end -M.get_kitty_colors = function(kitty_data) +M.get_kitty_colors = function(kitty_data, ignore_error, no_window_id) + local match = no_window_id and nil or '--match=id:' .. kitty_data.window_id local ok, result = system_handle_error({ 'kitty', '@', 'get-colors', - '--match=id:' .. kitty_data.window_id, - }) + match, + }, { text = true }, ignore_error) if not ok then - return ok + return ok, result end local kitty_colors_str = result.stdout or '' local kitty_colors = {} diff --git a/lua/kitty-scrollback/launch.lua b/lua/kitty-scrollback/launch.lua index a8ed3925..b9c2c096 100644 --- a/lua/kitty-scrollback/launch.lua +++ b/lua/kitty-scrollback/launch.lua @@ -387,11 +387,8 @@ M.launch = function() end vim.schedule(function() local esc = vim.fn.eval([["\e"]]) - local kitty_get_text_cmd = string.format( - [[kitty @ get-text --match="id:%s" %s | ]], - kitty_data.window_id, - get_text_opts - ) + local kitty_get_text_cmd = + string.format([[kitty @ get-text --match="id:%s" %s]], kitty_data.window_id, get_text_opts) local sed_cmd = string.format( [[sed -E -e 's/$/%s[0m/g' ]] -- append all lines with reset to avoid unintended colors .. [[-e 's/%s\[\?25.%s\[.*;.*H%s\[.*//g']], -- remove control sequence added by --add-cursor flag @@ -400,8 +397,9 @@ M.launch = function() esc, esc ) - local flush_stdout_cmd = [[ && kitty +runpy 'sys.stdout.flush()']] - vim.fn.termopen(kitty_get_text_cmd .. sed_cmd .. flush_stdout_cmd, { + local flush_stdout_cmd = [[kitty +runpy 'sys.stdout.flush()']] + local full_cmd = kitty_get_text_cmd .. ' | ' .. sed_cmd .. ' && ' .. flush_stdout_cmd + vim.fn.termopen(full_cmd, { stdout_buffered = true, on_exit = function() ksb_kitty_cmds.signal_winchanged_to_kitty_child_process()