This project packages a small helper that registers the helix://
URL scheme with the Helix terminal editor. Installing the handler lets links open directly in Helix from browsers, terminals, or other applications that support custom URL handlers.
- Supported URL formats
- What gets installed
- Prerequisites
- Quick start
- Prebuilt packages
- Uninstall
- Running in the dev container
- Tests
- Contributing
- License
- Structured query form –
helix://open?file=src/main.rs&line=12&col=4
- Parsed into
<file>:<line>:<col>
so Helix jumps straight to the location.
- Parsed into
- Shorthand form –
helix://path/to/file%20name.rs
- Decoded into a plain path and forwarded to Helix unchanged (e.g.
helix://path/file%20name.rs:10:2
openspath/file name.rs
at10:2
).
- Decoded into a plain path and forwarded to Helix unchanged (e.g.
Input | Result |
---|---|
helix://open?file=src/lib.rs&line=42 |
Opens src/lib.rs at line 42. |
helix://open?file=src/lib.rs&line=42&column=8 |
Accepts col or column query parameters for column hints. |
helix://~/notes/today.md |
Expands to the literal path ~/notes/today.md (no shell expansion). |
helix://projects/demo%20app/main.py:15 |
Decodes URL-escaped characters and honors trailing :line[:col] . |
file:///home/alex/project/todo.txt |
Treated like a file URL and forwarded without the file:// prefix. |
plain.txt |
Non-URL arguments pass through untouched; mixed invocations still work. |
- A managed Desktop Entry (
helix-url-handler.desktop
) marking Helix as the handler for thehelix://
scheme. - An
hx-url
wrapper script that decodes Helix URLs and forwards them to thehx
(orhelix
) binary with the appropriate file, line, and column arguments.
Both artifacts are created either in the current user’s home directory or system-wide, depending on the chosen scope.
The installation script requires a POSIX environment with the following commands available:
gio
(usually inlibglib2.0-bin
orglib2
)xdg-mime
(part ofxdg-utils
)update-desktop-database
(fromdesktop-file-utils
)install
,sed
,grep
(coreutils/GNU tools)
Distribution | Install command |
---|---|
Debian / Ubuntu | sudo apt install libglib2.0-bin xdg-utils desktop-file-utils |
Fedora | sudo dnf install glib2 xdg-utils desktop-file-utils |
Make sure the hx
(or helix
) binary is on your PATH
or pass --hx-bin /path/to/hx
during installation.
-
Install for the current user (default scope):
./src/helix-url-handler.sh --install
-
Install system-wide (requires root):
sudo ./src/helix-url-handler.sh --install --scope system --visible
GitHub releases publish ready-to-install bundles. Pick the artifact that fits your environment:
Artifact | Install command |
---|---|
Portable tarball (helix-url-handler-<version>.tar.gz ) |
tar -xf helix-url-handler-<version>.tar.gz && ./helix-url-handler/helix-url-handler.sh --install |
Debian / Ubuntu (helix-url-handler_<version>_all.deb ) |
sudo dpkg -i helix-url-handler_<version>_all.deb |
Fedora / RHEL (helix-url-handler-<version>-1.noarch.rpm ) |
sudo rpm -i helix-url-handler-<version>-1.noarch.rpm |
All packages install the tool under /usr/lib/helix-url-handler
and expose a helix-url-handler
binary on your PATH
. After installation, run helix-url-handler --install
(or --uninstall
) just like the source checkout. Each release also ships a SHASUMS256.txt
file so you can verify downloads.
The DEB declares
libglib2.0-bin
,xdg-utils
, anddesktop-file-utils
alongsidebash
; the RPM pulls the equivalentglib2
,xdg-utils
, anddesktop-file-utils
packages. Your package manager resolves these automatically.
Prefer building locally? Use make dist VERSION=<x.y.z>
to generate every package, or make dist-<tgz|deb|rpm> VERSION=<x.y.z>
to build a single format. Need a CI dry run? Trigger the Release workflow manually, deselect publish_release
, and tick only the artifact formats you care about.
--visible
– show the handler in graphical launchers.--takeover
– back up and replace existing handler files that are not managed by this tool.--allow-missing-hx
– allow system-scope installs even ifhx
is not yet available.--hx-bin /custom/hx
– specify where the Helix binary lives (useful in non-standard setups).--user-home DIR
– override the target home when running as root with--scope user
.
./src/helix-url-handler.sh --uninstall
Add --scope system
when removing a system-wide install, and optionally --keep-hx-url
to retain the URL wrapper script.
Uninstalling removes the .desktop
launcher, the optional hx-url
wrapper (unless kept), and scrubs helix-url-handler.desktop
entries from mimeapps.list
so the helix://
scheme returns to its previous handler.
The repo ships a single helper entry point at scripts/devcontainer/launcher.sh
that wraps every host-side workflow:
# Launch VS Code and attach a shell once the workspace is ready
scripts/devcontainer/launcher.sh vscode
# Attach a TUI session (defaults to helix) inside the running devcontainer
scripts/devcontainer/launcher.sh tui --command hx
# Run the devcontainer CLI within the lightweight helper image
scripts/devcontainer/launcher.sh helper -- up --workspace-folder /workspaces/helix-url-handler
The helper keeps the previous behaviour of detecting an available terminal before spawning docker exec
, waits for the container to come online, and automatically forwards any ${localEnv:...}
variables referenced by .devcontainer/devcontainer.json
when invoking the CLI wrapper.
If you prefer Make targets, the default make devcontainer
now shells out to the same launcher. Override the mode at call time to jump straight into a TUI session:
make devcontainer DEVCONTAINER_MODE=tui DEVCONTAINER_ARGS="--command hx"
On first boot the devcontainer provisioning performs:
- Starts an explainshell stack on the host network:
- Launches
explainshell_mongodb
(MongoDB 7) andexplainshell_app
containers. - Downloads the official DB dump and restores it in the background.
- Containers are configured with
--restart unless-stopped
.
- Launches
- Installs the codex CLI into
~/.local/bin/codex
and marks it executable. - Upgrades global npm and installs common CLI tools:
ripgrep
,fd
,lsd
,bat
,git-delta
, andbash-language-server
.
You can access explainshell at: http://localhost:5000
.
Tip: Run
scripts/devcontainer/launcher.sh vscode
from the repository root to launch VS Code, wait for the container, and drop into a shell automatically.
The devcontainer binds host files into the container to persist local state across rebuilds and reuse your Git identity:
Note: If any of the host paths do not exist, create an empty file or remove the corresponding entry before rebuilding to avoid mount warnings.
- Docker must be available on the host for the explainshell containers.
- Optionally export
GH_PAT
(also used asGITHUB_TOKEN
) in your local environment for authenticated GitHub operations; these are forwarded into the container bydevcontainer.json
.
A basic smoke-test suite verifies the hx-url
wrapper’s parsing logic and the installer’s ability to register the handler in an isolated environment.
make check
make check
runs shellcheck
across every shell script and executes ./tests/smoke-tests.sh
, which creates temporary directories and stubs desktop/xdg commands so it is safe outside a graphical session. You can launch the suite directly with ./tests/smoke-tests.sh
if you prefer.
To exercise the platform packages in clean environments, use the Docker-backed harness:
# Run the full matrix (Ubuntu 24.04, Debian 12, Fedora 42, Rocky Linux 9)
scripts/e2e/package-test.sh
# Target a single distribution
scripts/e2e/package-test.sh --distro fedora
The script builds ephemeral containers, installs Helix (default HELIX_VERSION=25.07.1
), installs the requested package from dist/
, and asserts that the installed hx-url
wrapper invokes Helix with the expected arguments (including exercising xdg-open
). Docker must be available locally.
The Makefile wraps these flows:
# Build every package format for VERSION and run the full matrix
make test-packages VERSION=0.1.0
# Target a specific distro (still requires VERSION to build packages)
make test-packages-fedora VERSION=0.1.0
# Remove generated artifacts and labeled test containers/images (requires CONFIRM=1)
make clean-packages CONFIRM=1
Each make test-packages*
invocation depends on make dist VERSION=…
, so ensure the version matches the artifacts you intend to validate.
See CONTRIBUTING.md for the branching strategy, development workflow, and release process.
This project is free software licensed under the GNU General Public License v3.0 or later.