From 13550672d5f91cf0c8cb95aaae3313c21faefdf8 Mon Sep 17 00:00:00 2001 From: Jackie Li Date: Wed, 22 Nov 2023 13:08:26 +0000 Subject: [PATCH 01/11] vendor vim system --- lua/kitty-scrollback/_system.lua | 375 ++++++++++++++++++++++++ lua/kitty-scrollback/health.lua | 10 +- lua/kitty-scrollback/kitty_commands.lua | 2 +- lua/kitty-scrollback/util.lua | 8 + 4 files changed, 389 insertions(+), 6 deletions(-) create mode 100644 lua/kitty-scrollback/_system.lua diff --git a/lua/kitty-scrollback/_system.lua b/lua/kitty-scrollback/_system.lua new file mode 100644 index 00000000..5b82f213 --- /dev/null +++ b/lua/kitty-scrollback/_system.lua @@ -0,0 +1,375 @@ +-- https://github.com/neovim/neovim/blob/master/runtime/lua/vim/_system.lua +local uv = require('luv') + +--- @class SystemOpts +--- @field stdin? string|string[]|true +--- @field stdout? fun(err:string?, data: string?)|false +--- @field stderr? fun(err:string?, data: string?)|false +--- @field cwd? string +--- @field env? table +--- @field clear_env? boolean +--- @field text? boolean +--- @field timeout? integer Timeout in ms +--- @field detach? boolean + +--- @class vim.SystemCompleted +--- @field code integer +--- @field signal integer +--- @field stdout? string +--- @field stderr? string + +--- @class vim.SystemState +--- @field handle? uv.uv_process_t +--- @field timer? uv.uv_timer_t +--- @field pid? integer +--- @field timeout? integer +--- @field done? boolean|'timeout' +--- @field stdin? uv.uv_stream_t +--- @field stdout? uv.uv_stream_t +--- @field stderr? uv.uv_stream_t +--- @field stdout_data? string[] +--- @field stderr_data? string[] +--- @field result? vim.SystemCompleted + +--- @enum vim.SystemSig +local SIG = { + HUP = 1, -- Hangup + INT = 2, -- Interrupt from keyboard + KILL = 9, -- Kill signal + TERM = 15, -- Termination signal + -- STOP = 17,19,23 -- Stop the process +} + +---@param handle uv.uv_handle_t? +local function close_handle(handle) + if handle and not handle:is_closing() then + handle:close() + end +end + +---@param state vim.SystemState +local function close_handles(state) + close_handle(state.handle) + close_handle(state.stdin) + close_handle(state.stdout) + close_handle(state.stderr) + close_handle(state.timer) +end + +--- @class vim.SystemObj +--- @field pid integer +--- @field private _state vim.SystemState +--- @field wait fun(self: vim.SystemObj, timeout?: integer): vim.SystemCompleted +--- @field kill fun(self: vim.SystemObj, signal: integer|string) +--- @field write fun(self: vim.SystemObj, data?: string|string[]) +--- @field is_closing fun(self: vim.SystemObj): boolean? +local SystemObj = {} + +--- @param state vim.SystemState +--- @return vim.SystemObj +local function new_systemobj(state) + return setmetatable({ + pid = state.pid, + _state = state, + }, { __index = SystemObj }) +end + +--- @param signal integer|string +function SystemObj:kill(signal) + self._state.handle:kill(signal) +end + +--- @package +--- @param signal? vim.SystemSig +function SystemObj:_timeout(signal) + self._state.done = 'timeout' + self:kill(signal or SIG.TERM) +end + +local MAX_TIMEOUT = 2 ^ 31 + +--- @param timeout? integer +--- @return vim.SystemCompleted +function SystemObj:wait(timeout) + local state = self._state + + local done = vim.wait(timeout or state.timeout or MAX_TIMEOUT, function() + return state.result ~= nil + end) + + if not done then + -- Send sigkill since this cannot be caught + self:_timeout(SIG.KILL) + vim.wait(timeout or state.timeout or MAX_TIMEOUT, function() + return state.result ~= nil + end) + end + + return state.result +end + +--- @param data string[]|string|nil +function SystemObj:write(data) + local stdin = self._state.stdin + + if not stdin then + error('stdin has not been opened on this object') + end + + if type(data) == 'table' then + for _, v in ipairs(data) do + stdin:write(v) + stdin:write('\n') + end + elseif type(data) == 'string' then + stdin:write(data) + elseif data == nil then + -- Shutdown the write side of the duplex stream and then close the pipe. + -- Note shutdown will wait for all the pending write requests to complete + -- TODO(lewis6991): apparently shutdown doesn't behave this way. + -- (https://github.com/neovim/neovim/pull/17620#discussion_r820775616) + stdin:write('', function() + stdin:shutdown(function() + if stdin then + stdin:close() + end + end) + end) + end +end + +--- @return boolean +function SystemObj:is_closing() + local handle = self._state.handle + return handle == nil or handle:is_closing() +end + +---@param output fun(err:string?, data: string?)|false +---@return uv.uv_stream_t? +---@return fun(err:string?, data: string?)? Handler +local function setup_output(output) + if output == nil then + return assert(uv.new_pipe(false)), nil + end + + if type(output) == 'function' then + return assert(uv.new_pipe(false)), output + end + + assert(output == false) + return nil, nil +end + +---@param input string|string[]|true|nil +---@return uv.uv_stream_t? +---@return string|string[]? +local function setup_input(input) + if not input then + return + end + + local towrite --- @type string|string[]? + if type(input) == 'string' or type(input) == 'table' then + towrite = input + end + + return assert(uv.new_pipe(false)), towrite +end + +--- @return table +local function base_env() + local env = vim.fn.environ() --- @type table + env['NVIM'] = vim.v.servername + env['NVIM_LISTEN_ADDRESS'] = nil + return env +end + +--- uv.spawn will completely overwrite the environment +--- when we just want to modify the existing one, so +--- make sure to prepopulate it with the current env. +--- @param env? table +--- @param clear_env? boolean +--- @return string[]? +local function setup_env(env, clear_env) + if clear_env then + return env + end + + --- @type table + env = vim.tbl_extend('force', base_env(), env or {}) + + local renv = {} --- @type string[] + for k, v in pairs(env) do + renv[#renv + 1] = string.format('%s=%s', k, tostring(v)) + end + + return renv +end + +--- @param stream uv.uv_stream_t +--- @param text? boolean +--- @param bucket string[] +--- @return fun(err: string?, data: string?) +local function default_handler(stream, text, bucket) + return function(err, data) + if err then + error(err) + end + if data ~= nil then + if text then + bucket[#bucket + 1] = data:gsub('\r\n', '\n') + else + bucket[#bucket + 1] = data + end + else + stream:read_stop() + stream:close() + end + end +end + +local M = {} + +--- @param cmd string +--- @param opts uv.spawn.options +--- @param on_exit fun(code: integer, signal: integer) +--- @param on_error fun() +--- @return uv.uv_process_t, integer +local function spawn(cmd, opts, on_exit, on_error) + local handle, pid_or_err = uv.spawn(cmd, opts, on_exit) + if not handle then + on_error() + error(pid_or_err) + end + return handle, pid_or_err --[[@as integer]] +end + +---@param timeout integer +---@param cb fun() +---@return uv.uv_timer_t +local function timer_oneshot(timeout, cb) + local timer = assert(uv.new_timer()) + timer:start(timeout, 0, function() + timer:stop() + timer:close() + cb() + end) + return timer +end + +--- @param state vim.SystemState +--- @param code integer +--- @param signal integer +--- @param on_exit fun(result: vim.SystemCompleted)? +local function _on_exit(state, code, signal, on_exit) + close_handles(state) + + local check = assert(uv.new_check()) + check:start(function() + for _, pipe in pairs({ state.stdin, state.stdout, state.stderr }) do + if not pipe:is_closing() then + return + end + end + check:stop() + check:close() + + if state.done == nil then + state.done = true + end + + if (code == 0 or code == 1) and state.done == 'timeout' then + -- Unix: code == 0 + -- Windows: code == 1 + code = 124 + end + + local stdout_data = state.stdout_data + local stderr_data = state.stderr_data + + state.result = { + code = code, + signal = signal, + stdout = stdout_data and table.concat(stdout_data) or nil, + stderr = stderr_data and table.concat(stderr_data) or nil, + } + + if on_exit then + on_exit(state.result) + end + end) +end + +--- Run a system command +--- +--- @param cmd string[] +--- @param opts? SystemOpts +--- @param on_exit? fun(out: vim.SystemCompleted) +--- @return vim.SystemObj +function M.run(cmd, opts, on_exit) + vim.validate({ + cmd = { cmd, 'table' }, + opts = { opts, 'table', true }, + on_exit = { on_exit, 'function', true }, + }) + + opts = opts or {} + + local stdout, stdout_handler = setup_output(opts.stdout) + local stderr, stderr_handler = setup_output(opts.stderr) + local stdin, towrite = setup_input(opts.stdin) + + --- @type vim.SystemState + local state = { + done = false, + cmd = cmd, + timeout = opts.timeout, + stdin = stdin, + stdout = stdout, + stderr = stderr, + } + + --- @diagnostic disable-next-line:missing-fields + state.handle, state.pid = spawn(cmd[1], { + args = vim.list_slice(cmd, 2), + stdio = { stdin, stdout, stderr }, + cwd = opts.cwd, + --- @diagnostic disable-next-line:assign-type-mismatch + env = setup_env(opts.env, opts.clear_env), + detached = opts.detach, + hide = true, + }, function(code, signal) + _on_exit(state, code, signal, on_exit) + end, function() + close_handles(state) + end) + + if stdout then + state.stdout_data = {} + stdout:read_start(stdout_handler or default_handler(stdout, opts.text, state.stdout_data)) + end + + if stderr then + state.stderr_data = {} + stderr:read_start(stderr_handler or default_handler(stderr, opts.text, state.stderr_data)) + end + + local obj = new_systemobj(state) + + if towrite then + obj:write(towrite) + obj:write(nil) -- close the stream + end + + if opts.timeout then + state.timer = timer_oneshot(opts.timeout, function() + if state.handle and state.handle:is_active() then + obj:_timeout() + end + end) + end + + return obj +end + +return M diff --git a/lua/kitty-scrollback/health.lua b/lua/kitty-scrollback/health.lua index 18a83b25..cc5c796b 100644 --- a/lua/kitty-scrollback/health.lua +++ b/lua/kitty-scrollback/health.lua @@ -21,7 +21,7 @@ local function check_kitty_remote_control() 'ls', } local sys_opts = {} - local proc = vim.system(cmd, sys_opts or {}) + local proc = ksb_util.vim_system(cmd, sys_opts or {}) local result = proc:wait() local ok = result.code == 0 local code_msg = '`kitty @ ls` exited with code *' .. result.code .. '*' @@ -131,7 +131,7 @@ local function check_sed() '-e', 's/' .. esc .. '\\[\\?25.' .. esc .. '\\[.*;.*H' .. esc .. '\\[.*//g', } - local ok, sed_proc = pcall(vim.system, cmd, { + local ok, sed_proc = pcall(ksb_util.vim_system, cmd, { stdin = 'expected' .. esc .. '[?25h' .. esc .. '[1;1H' .. esc .. '[notexpected', }) local result = {} @@ -225,7 +225,7 @@ local function check_kitty_debug_config() vim.api.nvim_get_runtime_file('python/kitty_debug_config.py', false)[1] local debug_config_log = vim.fn.stdpath('data') .. '/kitty-scrollback.nvim/debug_config.log' local result = - vim.system({ 'kitty', '@', 'kitten', kitty_debug_config_kitten, debug_config_log }):wait() + ksb_util.vim_system({ 'kitty', '@', 'kitten', kitty_debug_config_kitten, debug_config_log }):wait() if result.code == 0 then if vim.fn.filereadable(debug_config_log) then vim.health.ok(table.concat(vim.fn.readfile(debug_config_log), '\n ')) @@ -243,12 +243,12 @@ local function check_kitty_scrollback_nvim_version() local tag_cmd = { 'git', 'describe', '--exact-match', '--tags' } local ksb_dir = vim.fn.fnamemodify(vim.api.nvim_get_runtime_file('lua/kitty-scrollback', false)[1], ':h:h') - local tag_cmd_result = vim.system(tag_cmd, { cwd = ksb_dir }):wait() + local tag_cmd_result = ksb_util.vim_system(tag_cmd, { cwd = ksb_dir }):wait() if tag_cmd_result.code == 0 then current_version = tag_cmd_result.stdout else local commit_cmd = { 'git', 'rev-parse', '--short', 'HEAD' } - local commit_cmd_result = vim.system(commit_cmd, { cwd = ksb_dir }):wait() + local commit_cmd_result = ksb_util.vim_system(commit_cmd, { cwd = ksb_dir }):wait() if commit_cmd_result.code == 0 then current_version = commit_cmd_result.stdout end diff --git a/lua/kitty-scrollback/kitty_commands.lua b/lua/kitty-scrollback/kitty_commands.lua index f9245b39..a9fd1b39 100644 --- a/lua/kitty-scrollback/kitty_commands.lua +++ b/lua/kitty-scrollback/kitty_commands.lua @@ -99,7 +99,7 @@ local display_error = function(cmd, r) end local system_handle_error = function(cmd, sys_opts, ignore_error) - local proc = vim.system(cmd, sys_opts or {}) + local proc = ksb_util.vim_system(cmd, sys_opts or {}) local result = proc:wait() local ok = result.code == 0 diff --git a/lua/kitty-scrollback/util.lua b/lua/kitty-scrollback/util.lua index 62882e43..cf40d668 100644 --- a/lua/kitty-scrollback/util.lua +++ b/lua/kitty-scrollback/util.lua @@ -96,4 +96,12 @@ M.restore_and_redraw = function() vim.cmd.redraw() end +M.vim_system = function(cmd, opts, on_exit) + if vim['system'] ~= nil then + return vim.system(cmd, opts, on_exit) + end + local sys = require('kitty-scrollback._system') + return sys.run(cmd, opts, on_exit) +end + return M From 09636f4251f792c5172490b50ad5dc4ab854850c Mon Sep 17 00:00:00 2001 From: Mike Smith <10135646+mikesmithgh@users.noreply.github.com> Date: Wed, 22 Nov 2023 08:36:00 -0500 Subject: [PATCH 02/11] chore: formatting --- lua/kitty-scrollback/health.lua | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lua/kitty-scrollback/health.lua b/lua/kitty-scrollback/health.lua index cc5c796b..63a2423e 100644 --- a/lua/kitty-scrollback/health.lua +++ b/lua/kitty-scrollback/health.lua @@ -224,8 +224,9 @@ local function check_kitty_debug_config() local kitty_debug_config_kitten = vim.api.nvim_get_runtime_file('python/kitty_debug_config.py', false)[1] local debug_config_log = vim.fn.stdpath('data') .. '/kitty-scrollback.nvim/debug_config.log' - local result = - ksb_util.vim_system({ 'kitty', '@', 'kitten', kitty_debug_config_kitten, debug_config_log }):wait() + local result = ksb_util + .vim_system({ 'kitty', '@', 'kitten', kitty_debug_config_kitten, debug_config_log }) + :wait() if result.code == 0 then if vim.fn.filereadable(debug_config_log) then vim.health.ok(table.concat(vim.fn.readfile(debug_config_log), '\n ')) From 09237df50145ec85a31bbaaca48fe5cf495050b6 Mon Sep 17 00:00:00 2001 From: Mike Smith <10135646+mikesmithgh@users.noreply.github.com> Date: Wed, 22 Nov 2023 22:08:58 -0500 Subject: [PATCH 03/11] work in progress --- .github/workflows/vimdocs.yml | 2 +- README.md | 4 +- lua/kitty-scrollback/api.lua | 2 +- lua/kitty-scrollback/health.lua | 90 ++++---- lua/kitty-scrollback/kitty_commands.lua | 2 +- lua/kitty-scrollback/launch.lua | 19 +- lua/kitty-scrollback/util.lua | 15 +- lua/kitty-scrollback/vendor/.luarc.json | 5 + lua/kitty-scrollback/vendor/README.md | 3 + lua/kitty-scrollback/{ => vendor}/_system.lua | 4 +- lua/kitty-scrollback/windows.lua | 4 +- python/kitty_scrollback_bobnvim.py | 194 ++++++++++++++++++ scripts/dev_generate_vimdocs.sh | 2 +- 13 files changed, 284 insertions(+), 62 deletions(-) create mode 100644 lua/kitty-scrollback/vendor/.luarc.json create mode 100644 lua/kitty-scrollback/vendor/README.md rename lua/kitty-scrollback/{ => vendor}/_system.lua (98%) create mode 100755 python/kitty_scrollback_bobnvim.py diff --git a/.github/workflows/vimdocs.yml b/.github/workflows/vimdocs.yml index 0d5b877b..396db95e 100644 --- a/.github/workflows/vimdocs.yml +++ b/.github/workflows/vimdocs.yml @@ -35,7 +35,7 @@ jobs: with: vimdoc: kitty-scrollback.nvim pandoc: "tmp_vimdoc_workdir/README.md" - version: "NVIM v0.10+" + version: "NVIM v0.9+" toc: true demojify: true dedupsubheadings: false diff --git a/README.md b/README.md index af8feaec..6e989ba7 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Navigate your Kitty scrollback buffer to quickly search, copy, and execute comma -[![neovim: v0.10+](https://img.shields.io/static/v1?style=flat-square&label=neovim&message=v0.10%2b&logo=neovim&labelColor=282828&logoColor=8faa80&color=414b32)](https://neovim.io/) +[![neovim: v0.9+](https://img.shields.io/static/v1?style=flat-square&label=neovim&message=v0.9%2b&logo=neovim&labelColor=282828&logoColor=8faa80&color=414b32)](https://neovim.io/) [![kitty v0.29+](https://img.shields.io/badge/v0.29%2B-352217?style=flat-square&logo=data%3Aimage%2Fjpeg%3Bbase64%2C%2F9j%2F4AAQSkZJRgABAQAAAQABAAD%2F4gHYSUNDX1BST0ZJTEUAAQEAAAHIAAAAAAQwAABtbnRyUkdCIFhZWiAH4AABAAEAAAAAAABhY3NwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA9tYAAQAAAADTLQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlkZXNjAAAA8AAAACRyWFlaAAABFAAAABRnWFlaAAABKAAAABRiWFlaAAABPAAAABR3dHB0AAABUAAAABRyVFJDAAABZAAAAChnVFJDAAABZAAAAChiVFJDAAABZAAAAChjcHJ0AAABjAAAADxtbHVjAAAAAAAAAAEAAAAMZW5VUwAAAAgAAAAcAHMAUgBHAEJYWVogAAAAAAAAb6IAADj1AAADkFhZWiAAAAAAAABimQAAt4UAABjaWFlaIAAAAAAAACSgAAAPhAAAts9YWVogAAAAAAAA9tYAAQAAAADTLXBhcmEAAAAAAAQAAAACZmYAAPKnAAANWQAAE9AAAApbAAAAAAAAAABtbHVjAAAAAAAAAAEAAAAMZW5VUwAAACAAAAAcAEcAbwBvAGcAbABlACAASQBuAGMALgAgADIAMAAxADb%2F2wBDACodICUgGiolIiUvLSoyP2lEPzo6P4FcYUxpmYagnpaGk5GovfLNqLPltZGT0v%2FV5fr%2F%2F%2F%2F%2Fo8v%2F%2F%2F%2F%2F%2F%2FL%2F%2F%2F%2F%2F2wBDAS0vLz83P3xERHz%2FrpOu%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwAARCAEAAQADASIAAhEBAxEB%2F8QAGgABAAMBAQEAAAAAAAAAAAAAAAECAwQFBv%2FEAC8QAQACAQIEAgkFAQEAAAAAAAABAgMEERIhMVFBYQUTFCIyUnGRoUJTgZLB4SP%2FxAAXAQEBAQEAAAAAAAAAAAAAAAAAAQID%2F8QAGxEBAQEBAQEBAQAAAAAAAAAAAAERAhIhMUH%2F2gAMAwEAAhEDEQA%2FAPHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHXix1ikTtG8rzWs9ax9mfTXlwjrtgpPht9GVtPaPhnddieaxCYmJ2mNhUAiJmdojdpXBefCI%2BppjMbxpu9vwt7NXvKbF81zDp9mr3lWdN2t%2BDYeawGlsF48In6M5iYnnEwupgBETM7RG4A2rp7T8U7NK4KR4b%2FVNi%2Ba5R2xSsdKx9lcuOs0mdoiYhPS%2BXIA0yAAAAAAAAAA7MU746z5LsNNb3Zr2bud%2FXSfgAiotWLRtaN2UaesTvO8x2bC6YiIiI2iNkggAAAAImImNpjdIDGdPWZ3jeI7Na1isbVjZIumACAplnbHafJdhqbbVivdZ%2BpfxzgOjmAAAAAABtunhnsCBPDPZALY7cF4n7u1wOnT5N68M9Y6M9RrmtgGGwAATFLW%2BGsz9IJiYnaYmPqCAAAAAiJmdoiZnyWml6xvNbR9YBUAAABx5b8eSZ8PBvnvw02jrLlb5jHV%2FgCeGezTKBPDPZG2wAAAJisgg3nutwx3TwwmrisWlaJiUcMI4T4fUzWCsTF4267o3mq1bc%2FMHYKY78Uea7DoPQ02krWItkje3afBzaOkX1Fd%2Bkc3qNcxnqit6VvG16xMeaMlprtELVneIknUtxh5uq03qZ4q86T%2BHO9jNSMmK1Z8YeOlmOnN0b6XTzmtvblSOvmwevgpFMNKx25kmnVxalK442pWIjyWRadqzKuO02336r6kuObDU6St4m2ONrdo6S87o9t5mtpFNRO36o3Oo3zXOCmTJFeUdWWnNliZy23RFY8VrW57zzlTebNua0zEKzaThTwwfD6rvPcX4YRwx3NMVEzWUKgAALRXunesdk1cU3nunilbihpSsTG8gzj3vCUxXhtE7dJbgqs0%2FXjlpS3FXdTaazvX7d167Tzjlv1ZrUdWhtFdRG%2FjGz03iRMxMTHKYepp9RXNXaZ2v4wvNZ6i2X4o%2Bi%2BP4ILVi3VPKI7RDM5s6tZRktFMdrT4Ru8Z16zUxf8A86TvXxnu5F6rfMHsYrRfFW0eMPHdWj1MY%2FcvPuz0nsc06mu7J8CuLrLTlaO8SitYrHJLzb3Kws83X2i2o2j9MbOzUaiuGve3hDy7TNrTaZ3mectdVrmKZL8Fd%2FsypT9eWf4a2iN4tPPbpCm02ne327JGqyvXjvNoidlZ93wl0DWMuXilG89296REbwz4oEUF96yiax4GmKgKgAAtjpxz5Kt8HwT9QXisVjlCQRQAAAF6zunp0YZbzSu8TtLL12T5vwnlr09GuqzVjaMk%2FwA81b5smT47zMdnB67J834PXZPm%2FBlNjsb10ma0b8G31l5sZ8kTvFua%2Ftup%2Fev9zyXp3zpM0fo3%2BksJiYnaY2mHP7bqf3r%2FAHUnPlmZmbzMz4nlJ07qZsmP4LzEdl51Wa0bTkn%2BOTzfXZPm%2FB67J834Mq%2Bo7JmZneecomdnJ67J834a4rzeJ4p3lPJ6XmdwGkABBW1K26wsA5r0mk%2BSrfP8H8sFQAAAAXx34J59JUAdUTExyndLkImYneBddYyrm5e9H2JzRtyj7g0m0R1mIVnLWPHdzzMzO89QNTe03neUAIAAAAAAAAJpaazvCAHRXLWevJaLRPSYlykTMTvAuusZVzRt70fYtm5e7H3BqiZiOs7OWZmZ3nqBq%2BS%2FHPLpCgCAAAAAAAAAAAALY8d8s7Y6WtPlCLVtS01tExMdYl6vobJj4L4%2BUZN9%2FrDp12jrqqbxtGSOk%2F5IPAFslLY7zS8TFo6xKoAAAAAAAAAAAAAAAAAAAAAAAAAAAAJpa1LRaszFo6TD3dBra6mvDfaMsdY7vBTW1qWi1ZmLR0mAe9rtHXVU3jaMkdJ%2FyXhZKWx3ml4mLR1h7eg1tdTXhvtGWOsd1tdo66qm8bRkjpP%2BSDwBOSlsd5peJi0dYQAAAAAAAAAAAAAAAAAAAAAAAAAAAACa2tS0WrMxaOkw93QayNVThtyyVjn5%2BbxcGG%2BoyxTHG8z%2BHv6XTU02Phrzmetu4M9fo66jHNo5ZKxynv5PAex6S10Y4nDine88rT2eOAAAAAAAAAAAAAAAAAAAAAAAAAAA0wYb6jLFMcbzP4MGG%2BoyxTHG8z%2BHv6XTU02Lhpzmetu4Gl01NNj4a85nrbu5fSOv9VE4sM%2B%2F4z8v%2FT0jr%2FVb4sM%2B%2FwCNvl%2F68br1A6zzAAF64ct43pjvaO8VmU%2BzZ%2F2cn9ZBmNfZs%2F7OT%2Bsns2f9nJ%2FWQZDT2bP%2Bzk%2FrKLYctI3vjvWO81mAUAAAAAAAAAAAAAAAAAAAB6vobJirjvWZiMkzvz8YX9IekIxxOLBaJvPW0eDxwDr1AAI68%2BgA%2BmwXx2xVnFMTXblsu%2BWAfVIfLAPqVM18dMVpyzEV257vmQCevIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH%2F9k%3D&label=kitty&labelColor=282828)](https://sw.kovidgoyal.net/kitty/) [![semantic-release: angular](https://img.shields.io/static/v1?style=flat-square&label=semantic-release&message=angular&logo=semantic-release&labelColor=282828&logoColor=d8869b&color=8f3f71)](https://github.com/semantic-release/semantic-release) @@ -187,7 +187,7 @@ Navigate your Kitty scrollback buffer to quickly search, copy, and execute comma ## 📚 Prerequisites -- Neovim [v0.10+](https://github.com/neovim/neovim/releases) +- Neovim [v0.9+](https://github.com/neovim/neovim/releases) - Kitty [v0.29+](https://github.com/kovidgoyal/kitty/releases) ## 🏃 Quickstart diff --git a/lua/kitty-scrollback/api.lua b/lua/kitty-scrollback/api.lua index 76e7e95c..3b596a1f 100644 --- a/lua/kitty-scrollback/api.lua +++ b/lua/kitty-scrollback/api.lua @@ -183,7 +183,7 @@ end M.checkhealth = function() local kitty_scrollback_kitten = vim.api.nvim_get_runtime_file('python/kitty_scrollback_nvim.py', false)[1] - if vim.fn.has('nvim-0.10') > 0 then + if vim.fn.has('nvim-0.9') > 0 then vim .system({ 'kitty', diff --git a/lua/kitty-scrollback/health.lua b/lua/kitty-scrollback/health.lua index 63a2423e..d6505cde 100644 --- a/lua/kitty-scrollback/health.lua +++ b/lua/kitty-scrollback/health.lua @@ -13,20 +13,25 @@ M.setup = function(private, options) opts = options ---@diagnostic disable-line: unused-local end +local start_health = vim.health.start or vim.health.report_start +local ok_health = vim.health.ok or vim.health.report_ok +local warn_health = vim.health.warn or vim.health.report_warn +local error_health = vim.health.error or vim.health.report_error + local function check_kitty_remote_control() - vim.health.start('kitty-scrollback: Kitty remote control') + start_health('kitty-scrollback: Kitty remote control') local cmd = { 'kitty', '@', 'ls', } local sys_opts = {} - local proc = ksb_util.vim_system(cmd, sys_opts or {}) + local proc = vim.system(cmd, sys_opts or {}) local result = proc:wait() local ok = result.code == 0 local code_msg = '`kitty @ ls` exited with code *' .. result.code .. '*' if ok then - vim.health.ok(code_msg) + ok_health(code_msg) return true else local stderr = result.stderr:gsub('\n', '') or '' @@ -54,15 +59,15 @@ local function check_kitty_remote_control() else table.insert(advice, 'ERROR Failed to read `allow_remote_control` and `listen_on`') end - vim.health.error(code_msg .. '\n `' .. stderr .. '` ', advice) + error_health(code_msg .. '\n `' .. stderr .. '` ', advice) end return false end local function check_has_kitty_data() - vim.health.start('kitty-scrollback: Kitty data') + start_health('kitty-scrollback: Kitty data') if type(p) == 'table' and next(p.kitty_data) then - vim.health.ok('Kitty data available\n>lua\n' .. vim.inspect(p.kitty_data) .. '\n') + ok_health('Kitty data available\n>lua\n' .. vim.inspect(p.kitty_data) .. '\n') return true else local kitty_scrollback_kitten = @@ -70,7 +75,7 @@ local function check_has_kitty_data() local checkhealth_command = '`kitty @ kitten ' .. kitty_scrollback_kitten .. ' --config ksb_builtin_checkhealth`' - vim.health.warn('No Kitty data available unable to perform a complete healthcheck', { + warn_health('No Kitty data available unable to perform a complete healthcheck', { 'Add the config options `checkhealth = true` to your *config* or execute the command `:KittyScrollbackCheckHealth` ' .. 'to run `checkhealth` within the context of a Kitten', checkhealth_command, @@ -83,12 +88,12 @@ local function check_clipboard() local function is_blank(s) return s:find('^%s*$') ~= nil end - vim.health.start('kitty-scrollback: clipboard') + start_health('kitty-scrollback: clipboard') local clipboard_tool = vim.fn['provider#clipboard#Executable']() -- copied from health.lua if vim.fn.has('clipboard') > 0 and not is_blank(clipboard_tool) then - vim.health.ok('Clipboard tool found: *' .. clipboard_tool .. '*') + ok_health('Clipboard tool found: *' .. clipboard_tool .. '*') else - vim.health.warn( + warn_health( 'Neovim does not have a clipboard provider.\n Some functionality will not work when there is no clipboard ' .. 'provider, such as copying Kitty scrollback buffer text to the system clipboard.', 'See `:help` |provider-clipboard| for more information on enabling system clipboard integration.' @@ -97,16 +102,16 @@ local function check_clipboard() end local function check_kitty_shell_integration() - vim.health.start('kitty-scrollback: Kitty shell integration') + start_health('kitty-scrollback: Kitty shell integration') if not next(p or {}) then - vim.health.error('No Kitty data') + error_health('No Kitty data') return end -- use last_cmd_output because it is valid and requires shell integration if M.is_valid_extent_keyword('last_cmd_output') then - vim.health.ok('Kitty shell integration is enabled') + ok_health('Kitty shell integration is enabled') else - vim.health.warn( + warn_health( 'Kitty shell integration is disabled and/or `no-prompt-mark` is set.\n Some functionality will not work when Kitty shell ' .. 'integration is disabled or `no-prompt-mark` is set, such as capturing the last command output.', table.concat(M.advice().kitty_shell_integration, '\n') @@ -115,10 +120,10 @@ local function check_kitty_shell_integration() end local function check_sed() - vim.health.start('kitty-scrollback: sed') + start_health('kitty-scrollback: sed') local sed_path = vim.fn.exepath('sed') if not sed_path or sed_path == '' then - vim.health.error('*sed* : command not found\n') + error_health('*sed* : command not found\n') return end @@ -131,7 +136,7 @@ local function check_sed() '-e', 's/' .. esc .. '\\[\\?25.' .. esc .. '\\[.*;.*H' .. esc .. '\\[.*//g', } - local ok, sed_proc = pcall(ksb_util.vim_system, cmd, { + local ok, sed_proc = pcall(vim.system, cmd, { stdin = 'expected' .. esc .. '[?25h' .. esc .. '[1;1H' .. esc .. '[notexpected', }) local result = {} @@ -144,7 +149,7 @@ local function check_sed() end ok = ok and result.code == 0 and result.stdout == 'expected' if ok then - vim.health.ok( + ok_health( '`' .. table.concat(cmd, ' ') .. '` exited with code *' @@ -161,7 +166,7 @@ local function check_sed() if result_err ~= '' then result_err = ' `' .. result_err .. '`' end - vim.health.error( + error_health( '`' .. table.concat(cmd, ' ') .. '` exited with code *' @@ -178,23 +183,21 @@ local function check_sed() end end -M.check_nvim_version = function(check_only) +M.check_nvim_version = function(version, check_only) + -- TODO: check min nvim version now -- fallback to older health report calls if using < 0.10 - local start_fn = vim.health.start or vim.health.report_start - local ok_fn = vim.health.ok or vim.health.report_ok - local error_fn = vim.health.error or vim.health.report_error if not check_only then - start_fn('kitty-scrollback: Neovim version 0.10+') + start_health('kitty-scrollback: Neovim version 0.9+') end local nvim_version = 'NVIM ' .. ksb_util.nvim_version_tostring() - if vim.fn.has('nvim-0.10') > 0 then + if vim.fn.has(version) > 0 then if not check_only then - ok_fn(nvim_version) + ok_health(nvim_version) end return true else if not check_only then - error_fn(nvim_version, M.advice().nvim_version) + error_health(nvim_version, M.advice().nvim_version) end end return false @@ -202,40 +205,39 @@ end M.check_kitty_version = function(check_only) if not check_only then - vim.health.start('kitty-scrollback: Kitty version 0.29+') + start_health('kitty-scrollback: Kitty version 0.29+') end local kitty_version = p.kitty_data.kitty_version local kitty_version_str = 'kitty ' .. table.concat(kitty_version, '.') if vim.version.cmp(kitty_version, { 0, 29, 0 }) >= 0 then if not check_only then - vim.health.ok(kitty_version_str) + ok_health(kitty_version_str) end return true else if not check_only then - vim.health.error(kitty_version_str, M.advice().kitty_version) + error_health(kitty_version_str, M.advice().kitty_version) end end return false end local function check_kitty_debug_config() - vim.health.start('kitty-scrollback: Kitty debug config') + start_health('kitty-scrollback: Kitty debug config') local kitty_debug_config_kitten = vim.api.nvim_get_runtime_file('python/kitty_debug_config.py', false)[1] local debug_config_log = vim.fn.stdpath('data') .. '/kitty-scrollback.nvim/debug_config.log' - local result = ksb_util - .vim_system({ 'kitty', '@', 'kitten', kitty_debug_config_kitten, debug_config_log }) - :wait() + local result = + vim.system({ 'kitty', '@', 'kitten', kitty_debug_config_kitten, debug_config_log }):wait() if result.code == 0 then if vim.fn.filereadable(debug_config_log) then - vim.health.ok(table.concat(vim.fn.readfile(debug_config_log), '\n ')) + ok_health(table.concat(vim.fn.readfile(debug_config_log), '\n ')) else - vim.health.error('cannot read ' .. debug_config_log) + error_health('cannot read ' .. debug_config_log) end else local stderr = result.stderr:gsub('\n', '') or '' - vim.health.error(stderr) + error_health(stderr) end end @@ -244,12 +246,12 @@ local function check_kitty_scrollback_nvim_version() local tag_cmd = { 'git', 'describe', '--exact-match', '--tags' } local ksb_dir = vim.fn.fnamemodify(vim.api.nvim_get_runtime_file('lua/kitty-scrollback', false)[1], ':h:h') - local tag_cmd_result = ksb_util.vim_system(tag_cmd, { cwd = ksb_dir }):wait() + local tag_cmd_result = vim.system(tag_cmd, { cwd = ksb_dir }):wait() if tag_cmd_result.code == 0 then current_version = tag_cmd_result.stdout else local commit_cmd = { 'git', 'rev-parse', '--short', 'HEAD' } - local commit_cmd_result = ksb_util.vim_system(commit_cmd, { cwd = ksb_dir }):wait() + local commit_cmd_result = vim.system(commit_cmd, { cwd = ksb_dir }):wait() if commit_cmd_result.code == 0 then current_version = commit_cmd_result.stdout end @@ -260,11 +262,11 @@ local function check_kitty_scrollback_nvim_version() version_found and '`' .. current_version:gsub('%s$', '`\n') ---@diagnostic disable-line: need-check-nil or 'ERROR failed to determine version\n' ) - local health_fn = not version_found and vim.health.warn + local health_fn = not version_found and warn_health or function(msg) - vim.health.ok(' ' .. msg) + ok_health(' ' .. msg) end - vim.health.start('kitty-scrollback: kitty-scrollback.nvim version') + start_health('kitty-scrollback: kitty-scrollback.nvim version') health_fn([[ `|`\___/`|` ]] .. header .. [[ =) `^`Y`^` (= \ *^* / If you have any issues or questions using *kitty-scrollback.nvim* then @@ -282,7 +284,7 @@ end M.check = function() if - M.check_nvim_version() -- always check first to avoid undefined calls in versions < 0.10 + M.check_nvim_version('nvim-0.9') -- always check first to avoid undefined calls in versions < 0.10 and check_kitty_scrollback_nvim_version() and check_kitty_remote_control() and check_has_kitty_data() @@ -319,7 +321,7 @@ M.advice = function() end return { nvim_version = { - 'Neovim version 0.10 or greater is required to work with kitty-scrollback.nvim', + 'Neovim version 0.9 or greater is required to work with kitty-scrollback.nvim', }, kitty_version = { 'Kitty version 0.29 or greater is required to work with kitty-scrollback.nvim', diff --git a/lua/kitty-scrollback/kitty_commands.lua b/lua/kitty-scrollback/kitty_commands.lua index 2ed1af94..46f870ff 100644 --- a/lua/kitty-scrollback/kitty_commands.lua +++ b/lua/kitty-scrollback/kitty_commands.lua @@ -99,7 +99,7 @@ local display_error = function(cmd, r) end local system_handle_error = function(cmd, sys_opts, ignore_error) - local proc = ksb_util.vim_system(cmd, sys_opts or {}) + local proc = vim.system(cmd, sys_opts or {}) local result = proc:wait() local ok = result.code == 0 diff --git a/lua/kitty-scrollback/launch.lua b/lua/kitty-scrollback/launch.lua index ffc27c60..d0115e02 100644 --- a/lua/kitty-scrollback/launch.lua +++ b/lua/kitty-scrollback/launch.lua @@ -273,7 +273,7 @@ M.setup = function(kitty_data_str) vim.cmd.checkhealth('kitty-scrollback') return end - if not ksb_health.check_nvim_version(true) then + if not ksb_health.check_nvim_version('nvim-0.9', true) then local prompt_msg = 'kitty-scrollback.nvim: Fatal error, on version NVIM ' .. ksb_util.nvim_version_tostring() .. '. ' @@ -283,6 +283,15 @@ M.setup = function(kitty_data_str) ksb_kitty_cmds.signal_term_to_kitty_child_process(true) end end + if not ksb_health.check_nvim_version('nvim-0.10', true) then + -- assume nvim-0.9 and vendor required nvim-0.10 dependencies + if not vim.uv then + vim.uv = vim.loop + end + if not vim.system then + vim.system = ksb_util.vendored_vim_system + end + end if not ksb_health.check_kitty_version(true) then local prompt_msg = 'kitty-scrollback.nvim: Fatal error, on version kitty ' .. table.concat(p.kitty_data.kitty_version, '.') @@ -386,8 +395,6 @@ M.launch = function() -- increase the number of columns temporary so that the width is used during the -- terminal command kitty @ get-text. this avoids hard wrapping lines to the -- current window size. Note: a larger min_cols appears to impact performance - -- do not worry about setting vim.o.columns back to original value that is taken - -- care of when we trigger kitty to send a SIGWINCH to the nvim process local min_cols = 300 p.orig_columns = vim.o.columns if vim.o.columns < min_cols then @@ -395,6 +402,12 @@ M.launch = function() end vim.schedule(function() ksb_kitty_cmds.get_text_term(kitty_data, get_text_opts, function() + -- NOTE(#58): nvim v0.9 support + -- vim.o.columns is resized automatically in nvim v0.9.1 when we trigger kitty so send a SIGWINCH signal + -- vim.o.columns is explicitly set to resize appropriatley on v0.9.0 + -- see https://github.com/neovim/neovim/pull/23503 + vim.o.columns = p.orig_columns + ksb_kitty_cmds.signal_winchanged_to_kitty_child_process() if opts.kitty_get_text.extent == 'screen' or opts.kitty_get_text.extent == 'all' then set_cursor_position(kitty_data) diff --git a/lua/kitty-scrollback/util.lua b/lua/kitty-scrollback/util.lua index cf40d668..154e3ce7 100644 --- a/lua/kitty-scrollback/util.lua +++ b/lua/kitty-scrollback/util.lua @@ -81,8 +81,10 @@ M.nvim_version_tostring = function() local nvim_ver = vim.version() local ret = table.concat({ nvim_ver.major, nvim_ver.minor, nvim_ver.patch }, '.') if nvim_ver.prerelease then - ret = ret .. '-' .. nvim_ver.prerelease + local prerelease = type(nvim_ver.prerelease) == 'boolean' and 'dev' or nvim_ver.prerelease + ret = ret .. '-' .. prerelease end + vim.print(nvim_ver) if nvim_ver.build and nvim_ver.build ~= vim.NIL then ret = ret .. '+' .. nvim_ver.build end @@ -96,12 +98,13 @@ M.restore_and_redraw = function() vim.cmd.redraw() end -M.vim_system = function(cmd, opts, on_exit) - if vim['system'] ~= nil then - return vim.system(cmd, opts, on_exit) +-- copied from _editor.lua +M.vendored_vim_system = function(cmd, o, on_exit) + if type(o) == 'function' then + on_exit = o + o = nil end - local sys = require('kitty-scrollback._system') - return sys.run(cmd, opts, on_exit) + return require('kitty-scrollback.vendor._system').run(cmd, o, on_exit) end return M diff --git a/lua/kitty-scrollback/vendor/.luarc.json b/lua/kitty-scrollback/vendor/.luarc.json new file mode 100644 index 00000000..5ff34848 --- /dev/null +++ b/lua/kitty-scrollback/vendor/.luarc.json @@ -0,0 +1,5 @@ +{ + "diagnostics": { + "enable": false, + } +} diff --git a/lua/kitty-scrollback/vendor/README.md b/lua/kitty-scrollback/vendor/README.md new file mode 100644 index 00000000..fc2a6c7f --- /dev/null +++ b/lua/kitty-scrollback/vendor/README.md @@ -0,0 +1,3 @@ +# Vendored dependencies + +- _system.lua diff --git a/lua/kitty-scrollback/_system.lua b/lua/kitty-scrollback/vendor/_system.lua similarity index 98% rename from lua/kitty-scrollback/_system.lua rename to lua/kitty-scrollback/vendor/_system.lua index 5b82f213..0d814414 100644 --- a/lua/kitty-scrollback/_system.lua +++ b/lua/kitty-scrollback/vendor/_system.lua @@ -1,5 +1,4 @@ --- https://github.com/neovim/neovim/blob/master/runtime/lua/vim/_system.lua -local uv = require('luv') +local uv = vim.uv --- @class SystemOpts --- @field stdin? string|string[]|true @@ -373,3 +372,4 @@ function M.run(cmd, opts, on_exit) end return M + diff --git a/lua/kitty-scrollback/windows.lua b/lua/kitty-scrollback/windows.lua index d7dd7089..47c02c78 100644 --- a/lua/kitty-scrollback/windows.lua +++ b/lua/kitty-scrollback/windows.lua @@ -148,14 +148,16 @@ M.show_status_window = function() end local popup_bufid = vim.api.nvim_create_buf(false, true) local winopts = function() + local w = M.size((p.orig_columns or vim.o.columns), width) return { relative = 'editor', zindex = 39, style = 'minimal', focusable = false, - width = M.size(p.orig_columns or vim.o.columns, width), + width = w, height = 1, row = 0, + -- col = (p.orig_columns or vim.o.columns) - 10, v0.9.0 col = vim.o.columns, border = 'none', } diff --git a/python/kitty_scrollback_bobnvim.py b/python/kitty_scrollback_bobnvim.py new file mode 100755 index 00000000..6ee18580 --- /dev/null +++ b/python/kitty_scrollback_bobnvim.py @@ -0,0 +1,194 @@ +#!/usr/bin/env python3 +from typing import List +from kitty.boss import Boss +from kittens.tui.handler import result_handler +from kitty.fast_data_types import get_options +from kitty.constants import config_dir, version + +import json +import os +import inspect + +ksb_dir = os.path.dirname( + os.path.dirname(os.path.abspath(inspect.getfile(lambda: None)))) + + +def main(): + raise SystemExit('Must be run as kitten kitty_scrollback_nvim') + + +def get_kitty_shell_integration(kitty_opts, w): + # KITTY_SHELL_INTEGRATION env var takes precedence over opts + # kitty v0.30.1 is returning empty window envs so fallback on opts + # see https://github.com/kovidgoyal/kitty/issues/6749 + shell_integration_opts = kitty_opts.shell_integration or frozenset( + {'enabled'}) + shell_integration = w.child.environ.get( + 'KITTY_SHELL_INTEGRATION', + ' '.join(list(shell_integration_opts))) + return shell_integration.split() + + +# based on kitty source window.py +def pipe_data(w, target_window_id, ksb_dir, config): + kitty_opts = get_options() + kitty_shell_integration = get_kitty_shell_integration(kitty_opts, w) + return { + 'kitty_scrollback_config': config, + 'scrolled_by': w.screen.scrolled_by, + 'cursor_x': w.screen.cursor.x + 1, + 'cursor_y': w.screen.cursor.y + 1, + 'lines': w.screen.lines + 1, + 'columns': w.screen.columns, + 'window_id': int(target_window_id), + 'window_title': w.title, + 'ksb_dir': ksb_dir, + 'kitty_opts': { + "shell_integration": + kitty_shell_integration, + "scrollback_fill_enlarged_window": + kitty_opts.scrollback_fill_enlarged_window, + "scrollback_lines": + kitty_opts.scrollback_lines, + "scrollback_pager": + kitty_opts.scrollback_pager, + "allow_remote_control": + kitty_opts.allow_remote_control, + "listen_on": + kitty_opts.listen_on, + "scrollback_pager_history_size": + kitty_opts.scrollback_pager_history_size + }, + 'kitty_config_dir': config_dir, + 'kitty_version': version, + } + + +def parse_nvim_args(args=[]): + for idx, arg in enumerate(args): + if arg.startswith('--no-nvim-args'): + return () + if arg.startswith('--nvim-args'): + if idx + 1 < len(args): + return tuple(filter(None, args[idx + 1:])) + return () + return ( + '--clean', + '--noplugin', + '-n', + ) + + +def parse_env(args): + env_args = [] + for idx, arg in reversed(list(enumerate(args))): + if arg.startswith('--env') and (idx + 1 < len(args)): + env_args.append('--env') + env_args.append(args[idx + 1]) + del args[idx:idx + 2] + return tuple(env_args) + + +def parse_config(args): + config_args = [] + for idx, arg in reversed(list(enumerate(args))): + if arg.startswith('--config-file'): + return 'crying cat --config-file' + if arg.startswith('--config') and (idx + 1 < len(args)): + config_args = args[idx + 1] + del args[idx:idx + 2] + return config_args + return 'default' + + +def parse_cwd(args): + for idx, arg in reversed(list(enumerate(args))): + if arg.startswith('--cwd') and (idx + 1 < len(args)): + cwd_args = args[idx + 1] + del args[idx:idx + 2] + return ('--cwd', cwd_args) + return () + + +@result_handler(type_of_input=None, no_ui=True, has_ready_notification=False) +def handle_result(args: List[str], + result: str, + target_window_id: int, + boss: Boss) -> None: + del args[0] + w = boss.window_id_map.get(target_window_id) + if w is not None: + config = parse_config(args) + if config == 'crying cat --config-file': + err_cmd = ( + 'launch', + '--copy-env', + '--type', + 'overlay', + '--title', + 'kitty-scrollback.nvim', + 'nvim', + ) + parse_nvim_args() + ( + '-c', + 'set laststatus=0', + '-c', + 'set fillchars=eob:\\ ', + '-c', + 'set filetype=checkhealth', + f'{ksb_dir}/scripts/breaking_change_config_file.txt', + ) + + err_winid = boss.call_remote_control(w, err_cmd) + + set_logo_cmd = ('set-window-logo', + '--no-response', + '--alpha', + '0.5', + '--position', + 'bottom-right', + f'{ksb_dir}/media/sad_kitty_thumbs_up.png') + + err_win = boss.window_id_map.get(err_winid) + err_winid = boss.call_remote_control(err_win, set_logo_cmd) + return + + cwd = parse_cwd(args) + env = parse_env(args) + kitty_data_str = pipe_data(w, target_window_id, ksb_dir, config) + kitty_data = json.dumps(kitty_data_str) + + if w.title.startswith('kitty-scrollback.nvim'): + print( + f'[Warning] kitty-scrollback.nvim: skipping action, window {target_window_id} has title that ' + 'starts with "kitty-scrollback.nvim"') + print(json.dumps(kitty_data_str, indent=2)) + return + + kitty_args = ( + '--copy-env', + '--env', + 'VIMRUNTIME=', + '--type', + 'overlay', + '--title', + 'kitty-scrollback.nvim', + ) + env + cwd + + nvim_args = parse_nvim_args(args) + ( + '--cmd', + ' lua vim.api.nvim_create_autocmd([[VimEnter]], { ' + ' group = vim.api.nvim_create_augroup([[KittyScrollBackNvimVimEnter]], { clear = true }), ' + ' pattern = [[*]], ' + ' callback = function() ' + f' vim.opt.runtimepath:append([[{ksb_dir}]])' + ' vim.api.nvim_exec_autocmds([[User]], { pattern = [[KittyScrollbackLaunch]], modeline = false })' + f' require([[kitty-scrollback.launch]]).setup_and_launch([[{kitty_data}]])' + ' end, ' + ' })') + + cmd = ('launch', + ) + kitty_args + ('/Users/mike/.local/share/bob/nvim-bin/nvim', + ) + nvim_args + boss.call_remote_control(w, cmd) + else: + raise Exception(f'Failed to get window with id: {target_window_id}') diff --git a/scripts/dev_generate_vimdocs.sh b/scripts/dev_generate_vimdocs.sh index 75d976ed..b5904b67 100755 --- a/scripts/dev_generate_vimdocs.sh +++ b/scripts/dev_generate_vimdocs.sh @@ -10,7 +10,7 @@ sed -E -e's/\[!(NOTE|WARNING|IMPORTANT)\].*/[!\1]\n>/Ig' -e 's/.*(.+)<\ -e 's/(.+)<\/a>/\2 <\1>/g' tmp_vimdoc_workdir/README.md # panvimdoc -~/gitrepos/panvimdoc/panvimdoc.sh --project-name kitty-scrollback.nvim --input-file tmp_vimdoc_workdir/README.md --demojify true --vim-version 'NVIM v0.10+' --toc true --dedup-subheadings false --treesitter true +~/gitrepos/panvimdoc/panvimdoc.sh --project-name kitty-scrollback.nvim --input-file tmp_vimdoc_workdir/README.md --demojify true --vim-version 'NVIM v0.9+' --toc true --dedup-subheadings false --treesitter true # postformat kitty-scrollback.nvim.txt From b6e34c0cd44081a8185dec80e39f9a1b7067bb04 Mon Sep 17 00:00:00 2001 From: Mike Smith <10135646+mikesmithgh@users.noreply.github.com> Date: Wed, 22 Nov 2023 23:39:44 -0500 Subject: [PATCH 04/11] work in progress --- lua/kitty-scrollback/backport.lua | 50 +++++++++++++++++++++ lua/kitty-scrollback/health.lua | 75 +++++++++++++++---------------- lua/kitty-scrollback/launch.lua | 6 ++- lua/kitty-scrollback/util.lua | 15 ------- lua/kitty-scrollback/windows.lua | 4 +- 5 files changed, 92 insertions(+), 58 deletions(-) create mode 100644 lua/kitty-scrollback/backport.lua diff --git a/lua/kitty-scrollback/backport.lua b/lua/kitty-scrollback/backport.lua new file mode 100644 index 00000000..05e4524c --- /dev/null +++ b/lua/kitty-scrollback/backport.lua @@ -0,0 +1,50 @@ +local ksb_health = require('kitty-scrollback.health') + +local M = {} + +local function backport_version() + if type(vim.version().__tostring) ~= 'function' then + -- NOTE: copied __tostring from + -- https://github.com/neovim/neovim/blob/879617c9bbbacb0d0f778ff6dd53cc7c95794abe/runtime/lua/vim/version.lua + + local Version = {} + function Version:__tostring() + local ret = table.concat({ self.major, self.minor, self.patch }, '.') + if self.prerelease then + ret = ret .. '-' .. self.prerelease + end + if self.build and self.build ~= vim.NIL then + ret = ret .. '+' .. self.build + end + return ret + end + + setmetatable(vim.version, { + --- Returns the current Nvim version. + __call = function() + local version = vim.fn.api_info().version + -- Workaround: vim.fn.api_info().version reports "prerelease" as a boolean. + version.prerelease = version.prerelease and 'dev' or nil + return setmetatable(version, Version) + end, + }) + end +end + +local function backport_health() + vim.health.start = vim.health.start or vim.health.report_start + vim.health.info = vim.health.info or vim.health.report_info + vim.health.ok = vim.health.ok or vim.health.report_ok + vim.health.warn = vim.health.warn or vim.health.report_warn + vim.health.error = vim.health.error or vim.health.report_error +end + +M.setup = function() + if ksb_health.check_nvim_version('nvim-0.10', true) then + return + end + backport_version() + backport_health() +end + +return M diff --git a/lua/kitty-scrollback/health.lua b/lua/kitty-scrollback/health.lua index d6505cde..6ed1fcb7 100644 --- a/lua/kitty-scrollback/health.lua +++ b/lua/kitty-scrollback/health.lua @@ -1,4 +1,3 @@ -local ksb_util = require('kitty-scrollback.util') ---@mod kitty-scrollback.health local M = {} @@ -13,13 +12,8 @@ M.setup = function(private, options) opts = options ---@diagnostic disable-line: unused-local end -local start_health = vim.health.start or vim.health.report_start -local ok_health = vim.health.ok or vim.health.report_ok -local warn_health = vim.health.warn or vim.health.report_warn -local error_health = vim.health.error or vim.health.report_error - local function check_kitty_remote_control() - start_health('kitty-scrollback: Kitty remote control') + vim.health.start('kitty-scrollback: Kitty remote control') local cmd = { 'kitty', '@', @@ -31,7 +25,7 @@ local function check_kitty_remote_control() local ok = result.code == 0 local code_msg = '`kitty @ ls` exited with code *' .. result.code .. '*' if ok then - ok_health(code_msg) + vim.health.ok(code_msg) return true else local stderr = result.stderr:gsub('\n', '') or '' @@ -59,15 +53,15 @@ local function check_kitty_remote_control() else table.insert(advice, 'ERROR Failed to read `allow_remote_control` and `listen_on`') end - error_health(code_msg .. '\n `' .. stderr .. '` ', advice) + vim.health.error(code_msg .. '\n `' .. stderr .. '` ', advice) end return false end local function check_has_kitty_data() - start_health('kitty-scrollback: Kitty data') + vim.health.start('kitty-scrollback: Kitty data') if type(p) == 'table' and next(p.kitty_data) then - ok_health('Kitty data available\n>lua\n' .. vim.inspect(p.kitty_data) .. '\n') + vim.health.ok('Kitty data available\n>lua\n' .. vim.inspect(p.kitty_data) .. '\n') return true else local kitty_scrollback_kitten = @@ -75,7 +69,7 @@ local function check_has_kitty_data() local checkhealth_command = '`kitty @ kitten ' .. kitty_scrollback_kitten .. ' --config ksb_builtin_checkhealth`' - warn_health('No Kitty data available unable to perform a complete healthcheck', { + vim.health.warn('No Kitty data available unable to perform a complete healthcheck', { 'Add the config options `checkhealth = true` to your *config* or execute the command `:KittyScrollbackCheckHealth` ' .. 'to run `checkhealth` within the context of a Kitten', checkhealth_command, @@ -88,12 +82,12 @@ local function check_clipboard() local function is_blank(s) return s:find('^%s*$') ~= nil end - start_health('kitty-scrollback: clipboard') + vim.health.start('kitty-scrollback: clipboard') local clipboard_tool = vim.fn['provider#clipboard#Executable']() -- copied from health.lua if vim.fn.has('clipboard') > 0 and not is_blank(clipboard_tool) then - ok_health('Clipboard tool found: *' .. clipboard_tool .. '*') + vim.health.ok('Clipboard tool found: *' .. clipboard_tool .. '*') else - warn_health( + vim.health.warn( 'Neovim does not have a clipboard provider.\n Some functionality will not work when there is no clipboard ' .. 'provider, such as copying Kitty scrollback buffer text to the system clipboard.', 'See `:help` |provider-clipboard| for more information on enabling system clipboard integration.' @@ -102,16 +96,16 @@ local function check_clipboard() end local function check_kitty_shell_integration() - start_health('kitty-scrollback: Kitty shell integration') + vim.health.start('kitty-scrollback: Kitty shell integration') if not next(p or {}) then - error_health('No Kitty data') + vim.health.error('No Kitty data') return end -- use last_cmd_output because it is valid and requires shell integration if M.is_valid_extent_keyword('last_cmd_output') then - ok_health('Kitty shell integration is enabled') + vim.health.ok('Kitty shell integration is enabled') else - warn_health( + vim.health.warn( 'Kitty shell integration is disabled and/or `no-prompt-mark` is set.\n Some functionality will not work when Kitty shell ' .. 'integration is disabled or `no-prompt-mark` is set, such as capturing the last command output.', table.concat(M.advice().kitty_shell_integration, '\n') @@ -120,10 +114,10 @@ local function check_kitty_shell_integration() end local function check_sed() - start_health('kitty-scrollback: sed') + vim.health.start('kitty-scrollback: sed') local sed_path = vim.fn.exepath('sed') if not sed_path or sed_path == '' then - error_health('*sed* : command not found\n') + vim.health.error('*sed* : command not found\n') return end @@ -149,7 +143,7 @@ local function check_sed() end ok = ok and result.code == 0 and result.stdout == 'expected' if ok then - ok_health( + vim.health.ok( '`' .. table.concat(cmd, ' ') .. '` exited with code *' @@ -166,7 +160,7 @@ local function check_sed() if result_err ~= '' then result_err = ' `' .. result_err .. '`' end - error_health( + vim.health.error( '`' .. table.concat(cmd, ' ') .. '` exited with code *' @@ -184,20 +178,23 @@ local function check_sed() end M.check_nvim_version = function(version, check_only) - -- TODO: check min nvim version now - -- fallback to older health report calls if using < 0.10 if not check_only then - start_health('kitty-scrollback: Neovim version 0.9+') + vim.health.start('kitty-scrollback: Neovim version 0.9+') end - local nvim_version = 'NVIM ' .. ksb_util.nvim_version_tostring() + local nvim_version = 'NVIM ' .. tostring(vim.version()) if vim.fn.has(version) > 0 then if not check_only then - ok_health(nvim_version) + vim.health.ok(nvim_version) + if vim.fn.has('nvim-0.10') <= 0 then + vim.health.info( + 'If you are using a version of nvim that is less than 0.10, then formatting on this checkhealth may be malformed' + ) + end end return true else if not check_only then - error_health(nvim_version, M.advice().nvim_version) + vim.health.error(nvim_version, M.advice().nvim_version) end end return false @@ -205,25 +202,25 @@ end M.check_kitty_version = function(check_only) if not check_only then - start_health('kitty-scrollback: Kitty version 0.29+') + vim.health.start('kitty-scrollback: Kitty version 0.29+') end local kitty_version = p.kitty_data.kitty_version local kitty_version_str = 'kitty ' .. table.concat(kitty_version, '.') if vim.version.cmp(kitty_version, { 0, 29, 0 }) >= 0 then if not check_only then - ok_health(kitty_version_str) + vim.health.ok(kitty_version_str) end return true else if not check_only then - error_health(kitty_version_str, M.advice().kitty_version) + vim.health.error(kitty_version_str, M.advice().kitty_version) end end return false end local function check_kitty_debug_config() - start_health('kitty-scrollback: Kitty debug config') + vim.health.start('kitty-scrollback: Kitty debug config') local kitty_debug_config_kitten = vim.api.nvim_get_runtime_file('python/kitty_debug_config.py', false)[1] local debug_config_log = vim.fn.stdpath('data') .. '/kitty-scrollback.nvim/debug_config.log' @@ -231,13 +228,13 @@ local function check_kitty_debug_config() vim.system({ 'kitty', '@', 'kitten', kitty_debug_config_kitten, debug_config_log }):wait() if result.code == 0 then if vim.fn.filereadable(debug_config_log) then - ok_health(table.concat(vim.fn.readfile(debug_config_log), '\n ')) + vim.health.ok(table.concat(vim.fn.readfile(debug_config_log), '\n ')) else - error_health('cannot read ' .. debug_config_log) + vim.health.error('cannot read ' .. debug_config_log) end else local stderr = result.stderr:gsub('\n', '') or '' - error_health(stderr) + vim.health.error(stderr) end end @@ -262,11 +259,11 @@ local function check_kitty_scrollback_nvim_version() version_found and '`' .. current_version:gsub('%s$', '`\n') ---@diagnostic disable-line: need-check-nil or 'ERROR failed to determine version\n' ) - local health_fn = not version_found and warn_health + local health_fn = not version_found and vim.health.warn or function(msg) - ok_health(' ' .. msg) + vim.health.ok(' ' .. msg) end - start_health('kitty-scrollback: kitty-scrollback.nvim version') + vim.health.start('kitty-scrollback: kitty-scrollback.nvim version') health_fn([[ `|`\___/`|` ]] .. header .. [[ =) `^`Y`^` (= \ *^* / If you have any issues or questions using *kitty-scrollback.nvim* then diff --git a/lua/kitty-scrollback/launch.lua b/lua/kitty-scrollback/launch.lua index d0115e02..40b75212 100644 --- a/lua/kitty-scrollback/launch.lua +++ b/lua/kitty-scrollback/launch.lua @@ -18,6 +18,8 @@ local ksb_util local ksb_autocmds ---@module 'kitty-scrollback.health' local ksb_health +---@module 'kitty-scrollback.backport' +local ksb_backport local M = {} @@ -247,6 +249,7 @@ local function load_requires() ksb_util = require('kitty-scrollback.util') ksb_autocmds = require('kitty-scrollback.autocommands') ksb_health = require('kitty-scrollback.health') + ksb_backport = require('kitty-scrollback.backport') end ---Setup and configure kitty-scrollback.nvim @@ -267,6 +270,7 @@ M.setup = function(kitty_data_str) local user_opts = config_fn and config_fn(p.kitty_data) or {} opts = vim.tbl_deep_extend('force', default_opts, user_opts) + ksb_backport.setup() ksb_health.setup(p, opts) if opts.checkhealth then vim.o.foldenable = false @@ -275,7 +279,7 @@ M.setup = function(kitty_data_str) end if not ksb_health.check_nvim_version('nvim-0.9', true) then local prompt_msg = 'kitty-scrollback.nvim: Fatal error, on version NVIM ' - .. ksb_util.nvim_version_tostring() + .. tostring(vim.version()) .. '. ' .. table.concat(ksb_health.advice().nvim_version) local response = vim.fn.confirm(prompt_msg, '&Quit\n&Continue') diff --git a/lua/kitty-scrollback/util.lua b/lua/kitty-scrollback/util.lua index 154e3ce7..9beba3b6 100644 --- a/lua/kitty-scrollback/util.lua +++ b/lua/kitty-scrollback/util.lua @@ -76,21 +76,6 @@ M.remove_process_exited = function() return false end --- nvim 0.10+ has tostring builtin but need this for previous versions during healthcheck -M.nvim_version_tostring = function() - local nvim_ver = vim.version() - local ret = table.concat({ nvim_ver.major, nvim_ver.minor, nvim_ver.patch }, '.') - if nvim_ver.prerelease then - local prerelease = type(nvim_ver.prerelease) == 'boolean' and 'dev' or nvim_ver.prerelease - ret = ret .. '-' .. prerelease - end - vim.print(nvim_ver) - if nvim_ver.build and nvim_ver.build ~= vim.NIL then - ret = ret .. '+' .. nvim_ver.build - end - return ret -end - M.restore_and_redraw = function() if p.orig_columns then vim.o.columns = p.orig_columns diff --git a/lua/kitty-scrollback/windows.lua b/lua/kitty-scrollback/windows.lua index 47c02c78..d7dd7089 100644 --- a/lua/kitty-scrollback/windows.lua +++ b/lua/kitty-scrollback/windows.lua @@ -148,16 +148,14 @@ M.show_status_window = function() end local popup_bufid = vim.api.nvim_create_buf(false, true) local winopts = function() - local w = M.size((p.orig_columns or vim.o.columns), width) return { relative = 'editor', zindex = 39, style = 'minimal', focusable = false, - width = w, + width = M.size(p.orig_columns or vim.o.columns, width), height = 1, row = 0, - -- col = (p.orig_columns or vim.o.columns) - 10, v0.9.0 col = vim.o.columns, border = 'none', } From 54924eae5bdfe827fee730aea6bdc03875187395 Mon Sep 17 00:00:00 2001 From: Mike Smith <10135646+mikesmithgh@users.noreply.github.com> Date: Thu, 23 Nov 2023 20:26:28 -0500 Subject: [PATCH 05/11] chore: add v0.9 backport --- lua/kitty-scrollback/api.lua | 5 +++++ lua/kitty-scrollback/backport.lua | 28 +++++++++++++++++++++++++++- lua/kitty-scrollback/launch.lua | 9 --------- lua/kitty-scrollback/util.lua | 9 --------- 4 files changed, 32 insertions(+), 19 deletions(-) diff --git a/lua/kitty-scrollback/api.lua b/lua/kitty-scrollback/api.lua index 3b596a1f..7dd9316f 100644 --- a/lua/kitty-scrollback/api.lua +++ b/lua/kitty-scrollback/api.lua @@ -183,6 +183,11 @@ end M.checkhealth = function() local kitty_scrollback_kitten = vim.api.nvim_get_runtime_file('python/kitty_scrollback_nvim.py', false)[1] + -- NOTE(#58): nvim v0.9 support + -- setup backports for v0.9 because checkhealth can be called outside of standard setup flow + if vim.fn.has('nvim-0.10') <= 0 then + require('kitty-scrollback.backport').setup() + end if vim.fn.has('nvim-0.9') > 0 then vim .system({ diff --git a/lua/kitty-scrollback/backport.lua b/lua/kitty-scrollback/backport.lua index 05e4524c..cbfb12d5 100644 --- a/lua/kitty-scrollback/backport.lua +++ b/lua/kitty-scrollback/backport.lua @@ -1,3 +1,6 @@ +---@mod kitty-scrollback.backport +-- NOTE(#58): nvim v0.9 support + local ksb_health = require('kitty-scrollback.health') local M = {} @@ -19,6 +22,9 @@ local function backport_version() return ret end + if type(vim.version) == 'function' then -- nvim 0.8 vim.version is a table instead of function + vim.version = vim.version() + end setmetatable(vim.version, { --- Returns the current Nvim version. __call = function() @@ -39,12 +45,32 @@ local function backport_health() vim.health.error = vim.health.error or vim.health.report_error end +local function backport_uv() + if not vim.uv then + vim.uv = vim.loop + end +end + +local function backport_system() + -- copied from _editor.lua + ---@diagnostic disable-next-line: duplicate-set-field + vim.system = function(cmd, opts, on_exit) + if type(opts) == 'function' then + on_exit = opts + opts = nil + end + return require('kitty-scrollback.vendor._system').run(cmd, opts, on_exit) + end +end + M.setup = function() + backport_uv() + backport_health() if ksb_health.check_nvim_version('nvim-0.10', true) then return end backport_version() - backport_health() + backport_system() end return M diff --git a/lua/kitty-scrollback/launch.lua b/lua/kitty-scrollback/launch.lua index 40b75212..bc5701d2 100644 --- a/lua/kitty-scrollback/launch.lua +++ b/lua/kitty-scrollback/launch.lua @@ -287,15 +287,6 @@ M.setup = function(kitty_data_str) ksb_kitty_cmds.signal_term_to_kitty_child_process(true) end end - if not ksb_health.check_nvim_version('nvim-0.10', true) then - -- assume nvim-0.9 and vendor required nvim-0.10 dependencies - if not vim.uv then - vim.uv = vim.loop - end - if not vim.system then - vim.system = ksb_util.vendored_vim_system - end - end if not ksb_health.check_kitty_version(true) then local prompt_msg = 'kitty-scrollback.nvim: Fatal error, on version kitty ' .. table.concat(p.kitty_data.kitty_version, '.') diff --git a/lua/kitty-scrollback/util.lua b/lua/kitty-scrollback/util.lua index 9beba3b6..eeb1a381 100644 --- a/lua/kitty-scrollback/util.lua +++ b/lua/kitty-scrollback/util.lua @@ -83,13 +83,4 @@ M.restore_and_redraw = function() vim.cmd.redraw() end --- copied from _editor.lua -M.vendored_vim_system = function(cmd, o, on_exit) - if type(o) == 'function' then - on_exit = o - o = nil - end - return require('kitty-scrollback.vendor._system').run(cmd, o, on_exit) -end - return M From 64a62b20cb3cfbce9c88e8103f8700bfc609cf00 Mon Sep 17 00:00:00 2001 From: Mike Smith <10135646+mikesmithgh@users.noreply.github.com> Date: Thu, 23 Nov 2023 20:28:22 -0500 Subject: [PATCH 06/11] chore: remove bob --- python/kitty_scrollback_bobnvim.py | 194 ----------------------------- 1 file changed, 194 deletions(-) delete mode 100755 python/kitty_scrollback_bobnvim.py diff --git a/python/kitty_scrollback_bobnvim.py b/python/kitty_scrollback_bobnvim.py deleted file mode 100755 index 6ee18580..00000000 --- a/python/kitty_scrollback_bobnvim.py +++ /dev/null @@ -1,194 +0,0 @@ -#!/usr/bin/env python3 -from typing import List -from kitty.boss import Boss -from kittens.tui.handler import result_handler -from kitty.fast_data_types import get_options -from kitty.constants import config_dir, version - -import json -import os -import inspect - -ksb_dir = os.path.dirname( - os.path.dirname(os.path.abspath(inspect.getfile(lambda: None)))) - - -def main(): - raise SystemExit('Must be run as kitten kitty_scrollback_nvim') - - -def get_kitty_shell_integration(kitty_opts, w): - # KITTY_SHELL_INTEGRATION env var takes precedence over opts - # kitty v0.30.1 is returning empty window envs so fallback on opts - # see https://github.com/kovidgoyal/kitty/issues/6749 - shell_integration_opts = kitty_opts.shell_integration or frozenset( - {'enabled'}) - shell_integration = w.child.environ.get( - 'KITTY_SHELL_INTEGRATION', - ' '.join(list(shell_integration_opts))) - return shell_integration.split() - - -# based on kitty source window.py -def pipe_data(w, target_window_id, ksb_dir, config): - kitty_opts = get_options() - kitty_shell_integration = get_kitty_shell_integration(kitty_opts, w) - return { - 'kitty_scrollback_config': config, - 'scrolled_by': w.screen.scrolled_by, - 'cursor_x': w.screen.cursor.x + 1, - 'cursor_y': w.screen.cursor.y + 1, - 'lines': w.screen.lines + 1, - 'columns': w.screen.columns, - 'window_id': int(target_window_id), - 'window_title': w.title, - 'ksb_dir': ksb_dir, - 'kitty_opts': { - "shell_integration": - kitty_shell_integration, - "scrollback_fill_enlarged_window": - kitty_opts.scrollback_fill_enlarged_window, - "scrollback_lines": - kitty_opts.scrollback_lines, - "scrollback_pager": - kitty_opts.scrollback_pager, - "allow_remote_control": - kitty_opts.allow_remote_control, - "listen_on": - kitty_opts.listen_on, - "scrollback_pager_history_size": - kitty_opts.scrollback_pager_history_size - }, - 'kitty_config_dir': config_dir, - 'kitty_version': version, - } - - -def parse_nvim_args(args=[]): - for idx, arg in enumerate(args): - if arg.startswith('--no-nvim-args'): - return () - if arg.startswith('--nvim-args'): - if idx + 1 < len(args): - return tuple(filter(None, args[idx + 1:])) - return () - return ( - '--clean', - '--noplugin', - '-n', - ) - - -def parse_env(args): - env_args = [] - for idx, arg in reversed(list(enumerate(args))): - if arg.startswith('--env') and (idx + 1 < len(args)): - env_args.append('--env') - env_args.append(args[idx + 1]) - del args[idx:idx + 2] - return tuple(env_args) - - -def parse_config(args): - config_args = [] - for idx, arg in reversed(list(enumerate(args))): - if arg.startswith('--config-file'): - return 'crying cat --config-file' - if arg.startswith('--config') and (idx + 1 < len(args)): - config_args = args[idx + 1] - del args[idx:idx + 2] - return config_args - return 'default' - - -def parse_cwd(args): - for idx, arg in reversed(list(enumerate(args))): - if arg.startswith('--cwd') and (idx + 1 < len(args)): - cwd_args = args[idx + 1] - del args[idx:idx + 2] - return ('--cwd', cwd_args) - return () - - -@result_handler(type_of_input=None, no_ui=True, has_ready_notification=False) -def handle_result(args: List[str], - result: str, - target_window_id: int, - boss: Boss) -> None: - del args[0] - w = boss.window_id_map.get(target_window_id) - if w is not None: - config = parse_config(args) - if config == 'crying cat --config-file': - err_cmd = ( - 'launch', - '--copy-env', - '--type', - 'overlay', - '--title', - 'kitty-scrollback.nvim', - 'nvim', - ) + parse_nvim_args() + ( - '-c', - 'set laststatus=0', - '-c', - 'set fillchars=eob:\\ ', - '-c', - 'set filetype=checkhealth', - f'{ksb_dir}/scripts/breaking_change_config_file.txt', - ) - - err_winid = boss.call_remote_control(w, err_cmd) - - set_logo_cmd = ('set-window-logo', - '--no-response', - '--alpha', - '0.5', - '--position', - 'bottom-right', - f'{ksb_dir}/media/sad_kitty_thumbs_up.png') - - err_win = boss.window_id_map.get(err_winid) - err_winid = boss.call_remote_control(err_win, set_logo_cmd) - return - - cwd = parse_cwd(args) - env = parse_env(args) - kitty_data_str = pipe_data(w, target_window_id, ksb_dir, config) - kitty_data = json.dumps(kitty_data_str) - - if w.title.startswith('kitty-scrollback.nvim'): - print( - f'[Warning] kitty-scrollback.nvim: skipping action, window {target_window_id} has title that ' - 'starts with "kitty-scrollback.nvim"') - print(json.dumps(kitty_data_str, indent=2)) - return - - kitty_args = ( - '--copy-env', - '--env', - 'VIMRUNTIME=', - '--type', - 'overlay', - '--title', - 'kitty-scrollback.nvim', - ) + env + cwd - - nvim_args = parse_nvim_args(args) + ( - '--cmd', - ' lua vim.api.nvim_create_autocmd([[VimEnter]], { ' - ' group = vim.api.nvim_create_augroup([[KittyScrollBackNvimVimEnter]], { clear = true }), ' - ' pattern = [[*]], ' - ' callback = function() ' - f' vim.opt.runtimepath:append([[{ksb_dir}]])' - ' vim.api.nvim_exec_autocmds([[User]], { pattern = [[KittyScrollbackLaunch]], modeline = false })' - f' require([[kitty-scrollback.launch]]).setup_and_launch([[{kitty_data}]])' - ' end, ' - ' })') - - cmd = ('launch', - ) + kitty_args + ('/Users/mike/.local/share/bob/nvim-bin/nvim', - ) + nvim_args - boss.call_remote_control(w, cmd) - else: - raise Exception(f'Failed to get window with id: {target_window_id}') From e609248d336e353f4a6cf1eb61c94c9e660601c7 Mon Sep 17 00:00:00 2001 From: Mike Smith <10135646+mikesmithgh@users.noreply.github.com> Date: Thu, 23 Nov 2023 20:49:42 -0500 Subject: [PATCH 07/11] chore: add backport sha --- lua/kitty-scrollback/backport/README.md | 10 ++++++++++ lua/kitty-scrollback/{vendor => backport}/_system.lua | 5 ++++- lua/kitty-scrollback/backport/backport-sha.json | 4 ++++ .../{backport.lua => backport/init.lua} | 2 +- lua/kitty-scrollback/vendor/.luarc.json | 5 ----- lua/kitty-scrollback/vendor/README.md | 3 --- 6 files changed, 19 insertions(+), 10 deletions(-) create mode 100644 lua/kitty-scrollback/backport/README.md rename lua/kitty-scrollback/{vendor => backport}/_system.lua (98%) create mode 100644 lua/kitty-scrollback/backport/backport-sha.json rename lua/kitty-scrollback/{backport.lua => backport/init.lua} (96%) delete mode 100644 lua/kitty-scrollback/vendor/.luarc.json delete mode 100644 lua/kitty-scrollback/vendor/README.md diff --git a/lua/kitty-scrollback/backport/README.md b/lua/kitty-scrollback/backport/README.md new file mode 100644 index 00000000..ad47de0a --- /dev/null +++ b/lua/kitty-scrollback/backport/README.md @@ -0,0 +1,10 @@ +# Backported functionality from v0.10 to v0.9 + +## Files +- runtime/lua/vim/_system.lua +- runtime/lua/vim/version.lua + +## Backport sha256s +- backport-sha.json contains the file and sha256 checksums at the time of copy +- TODO: add a cron to have a nighlty check if these files changes in Neovim + diff --git a/lua/kitty-scrollback/vendor/_system.lua b/lua/kitty-scrollback/backport/_system.lua similarity index 98% rename from lua/kitty-scrollback/vendor/_system.lua rename to lua/kitty-scrollback/backport/_system.lua index 0d814414..75a689e5 100644 --- a/lua/kitty-scrollback/vendor/_system.lua +++ b/lua/kitty-scrollback/backport/_system.lua @@ -1,3 +1,7 @@ +-- NOTE: copied from +-- https://github.com/neovim/neovim/blob/a8a93e517f9eb988ee86170d9a77382637dd24a3/runtime/lua/vim/_system.lua + +---@diagnostic disable local uv = vim.uv --- @class SystemOpts @@ -372,4 +376,3 @@ function M.run(cmd, opts, on_exit) end return M - diff --git a/lua/kitty-scrollback/backport/backport-sha.json b/lua/kitty-scrollback/backport/backport-sha.json new file mode 100644 index 00000000..b66534e8 --- /dev/null +++ b/lua/kitty-scrollback/backport/backport-sha.json @@ -0,0 +1,4 @@ +{ + "runtime/lua/vim/_system.lua": "9e8813381da9093060dfd09065499e87ac23d673a7fa53a52b6e6dfac0cd6e7e", + "runtime/lua/vim/version.lua": "d94c6888586745fb04b76037db70d5bf82e0d2a376d2e3e18bc0e162f421857d" +} diff --git a/lua/kitty-scrollback/backport.lua b/lua/kitty-scrollback/backport/init.lua similarity index 96% rename from lua/kitty-scrollback/backport.lua rename to lua/kitty-scrollback/backport/init.lua index cbfb12d5..299474b0 100644 --- a/lua/kitty-scrollback/backport.lua +++ b/lua/kitty-scrollback/backport/init.lua @@ -59,7 +59,7 @@ local function backport_system() on_exit = opts opts = nil end - return require('kitty-scrollback.vendor._system').run(cmd, opts, on_exit) + return require('kitty-scrollback.backport._system').run(cmd, opts, on_exit) end end diff --git a/lua/kitty-scrollback/vendor/.luarc.json b/lua/kitty-scrollback/vendor/.luarc.json deleted file mode 100644 index 5ff34848..00000000 --- a/lua/kitty-scrollback/vendor/.luarc.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "diagnostics": { - "enable": false, - } -} diff --git a/lua/kitty-scrollback/vendor/README.md b/lua/kitty-scrollback/vendor/README.md deleted file mode 100644 index fc2a6c7f..00000000 --- a/lua/kitty-scrollback/vendor/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Vendored dependencies - -- _system.lua From b9d0a7c8305ba41a3f307da99878eb02c286c8bf Mon Sep 17 00:00:00 2001 From: Mike Smith <10135646+mikesmithgh@users.noreply.github.com> Date: Thu, 23 Nov 2023 20:54:40 -0500 Subject: [PATCH 08/11] chore: typo --- lua/kitty-scrollback/backport/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/kitty-scrollback/backport/README.md b/lua/kitty-scrollback/backport/README.md index ad47de0a..a5fc86ac 100644 --- a/lua/kitty-scrollback/backport/README.md +++ b/lua/kitty-scrollback/backport/README.md @@ -6,5 +6,5 @@ ## Backport sha256s - backport-sha.json contains the file and sha256 checksums at the time of copy -- TODO: add a cron to have a nighlty check if these files changes in Neovim +- TODO: add a cron to have a nightly check if these files changes in Neovim From 80eb539ed45d2ce0d5f66ef2f202f5a1abb665b0 Mon Sep 17 00:00:00 2001 From: Mike Smith <10135646+mikesmithgh@users.noreply.github.com> Date: Thu, 23 Nov 2023 20:57:17 -0500 Subject: [PATCH 09/11] chore: remove comment no longer necessary --- lua/kitty-scrollback/health.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/kitty-scrollback/health.lua b/lua/kitty-scrollback/health.lua index 6ed1fcb7..5bf44057 100644 --- a/lua/kitty-scrollback/health.lua +++ b/lua/kitty-scrollback/health.lua @@ -281,7 +281,7 @@ end M.check = function() if - M.check_nvim_version('nvim-0.9') -- always check first to avoid undefined calls in versions < 0.10 + M.check_nvim_version('nvim-0.9') and check_kitty_scrollback_nvim_version() and check_kitty_remote_control() and check_has_kitty_data() From 9b282a0503ae5af26c9162ce9aced1d1c0855b12 Mon Sep 17 00:00:00 2001 From: Mike Smith <10135646+mikesmithgh@users.noreply.github.com> Date: Fri, 24 Nov 2023 13:39:11 -0500 Subject: [PATCH 10/11] chore: add backport to nerdfont check --- lua/kitty-scrollback/kitty_commands.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lua/kitty-scrollback/kitty_commands.lua b/lua/kitty-scrollback/kitty_commands.lua index 46f870ff..814dc993 100644 --- a/lua/kitty-scrollback/kitty_commands.lua +++ b/lua/kitty-scrollback/kitty_commands.lua @@ -345,6 +345,10 @@ M.send_text_to_clipboard = function(text) end M.try_detect_nerd_font = function() + -- setup backports for v0.9 because try_detect_nerd_font can be called outside of standard setup flow + if vim.fn.has('nvim-0.10') <= 0 then + require('kitty-scrollback.backport').setup() + end local has_nerd_font = false vim .system({ From ed36ffc95017db8fb9e3a37b5475ef7ce0d1209f Mon Sep 17 00:00:00 2001 From: Mike Smith <10135646+mikesmithgh@users.noreply.github.com> Date: Fri, 24 Nov 2023 13:43:03 -0500 Subject: [PATCH 11/11] chore: generate helpdocs --- doc/kitty-scrollback.nvim.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/kitty-scrollback.nvim.txt b/doc/kitty-scrollback.nvim.txt index 8682cd43..bd3974c3 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 November 23 +*kitty-scrollback.nvim.txt* For NVIM v0.9+ Last change: 2023 November 24 ============================================================================== Table of Contents *kitty-scrollback.nvim-table-of-contents* @@ -162,7 +162,7 @@ EXAMPLE USE CASES *kitty-scrollback.nvim-example-use-cases* PREREQUISITES *kitty-scrollback.nvim-prerequisites* -- Neovim v0.10+ +- Neovim v0.9+ - Kitty v0.29+