Skip to content

Instantly share code, notes, and snippets.

@galaxia4Eva
Last active April 23, 2024 07:05
Show Gist options
  • Star 13 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save galaxia4Eva/9e91c4f275554b4bd844b6feece16b3d to your computer and use it in GitHub Desktop.
Save galaxia4Eva/9e91c4f275554b4bd844b6feece16b3d to your computer and use it in GitHub Desktop.
nvim pager for kitty history
return function(INPUT_LINE_NUMBER, CURSOR_LINE, CURSOR_COLUMN)
print('kitty sent:', INPUT_LINE_NUMBER, CURSOR_LINE, CURSOR_COLUMN)
vim.opt.encoding='utf-8'
vim.opt.clipboard = 'unnamed'
vim.opt.compatible = false
vim.opt.number = false
vim.opt.relativenumber = false
vim.opt.termguicolors = true
vim.opt.showmode = false
vim.opt.ruler = false
vim.opt.laststatus = 0
vim.o.cmdheight = 0
vim.opt.showcmd = false
vim.opt.scrollback = INPUT_LINE_NUMBER + CURSOR_LINE
local term_buf = vim.api.nvim_create_buf(true, false);
local term_io = vim.api.nvim_open_term(term_buf, {})
vim.api.nvim_buf_set_keymap(term_buf, 'n', 'q', '<Cmd>q<CR>', { })
vim.api.nvim_buf_set_keymap(term_buf, 'n', '<ESC>', '<Cmd>q<CR>', { })
local group = vim.api.nvim_create_augroup('kitty+page', {})
local setCursor = function()
vim.api.nvim_feedkeys(tostring(INPUT_LINE_NUMBER) .. [[ggzt]], 'n', true)
local line = vim.api.nvim_buf_line_count(term_buf)
if (CURSOR_LINE <= line) then
line = CURSOR_LINE
end
vim.api.nvim_feedkeys(tostring(line - 1) .. [[j]], 'n', true)
vim.api.nvim_feedkeys([[0]], 'n', true)
vim.api.nvim_feedkeys(tostring(CURSOR_COLUMN - 1) .. [[l]], 'n', true)
end
vim.api.nvim_create_autocmd('ModeChanged', {
group = group,
buffer = term_buf,
callback = function()
local mode = vim.fn.mode()
if mode == 't' then
vim.cmd.stopinsert()
vim.schedule(setCursor)
end
end,
})
vim.api.nvim_create_autocmd('VimEnter', {
group = group,
pattern = '*',
once = true,
callback = function(ev)
local current_win = vim.fn.win_getid()
for _, line in ipairs(vim.api.nvim_buf_get_lines(ev.buf, 0, -2, false)) do
vim.api.nvim_chan_send(term_io, line)
vim.api.nvim_chan_send(term_io, '\r\n')
end
for _, line in ipairs(vim.api.nvim_buf_get_lines(ev.buf, -2, -1, false)) do
vim.api.nvim_chan_send(term_io, line)
end
vim.api.nvim_win_set_buf(current_win, term_buf)
vim.api.nvim_buf_delete(ev.buf, { force = true } )
vim.schedule(setCursor)
end
})
end
# ...
scrollback_pager nvim -u NONE -R -M -c 'lua require("kitty+page")(INPUT_LINE_NUMBER, CURSOR_LINE, CURSOR_COLUMN)' -
# ...
@mikesmithgh
Copy link

This works great, very nice solution! I'm curious, is term_io = false intentional? If so, what does that do?

@galaxia4Eva
Copy link
Author

@mikesmithgh it's, probably, an artifact from the previous version where term_io was a global variable. Good find! Thank you!

@jackielii
Copy link

@mikesmithgh thanks for the snippet! I tried to follow the original thread and get the set cursor position. I just couldn't get it to work: if the lines are within the number of lines of the window, it works. Otherwise it just reports cursor position outside of buffer...

@galaxia4Eva
Copy link
Author

Dear @jackielii,

From my observations, kitty sometimes replaces INPUT_LINE_NUMBER, CURSOR_LINE, CURSOR_COLUMN with not incorrect values when there was output to stderr in one of the scripts (kitty and fish shell on MacBook)

Maybe there's a more precise way that would also account for stderr lines, but I'm not aware of it.

@galaxia4Eva
Copy link
Author

@mikesmithgh @jackielii @SmartFinn @Ssnnee

I have updated kitty+page.lua

now, while still problematic with codepages that take more bytes that display length, it should place cursor properly. Pay attention to detail:

  vim.api.nvim_create_autocmd('ModeChanged', {
    group = group,
    buffer = term_buf,
    callback = function()
      local mode = vim.fn.mode()
      if mode == 't' then
        vim.cmd.stopinsert()
        vim.schedule(setCursor)
      end
    end,
  })

