Hi,
I've recently discovered Kitty and I really like it and I'm considering switching to it from URxvt. There's one feature, though, that I use quite often and it seems missing from Kitty. It's toggling alternate screen. E.g. when you are inside vim editor and want to temporarily look 'behind' it for the previous screen output, or the other way round, when you want to see screen output from a closed vim window.
Is there a way to map a shortcut to switch to alternate screen?
It's possible to do in URrxvt with:
URxvt.keysym.M-S-A: command:\033[?47h
URxvt.keysym.M-S-Z: command:\033[?47l
URxvt.keysym.M-S-X: eval:$self->scr_change_screen(not $self->current_screen())
or for XTerm using:
*VT100*translations: #override \n\
Alt Shift <KeyPress> a: set-altscreen(on) \n\
Alt Shift <KeyPress> z: set-altscreen(off) \n\
Alt Shift <KeyPress> x: set-altscreen(toggle) \n\
I've tried a few different combinations for Kitty, but I couldn't find anything that would work. I was expecting this to work:
map ctrl+alt+z send_text all \033[?1049h
map ctrl+alt+x send_text all \033[?1049l
If you want to look behind vim, simply use ctrl-z it works in all terminals and doesn't require any special setup. And it does not have the potential to break your screen if vim decides to write something to the terminal while you are peeking behind it.
Similarly if you want to switch to the alternate screen from the main screen use
tput smcup
Note however that if you entered the main screen by using ctrl-z use fg to get back to vim instead.
Or even better, make your ctrl-z toggle between "hide" and "restore" using something like this.
Oh and just to note, using send_text will not work for this. alternate screen changing happens when the child program sends the escape code to kitty. send_text sends the escape code from kitty to the child program.
Thanks for the replies, I'm well aware of the ^Z and fg, but those are not exactly equivalent as toggling alternate screen. E.g. Sometimes I want toggle alternate screen to 'save' the contents of the screen, so later, I can refer to it by quickly toggling it with Alt-Shift-x. This is much quicker than running tput smcup and then tput rmcup commands.
Additionally, I prefer to toggle alternate screen using terminal shortcuts as it's quicker than typing '^Z' and then 'fg' and also works on remote SSH connections without setting up shell in advance.
@kovidgoyal Will sending of control sequences to kitty work using a remote control protocol (by setting up allow_remote_control in the config) ?
So map alt+shift+x to send_text all 'tput rmcup\r' and similar, then you dont need to type anything. Toggling screens without the program you are running being aware of it is a really bad practice, it can lead to screen corruption. No terminal program expects the screen it is writing to to change at arbitrary points during its execution.
And no remote control will not help, it has no mechanism to write control codes from arbitrary child program to kitty.
Toggling screens without the program you are running being aware of it is a really bad practice, it can lead to screen corruption.
I know what you mean. However, my shell really doesn't mind me changing to alternate screen at all. For programs like 'vim' or 'less', even if you mess up the screen, just hitting CTRL-L will refresh the screen back to normal.
On the other hand, XTerm finds the feature quite important and consider the lack of it in other terminals a bug.
From XTerm documentation: http://invisible-island.net/xterm/xterm.faq.html#xterm_tite
Since patch #90 in 1998 xterm allows you (with a popup menu entry designed to exploit this behavior) to switch the display back to the alternate screen to select text from it, to paste into the normal screen. You can also set or clear the titeInhibit resource using another popup menu entry (Enable Alternate Screen Switching).
Most other terminal emulators implement only half of the feature. They recognize the control sequence, but do not provide the ability to change it at runtime, e.g., using a menu entry. Like any other half-done implementation, that is a bug which should be reported to the developers of those programs.
Sure but then that means that every program has to implement some manual redraw function to deal with the possibility that the screen could be arbitrarily corrupted at any time. This is a really bad idea, regardless of what the XTerm maintainer thinks. On what planet is deliberately causing undefined behavior ever a good idea?
And what's your actual use case anyway? You want to copy stuff from whichever screen is hidden? A much better implementation would be to have a function like the existing one for viewing the scrollback buffer in a separate window or an overlay, except that you do it with the contents of the alternate screen instead.
Just for completeness, here is how you would do it:
map f1 pipe @ansi_alternate overlay less +G -R
This will show you the contents of the hidden screen in an overlay window over the current window within less. Press q to close the overlay window when you are done doing whatever you need to do.
And this technique has no risk of screen corruption.
Just curious, is it possible to make a shortcut that will open new OS window (not overlay) with this content? This would be quite cool, I could put the two windows side by side if I need to often refer to the hidden screen.
map kitty_mod+y new_os_window @ansi less +G -R
This shows the current screen in a new window, so I assumed this would work, but it doesn't:
map kitty_mod+y new_os_window @ansi_overlay less +G -R
What is the correct syntax? 🙂
There's no new_os_window there is window and tab and overlay. I suppose os_window could be added as well.
Yes, that would be awesome — want to keep managing windows with i3 😉 Thanks!
One more question to this, with the mapping map f1 pipe @ansi_alternate os_window less +G -R I can now look behind text editor, but I cannot scroll up to see the scrollback — only one page of contents was piped to less. Is it possible to pipe everything?
No there is no way to look at scrollback in the alternate screen. Just suspend your editor, pipe and fg if you need to do that.
I had five minutes, so https://github.com/kovidgoyal/kitty/commit/15f534a8f9d44d9873b07d8309db498aca7c6cd1
Woow, thanks!