Seamless workflow integration for Helix editor: Git operations, live search, file browsing, and text replacement with automatic file opening via Kitty terminal tabs.
Helix's design philosophy embraces simplicity without plugins, following Unix principles of composing specialized tools. Rather than constraining functionality within Helix's limited buffer system, this project leverages Kitty terminal's powerful windowing to integrate best-in-class tools like fzf, yazi, scooter or lazygit. Each tool excels in its domain, providing capabilities no plugin could match.
| Keybinding | Mode | Description | Script |
|---|---|---|---|
space-g-b |
Normal | Git blame with PR/commit URLs | kittyx-git-blame |
space-g-f |
Normal | Interactive git file browser with commit history | kittyx-tab git-file |
space-g-g |
Normal | Interactive git browser (lazygit) | kittyx-tab git |
space-g-l |
Normal | Interactive git log browser | kittyx-tab git-log |
space-g-u |
Normal | Copy Git URL to clipboard (cursor line) | kittyx-git-url-copy |
space-g-o |
Normal | Open Git URL in browser (cursor line) | kittyx-git-url-open |
space-e |
Normal | File browser (yazi) - manipulate selected file | kittyx-tab tree |
space-/ |
Normal | Live grep search - opens selected file | kittyx-tab live-grep |
space-/ |
Select | Live grep with selected text as query - opens selected file | kittyx-tab live-grep |
space-? |
Normal | Structural search (ast-grep) - opens selected file | kittyx-tab ast-grep |
space-? |
Select | Structural search with selected text as pattern - opens selected file | kittyx-tab ast-grep |
C-S-f |
Tree | Live grep within selected folder - opens selected file | kittyx-tab live-grep |
C-S-r |
Tree | Replace text within selected folder | kittyx-tab replace |
C-S-g |
Tree | Git history for selected file/folder | kittyx-tab git-browse |
space-r |
Normal | Replace in current file | kittyx-replace |
space-R |
Normal | Replace across project | kittyx-replace |
space-r |
Select | Replace selected text in current file | kittyx-replace |
space-R |
Select | Replace selected text across project | kittyx-replace |
ctrl-space |
Kitty | View scrollback buffer in Helix overlay | kittyx-scrollback |
alt-space |
Kitty | View last command output in Helix overlay | kittyx-scrollback |
- Smart PR/commit URL detection: Automatically detects and shows PR URLs when available, falls back to commit URLs
- Multi-platform support: GitHub, GitLab, Bitbucket, Azure DevOps, and Gerrit
- Platform-specific patterns: Recognizes different PR formats (
#123for GitHub,!123for GitLab, Change-Id for Gerrit) - Rich output: Shows author, time since commit, commit message, and clickable URL
- URL-only mode:
--url-onlyflag for integration with other tools
- Lazygit integration: Full-featured git interface in dedicated tab
- Git log browser: Interactive commit history with fzf
- Modified files browser: Interactive browser for git status files
- Interactive file browser: Full-featured yazi file manager in dedicated tab
- Smart directory detection: Opens from current buffer's directory or specified path
- Seamless file opening: Selected files automatically open in Helix after tab closes
- Live grep integration: Press
Shift+Ctrl+Fin yazi to search within the current directory - Unified workflow: Both yazi selection and live-grep from yazi work seamlessly together
- Interactive ripgrep with fzf interface in dedicated tab
- Copy file:line references with
ctrl-y - Selection mode prepopulates search query
- Seamless file opening: Selected files automatically open in Helix after tab closes
- Rich syntax highlighting in preview
- Single file selection only (no multi-select)
Where live grep matches text, this matches code shape. You write a snippet in
the target language with metavariables standing in for the parts you don't care
about, so $A($$$ARGS) finds every call regardless of name or argument count —
no regex gymnastics, no matches inside comments or strings.
$A— exactly one node (an expression, an identifier, an argument). Named, sobar($A, $A)requires both to be identical.$$$ARGS— zero or more nodes (an argument list, a function body). Bare$$$works too, except on its own.- The pattern must be syntactically complete:
foo(matches nothing,foo($$$)works. Incomplete patterns while typing simply yield an empty list.
The search re-runs on each keystroke once the query reaches 3 characters
(--min-chars), since a shorter pattern matches nearly every node. The language
is inferred from the file extension; add a lang: token to the query to restrict
it, as in $A.$B($$$C) lang:java,py. Markdown files are excluded — its grammar
has no call expressions, so any pattern would match arbitrary prose.
Beware that ast-grep matches a syntactic shape, not text: check($A) finds calls
only, never the def check(x) that declares it, and it excludes both check()
and obj.check(x). Use def check($A): $$$B for the declaration and
$X.check($$$) for method calls.
Requires the ast-grep binary, invoked as
ast-grep: the short sg alias collides with the setgid sg from
shadow-utils. Full pattern reference: the
syntax guide and
playground.
- File-scoped replacement: Replace in current file with interactive preview
- Project-wide replacement: Replace across entire project with scooter integration
- Selection-aware: Works with selected text in Helix
- Terminal scrollback integration: View terminal scrollback buffer in Helix overlay
- Command output viewer: View last command output in Helix overlay
- Smart cursor positioning: Positions at cursor location for vim/less windows, jumps to end for other content
- Custom keybindings: Inherits your Helix config with added
qkey for force quit - Fast temporary files: Uses
/dev/shmfor optimal performance
- Live preview: Converts markdown to HTML with automatic browser opening
- GitHub styling: Uses GitHub markdown CSS for consistent appearance
- Isolated serving: Each markdown file gets its own preview directory
- Live reload: Uses live-server for automatic refresh on changes
- Pandoc integration: Full-featured markdown conversion with self-contained HTML
-
Clone the repository:
git clone https://github.com/parisni/kittyx.git
-
Add the
bin/directory to your PATH:export PATH="$PATH:/path/to/kittyx/bin"
-
Add the key mappings to your Helix
config.toml:
Add the following key mappings to your Helix configuration file (~/.config/helix/config.toml):
[keys.normal.space]
# Live grep search with automatic file opening
"/" = [":open %sh{kittyx-tab live-grep}"]
# Structural search (ast-grep) with automatic file opening
"?" = [":open %sh{kittyx-tab ast-grep}"]
# Git operations
g = { "b" = ":sh kittyx-git-blame %{buffer_name} %{cursor_line}", "f" = ":sh kittyx-tab git-file %{buffer_name}", "l" = ":sh kittyx-tab git-log", "u" = ":sh kittyx-git-url-copy %{buffer_name} %{cursor_line}", "o" = ":sh kittyx-git-url-open %{buffer_name} %{cursor_line}", "g" = ":sh kittyx-tab git" }
# File browser with automatic file opening
e = ":open %sh{kittyx-tab tree '%{buffer_name}'}"
# Text replacement
R = [ ":write-all", ":sh kittyx-tab replace", ":reload-all" ]
r = [ ":write-all", ":sh kittyx-tab replace %{buffer_name}", ":reload-all" ]
[keys.select.space]
# Live grep with selected text as query
"/" = [":pipe tee /tmp/kittyx-live-grep-query", ":open %sh{kittyx-tab live-grep}"]
# Structural search with selected text as pattern
"?" = [":pipe tee /tmp/kittyx-ast-grep-query", ":open %sh{kittyx-tab ast-grep}"]
# Text replacement with selection
r = [ ":pipe tee /tmp/kittyx-replace.tmp", ":sh kittyx-tab replace %{buffer_name}", ":reload-all" ]
R = [ ":pipe tee /tmp/kittyx-replace.tmp", ":sh kittyx-tab replace", ":reload-all" ]Add the following to your Kitty configuration file (~/.config/kitty/kitty.conf):
# Scrollback viewer with Helix
map ctrl+space launch --type=overlay --title=current --stdin-source=@screen_scrollback kittyx-scrollback
map alt+space launch --type=overlay --title=current --stdin-source=@last_cmd_output kittyx-scrollbackFor enhanced yazi integration, add the following to your yazi keymap configuration file (~/.config/yazi/keymap.toml):
[[manager.prepend_keymap]]
on = "<S-C-f>"
run = 'shell -- kittyx-tab live-grep --open-in-helix --quit-tree --filepath "$@"'
desc = "Live grep on the given folder"
[[manager.prepend_keymap]]
on = "<S-C-r>"
run = 'shell -- kittyx-tab replace --quit-tree --filepath "$@"'
desc = "Replace text in the given folder"
[[manager.prepend_keymap]]
on = "<S-C-g>"
run = 'shell -- kittyx-tab git-browse --filepath "$@"'
desc = "Git history for the selected file/folder"This enables:
Shift+Ctrl+Fin yazi: Launch live grep search in the current directoryShift+Ctrl+Rin yazi: Launch text replacement in the current directoryShift+Ctrl+Gin yazi: View git history for the selected file/folder- Automatic integration: Search results open directly in Helix, replacements work within selected directory
- Smart cleanup: Yazi automatically closes after file selection
- Helix Editor
- Kitty Terminal
- fzf
- ripgrep
- ast-grep (for structural search)
- bat (for syntax highlighting in preview)
- jq (for JSON processing)
- lazygit
- scooter
- yazi