maybe you would like to remove vim.schedule(setCursor) on ModeChanged for *:t

@sohanglal
Copy link

Error detected while processing command line:
E5108: Error executing lua vim/_options.lua:0: E474: Invalid argument
stack traceback:
        [C]: in function 'nvim_set_option_value'
        vim/_options.lua: in function '_set'
        vim/_options.lua: in function '__newindex'
        /home/sl/.config/nvim/lua/kitty+page.lua:17: in function </home/sl/.config/nvim/lua/kitty+page.lua
:4>
        [string ":lua"]:1: in main chunk
Press ENTER or type command to continue

This error sometimes occurs when the output of the scollback buffer becomes rather large?! I don't know what is causing this. It seems to work great most of the time
Any pointers would be helpful thanks!

@sohanglal
Copy link

Solved it by handling the error when it occurs. I am using fish shell. This is the code:

return function(INPUT_LINE_NUMBER, CURSOR_LINE, CURSOR_COLUMN)
  print('kitty sent:', INPUT_LINE_NUMBER, CURSOR_LINE, CURSOR_COLUMN)

local function setOptions()
  vim.opt.encoding='utf-8'
  vim.opt.clipboard = 'unnamedplus'
  vim.opt.compatible = false
  vim.opt.number = false
  vim.opt.relativenumber = false
  vim.opt.termguicolors = true
  vim.opt.showmode = false
  vim.opt.ruler = false
  vim.opt.laststatus = 0
  vim.o.cmdheight = 0
  vim.opt.showcmd = false
  vim.opt.scrollback = INPUT_LINE_NUMBER + CURSOR_LINE
end
 -- Use pcall to execute setOptions and catch any errors
 local success, errorMessage = pcall(setOptions)

 -- If an error occurred, substitute INPUT_LINE_NUMBER, CURSOR_LINE, CURSOR_COLUMN with 0,0,0
 if not success then
    -- print("Error setting options:", errorMessage)
    INPUT_LINE_NUMBER, CURSOR_LINE, CURSOR_COLUMN = 0, 0, 0
 end
  local term_buf = vim.api.nvim_create_buf(true, false);
  local term_io = vim.api.nvim_open_term(term_buf, {})
  vim.api.nvim_buf_set_keymap(term_buf, 'n', 'i', '<Cmd>q<CR>', { })
  vim.api.nvim_buf_set_keymap(term_buf, 'n', 'q', '<Nop>', { })
  -- vim.api.nvim_buf_set_keymap(term_buf, 'n', '<ESC>', '<Cmd>q<CR>', { })
  local group = vim.api.nvim_create_augroup('kitty+page', {})

  local setCursor = function()
    vim.api.nvim_feedkeys(tostring(INPUT_LINE_NUMBER) .. [[ggzt]], 'n', true)
    local line = vim.api.nvim_buf_line_count(term_buf)
    if (CURSOR_LINE <= line) then
      line = CURSOR_LINE
    end
    vim.api.nvim_feedkeys(tostring(line - 1) .. [[j]], 'n', true)
    vim.api.nvim_feedkeys([[0]], 'n', true)
    vim.api.nvim_feedkeys(tostring(CURSOR_COLUMN - 1) .. [[l]], 'n', true)
  end

  vim.api.nvim_create_autocmd('ModeChanged', {
    group = group,
    buffer = term_buf,
    callback = function()
      local mode = vim.fn.mode()
      if mode == 't' then
        vim.cmd.stopinsert()
      end
    end,
  })

  vim.api.nvim_create_autocmd('VimEnter', {
    group = group,
    pattern = '*',
    once = true,
    callback = function(ev)
        local current_win = vim.fn.win_getid()
        for _, line in ipairs(vim.api.nvim_buf_get_lines(ev.buf, 0, -2, false)) do
          vim.api.nvim_chan_send(term_io, line)
          vim.api.nvim_chan_send(term_io, '\r\n')
        end
        for _, line in ipairs(vim.api.nvim_buf_get_lines(ev.buf, -2, -1, false)) do
          vim.api.nvim_chan_send(term_io, line)
        end
        vim.api.nvim_win_set_buf(current_win, term_buf)
        vim.api.nvim_buf_delete(ev.buf, { force = true } )
        vim.schedule(setCursor)
    end
  })
end

@mikesmithgh
Copy link

FYI If anyone is interested. I developed the plugin kitty-scrollback.nvim to navigate your Kitty scrollback buffer to quickly search, copy, and execute commands in Neovim. Feel free to check it out 😺!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment