"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:

For more information about this error, try `rustc --explain E0382`.
warning: `ownership` (bin "ownership") generated 1 warning
error: 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:

  {
    key = 's',
    mods = 'CMD|SHIFT',
    action = wezterm.action.QuickSelectArgs {
      label = 'open url',
      patterns = {
        'rustc --explain E\\d+',
      },
      action = wezterm.action_callback(function(window, pane)
        local selection = window:get_selection_text_for_pane(pane)
        wezterm.log_info('opening: ' .. selection)
        if startswith(selection, "http") then
          wezterm.open_with(selection)
        elseif startswith(selection, "rustc --explain") then
          local action = wezterm.action{
            SplitPane={
              direction = 'Right',
              command = {
                args = {
                  'rustc',
                  '--explain',
                  selection:match("(%S+)$"),
                },
              },
            };
          };
          window:perform_action(action, pane);
        else
          selection = "$EDITOR:" .. selection
          return open_with_hx(window, pane, selection)
        end
      end),
    },
  },

This script works perfectly.

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

          local action = wezterm.action{
            SplitPane={
              direction = 'Right',
              command = {
                args = {
                  'rustc',
                  '--explain',
                  selection:match("(%S+)$"),
                  '|',
                  'mdcat',
                  '-p',
                },
              },
            };
          };

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

error: Unrecognized option: 'p'

⚠️  Process "rustc --explain E0382 '|' mdcat -p" in domain "local" didn't exit cleanly
Exited with code 1
This 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:

          local action = wezterm.action{
            SplitPane={
              direction = 'Right',
              command = {
                args = {
                  '/bin/sh',
                  '-c',
                  'rustc --explain ' .. selection:match("(%S+)$") .. ' | mdcat -p',
                },
              },
            };
          };

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