"Life is all about sharing. If we are good at something, pass it on." - Mary Berry

WezTerm: quickly select a command and open it in a new pane

2023-08-04

Categories: Development Environment

In my previous post, jump to build errors with WezTerm, I demostrated how to navigate to build error using hyperlinks. One limitation of that approach is that it requires a mouse click.

In this post, I explore how to achieve the same functionality using a shortcut key in WezTerm, thanks to QuickSelectArgs feature.

WezTerm’s QuickSelectArgs allows us to bind a shortcut key to select specific patterns and perform actions on the selected text. Let’s say we have the following warning:

1For more information about this error, try `rustc --explain E0382`.
2warning: `ownership` (bin "ownership") generated 1 warning
3error: could not compile `ownership` (bin "ownership") due to previous error; 1 warning emitted

Out goal is to quickly select rustc --explain E0382 and open it in a new pane.

Here’s what I’ve come up with to accomplish this:

 1  {
 2    key = 's',
 3    mods = 'CMD|SHIFT',
 4    action = wezterm.action.QuickSelectArgs {
 5      label = 'open url',
 6      patterns = {
 7        'rustc --explain E\\d+',
 8      },
 9      action = wezterm.action_callback(function(window, pane)
10        local selection = window:get_selection_text_for_pane(pane)
11        wezterm.log_info('opening: ' .. selection)
12        if startswith(selection, "http") then
13          wezterm.open_with(selection)
14        elseif startswith(selection, "rustc --explain") then
15          local action = wezterm.action{
16            SplitPane={
17              direction = 'Right',
18              command = {
19                args = {
20                  'rustc',
21                  '--explain',
22                  selection:match("(%S+)$"),
23                },
24              },
25            };
26          };
27          window:perform_action(action, pane);
28        else
29          selection = "$EDITOR:" .. selection
30          return open_with_hx(window, pane, selection)
31        end
32      end),
33    },
34  },

This script works perfectly.

Now, let’s take it up a notch and make the output even fancier by using mdcat:

 1          local action = wezterm.action{
 2            SplitPane={
 3              direction = 'Right',
 4              command = {
 5                args = {
 6                  'rustc',
 7                  '--explain',
 8                  selection:match("(%S+)$"),
 9                  '|',
10                  'mdcat',
11                  '-p',
12                },
13              },
14            };
15          };

but the pipe operator is wrapped with single quotes, leading to an error:

1error: Unrecognized option: 'p'
2
3⚠️  Process "rustc --explain E0382 '|' mdcat -p" in domain "local" didn't exit cleanly
4Exited with code 1
5This message is shown because exit_behavior="Hold"

The reason behind this error is WezTerm doesn’t use the shell to launch the programs, therefore, I need to run it as a sub-command using sh -c, like this:

 1          local action = wezterm.action{
 2            SplitPane={
 3              direction = 'Right',
 4              command = {
 5                args = {
 6                  '/bin/sh',
 7                  '-c',
 8                  'rustc --explain ' .. selection:match("(%S+)$") .. ' | mdcat -p',
 9                },
10              },
11            };
12          };

With this setup, whenever I want to explore an error further, I can quickly select the rustc --explain Exxxx command and spawn it in a newly created pane or tab.

Tags: helix wezterm

Edit on GitHub

Related Posts: