Skip to content

completion: generate fish completions, remove hand-written ones - #9990

Draft
ThomasWaldmann wants to merge 1 commit into
borgbackup:masterfrom
ThomasWaldmann:fish-completions-9989
Draft

completion: generate fish completions, remove hand-written ones#9990
ThomasWaldmann wants to merge 1 commit into
borgbackup:masterfrom
ThomasWaldmann:fish-completions-9989

Conversation

@ThomasWaldmann

@ThomasWaldmann ThomasWaldmann commented Aug 1, 2026

Copy link
Copy Markdown
Member

Fixes #9989.

borg completion fish now generates fish shell completions automatically, the same way bash/zsh completions are generated. borg brings its own fish backend rather than using shtab's (which appeared in shtab 1.9.0): shtab's fish backend bases its conditions on __fish_seen_subcommand_from (which can misfire when positional values collide with command names) and is not positional-aware. borg's generator walks the parser tree and emits fish complete commands, plus a preamble with fish versions of the same dynamic completion functions the bash/zsh scripts have (archive names, aid: archive IDs with metadata descriptions, tags, sort keys, files cache modes, compression specs, chunker params, relative time markers, timestamps, file sizes, help topics).

Details:

  • shtab >= 1.9.2 is now required (older versions generate broken zsh completions, see zsh: shlex.quote() in help breaks generated script — any apostrophe corrupts quoting (regression in 1.8.2) tqdm/shtab#224, or have no fish support), so shtab.SUPPORTED_SHELLS already contains "fish" and is used as-is for the SHELL choices; borg completion fish dispatches to borg's own backend.
  • The generated script parses the command line to track the current (sub)command path (e.g. key export) and the number of positional arguments already given, so completions are position-aware — e.g. borg diff offers archive names for both the first and second positional, and file completion still works for PATH arguments after them.
  • Common options (identical in every context) are emitted once without a condition; everything else is guarded by a per-command condition.
  • Option strings that take a value are tracked so their values are not mistaken for subcommands/positionals. --keep is a flag in key change-location but takes a value in prune; it is treated as value-taking (the lesser evil).
  • The hand-written, unmaintained scripts/shell_completions/fish/borg.fish and its test are removed.
  • New tests cover script size/syntax (fish --no-execute) and, via fish's complete -C, subcommand/option/value completion, sort-key dedup, files-cache exclusivity, and archive name / aid: completion against a real repo (running the borg under test via a small PATH shim). CI already installs fish for completion tests.
  • Verified locally against shtab 1.9.2: bash/zsh/tcsh/fish generation all work, full completion test suite passes.

Upstream shtab work resulting from this evaluation (issues filed for each problem found in shtab's fish backend, plus fix PRs):

For now, borg ships its own fish backend so this doesn't have to wait on upstream. Once the shtab fixes are merged and released, we will adapt borg to use shtab's fish backend (like it already does for bash/zsh) and remove any then-duplicate fish code here.

🤖 Generated with Claude Code

@ThomasWaldmann
ThomasWaldmann force-pushed the fish-completions-9989 branch 2 times, most recently from 3b28d84 to af89360 Compare August 1, 2026 01:13
@codecov

codecov Bot commented Aug 1, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.39640% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 85.94%. Comparing base (a293a67) to head (593b1e8).
⚠️ Report is 1 commits behind head on master.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
src/borg/archiver/completion_cmd.py 96.39% 2 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #9990      +/-   ##
==========================================
+ Coverage   85.88%   85.94%   +0.06%     
==========================================
  Files          95       95              
  Lines       17088    17187      +99     
  Branches     2616     2643      +27     
==========================================
+ Hits        14676    14772      +96     
- Misses       1674     1675       +1     
- Partials      738      740       +2     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

…borgbackup#9989

borg brings its own fish backend instead of using shtab's (new in shtab
1.9.0): it walks the parser tree and emits fish complete commands, with
a preamble providing fish versions of the same dynamic completions the
bash/zsh scripts have (archive names, aid: archive IDs, tags, sort keys,
files cache modes, compression specs, chunker params, relative time
markers, timestamps, file sizes, help topics).

The generated script tracks the (sub)command path and the number of
positional arguments already given, so completions are offered in the
right place (e.g. the second archive name for borg diff) - more precise
than shtab's __fish_seen_subcommand_from based conditions.

shtab >= 1.9.2 is required now (older versions generate broken zsh
completions or have no fish support), so shtab.SUPPORTED_SHELLS already
contains fish and is used as-is for the SHELL argument choices.

The hand-written, unmaintained fish completions in
scripts/shell_completions/ are removed, as are their tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.

borg2: automate fish shell completions

1 participant