Skip to content

feat: native Rust file watcher (auto-reload open buffers) + gotmpl build fix - #64

Open
parisni wants to merge 2 commits into
badranX:mainfrom
parisni:watcher-clean
Open

feat: native Rust file watcher (auto-reload open buffers) + gotmpl build fix#64
parisni wants to merge 2 commits into
badranX:mainfrom
parisni:watcher-clean

Conversation

@parisni

@parisni parisni commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Reimplements the auto-reload idea from the Steel helix-file-watcher
plugin, but in native Rust — so the plain hx binary reloads open buffers
on external changes without loading any Scheme.

  • Backed by notify, so it's lightweight and fast (debounced, reload runs on
    the main thread; the editor is untouched while idle).
  • Watches the parent directory rather than the file inode, so it keeps
    working when the file is renamed/replaced (atomic saves from :w or external
    editors).
  • Designed for easy upstream merges: all logic lives in a new
    helix-term/src/file_watcher.rs; the only wiring is a pub mod in lib.rs,
    a register() call in events.rs, and notify in Cargo.toml.

Also includes a one-line build fix: the gotmpl grammar pointed to a dead repo
(404), which broke the all-or-nothing grammar build. Repointed to the live
ngalaiko fork (same rev helix upstream uses).

parisni added 2 commits July 19, 2026 18:56
The gotmpl tree-sitter grammar pointed to
github.com/dannylongeuay/tree-sitter-go-template, which no longer exists
(404 / "Repository not found"). The grammar build script is all-or-nothing,
so this single dead source broke every build.

Repoint it to github.com/ngalaiko/tree-sitter-go-template at the same rev
helix-editor/helix now uses (aa71f63), keeping helm/gotmpl highlighting and
staying aligned with upstream to avoid future merge conflicts.
Reimplement the Steel helix-file-watcher plugin in pure Rust so the native
hx binary auto-reloads buffers when their file changes on disk, without
loading any Scheme.

Design goals (minimize upstream merge conflicts):
- All logic lives in a new file, helix-term/src/file_watcher.rs. Upstream
  wiring is only three tiny anchors: a pub mod in lib.rs, a register() call
  in events.rs, and notify = "8" in Cargo.toml.
- notify watches the *parent directory* (not the file inode), so watches
  survive atomic saves (helix's own :w rename+create, and external editors
  that save atomically). A per-file set filters directory events down to open
  buffers; a per-directory refcount drops the watch when the last file closes.
- Reload is unconditional and recorded in the undo history, so external
  changes always refresh the view and in-session local edits stay
  recoverable via undo. This avoids silently leaving a buffer out of sync
  with disk.
- FS events are debounced via AsyncHook; the reload runs on the main thread
  through job::dispatch_blocking, so application.rs is untouched.
- (Re)watch is driven by the DocumentDidOpen / DocumentDidClose hooks.
@badranX

badranX commented Aug 9, 2026

Copy link
Copy Markdown
Owner

I'm thinking it is better to wait master. Otherwise, we would have to undo this custom feature once they merge their file watcher PR. Still, I might end up using this PR locally as it's easier to merge.

I'm still not sure yet if adding non-Vim features is a good idea. I can't merge their PR independently here as well. There should be a git repo that provide diff files for Vim features only.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants