Skip to content

Fix bash completion failing on stock macOS without bash-completion#355

Merged
gtsiolis merged 2 commits into
mainfrom
devx-950-bash-completion-broken-on-stock-macos-_get_comp_words_by_ref
Jul 20, 2026
Merged

Fix bash completion failing on stock macOS without bash-completion#355
gtsiolis merged 2 commits into
mainfrom
devx-950-bash-completion-broken-on-stock-macos-_get_comp_words_by_ref

Conversation

@gtsiolis

@gtsiolis gtsiolis commented Jul 2, 2026

Copy link
Copy Markdown
Member

Motivation

On stock macOS (bash 3.2.57, no bash-completion package) the generated bash completion script failed on every Tab with _get_comp_words_by_ref: command not found and produced zero completions, even when loaded correctly. Cobra's script depends on that function from the bash-completion package on both of its init paths, and a stock Mac has neither. Zsh was unaffected because Cobra's zsh script is self-contained.

The completion bash --help text also recommended source <(lstk completion bash), which is a silent no-op on bash 3.2.

Changes

  • Prepend a guarded pure-bash _get_comp_words_by_ref fallback to the generated script (cmd/completion.go), defined only when the bash-completion package is absent. This is the pattern git ships in git-completion.bash. It uses COMP_LINE to recover word adjacency so --flag=value and pod: shapes complete correctly, and stays bash 3.2 compatible.
  • Replace the bash help text to recommend eval "$(lstk completion bash)", which works on every bash, and document per-shell setup.
  • Generate the fallback and Cobra's body against the writer resolved at execution time, so a SetOut after NewRootCmd does not split them across writers.

When the bash-completion package is installed, the guard skips the fallback and behavior is unchanged. Zsh, fish, and PowerShell output is byte-identical to before.

Scope

This makes the generated script work when loaded. It does not enable completion by default, which still depends on the install method and shell. Auto-enabling completion during install is tracked separately.

Tests

  • 6 integration tests drive the real generated script in a bare bash (--noprofile --norc, no bash-completion): completion works without the package, wordbreak reassembly parity across 4 fixtures, and the fallback yielding to an installed package. All failed before the fix with the reported error.
  • 2 unit tests pin the single-writer wiring and --no-descriptions passthrough.
  • Verified on stock /bin/bash 3.2.57 and Homebrew bash 5.2 in a clean environment.

Closes DEVX-950

@gtsiolis
gtsiolis requested a review from a team as a code owner July 2, 2026 09:37
@gtsiolis gtsiolis self-assigned this Jul 2, 2026
@gtsiolis gtsiolis added semver: patch docs: skip Pull request does not require documentation changes labels Jul 2, 2026
@gtsiolis
gtsiolis force-pushed the devx-950-bash-completion-broken-on-stock-macos-_get_comp_words_by_ref branch 4 times, most recently from d623367 to 8293946 Compare July 9, 2026 07:08
@gtsiolis
gtsiolis force-pushed the devx-950-bash-completion-broken-on-stock-macos-_get_comp_words_by_ref branch from 8293946 to 40b499d Compare July 13, 2026 07:08
@gtsiolis

Copy link
Copy Markdown
Member Author

Commenting for reach as this would be nice to merge before Thursday's release.

@gtsiolis
gtsiolis force-pushed the devx-950-bash-completion-broken-on-stock-macos-_get_comp_words_by_ref branch 2 times, most recently from 43dd2b6 to 87ca9d7 Compare July 20, 2026 07:09
@skyrpex

skyrpex commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Currently reviewing and testing 👍🏻 Will merge soon if all is good.

@skyrpex

skyrpex commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

@gtsiolis as far as I understand, this PR isn't enough to enable the autocompletion for lstk users in all scenarios, right? Depending on the installation method (brew or npm) and their shell of choice (fish, zsh or bash) they'll have to source or eval the completion anyways?

Cobra's generated bash completion script calls _get_comp_words_by_ref from
the bash-completion package on both of its init paths, so on stock macOS
(bash 3.2, no bash-completion) every Tab press failed with
"_get_comp_words_by_ref: command not found" (DEVX-950).

Prepend a guarded pure-bash fallback to the generated script (defined only
when the package is absent, the git-completion.bash approach). The fallback
re-joins COMP_WORDS pieces split at COMP_WORDBREAKS separators using
COMP_LINE to recover adjacency, matching the package's reassembly semantics,
and stays bash 3.2 compatible.

Both the fallback and Cobra's script body are generated against the writer
resolved at execution time; delegating to Cobra's own RunE would write the
body to the writer captured at InitDefaultCompletionCmd time, splitting the
two halves across destinations when SetOut is called after NewRootCmd.

Also replace the bash completion help text: the default recommended
'source <(lstk completion bash)', which is a silent no-op on bash 3.2 —
recommend 'eval "$(lstk completion bash)"' instead.
@gtsiolis
gtsiolis force-pushed the devx-950-bash-completion-broken-on-stock-macos-_get_comp_words_by_ref branch from 87ca9d7 to f71375b Compare July 20, 2026 11:26
@gtsiolis gtsiolis changed the title fix: make bash completion work without the bash-completion package Fix bash completion failing on stock macOS without bash-completion Jul 20, 2026
@gtsiolis

Copy link
Copy Markdown
Member Author

You're right, @skyrpex! This is only fixing the bug mentioned in the linked discussion in the issue.

More specifically, on stock macOS bash the generated script was crashing. This makes the script work when loaded, it doesn't turn completion on by default.

Small nuance: brew ships the completion files, so zsh/fish auto-load there. npm (any shell) and bash are the manual cases. Updated the PR title and description to be more accurate.

The enablement piece you're describing is already tracked in PRO-245, which I opened some months ago to add a prompt for completions during install. That relies on DEVX-877 (curl install script) as the natural place to wire it in. I'd keep those separate from this fix.

What do you think?

@gtsiolis
gtsiolis requested a review from skyrpex July 20, 2026 11:27
@skyrpex

skyrpex commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Thanks, it makes perfect sense with that piece of context!

@gtsiolis

gtsiolis commented Jul 20, 2026

Copy link
Copy Markdown
Member Author

Pushed f7548df — a small 3-line fix for one more issue turning CI red here: under Go 1.26, an interrupted lstk start (Ctrl+C during the readiness wait) was recorded as a status-check failure instead of a clean cancellation, which made TestStartEmitsTelemetryWhenInterruptedDuringStartup flaky.

@gtsiolis
gtsiolis merged commit d8411eb into main Jul 20, 2026
17 checks passed
@gtsiolis
gtsiolis deleted the devx-950-bash-completion-broken-on-stock-macos-_get_comp_words_by_ref branch July 20, 2026 12:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs: skip Pull request does not require documentation changes semver: patch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants