Luke Smith has a great video about a script he made with a guy called
Jaywalker. It lets you copy the output from commands you have run in the
suckless terminal (st
) by selecting it in dmenu
.
Since I already use Luke’s dropdown tmux
terminal 99% of the time (see
ddspawn) I started thinking about how to achieve the same thing with tmux=.
The benefits being that it would work in any terminal emulator. I also want to
use fzf
instead of dmenu
.
People in the comments had some ideas, like running tee
:
| tee >(xclip -selection clipboard)"
It could be a convenient alias. The downside for me is that I don’t really plan ahead that I want to copy a command’s output. And you can’t know in advance if the output is surprising.
urxvt
got print-pipe:
URxvt*print-pipe: cat > $HOME/$(echo urxvt.dump.$(date +'%Y%M%d%H%m%S'))
But I still prefer to use tmux
since I can use it in any terminal. I also
enjoy it’s API compared to URXvt.
My idea is to use tmux capture-pane
. To print the visible contents of the
last visited pane:
tmux capture-pane -p
You got the -t
parameter to specify a session name or pane ID (echo $TMUX_PANE
in that case). -S
controls how many lines of the scrollback
buffer to get. -S -100
gives you the last 100 lines. If you want everything,
you should set -S
to the the same value as history-limit
in the tmux
config file. I did not investigate what part of this code is st
specific, so
let’s just try something like this:
tmpfile=$(mktemp /tmp/st-cmd-output.XXXXXX)
tmux capture-pane -p -S -1000 > "$tmpfile"
trap 'rm "$tmpfile"' 0 1 15
sed -n "w $tmpfile"
ps1="$(grep "\S" "$tmpfile" | tail -n 1 | cut -d' ' -f1)"
chosen="$(grep -F "$ps1" "$tmpfile" | sed '$ d' | tac | dmenu -p "Copy which command's output?" -i -l 10 | sed 's/[^^]/[&]/g; s/\^/\\^/g')"
eps1="$(echo "$ps1" | sed 's/[^^]/[&]/g; s/\^/\\^/g')"
- Use fzf - cross-compatible with Mac and whatever
For times I just want to browse around and copy different stuff using Vim
movements, I found a simple way to get the contents into a Emacs temp buffer:
(defun tmux-capture-pane()
(interactive)
(with-output-to-temp-buffer "*tmux-capture-pane*"
(shell-command "tmux capture-pane -p"
"*tmux-capture-pane*"
"*Messages*")
(pop-to-buffer "*tmux-capture-pane*")))
- Mention ob-tmux
- Mention the tao of tmux
I have started to rewrite the matching using regex:
import re
command = re.escape('[const@main]~% lsblk')
output = r'.*?'
prompt = re.escape('[const@main]')
# Notice the capture group around "output"
pattern = r'{command}\n({output}){prompt}'.format(command=command, output=output, prompt=prompt)
match = re.search(pattern, cap, re.MULTILINE|re.DOTALL)
There’s sed
:
sed -n '/BEGIN/,/END/p' tmux.txt
And awk
:
awk '/StartPattern/,/EndPattern/' FileName
Seems like you have to escape a bunch of stuff though.
I have no idea what sed -n "w $tmpfile"
does. On my system it deletes the
contents of the file.