Terminal hacks: Async paging and getting text out fast
1. The Async pop-out Pager
I have a requirement which comes up often, leading to some non-smooth workflows. You need to view the output of the last command in a non-blocking manner to run the next command.
For example:
- You have searched for packages using apt or dnf and now want to install a few of them.
- You opened the man page to see some flags, closed it to run the command and realized that you need to check up another flag etc.
The normal solution to this problem is one of the following:
- Scroll up and look for the value, scroll down and enter it in.
- Open another terminal tab and move back-forth.
- Open another tmux/screen window and move back-forth.
- Re-run the two commands back and forth.
None of these are efficient and more importantly, use the full real-estate of the screen as promised by tiliing window managers. For anyone using twms, the best option is to have the info in a separate window managed by the twm, not a tab or worse. Use the twm - why waste it and go to another embedded layer - the terminal emulator or the multiplexor.
So, what we need is a non-blocking external pager, the inverse of in-place, blocking pagers like less or more.
The solution is simple, depending on which external program you wish to use.
- Text editors like gedit or leafpad.
- Custom programs like trowser.py (not that great), or write your own.
- Existing editor (doesn't work if your editor is open on a different window/workspace). Opening a full editor is usually not fast enough.
- Emacsclient - opening a new frame is blazing fast.
I use a script that looks like the following, called e
:
#!/usr/bin/env bash TMP="$(mktemp /tmp/emacs-stdin-XXX)" cat >"$TMP" | emacsclient -cn "$TMP"
which simply redirects the ouput of the pipeline into a file and opens it using a new emacs frame. Note: such a trick is required since emacs does not have the ability to directly open stdin for some reason.
This is, of course, a manual process. So I need to simply append "| e" to my command to get it spawned out into its own window.
The other option to use this seamlessly is to set export PAGER="e"
. This also directly now opens a new emacs frame for commands like less or man!
Sometimes the output contains ANSI escape codes (used for formatting text in the terminal), but emacs can render those with the following command:
(ansi-color-apply-on-region (point-min) (point-max))
I think this workflow can definitely be improved further, but I will stick to this for a few months and see how it goes.
2. Faster Text Exfilteration
Copy-pasting stuff out of the terminal is one thing, but what are alternatives that can make this faster? Here, I talk about the options one has if using the suckless terminal st.
2.1. st's iofile option
St allows setting an iofile using the flag -o
which will then capture all text from the terminal into the file. This works similar to the script
command or asciinema, if you have used these tools, except it captures everything from the terminal, all the time.
By default, it captures everything, this can be toggled with Ctrl-Print
command. Otherwise, using Shift-Print
captures all the screen (which seems to be everything from the beginning since I am using the scrollback patch) into the file. The better option seems to be Print
which prints just the selected text.
2.2. The externalpipe patch for st
The externalpipe patch for st can be used to some interesting effects. I only got to know about this from Luke Smith's video on st. Specifically, see this chapter where he sets up a shortcut to copy the output of a previously run command from the local history - this uses externalpipe with a custom script that can be found here.
This can be used as the starting point for some intersting hacks, I am sure.