scrollback.lua (2612B)
1 -- scrollback.lua — kitty's copy mode (ctrl+a>[) as a Neovim buffer. 2 -- Started by home/modules/terminal.nix as 3 -- bash -c 'exec nvim 63<&0 0</dev/null -u <this file> -c "let g:kitty_input_line=INPUT_LINE_NUMBER" …' 4 -- kitty hands the scrollback (with colours) on fd 63; it is rendered through a 5 -- :terminal so the ANSI colours survive, then the buffer is left in normal 6 -- mode at the line that was under the cursor. Vi motions and search work as 7 -- usual; / ? n N, v V ctrl-v select, y copies to the clipboard (wl-copy), 8 -- Enter copies and leaves, q or Esc leave. Nothing from the AstroNvim config 9 -- is loaded (-u), so this starts instantly. 10 11 local o = vim.opt 12 o.number = false 13 o.relativenumber = false 14 o.list = false 15 o.showtabline = 0 16 o.foldcolumn = "0" 17 o.laststatus = 0 18 o.signcolumn = "no" 19 o.ruler = false 20 o.showmode = false 21 o.cmdheight = 1 22 o.scrollback = 100000 23 o.termguicolors = true 24 o.background = "dark" 25 o.clipboard = "unnamedplus" -- y → system clipboard 26 o.ignorecase = true 27 o.smartcase = true 28 o.incsearch = true 29 o.hlsearch = true 30 o.shell = "bash" 31 32 local function quit() 33 vim.cmd("qa!") 34 end 35 local map = vim.keymap.set 36 map({ "n", "v" }, "q", quit, { silent = true, desc = "leave copy mode" }) 37 map("n", "<Esc>", quit, { silent = true, desc = "leave copy mode" }) 38 map("n", "i", "<Nop>") -- no insert in a dead terminal 39 map("n", "a", "<Nop>") 40 map("v", "y", '"+y', { silent = true, desc = "copy selection" }) 41 map("v", "<CR>", '"+y<cmd>qa!<CR>', { silent = true, desc = "copy selection and leave (tmux)" }) 42 map("n", "<CR>", "<Nop>") 43 44 vim.schedule(function() 45 -- the -c flags have run by now, so the kitty positions are in vim.g 46 local input_line = tonumber(vim.g.kitty_input_line) or 0 47 local cursor_line = tonumber(vim.g.kitty_cursor_line) or 1 48 local cursor_col = tonumber(vim.g.kitty_cursor_col) or 1 49 50 vim.api.nvim_create_autocmd("TermEnter", { callback = function() vim.cmd("stopinsert") end }) 51 vim.api.nvim_create_autocmd("TermClose", { 52 once = true, 53 callback = function() 54 vim.cmd("stopinsert") 55 local target = math.max(0, input_line - 1) + cursor_line 56 pcall(vim.fn.cursor, target, cursor_col) 57 vim.cmd("normal! zz") 58 if vim.env.KITTY_SCROLLBACK_TEST then 59 -- smoke test (terminal.nix build check): print the text and leave 60 io.stdout:write(table.concat(vim.api.nvim_buf_get_lines(0, 0, -1, false), "\n"), "\n") 61 quit() 62 end 63 end, 64 }) 65 -- strip kitty's OSC 8 file:// hyperlinks, which would print as noise 66 vim.cmd([[terminal sed </dev/fd/63 -e 's/\x1b]8;;file:[^\\]*\\//g' && sleep 0.01 && printf '\x1b]2;\a']]) 67 end)