Skip to content

Zsh shell completion is broken when short flags exist #631

@bartekpacia

Description

@bartekpacia

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:

bugdemo.mp4

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

  • If possible, I've reproduced the issue using the main branch of this package
  • I've searched for existing GitHub 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-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
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
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:

swift build

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

./.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

Metadata

Metadata

Assignees

No one assigned

    Labels

    help wantedExtra attention is needed

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions