WezTerm: Easily copy text or send notification to local machine (even when connected via SSH)

Ever had a long-running command in terminal but forget to check back on it?

I’ve used do_long_think; notify-send "thing finished" in the past to help. I can do other stuff then be interrupted when it finishes.

Annoyingly that doesn’t work if you’re over an SSH connection, in a DevContainer or using Codespaces.

To fix that up I’m now using WezTerm’s user-var-changed event, and it’s sooo good!

Any window in WezTerm which writes out the user var escape sequence triggers a function in the WezTerm lua config. For example 👇 will send name: foo value: bar

printf "\033]1337;SetUserVar=%s=%s\007" foo echo -n bar | base64 -w 0`

Note: -w 0 on base64 command otherwise the base64 output is automatically wrapped by inserting newlines which breaks the escape sequence.

This doesn’t care if it’s in TMUX over nested SSH. It just works.

To receive these events do stuff with them, you add wezterm.on('user-var-changed.. to WezTerm config.

Here I wire up weznot and weznot. weznot triggers a notification with the value passed in and wezcopy copies the value to the clipboard.

wezterm.on('user-var-changed', function(window, pane, name, value)
  wezterm.log_info('var', name, value)
  if name == 'wez_not' then
    window:toast_notification('wezterm', 'msg: ' .. value, nil, 1000)
  end

  if name == 'wez_copy' then
    window:copy_to_clipboard(value, 'Clipboard')
  end
end)

To use these easily I create functions in dotfiles which output the escape sequences (these work over ssh as load into my SSH connections with sshrc).

# Send a notification with wezterm use like `do think && weznot "think is done"`
function weznot() {
    title=$1
    printf "\033]1337;SetUserVar=%s=%s\007" wez_not $(echo -n "$title" | base64 -w 0)
}

# Pipeline content to the clipboard `echo "hello" | wezcopy`
function wezcopy() {
    read clip_stuff
    printf "\033]1337;SetUserVar=%s=%s\007" wez_copy $(echo -n "$clip_stuff" | base64 -w 0)
}

# Run a command and notify that the command has failed or succeeded
function wezmon() {
    command=$*
    
    eval $command
    
    last_exit_code=$?
    if [ $last_exit_code -eq 0 ]; then
        weznot "✅ '$command' completed successfully"
    else
        weznot "❌ '$command' failed"
    fi
}

Now you can use them like 👇

weznot "Hey stuff finished!"

# or 

cat /some/log/file.txt | wezcopy

Even better, to save a few keystrokes with dothing; weznot "thing finished" you can do

wezmon do_thing

Notification will be: ✅ 'do_thing' completed successfully or ❌ 'do_thing' failed automatically

🎉 Happy terminal-ing