Navigate your Kitty scrollback buffer to quickly search, copy, and execute commands in Neovim.
[!NOTE]
👀 Check out Advanced Configuration for more demos! 🎥
Check out my lighting talk on Dec 8th at Neovim Conf 2023 about kitty-scrollback.nvim!
[!IMPORTANT]
v2.0.0 has breaking changes and requires steps to properly migrate from v1.X.X.You can ignore this section if you have not previously installed any version of kitty-scrollback.nvim
If you are using the lazy.nvim or packer.nvim package manager, then
add the custom User
event KittyScrollbackLaunch
as a trigger for lazy loading.
See Installation for additional details.
event = { 'User KittyScrollbackLaunch' }
Regenerate default Kitten mappings and add to kitty.conf
nvim --headless +'KittyScrollbackGenerateKittens' +'set nonumber' +'set norelativenumber' +'%print' +'quit!' 2>&1
Remove previous kitty-scrollback.nvim Kitten mappings in kitty.conf
The default mapping keys changed from ctrl+shift
to kitty_mod
. The default values for kitty_mod
in Kitty is ctrl+shift
.
kitty_mod
of ctrl+shift
, then no change is needed.kitty_mod
, then you should correct any potential mapping conflicts that may occur
now that kitty-scrollback.nvim
is using kitty_mod
.Migrate any customized configurations to the new format
--config-file
yourconfigfile.lua
. Instead,
move the contents of yourconfigfile.lua
to an entry in the configuration passed to the kitty-scrollback.nvim setup function.require('kitty-scrollback').setup({
yourconfig = function()
...
end,
})
Update your Kitten to use the name of the configuration defined in the setup function. In this example,
--config-file yourconfigfile.lua
changes to --config yourconfig
[!NOTE]
The configuration to view the last command output now references a builtin configuration instead of a file. The new configuration can be viewed by running:KittyScrollbackGenerateKittens
.
Old configuration
kitty.conf
references the configuration file get_text_last_cmd_output.lua
# Browse output of the last shell command in nvim
map kitty_mod+g kitty_scrollback_nvim --config-file get_text_last_cmd_output.lua
-- get_text_last_cmd_output.lua
local M = {}
M.config = function()
return {
kitty_get_text = {
extent = 'last_visited_cmd_output',
ansi = true,
},
}
end
return M
kitty.conf
references the builtin configuration name ksb_builtin_last_cmd_output
# Browse output of the last shell command in nvim
map kitty_mod+g kitty_scrollback_nvim --config ksb_builtin_last_cmd_output
require('kitty-scrollback').setup({
ksb_builtin_last_cmd_output = function()
return {
kitty_get_text = {
extent = 'last_visited_cmd_output',
ansi = true,
},
}
end
})
<C-S-h>
)?{pattern}<CR>
v
and select desired text<leader>y
)kitty-scrollback.nvim
automatically closes and returns to Kitty<C-S-h>
)yy
)i
or a
) to open an empty floating window (similar to <C-x><C-e>
in Bash)kitty-scrollback.nvim
opens a floating window in Neovim with the contents of the selection<C-CR>
)kitty-scrollback.nvim
automatically closes and executes the command in Kitty<C-S-h>
)yy
)kitty-scrollback.nvim
opens a floating window in Neovim with the contents of the selection<ESC>
) and reopen (yank or enter Insert mode) the floating window multiple times<S-CR>
or :w
)kitty-scrollback.nvim
automatically closes and paste the contents in Kitty for further editingTo quickly test this plugin without changing your configuration run the command:
sh -c "$(curl -s https://raw.githubusercontent.com/mikesmithgh/kitty-scrollback.nvim/main/scripts/mini.sh)"
[!NOTE]
It is good practice to first read the script before runningsh -c
directly from the web
{
'mikesmithgh/kitty-scrollback.nvim',
enabled = true,
lazy = true,
cmd = { 'KittyScrollbackGenerateKittens', 'KittyScrollbackCheckHealth' },
event = { 'User KittyScrollbackLaunch' },
-- version = '*', -- latest stable version, may have breaking changes if major version changed
-- version = '^2.0.0', -- pin major version, include fixes and features that do not have breaking changes
config = function()
require('kitty-scrollback').setup()
end,
}
use({
'mikesmithgh/kitty-scrollback.nvim',
disable = false,
opt = true,
cmd = { 'KittyScrollbackGenerateKittens', 'KittyScrollbackCheckHealth' },
event = { 'User KittyScrollbackLaunch' },
-- tag = '*', -- latest stable version, may have breaking changes if major version changed
-- tag = 'v2.0.0', -- pin specific tag
config = function()
require('kitty-scrollback').setup()
end,
})
mkdir -p "$HOME/.local/share/nvim/site/pack/mikesmithgh/start/"
cd $HOME/.local/share/nvim/site/pack/mikesmithgh/start
git clone git@github.com:mikesmithgh/kitty-scrollback.nvim.git
nvim -u NONE -c "helptags kitty-scrollback.nvim/doc" -c q
mkdir -p "$HOME/.config/nvim"
echo "require('kitty-scrollback').setup()" >> "$HOME/.config/nvim/init.lua"
[!NOTE]
The Advanced Configuration section of the Wiki provides detailed demos of each configuration option.
The following steps outline how to properly configure kitty.conf
yes
, socket
, socket-only
kitty-scrollback.nvim
is the only application controlling Kitty then socket-only
is preferred to continue denying TTY requests.listen_on unix:/tmp/kitty
shell_integration
to enabled
no-prompt-mark
kitty.conf
nvim --headless +'KittyScrollbackGenerateKittens' +'set nonumber' +'set norelativenumber' +'%print' +'quit!' 2>&1
nvim +'KittyScrollbackCheckHealth'
ERROR
or WARNINGS
reported during the healthcheckkitty_mod
is a special modifier key alias for default shortcuts. You can change the value of this option to
alter all default shortcuts that use kitty_mod
. See Kitty documentation #opt-kitty.kitty_mod.
The default value of kitty_mod
is ctrl+shift
. In this example, kitty_mod+h
represents ctrl+shift+h
.
allow_remote_control yes
listen_on unix:/tmp/kitty
shell_integration enabled
# kitty-scrollback.nvim Kitten alias
action_alias kitty_scrollback_nvim kitten /Users/mike/gitrepos/kitty-scrollback.nvim/python/kitty_scrollback_nvim.py
# Browse scrollback buffer in nvim
map kitty_mod+h kitty_scrollback_nvim
# Browse output of the last shell command in nvim
map kitty_mod+g kitty_scrollback_nvim --config ksb_builtin_last_cmd_output
# Show clicked command output in nvim
mouse_map kitty_mod+right press ungrabbed combine : mouse_select_command_output : kitty_scrollback_nvim --config ksb_builtin_last_visited_cmd_output
Arguments that can be passed to the kitty_scrollback_nvim
Kitten defined in kitty.conf.
Argument | Description |
---|---|
--config |
The name of the kitty-scrollback.nvim plugin configuration. The configuration can be defined during plugin setup (i.e., require('kitty-scrollback').setup({ ... }) ). |
--no-nvim-args |
Do not provide any arguments to the Neovim instance that displays the scrollback buffer. The default arguments passed to Neovim are --clean --noplugin -n . This flag removes those options. |
--nvim-args |
All arguments after this flag are passed to the Neovim instance that displays the scrollback buffer. This must be the last of the kitty-scrollback.nvim Kitten arguments that are configured. Otherwise, you may unintentionally send the wrong arguments to Neovim. The default arguments passed to Neovim are --clean --noplugin -n . This flag removes those options. |
--env |
Environment variable that is passed to the Neovim instance that displays the scrollback buffer. Format is --env var_name=var_value . You may specify multiple config files that will merge all configuration options. Useful for setting NVIM_APPNAME |
--cwd |
The current working directory of the Neovim instance that displays the scrollback buffer. |
kitty-scrollback.nvim
configuration fileOptions | Type | Description |
---|---|---|
callbacks | KsbCallbacks? |
fire and forget callback functions |
callbacks.after_setup | fun(kitty_data: KsbKittyData, opts: KsbOpts)? |
callback executed after initializing kitty-scrollback.nvim |
callbacks.after_launch | fun(kitty_data: KsbKittyData, opts: KsbOpts)? |
callback executed after launch started to process the scrollback buffer |
callbacks.after_ready | fun(kitty_data: KsbKittyData, opts: KsbOpts)? |
callback executed after scrollback buffer is loaded and cursor is positioned |
keymaps_enabled | boolean? |
if true, enabled all default keymaps |
restore_options | boolean? |
if true, restore options that were modified while processing the scrollback buffer |
highlight_overrides | KsbHighlights? |
kitty-scrollback.nvim highlight overrides |
highlight_overrides.KittyScrollbackNvimNormal | table? |
status window Normal highlight group |
highlight_overrides.KittyScrollbackNvimHeart | table? |
status window heart icon highlight group |
highlight_overrides.KittyScrollbackNvimSpinner | table? |
status window spinner icon highlight group |
highlight_overrides.KittyScrollbackNvimReady | table? |
status window ready icon highlight group |
highlight_overrides.KittyScrollbackNvimKitty | table? |
status window kitty icon highlight group |
highlight_overrides.KittyScrollbackNvimVim | table? |
status window vim icon highlight group |
highlight_overrides.KittyScrollbackNvimPasteWinNormal | table? |
paste window Normal highlight group |
highlight_overrides.KittyScrollbackNvimPasteWinFloatBorder | table? |
paste window FloatBorder highlight group |
highlight_overrides.KittyScrollbackNvimPasteWinFloatTitle | table? |
paste window FloatTitle highlight group |
highlight_overrides.KittyScrollbackNvimVisual | table? |
scrollback buffer window visual selection highlight group |
status_window | KsbStatusWindowOpts? |
options for status window indicating that kitty-scrollback.nvim is ready |
status_window.enabled | boolean |
If true, show status window in upper right corner of the screen |
status_window.style_simple | boolean |
If true, use plaintext instead of nerd font icons |
status_window.autoclose | boolean |
If true, close the status window after kitty-scrollback.nvim is ready |
status_window.show_timer | boolean |
If true, show a timer in the status window while kitty-scrollback.nvim is loading |
status_window.icons | KsbStatusWindowIcons? |
Icons displayed in the status window |
status_window.icons.kitty | string |
kitty status window icon |
status_window.icons.heart | string |
heart string heart status window icon |
status_window.icons.nvim | string |
nvim status window icon |
paste_window | KsbPasteWindowOpts? |
options for paste window that sends commands to Kitty |
paste_window.highlight_as_normal_win | fun(): boolean? |
If function returns true, use Normal highlight group. If false, use NormalFloat |
paste_window.filetype | string? |
The filetype of the paste window |
paste_window.hide_footer | boolean? |
If true, hide mappings in the footer when the paste window is initially opened |
paste_window.winblend | integer? |
The winblend setting of the window, see :help winblend |
paste_window.winopts_overrides | fun(paste_winopts: KsbWinOpts): table<string,any>? |
Paste float window overrides, see nvim_open_win() for configuration |
paste_window.footer_winopts_overrides | fun(footer_winopts: KsbWinOpts, paste_winopts: KsbWinOpts): table<string,any>? |
Paste footer window overrides, see nvim_open_win() for configuration |
paste_window.yank_register | string? |
register used during yanks to paste window, see :h registers |
paste_window.yank_register_enabled | boolean? |
If true, the yank_register copies content to the paste window. If false, disable yank to paste window |
kitty_get_text | KsbKittyGetText? |
options passed to get-text when reading scrollback buffer, see kitty @ get-text --help |
kitty_get_text.ansi | boolean |
If true, the text will include the ANSI formatting escape codes for colors, bold, italic, etc. |
kitty_get_text.clear_selection | boolean |
If true, clear the selection in the matched window, if any. |
kitty_get_text.extent | string |
What text to get. The default of screen means all text currently on the screen. all means all the screen+scrollback and selection means the currently selected text. first_cmd_output_on_screen means the output of the first command that was run in the window on screen. last_cmd_output means the output of the last command that was run in the window. last_visited_cmd_output means the first command output below the last scrolled position via scroll_to_prompt. last_non_empty_output is the output from the last command run in the window that had some non empty output. The last four require shell_integration to be enabled. Choices: screen , all , first_cmd_output_on_screen , last_cmd_output , last_non_empty_output , last_visited_cmd_output , selection |
checkhealth | boolean? |
if true execute :checkhealth kitty-scrollback and skip setup |
visual_selection_highlight_mode | string? |
Sets the mode for coloring the Visual highlight group in the scrollback buffer window. darken uses a darkened version of the Normal highlight group to improve readability. kitty uses the colors defined for selection_foreground and selection_background in your Kitty configuration. nvim uses the default colors defined in the Visual highlight group. reverse reverses the foreground and background colors of the visual selection. |
By default, kitty-scrollback.nvim
uses Nerd Fonts in the status window. If you would like to
use ASCII instead, set the option status_window.style_simple
to true
.
[!NOTE]
Nerd Fonts release v3.1.0 added the Neovim icon! See ksb_example_status_win_nvim in Advanced Configuration for a demo and example configuration.The following example configuration sets a global kitty-scrollback.nvim configuration to use the neovim icon instead of vim icon
kitty.conf
action_alias kitty_scrollback_nvim kitten /Users/mike/gitrepos/kitty-scrollback.nvim/python/kitty_scrollback_nvim.py --nvim-args -u kitty-scrollback-nvim-kitten-config.lua
kitty-scrollback-nvim-kitten-config.lua
-- I am still working on a better experience for configuring kitty-scrollback.nvim, but this works for now vim.opt.runtimepath:append(vim.fn.stdpath('data') .. '/lazy/kitty-scrollback.nvim') -- assuming lazy.nvim setup require('kitty-scrollback').setup({ global = function() return { status_window = { icons = { nvim = '', }, }, } end, })
Status window with Nerd Fonts v3.1.0+ opts.status_window.icons.nvim = '' opts.status_window.style_simple = false
Status window with Nerd Fonts < v3.1.0 opts.status_window.icons.nvim = '' opts.status_window.style_simple = false
Status window with ASCII text opts.status_window.style_simple = true
The API is available via the kitty-scrollback.api
module. e.g., require('kitty-scrollback.api')
Command | API | Description |
---|---|---|
:KittyScrollbackGenerateKittens[!] [generate_modes] |
generate_kittens(boolean?, table<string|'commands'|'maps'>)? |
Generate Kitten commands used as reference for configuring kitty.conf |
:KittyScrollbackCheckHealth |
checkhealth() |
Run :checkhealth kitty-scrollback in the context of Kitty |
The API is available via the kitty-scrollback.api
module. e.g., require('kitty-scrollback.api')
<Plug> Mapping |
Default Mapping | Mode | API | Description |
---|---|---|---|---|
<Plug>(KsbExecuteCmd) |
<C-CR> |
n,i | execute_command() |
Execute the contents of the paste window in Kitty |
<Plug>(KsbPasteCmd) |
<S-CR> |
n,i | paste_command() |
Paste the contents of the paste window to Kitty without executing |
<Plug>(KsbToggleFooter) |
g? |
n | toggle_footer() |
Toggle the paste window footer that displays mappings |
<Plug>(KsbCloseOrQuitAll) |
<Esc> |
n | close_or_quit_all() |
If the current buffer is the paste buffer, then close the window. Otherwise quit Neovim |
<Plug>(KsbQuitAll) |
<C-c> |
n,i,t | quit_all() |
Quit Neovim |
<Plug>(KsbVisualYankLine) |
<Leader>Y |
v | Maps to "+Y |
|
<Plug>(KsbVisualYank) |
<Leader>y |
v | Maps to "+y |
|
<Plug>(KsbNormalYankEnd) |
<Leader>Y |
n | Maps to "+y$ |
|
<Plug>(KsbNormalYank) |
<Leader>y |
n | Maps to "+y |
|
<Plug>(KsbNormalYankLine) |
<Leader>yy |
n | Maps to "+yy |
The following plugins are nice additions to your Neovim and Kitty setup.
set title
escape code to hide the [Process exited]
messagelisten_on unix:/tmp/mykitty
mini.sh
and inspiration/reference for displaying keymapping footerSCREAMING_SNAKE_CASE
scrollback_pager