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

Turning Helix into an IDE with the help of WezTerm and CLI tools

2023-08-19

Helix as IDE

This post recaps previous series of posts about Helix.

  1. Running code
  2. Jumping to build errors
  3. Quickly select a command and open it in a new pane
  4. Testing a single function
  5. Git integration
  6. File tree
  7. Creating snippets
  8. How to debug?
  9. Interactive global search
  10. Opening file in GitHub

1. Running code

In my previous post, I shared a method for running code from within Helix by using this PR.

I later discovered another useful trick here. We can use wezterm cli get-text command to extract the filename and line number from the status line:

status_line=$(wezterm cli get-text | rg -e "(?:NORMAL|INSERT|SELECT)\s+[\x{2800}-\x{28FF}]*\s+(\S*)\s[^│]* (\d+):*.*" -o --replace '$1 $2')
filename=$(echo $status_line | awk '{ print $1}')
line_number=$(echo $status_line | awk '{ print $2}')

2. Jumping to build errors

3. Quickly select a command and open it in a new pane

4. Testing a single function

As we can retrieve the filename and line number from the status line, we can easily extract the test name and pass it to cargo test:

  "test_single")
    test_name=$(head -$line_number $filename | tail -1 | sed -n 's/^.*fn \([^ ]*\)().*$/\1/p')
    split_pane_down
    case "$extension" in
      "rs")
        run_command="cd $PWD/$(dirname "$basedir"); cargo test $test_name; if [ \$status = 0 ]; wezterm cli activate-pane-direction up; end;"
        ;;
    esac
    echo "$run_command" | $send_to_bottom_pane
    ;;

5. Git integration

While Helix currently does not support Git, we can open lazygit in the bottom pane using the following script:

  "lazygit")
    split_pane_down
    program=$(wezterm cli list | awk -v pane_id="$pane_id" '$3==pane_id { print $6 }')
    if [ "$program" = "lazygit" ]; then
        wezterm cli activate-pane-direction down
    else
        echo "lazygit" | $send_to_bottom_pane
    fi
    ;;

and reload automatically after switching back.

git blame

Since we can obtain the filename and line number, we can easily send it to tig:

  "blame")
    split_pane_down
    echo "tig blame $filename +$line_number" | $send_to_bottom_pane
    ;;

6. File tree

Discover how to open broot from within Helix:

  "explorer")
    left_pane_id=$(wezterm cli get-pane-direction left)
    if [ -z "${left_pane_id}" ]; then
      left_pane_id=$(wezterm cli split-pane --left --percent 20)
    fi

    left_program=$(wezterm cli list | awk -v pane_id="$left_pane_id" '$3==pane_id { print $6 }')
    if [ "$left_program" != "br" ]; then
      echo "br" | wezterm cli send-text --pane-id $left_pane_id --no-paste
    fi

    wezterm cli activate-pane-direction left
    ;;

And when opening a file from broot, ensure it opens in the right pane:

fpath="$1"

pane_id=$(wezterm cli get-pane-direction right)
if [ -z "${pane_id}" ]; then
  pane_id=$(wezterm cli split-pane --right --percent 80)
fi

program=$(wezterm cli list | awk -v pane_id="$pane_id" '$3==pane_id { print $6 }')
if [ "$program" = "hx" ]; then
  echo ":open ${fpath}\r" | wezterm cli send-text --pane-id $pane_id --no-paste
else
  echo "hx ${fpath}" | wezterm cli send-text --pane-id $pane_id --no-paste
fi

wezterm cli activate-pane-direction --pane-id $pane_id right

7. Creating snippets

8. How to debug?

I submitted this PR to allow the target directory to appear in the completion list in the debugger prompt, and it got merged so quickly.

I’m implementing a mechanism that involves sending a command using fzf (combine with ripgrep) to the bottom pane when a key is pressed:

  "fzf")
    split_pane_down
    echo "hx-fzf.sh \$(rg --line-number --column --no-heading --smart-case . | fzf --delimiter : --preview 'bat --style=full --color=always --highlight-line {2} {1}' --preview-window '~3,+{2}+3/2' | awk '{ print \$1 }' | cut -d: -f1,2,3)" | $send_to_bottom_pane
    ;;

Once a selection is made, the file will be opened by Helix in the top pane:

selected_file=$1
top_pane_id=$(wezterm cli get-pane-direction Up)
if [ -z "$selected_file" ]; then
    if [ -n "${top_pane_id}" ]; then
        wezterm cli activate-pane-direction --pane-id $top_pane_id Up
        wezterm cli toggle-pane-zoom-state
    fi
    exit 0
fi

if [ -z "${top_pane_id}" ]; then
    top_pane_id=$(wezterm cli split-pane --top)
fi

wezterm cli activate-pane-direction --pane-id $top_pane_id Up

send_to_top_pane="wezterm cli send-text --pane-id $top_pane_id --no-paste"

program=$(wezterm cli list | awk -v pane_id="$top_pane_id" '$3==pane_id { print $6 }')
if [ "$program" = "hx" ]; then
    echo ":open $selected_file\r" | $send_to_top_pane
else
    echo "hx $selected_file" | $send_to_top_pane
fi

wezterm cli toggle-pane-zoom-state

I have submitted this PR to hide the bottom pane after that.

10. Opening file in GitHub

As simple it seems:

  "open")
    gh browse $filename:$line_number  
    ;;

You can see my full script here and the Helix configuration below:

[keys.normal.";"]
b = ":sh hx-wezterm.sh blame"
e = ":sh hx-wezterm.sh explorer"
f = ":sh hx-wezterm.sh fzf"
g = ":sh hx-wezterm.sh lazygit"
o = ":sh hx-wezterm.sh open"
r = ":sh hx-wezterm.sh run"
s = ":sh hx-wezterm.sh test_single"
t = ":sh hx-wezterm.sh test_all"

Categories: Development Environment

Tags: broot helix lazygit tig wezterm

Edit on GitHub