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

Helix: How to jump to the build error from the terminal output?

2023-07-21

Categories: Development Environment

In my previous post, I shared how I run code in Helix, and today I’ve taken things a step further by integrating WezTerm into Helix. Now, after running the code, if I encountered errors or warnings, I can simply click on the corresponding file to open it in Helix at the specific line and column number.

Previously, I had to either look at the line number and navigate to that specific line or manually copy the file path and open it in Helix, which was somewhat cumbersome.

That’s when I wondered if I could convert the file path into a hyperlink, and have it open in Helix with just a click.

To generate a hyperlink from terminal output, I made the following addition to the WezTerm config file:

1config.hyperlink_rules = wezterm.default_hyperlink_rules()
2
3table.insert(config.hyperlink_rules, {
4  regex = '^/[^/\r\n]+(?:/[^/\r\n]+)*:\\d+:\\d+',
5  format = "$0",
6})

Additionally, to open the file in the Helix editor, I needed a way to find the pane that is on top of the current pane:

1local hx_pane = pane:tab():get_pane_direction("Up")

If it does not exist, I will create a new one:

1    if hx_pane == nil then
2      local action = wezterm.action{
3        SplitPane={
4          direction = direction,
5          command = { args = { 'hx', uri } }
6        };
7      };
8      window:perform_action(action, pane);

Otherwise I can send a command to that pane to open the file:

1    local action = wezterm.action.SendString(":open " .. uri .. "\r\n")
2    window:perform_action(action, hx_pane);

The full configuration looks like this:

 1config.set_environment_variables = {
 2  PATH = '/Users/quantong/.cargo/bin:'
 3      .. '/opt/homebrew/bin:'
 4      .. os.getenv('PATH')
 5}
 6
 7wezterm.on('open-uri', function(window, pane, uri)
 8  local user = os.getenv('USER')
 9  local start, _ = string.find(uri, '/Users/' .. user)
10  if start == 1 then
11    local direction = 'Up'
12    local hx_pane = pane:tab():get_pane_direction(direction)
13    if hx_pane == nil then
14      local action = wezterm.action{
15        SplitPane={
16          direction = direction,
17          command = { args = { 'hx', uri } }
18        };
19      };
20      window:perform_action(action, pane);
21    else
22      local action = wezterm.action.SendString(':open ' .. uri .. '\r\n')
23      window:perform_action(action, hx_pane);
24    end
25    -- prevent the default action from opening in a browser
26    return false
27  end
28  -- otherwise, by not specifying a return value, we allow later
29  -- handlers and ultimately the default action to caused the
30  -- URI to be opened in the browser
31end)
32
33config.hyperlink_rules = wezterm.default_hyperlink_rules()
34
35table.insert(config.hyperlink_rules, {
36  regex = '^/[^/\r\n]+(?:/[^/\r\n]+)*:\\d+:\\d+',
37  format = '$0',
38})

In the above code, I’ve utilized a trick to open only the local file paths (starting with /Users/<my_username>) in Helix. Other links like https://github.com/ will still be opened in the browser.

I’m delighted with the combination of WezTerm and Helix, as it enhances my workflow and productivity.

Tags: helix wezterm

Edit on GitHub

Related Posts: