"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

Categories: Development Environment

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"
          

Tags: broot helix lazygit tig wezterm

Edit on GitHub