My most used example for this would be to allow opening the scrollback buffer in vim, but there other programs would be situationally useful too
I think there are a couple of paths that could be taken to achieve this:
Build on the APIs from https://github.com/wez/wezterm/issues/225 so that you can define an action that will capture the scrollback into a file and spawn a program in a new window. There are some details to work out around the lifetime and cleanup of that file, as well as the lifetime of the callback itself (there are some threading/blocking concerns).
Expand the mux protocol and add a wezterm cli get-scrollback --tabid X command that will return the scrollback for the specified tab (you can use wezterm cli list today to enumerate windows/tabs in the mux). In this strategy you'd probably still want to use the foundation from https://github.com/wez/wezterm/issues/225 so that you can obtain the tabid and then pass that to the command that you want to spawn. The advantage here is that wezterm doesn't have as much complexity around managing the lifetime of the file holding the scrollback; it forces it all into the called program and that runs as any other spawn program.
seems like it would be a little easier for the enduser. As to life-time and cleanup.... I kinda feel like wezterm can just punt on that? As if the scrollback buffer is dumped out into /tmp, the clean will happen next boot (which seems fine to me). I have no idea about mac or windows - but I guess they have some equivalent mechanism?
Is there any contract on the order of the list in wezterm cli list? As in, if the order was in the order of most recently used (which I think the mux server could know...) then that would make it easier for the enduser?
Ultimately, what I would want if just a keybinding to dump the current wezterm tab/window out on a keybinding. So whatever wezterm could do to make that more convenient would seem nice. And (without having put too much thought into it...) it seems like wezterm should be able to know what the current active window. Maybe something like wezterm cli get-scrollback --tabid current?
Having said all this I don't want to come off too presumptuous. I鈥檓 pretty sure I can make either 1 or 2 work and were it me, all things being equal, I guess I'd go with the simplest solution codewise.
master now allows this:
local wezterm = require 'wezterm';
local io = require 'io';
local os = require 'os';
wezterm.on("trigger-vim-with-scrollback", function(window, pane)
-- Retrieve the current viewport's text.
-- Pass an optional number of lines (eg: 2000) to retrieve
-- that number of lines starting from the bottom of the viewport
local scrollback = pane:get_lines_as_text();
-- Create a temporary file to pass to vim
local name = os.tmpname();
local f = io.open(name, "w+");
f:write(scrollback);
f:flush();
f:close();
-- Open a new window running vim and tell it to open the file
window:perform_action(wezterm.action{SpawnCommandInNewWindow={
args={"vim", name}}
}, pane)
-- wait "enough" time for vim to read the file before we remove it.
-- The window creation and process spawn are asynchronous
-- wrt. running this script and are not awaitable, so we just pick
-- a number.
wezterm.sleep_ms(1000);
os.remove(name);
end)
return {
keys = {
{key="E", mods="CTRL",
action=wezterm.action{EmitEvent="trigger-vim-with-scrollback"}},
}
}
There's an example of this in the docs: https://wezfurlong.org/wezterm/config/lua/wezterm/on.html#custom-events
Right, just took this for a spin and it looks primo. Thank you Wez!
So one nit with this btw. The following config renders the "parent" wezterm unresponsive
local dump_scrollback_to_file = function(window, pane)
-- Retrieve the current viewport's text.
-- Pass an optional number of lines (eg: 2000) to retrieve
-- that number of lines starting from the bottom of the viewport
local scrollback = pane:get_lines_as_text();
-- Create a temporary file to pass to vim
local name = os.tmpname();
local f = io.open(name, "w+");
f:write(scrollback);
f:flush();
f:close();
return name
end
wezterm.on("trigger-skim-with-scrollback", function(window, pane)
local filename = dump_scrollback_to_file(window, pane)
-- Open a new window running fzf to fuzzy search scrollback
window:perform_action(wezterm.action{SpawnCommandInNewWindow={
args={"fish", "-c", "fzf < " .. filename}}
}, pane)
end)
What happens is the new window launches just fine and fzf launches there too just fine, but once I'm done with fzf (either by selecting something or by CTRL-C-ing it) the parent window becomes unresponsive.
The point of what ^ is trying to do slightly overlaps with scrollback search, but it's a bit different (filtering vs searching)
@sanga hmm, I tried your config and it seems ok to me locally on a linux system. I suspect that something else is contributing to this. Things to try:
RUST_LOG=trace wezterm 2>/tmp/doh.txt, reproduce the issue and attach that file herea few random comments:
enable_wayland = false 2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > perform Print('\u{e0b0}')
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > perform CSI(Sgr(Reset))
2020-10-11T10:55:31.244Z TRACE wezterm_term::terminalstate > print x=30 y=86 cell=Cell { text: "\u{e0b0}", attrs: CellAttributes { attributes: 0, foreground: PaletteIndex(237), background: PaletteIndex(161), hyperlink: None, image: None } }
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > Reset
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > perform CSI(Sgr(Foreground(PaletteIndex(15))))
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > Foreground(PaletteIndex(15))
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > perform CSI(Sgr(Background(PaletteIndex(161))))
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > Background(PaletteIndex(161))
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > perform Print(' ')
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > perform Print('S')
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > perform Print('I')
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > perform Print('G')
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > perform Print('I')
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > perform Print('N')
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > perform Print('T')
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > perform Print(' ')
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > perform CSI(Sgr(Background(PaletteIndex(161))))
2020-10-11T10:55:31.244Z TRACE wezterm_term::terminalstate > print x=31 y=86 cell=Cell { text: " ", attrs: CellAttributes { attributes: 0, foreground: PaletteIndex(15), background: PaletteIndex(161), hyperlink: None, image: None } }
2020-10-11T10:55:31.244Z TRACE wezterm_term::terminalstate > print x=32 y=86 cell=Cell { text: "S", attrs: CellAttributes { attributes: 0, foreground: PaletteIndex(15), background: PaletteIndex(161), hyperlink: None, image: None } }
2020-10-11T10:55:31.244Z TRACE wezterm_term::terminalstate > print x=33 y=86 cell=Cell { text: "I", attrs: CellAttributes { attributes: 0, foreground: PaletteIndex(15), background: PaletteIndex(161), hyperlink: None, image: None } }
2020-10-11T10:55:31.244Z TRACE wezterm_term::terminalstate > print x=34 y=86 cell=Cell { text: "G", attrs: CellAttributes { attributes: 0, foreground: PaletteIndex(15), background: PaletteIndex(161), hyperlink: None, image: None } }
2020-10-11T10:55:31.244Z TRACE wezterm_term::terminalstate > print x=35 y=86 cell=Cell { text: "I", attrs: CellAttributes { attributes: 0, foreground: PaletteIndex(15), background: PaletteIndex(161), hyperlink: None, image: None } }
2020-10-11T10:55:31.244Z TRACE wezterm_term::terminalstate > print x=36 y=86 cell=Cell { text: "N", attrs: CellAttributes { attributes: 0, foreground: PaletteIndex(15), background: PaletteIndex(161), hyperlink: None, image: None } }
2020-10-11T10:55:31.244Z TRACE wezterm_term::terminalstate > print x=37 y=86 cell=Cell { text: "T", attrs: CellAttributes { attributes: 0, foreground: PaletteIndex(15), background: PaletteIndex(161), hyperlink: None, image: None } }
2020-10-11T10:55:31.244Z TRACE wezterm_term::terminalstate > print x=38 y=86 cell=Cell { text: " ", attrs: CellAttributes { attributes: 0, foreground: PaletteIndex(15), background: PaletteIndex(161), hyperlink: None, image: None } }
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > Background(PaletteIndex(161))
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > perform CSI(Sgr(Foreground(PaletteIndex(161))))
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > Foreground(PaletteIndex(161))
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > perform Print('\u{e0b0}')
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > perform CSI(Sgr(Reset))
2020-10-11T10:55:31.244Z TRACE wezterm_term::terminalstate > print x=39 y=86 cell=Cell { text: "\u{e0b0}", attrs: CellAttributes { attributes: 0, foreground: PaletteIndex(161), background: PaletteIndex(161), hyperlink: None, image: None } }
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > Reset
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > perform CSI(Sgr(Foreground(PaletteIndex(15))))
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > Foreground(PaletteIndex(15))
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > perform CSI(Sgr(Background(PaletteIndex(161))))
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > Background(PaletteIndex(161))
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > perform Print(' ')
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > perform Print('$')
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > perform Print(' ')
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > perform CSI(Sgr(Reset))
2020-10-11T10:55:31.244Z TRACE wezterm_term::terminalstate > print x=40 y=86 cell=Cell { text: " ", attrs: CellAttributes { attributes: 0, foreground: PaletteIndex(15), background: PaletteIndex(161), hyperlink: None, image: None } }
2020-10-11T10:55:31.244Z TRACE wezterm_term::terminalstate > print x=41 y=86 cell=Cell { text: "$", attrs: CellAttributes { attributes: 0, foreground: PaletteIndex(15), background: PaletteIndex(161), hyperlink: None, image: None } }
2020-10-11T10:55:31.244Z TRACE wezterm_term::terminalstate > print x=42 y=86 cell=Cell { text: " ", attrs: CellAttributes { attributes: 0, foreground: PaletteIndex(15), background: PaletteIndex(161), hyperlink: None, image: None } }
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > Reset
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > perform CSI(Sgr(Foreground(PaletteIndex(161))))
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > Foreground(PaletteIndex(161))
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > perform Print('\u{e0b0}')
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > perform CSI(Sgr(Reset))
2020-10-11T10:55:31.244Z TRACE wezterm_term::terminalstate > print x=43 y=86 cell=Cell { text: "\u{e0b0}", attrs: CellAttributes { attributes: 0, foreground: PaletteIndex(161), background: Default, hyperlink: None, image: None } }
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > Reset
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > perform Print(' ')
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > perform Control(CarriageReturn)
2020-10-11T10:55:31.244Z TRACE wezterm_term::terminalstate > print x=44 y=86 cell=Cell { text: " ", attrs: CellAttributes { attributes: 0, foreground: Default, background: Default, hyperlink: None, image: None } }
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > perform Control(LineFeed)
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > perform CSI(Sgr(Foreground(PaletteIndex(15))))
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > Foreground(PaletteIndex(15))
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > perform CSI(Sgr(Background(PaletteIndex(161))))
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > Background(PaletteIndex(161))
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > perform Print('$')
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > perform CSI(Sgr(Reset))
2020-10-11T10:55:31.244Z TRACE wezterm_term::terminalstate > print x=0 y=87 cell=Cell { text: "$", attrs: CellAttributes { attributes: 0, foreground: PaletteIndex(15), background: PaletteIndex(161), hyperlink: None, image: None } }
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > Reset
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > perform CSI(Sgr(Foreground(PaletteIndex(161))))
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > Foreground(PaletteIndex(161))
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > perform Print('\u{e0b0}')
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > perform CSI(Sgr(Reset))
2020-10-11T10:55:31.244Z TRACE wezterm_term::terminalstate > print x=1 y=87 cell=Cell { text: "\u{e0b0}", attrs: CellAttributes { attributes: 0, foreground: PaletteIndex(161), background: Default, hyperlink: None, image: None } }
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > Reset
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > perform Print(' ')
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > perform CSI(Edit(EraseInDisplay(EraseToEndOfDisplay)))
2020-10-11T10:55:31.244Z TRACE wezterm_term::terminalstate > print x=2 y=87 cell=Cell { text: " ", attrs: CellAttributes { attributes: 0, foreground: Default, background: Default, hyperlink: None, image: None } }
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > perform CSI(Cursor(Right(53)))
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > perform Print('1')
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > perform Print('.')
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > perform Print('2')
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > perform Print('7')
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > perform Print('9')
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > perform Print('s')
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > perform Control(CarriageReturn)
2020-10-11T10:55:31.244Z TRACE wezterm_term::terminalstate > print x=56 y=87 cell=Cell { text: "1", attrs: CellAttributes { attributes: 0, foreground: Default, background: Default, hyperlink: None, image: None } }
2020-10-11T10:55:31.244Z TRACE wezterm_term::terminalstate > print x=57 y=87 cell=Cell { text: ".", attrs: CellAttributes { attributes: 0, foreground: Default, background: Default, hyperlink: None, image: None } }
2020-10-11T10:55:31.244Z TRACE wezterm_term::terminalstate > print x=58 y=87 cell=Cell { text: "2", attrs: CellAttributes { attributes: 0, foreground: Default, background: Default, hyperlink: None, image: None } }
2020-10-11T10:55:31.244Z TRACE wezterm_term::terminalstate > print x=59 y=87 cell=Cell { text: "7", attrs: CellAttributes { attributes: 0, foreground: Default, background: Default, hyperlink: None, image: None } }
2020-10-11T10:55:31.244Z TRACE wezterm_term::terminalstate > print x=60 y=87 cell=Cell { text: "9", attrs: CellAttributes { attributes: 0, foreground: Default, background: Default, hyperlink: None, image: None } }
2020-10-11T10:55:31.244Z TRACE wezterm_term::terminalstate > print x=61 y=87 cell=Cell { text: "s", attrs: CellAttributes { attributes: 1024, foreground: Default, background: Default, hyperlink: None, image: None } }
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > perform CSI(Cursor(Right(56)))
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > perform Control(CarriageReturn)
2020-10-11T10:55:31.244Z DEBUG wezterm_term::terminalstate > perform CSI(Cursor(Right(3)))
2020-10-11T10:55:31.276Z DEBUG wezterm::font::ftwrap > set_char_size 10 dpi=138
2020-10-11T10:55:31.279Z DEBUG wezterm::gui::termwindow > paint_tab_opengl elapsed=5.446169ms
2020-10-11T10:55:31.280Z DEBUG wezterm::gui::termwindow > paint_tab_opengl elapsed=1.075017ms
2020-10-11T10:55:35.466Z DEBUG wezterm::gui::termwindow > paint_tab_opengl elapsed=3.870082ms
2020-10-11T10:55:35.797Z ERROR mux > read_pty EOF: pane_id 1
2020-10-11T10:55:35.806Z DEBUG wezterm::gui::termwindow > paint_tab_opengl elapsed=12.992921ms
2020-10-11T10:55:35.807Z DEBUG mux > removing pane 1
2020-10-11T10:55:35.807Z DEBUG mux > killing pane 1
2020-10-11T10:55:35.807Z DEBUG mux::localpane > killing process in pane 1
2020-10-11T10:55:35.807Z ERROR mux::localpane > Pane id 1 is_dead
2020-10-11T10:55:35.808Z DEBUG mux > prune_dead_windows: window is now empty
2020-10-11T10:55:35.808Z ERROR mux > tab 1 is dead
2020-10-11T10:55:35.808Z DEBUG mux > remove_tab_internal tab 1
2020-10-11T10:55:35.808Z DEBUG mux > remove_window_internal 1
2020-10-11T10:55:35.808Z DEBUG mux > removing pane 1
2020-10-11T10:55:35.817Z TRACE wezterm::gui::termwindow > Setting focus to false
2020-10-11T10:55:35.817Z TRACE wezterm::gui::termwindow > Setting focus to true
2020-10-11T10:55:35.817Z TRACE wezterm::gui::termwindow > Setting focus to false
2020-10-11T10:55:35.817Z TRACE wezterm::gui::termwindow > Setting focus to true
2020-10-11T10:55:35.817Z TRACE wezterm::gui::termwindow > resize event, current cells: RowsAndCols { rows: 88, cols: 62 }, new dims: Dimensions { pixel_width: 1127, pixel_height: 2135, dpi: 96 }
2020-10-11T10:55:35.817Z DEBUG wezterm::gui::renderstate > compute_vertices 93x88 1127x2135 padding=0 0
2020-10-11T10:55:35.827Z DEBUG wezterm_term::screen > resize screen to 93x88
2020-10-11T10:55:35.828Z DEBUG wezterm_term::screen > resize screen to 93x88
2020-10-11T10:55:35.835Z DEBUG wezterm::gui::termwindow > paint_tab_opengl elapsed=6.779261ms
Hopefully, that is of use to you. That full file is 192mb. I don't particularly like posting logs to the internet from my work machine without vetting them first and 192 meg is a bit much to vet...
I think this does sound like a wayland related issue.
Using weston under X11 I could produce a broken keyboard modifier state with CTRL+SHIFT+N creating a new window. That would leave CTRL+SHIFT active in the original window and lead to surprising and broken behavior. dedfc4513b60fa1cd2cf04da94f81b992b304b83 addresses that, but in my exposure to wayland, there's a lot of variance depending on the compositor implementation so I'm not 100% sure if that is what you encountered, especially as you mentioned some resize interactions!
Please try a build of dedfc4513b60fa1cd2cf04da94f81b992b304b83 or later (that rev should show up in the "nightly" downloads in an hour or two).
I'd be interested to know:
I don't think there is especially interesting wayland related trace logging present in the code today, so that big log file probably isn't useful right now.
Just checked it out now. It looks fixed to me now - thanks! For the record, you guessed correctly, I'm running Sway here.
Most helpful comment
master now allows this: