apple / apple/swift-argument-parser

Zsh shell completion is broken when short flags exist

Open
#631 6 comments 0 reactions 0 assignees View on GitHub
help wanted
Dominant language
Swift
Stars
3.8k
Forks
411
Avg merge
7d 14h
Merged PRs (30d)
15

Description

Hi,

This is my first issue in this repository. Thank you for creating and maintaining this great package!

Now onto the problem: I discovered a bug with shell completions. Please see video below:

https://github.com/apple/swift-argument-parser/assets/40357511/6cdeeb81-0ed8-43ee-b0a3-e26780f56540

**ArgumentParser version:**

```
1.3.1
```

**Swift version:**

```
$ swift --version
swift-driver version: 1.90.11.1 Apple Swift version 5.10 (swiftlang-5.10.0.13 clang-1500.3.9.4)
Target: arm64-apple-macosx14.0
```

### Checklist

- [x] If possible, I've reproduced the issue using the `main` branch of this package
- [x] I've searched for [existing GitHub issues](https://github.com/apple/swift-argument-parser/issues)

### Steps to Reproduce

Use `Zsh` with shell completion enabled.

Then create a simple Swift command line app that uses `swift-argument-parser`.

```
├── Package.resolved
├── Package.swift
├── Sources
│   ├── Example.swift
│   └── Root.swift
```

Package.swift

```swift
// swift-tools-version: 5.9

import PackageDescription

let package = Package(
name: "SAPbug",
dependencies: [
.package(url: "https://github.com/apple/swift-argument-parser", from: "1.0.0"),
],
targets: [
.executableTarget(
name: "SAPbug",
dependencies: [
.product(name: "ArgumentParser", package: "swift-argument-parser"),
],
path: "Sources"),
]
)
```

Sources/Root.swift

```swift
import ArgumentParser

@main
struct Root: ParsableCommand {
static var configuration = CommandConfiguration(
commandName: "SAPbug",
version: "1.0.0",
subcommands: [Example.self]
)

@Option(help: ArgumentHelp("Some caches option"))
var entries: String = "caches"

mutating func run() throws {
print("Root run")
}
}
```

Sources/Example.swift

```swift
import ArgumentParser

struct Example: ParsableCommand {
static var configuration = CommandConfiguration(
abstract: "Some example command to demo bug.",
helpNames: [.long, .customShort("h")]
)

@Option(
help: ArgumentHelp(
"Entries to remove: \"caches\" targets OCI and IPSW caches and \"vms\" targets local VMs."
)
)
var entries: String = "caches"

@Option(
help: ArgumentHelp(
"Remove entries that were last accessed more than n days ago",
valueName: "n"
)
)
var olderThan: UInt?

@Option(help: .hidden)
var cacheBudget: UInt?

@Option(
help: ArgumentHelp(
"Remove the least recently used entries that do not fit the specified space size budget n, expressed in gigabytes",
valueName: "n"
)
)
var spaceBudget: UInt?

@Flag()
var gc: Bool = false

mutating func run() throws {
print("Example run")
}
}
```

Then build the executable:

```console
swift build
```

Then source shell completions into FPATH. In my case I do:

```console
./.build/debug/SAPbug --generate-completion-script zsh > /opt/homebrew/share/zsh/site-functions/_SAPbug && exec zsh
```

Then run `./.build/debug/SAPbug` and try triggering various shell completions
(see video).

### Expected behavior

```
$ ./.build/debug/SAPbug example [tab]
--entries -- Entries to remove: "caches" targets OCI and IPSW caches and "vms" targets local VMs.
--help -- Show help information.
--older-than -- Remove entries that were last accessed more than n days ago
--space-budget -- Remove the least recently used entries that do not fit the specified space size budget n, expressed
--version -- Show the version.
--gc
```

Short options should not be suggested, or alternatively, they should not break
in such a bad way.

### Actual behavior

Completions are broken.

Command invocation

```
$ ./.build/debug/SAPbug example [tab]
--entries
--help
--older-than
--space-budget
--version

-h

-- Entries to remove: "caches" targets OCI and IPSW caches and "vms" targets local VMs.
-- Show help information.
-- Remove entries that were last accessed more than n days ago
-- Remove the least recently used entries that do not fit the specified space size budget n, express
-- Show the version.
--entries
--help
--older-than
--space-budget
--version

-h

-- Entries to remove: "caches" targets OCI and IPSW caches and "vms" targets local VMs.
-- Show help information.
-- Remove entries that were last accessed more than n days ago
-- Remove the least recently used entries that do not fit the specified space size budget n, express
-- Show the version.
--gc
```

Contributor guide

Open the contributing guide

Research direction

Reproduce the issue with Sources/Root.swift and Sources/Example.swift, then run swift build and generate the Zsh completion script with --generate-completion-script zsh. Inspect the generated _SAPbug behavior when short flags exist; done means Zsh suggestions remain usable and match the expected long-option output without duplicated descriptions.

Written by the indexing model from the issue text.

Assessment

Tech stack
swift, zsh
Domain
cli
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.