Summary
Helix's diff gutter and changed-files picker (<space>g) don't work for repositories managed by Sapling, Meta's open-source Mercurial-based VCS (sl). This includes plain Mercurial (hg) repositories as well.
Background
Sapling is an open-source VCS developed and used at Meta (and other companies) that is a spiritual successor to Mercurial. Repos are identified by a .sl/ directory at the root (or .hg/ for plain Mercurial). The sl CLI is the primary interface.
Current architecture
helix-vcs/src/lib.rs already has the right abstraction for this — the comment at the top says exactly:
"Currently git is the only supported provider for diffs, but this architecture allows for other providers to be added in the future."
The DiffProvider enum in lib.rs and the three-function interface (get_diff_base, get_current_head_name, for_each_changed_file) mirror what a Sapling provider would need to implement.
What a Sapling provider would look like
Since there is no pure-Rust Sapling/Mercurial library (unlike gix for git), the implementation would shell out to the sl (or hg) CLI:
| Function |
CLI equivalent |
get_diff_base(file) |
sl cat -r . <file> |
get_current_head_name(file) |
sl log -r . -T '{desc|firstline}\n' or '{node|short}' |
for_each_changed_file(cwd) |
sl status |
The provider would detect Sapling repos by walking up from the file path looking for a .sl/ or .hg/ directory — analogous to how gix discovers .git/.
Proposal
- Add a
sapling feature flag to helix-vcs/Cargo.toml (off by default, or enabled in the default feature set alongside git)
- Implement
helix-vcs/src/sapling.rs shelling out to the sl CLI
- Register
DiffProvider::Sapling in DiffProviderRegistry::default()
I'm happy to implement this if the approach looks good to maintainers. Happy to hear if there are concerns about CLI-shelling vs. a library approach, or whether hg and sl should be separate providers or unified.
Summary
Helix's diff gutter and changed-files picker (
<space>g) don't work for repositories managed by Sapling, Meta's open-source Mercurial-based VCS (sl). This includes plain Mercurial (hg) repositories as well.Background
Sapling is an open-source VCS developed and used at Meta (and other companies) that is a spiritual successor to Mercurial. Repos are identified by a
.sl/directory at the root (or.hg/for plain Mercurial). TheslCLI is the primary interface.Current architecture
helix-vcs/src/lib.rsalready has the right abstraction for this — the comment at the top says exactly:The
DiffProviderenum inlib.rsand the three-function interface (get_diff_base,get_current_head_name,for_each_changed_file) mirror what a Sapling provider would need to implement.What a Sapling provider would look like
Since there is no pure-Rust Sapling/Mercurial library (unlike
gixfor git), the implementation would shell out to thesl(orhg) CLI:get_diff_base(file)sl cat -r . <file>get_current_head_name(file)sl log -r . -T '{desc|firstline}\n'or'{node|short}'for_each_changed_file(cwd)sl statusThe provider would detect Sapling repos by walking up from the file path looking for a
.sl/or.hg/directory — analogous to howgixdiscovers.git/.Proposal
saplingfeature flag tohelix-vcs/Cargo.toml(off by default, or enabled in the default feature set alongsidegit)helix-vcs/src/sapling.rsshelling out to theslCLIDiffProvider::SaplinginDiffProviderRegistry::default()I'm happy to implement this if the approach looks good to maintainers. Happy to hear if there are concerns about CLI-shelling vs. a library approach, or whether
hgandslshould be separate providers or unified.