dotnetcore / dotnetcore/FlubuCore

Add shell tab-completion support for flubu commands outside interactive mode

Open
#370 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
C#
Stars
937
Forks
99
PR merge metrics
No merged PRs in 30d

Description

## Summary

Add shell tab-completion for `flubu` commands in bash, zsh, PowerShell, and fish. Currently completion only works inside `flubu -i` interactive mode. Users running normal `flubu ` commands get no tab-completion and must rely on `--help` or memory.

## Motivation

Modern CLIs (`dotnet`, `gh`, `kubectl`, `docker`) all support shell tab-completion. Users expect to type `flubu cl` and get `clean` completed. This is especially valuable for FlubuCore since target names are user-defined and vary per project — there's no way to know them without looking at the build script or running `--help`.

## Proposed Implementation

### 1. Add a hidden `--completions` command

A new option in `FlubuCommandParser` that outputs matching completions to stdout, one per line:

```bash
flubu --completions "flubu cl"
# output:
# clean
# clean.output

flubu --completions "flubu --"
# output:
# --parallel
# --dryrun
# --noColor
# --nodeps
# --script
# --debug
```

This command needs to:
- Load the build script (if present) to discover targets from `TargetTree`
- Include all registered options from `FlubuCommandParser`
- Include script property hints from `IScriptProperties.GetPropertiesHints()`
- Match the partial input against available completions (prefix match is sufficient)
- Output matches to stdout, one per line
- Exit with code 0

### 2. Add `--setup-completions ` command

Outputs the shell-specific completion script that users source once:

```bash
# Bash — add to ~/.bashrc
eval "$(flubu --setup-completions bash)"

# Zsh — add to ~/.zshrc
eval "$(flubu --setup-completions zsh)"

# PowerShell — add to $PROFILE
flubu --setup-completions pwsh | Invoke-Expression

# Fish
flubu --setup-completions fish | source
```

### 3. Shell completion scripts

Each script registers a completion function that calls `flubu --completions ""` on each tab press.

**Bash example:**
```bash
_flubu_completions() {
local IFS=$'\n'
COMPREPLY=($(flubu --completions "${COMP_LINE}" 2>/dev/null))
}
complete -F _flubu_completions flubu
```

**PowerShell example:**
```powershell
Register-ArgumentCompleter -CommandName flubu -Native -ScriptBlock {
param($wordToComplete, $commandAst, $cursorPosition)
$completions = flubu --completions "$commandAst" 2>$null
$completions -split "`n" | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
}
}
```

## What should complete

| Input | Completes with |
|-------|---------------|
| `flubu ` | All target names from build script |
| `flubu cl` | Targets starting with "cl" (e.g., `clean`) |
| `flubu --` | Global options: `--parallel`, `--dryrun`, `--noColor`, `--nodeps`, `--script`, `--debug` |
| `flubu -s ` | `.cs` files in current directory |
| `flubu test --` | Target-specific task options (from `[ArgKey]` attributes) |

## Existing code to reuse

All the hint/completion data already exists and is used by `flubu -i` interactive mode:

- **Target discovery:** `CommandExecutorInteractive.InitializeFlubuConsole()` already walks `TargetTree`
- **Script property hints:** `IScriptProperties.GetPropertiesHints()`
- **Task option hints:** `FlubuConsole` extracts these via `[ArgKey]` reflection
- **Command hints:** `GitCommands`, `DotnetCommands`, `DockerCommands`, `ChocolateyCommands`

The `--completions` command just needs to reuse this data and write matches to stdout instead of rendering them in the console.

## Why not migrate to System.CommandLine?

Evaluated and rejected because:
- FlubuCore targets are **dynamic** (discovered from user build scripts at runtime) — System.CommandLine's model expects static command trees
- Would require rewriting `FlubuCommandParser` and all option definitions
- System.CommandLine requires users to install `dotnet-suggest` global tool + shell shims — heavier setup
- Custom `--completions` is quite easy to implement and gives full control

## Why not use McMaster's completion support?

McMaster.Extensions.CommandLineUtils has **no shell completion support**. Feature requests ([#9](https://github.com/natemcmaster/CommandLineUtils/issues/9), [#438](https://github.com/natemcmaster/CommandLineUtils/issues/438)) were closed. The library is in maintenance mode.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.