38 Commits
Author SHA1 Message Date
Nate Cook 043bca1136 Revert source break in 1.8.0 parse methods (#908)
This removes the `async` overloads to `parse` and `parseAsRoot`
that caused a source break in 1.8.0, and introduces new names
that disambiguate the methods with `async` behavior. Instead of
calling the existing methods with the `await` keyword, users can
call `await asyncParse` or `await asyncParseAsRoot`.

This change also adds a validation step to the synchronous parsing
path to check if an async completions function is called.

Users that have already updated their code to work around the
source break will revert to the old methods with this change,
which will yield a "No 'async' operations occur within 'await'
expression" warning. They can remove the `await` keyword or update
to call the async versions directly to fix the warning.
2026-05-26 20:17:35 -05:00
Ross Goldberg d6f4e7a371 Support async custom completion functions for AsyncParsableCommand via async/await (#855)
* Support async custom completion functions for AsyncParsableCommand via async/await.
* Improve ParsableArguments#_errorLabel DocC.
* Fix preexisting typo.

Signed-off-by: Ross Goldberg <484615+rgoldberg@users.noreply.github.com>
2026-04-06 13:44:48 -05:00
Rauhul Varma 6924db870d Use Foundation Essentials when possible (#804)
* add implementation of replacing(_:with:)
* remove use of range(of:)
* Consolidate foundation usage
* Consolidate error to string logic
* Clean up env a bit
2025-09-11 18:44:31 -05:00
Ross Goldberg c94be10e10 Use enum raw values instead of description. (#801)
Signed-off-by: Ross Goldberg <484615+rgoldberg@users.noreply.github.com>
2025-09-09 13:43:31 -05:00
Ross Goldberg ec562e5b1c Support async custom completion closures (#782)
Signed-off-by: Ross Goldberg <484615+rgoldberg@users.noreply.github.com>
2025-06-03 22:40:23 -05:00
Ross Goldberg d8a9695190 Improve flag & option name quoting in completion generation for all 3 shells. (#767)
Improve zsh quoting.

Many quoting issues remain.

To fix them, there should first be enforced & documented limits on the acceptable characters in various values throughout SAP to avoid unnecessary quoting.

Signed-off-by: Ross Goldberg <484615+rgoldberg@users.noreply.github.com>
2025-05-19 18:24:11 -05:00
Ross Goldberg 42585ad612 Add 2 index arguments to custom shell completion calls (#763)
They indicate to the Swift custom completion function:

1. the word for which completions are being requested.
2. the location of the cursor within that word.
2025-05-07 16:32:11 -05:00
Nate Cook 134451f572 Fix up license headers and enable check (#746) 2025-02-24 06:53:19 -08:00
Ross Goldberg f2eda39df5 Improve zsh completion script generation (#727)
* Do not indent zsh cases.

Simplify zsh indent generation.

* Do not prefix zsh cases with an open parenthesis.

* Prevent zsh parameter word splitting.

Brace & quote parameter uses.

Use [@] for quoted array output.

* Improve comment in ZshCompletionsGenerator.swift.

* Fix incorrect zsh shellCommand single quotes:

4 consecutive single quotes were obviously intended to be 2 escaped single quotes, 
but that isn't zsh syntax.

Use 2 double quotes instead.

* Remove extraneous zsh newline.

* Improve zsh variable declarations: scoping, typing & readonly.

Remove trailing spaces from InstallingCompletionScripts.md.

* Include zsh words before current subcommand in custom completion arg.

* Make subcommandHandler in ZshCompletionsGenerator.swift immutable.

* Escape zsh single quotes via '\'' instead of via '"'"'.

* Escape single quotes in zsh shellCommand String.

If someone already escapes single quotes from the String, this will cause an issue, 
but no one should be required to go to the trouble to manually escape single quotes 
in their script, especially since the requirement isn't documented or normal.

* Fix zsh custom completions for empty [String] & String elements.

If a Swift custom completion function returns an empty [String], if the user tries to 
complete it, refuse to complete instead of inserting a blank space into the command line.

If a Swift custom completion function returns a [String] including a Swift empty String 
or including a String with a description but with a blank completion 
(e.g., ":description"), if that completion is selected, complete to a zsh empty string 
'' instead of inserting a blank space into the command line.

Disambiguating between an empty [String] & a [String] with one empty String element 
requires that an extra value be appended to the output of the Swift custom function, 
which is then removed by the completion script.

* Simplify zsh subcommand completion function dispatch.

* Restrict access to symbols in ZshCompletionsGenerator.swift.

* Add default help to zsh completions iff no existing help subcommand.

* Use interpolated Strings in ZshCompletionsGenerator.swift.

* Create & use zsh __completion function.

* Improve zsh escaping.

* Set zsh settings to a known state.

Disable history ! in zsh completion scripts.

* Inline single-use functions & variables in ZshCompletionsGenerator.swift.

* Overhaul ZshCompletionsGenerator.swift as [ParsableCommand.Type] extension.

* Move functions in ZshCompletionsGenerator.swift.

Move from ArgumentDefinition extension to [ParsableCommand.Type] extension.

* Move zsh helper functions before command functions to mirror other shells.

* Prefix zsh helper functions with command name to prevent naming clashes.

Function names are globally scoped.

Without namespacing, if 2 programs use different versions of Swift Argument Parser,
one could overwrite the other's different version of the same helper function.

Renamed functions from *_completion to *_complete, as they complete, not return a 
completion.

* Separate zsh _arguments flags from specs using :.

* Rename zsh args variable as arg_specs.

* Simplify zshCompletionString(…).

* Allow generating zsh setup scripts for arguments.

* Use zsh array for list completions instead of nested strings.

Allows list completions to contain spaces.

Resolve #726

* Make CompletionShell.format(…) internal instead of public.

* Reword uses of "iff" in completions code.

Redid a comment as a DocC.

* Replace zsh END_MARKER pseudo-completion with a space to ease migration.

Document why & how this pseudo-completion is used.

Do not trim whitespace in testing, as that breaks with the space pseudo-completion.

Testing should be as exact as possible; trimming whitespace makes it less exact.

* Throw error if attempting to generate a zsh completion script for no commands.

Force unwrap first in ZshCompletionsGenerator.swift.

---------

Signed-off-by: Ross Goldberg <484615+rgoldberg@users.noreply.github.com>
2025-02-15 10:56:19 -08:00
Rauhul Varma 47fe00c4fe Enable more ci (#712)
Enables and fixes issues with additional platform tests 
and the formatter with these additional rules:

- UseLetInEveryBoundCaseVariable
- NeverForceUnwrap
- BeginDocumentationCommentWithOneLineSummary
- ValidateDocumentationComments
- AlwaysUseCamelCase
2025-02-12 08:52:17 -06:00
Rauhul Varma 10d80282e5 Enable swift-format checking (#711)
Adopts the common swift-mmio and swift-argument-parser format and enables CI checking.

Fixes: #702
2025-02-10 14:58:19 -08:00
Rauhul Varma 45b5c745c7 Combine completion script tests (#699)
Removes a ton of redundant completion script tests and combines unique
components into a single common set of tests.
2025-02-06 09:50:30 -08:00
Rauhul Varma cea1a0837e Extend snapshot testing to completion scripts (#698)
As the title suggests this commit moves the completion script tests to
use the snapshot testing recently introduced.
2025-02-06 09:40:18 -08:00
Ross Goldberg 5f48a1614f Add singleton to indicate which shell version is requesting completion candidates (#690)
Create a `String?` singleton named `CompletionShell.requestingVersion` that
indicates which shell version is requesting completion candidates.

It will be set to the correct value while a Swift custom completion function is
executing to offer completions for a word from a command line (e.g., while
`customCompletion` from `@Option(completion: .custom(customCompletion))`
executes). Otherwise, it will be set to `nil`.

The requesting shell version is communicated to the Swift app via an environment
variable named `SAP_SHELL_VERSION`, which is exported by each of the generated
completion scripts.

Improve some nearby DocC.

Resolve #689

Signed-off-by: Ross Goldberg <484615+rgoldberg@users.noreply.github.com>
2025-01-22 09:22:35 -06:00
Ross Goldberg 2edadce25d Add singleton to indicate which shell is requesting completion candidates (#680)
A CompletionShell singleton named CompletionShell.requesting has been created
that indicates which shell is requesting completion candidates.

The singleton is populated when a completion script is generated, so functions
used to generate arguments for CompletionKind creation functions can return
completion candidate syntax / shell commands tailored for that shell.

For the custom(:) CompletionKind creation function, the singleton is populated
at runtime (when a completion script requests completions from the Swift app
after a user types tab while composing a command line to call the app).

The requesting shell is communicated to the Swift app via an environment variable
named SAP_SHELL, which is exported by each of the generated completion scripts.

Resolve #672

Signed-off-by: Ross Goldberg <484615+rgoldberg@users.noreply.github.com>
2025-01-21 23:57:36 -06:00
Nate Cook bb10ca8b70 Updates to support Swift 6 language version (#650)
Some minor NFC changes to resolve strict concurrency checking
warnings/errors and the warning about the change in meaning for
`#file`.
2024-07-15 15:37:38 -07:00
Craig Siemens d66d015418 Fix zsh/bash completions for arguments in option groups with a custom completion (#648)
* Added conversion for InputKey to/from fullPathString.

* Updated custom completions to use the IndexKey.fullPathString.

This resolves an issue where custom completion for arguments in an OptionGroup would fail to match the argument. It was caused by:
- the completion script only using the name of the argument (instead of the full path)
- the CommandParser looking for the matching argument by comparing a name only IndexKey with the “full” IndexKeys

* Updated BashCompletionsGenerator to use customCompletionCall.

The zsh completions already uses this function. The function’s implementation is the same as what the BashCompletionsGenerator is doing. This removes the duplicated logic.

* Updated completion tests to include nested arguments with custom completions.

* Switched to using the split method from the stdlib.

Prevously was using .components(seperatedBy:) from Foundation.

* Updated the fish completions to include arguments
2024-07-04 00:52:58 -05:00
Cœur 1c8215f18a Prefer let for private configurations (#617) 2024-02-28 11:29:01 -06:00
Rob Mayoff 76466cc870 Improve zsh completion for repeatable options (#614)
Some commands allow an option to be repeated to provide multiple values.
For example, ssh allows the -L flag to be repeated to establish multiple
port forwardings.

ArgumentParser supports this style when the Option value is an Array
and the parsingStrategy is ArrayParsingStrategy.singleValue or
.unconditionalSingleValue.

Without this patch, ArgumentParser generates a zsh completion script
that does not handle repeatable options correctly. The generated script
suppresses completion of any option after that option's first use, even
if the option is repeatable.

With this patch, ArgumentParser generates a zsh completion script that
allows a repeatable option to be completed each time it is used.

The relevant zsh _arguments syntax is documented here:
https://zsh.sourceforge.io/Doc/Release/Completion-System.html#Completion-Functions

Specifically, a repeatable option's optspec needs to start with '*'.
Furthermore, a repeatable argument must not list itself or its synonyms
in its own parenthesized suppression list. (This is not clearly
documented.)

fixes #564

* Add test for repeated flag completions
2024-02-24 11:36:22 -08:00
Kenny YorkandKenny York 9eded54997 Bash does not like '-' in function names (#573)
Co-authored-by: Kenny York <kenny_york@apple.com>
2023-11-20 08:41:23 -06:00
Gwynne Raskind ecac862002 [Bash completion]: Respects .file() extensions, uses _filedir (#590)
Bash completion scripts: Respects the `extensions` array for `CompletionKind.file()`
and uses `_filedir` when available for `.file` and `.directory`.
2023-11-14 10:51:03 -06:00
matsuji 99e2e97fd9 Improve fish completion (#376, #534) (#535)
A generated fish script didn't complete an option after an argument.

The cause is the generated fish script doesn't accept an input text which already has arguments.
For example, when the input is `repeat -`, the script can complete `--count`, but when the text is `repeat foo -`, the script cannot complete `repeat foo --count`, because the input text already has the argument "foo".

To fix the issue, `FishCompletionsGenerator` got a capability that can accept a text which has arguments.
2023-01-09 10:55:41 -06:00
Rauhul Varma 4f63cee952 Hide hidden subcommands from completions (#443) 2022-04-23 18:56:15 -07:00
Nate Cook 5540737e97 Add customization point for command usage text (#400) 2022-02-11 13:41:27 -06:00
Aaron Gyes 7e04f56c1d Rename ...using_command fish function, set $cmd in local scope (#377)
__fish_* should not be used by external projects.
set -l cmd in case user has a global or universal `cmd` defined.
2021-12-10 13:31:20 -06:00
Craig Siemens d7f63849fb Updated the zsh completions to escape the command name for a custom completion. (#364) 2021-12-07 10:47:43 -06:00
Nate Cook 685341f629 Use standard path for --dump-help help/completions, remove completions (#339) 2021-07-20 12:59:36 -05:00
Kotaro Suto cfcb9cb0cd Add new built-in flag --dump-help (#310)
This commit will add a new builtin option named `--dump-help-info` which
outputs help information in JSON.
2021-07-07 13:09:21 -05:00
Nate Cook 267f707294 Use custom help flags in completion scripts (#308)
* Standardize the help and version flag generation
* Simplify some help generation code
* Support custom help flags in completion scripts
2021-05-14 10:27:05 -05:00
Alfredo Delli Bovi 26744de9d8 Fix zsh dashes in command names (#284) 2021-03-06 13:10:43 -06:00
Nate Cook 605a2330c5 Suppress hidden arguments from completion scripts (#271) 2021-02-11 10:41:46 -06:00
Nate Cook 365ca6a987 Remove an unnecessary print statement (#233) 2020-08-28 16:37:31 -05:00
Daniel Duan 2104b1a314 Add Fish completion generator (#226) 2020-08-13 12:11:08 -05:00
Nate Cook b905f5c777 Improve the completion tests a bit (#228) 2020-08-12 14:17:58 -05:00
Brandon Evans 115cacd4a1 Improve support for multi-word completion strings in ZSH (#216)
* Improve support for multi-word completions in Z shell

I will not pretend to fully understand why this new "expand string into array" expression works when the other didn't, but it does. The new expression is based on this SO answer: https://unix.stackexchange.com/a/29748.

The motivation for this change was for the install command of xcodes (https://github.com/RobotsAndPencils/xcodes) to support Xcode version completion strings with multiple words, like "11.6 Beta". The previous version of this expression would split this string into two, so that "11.6" and "Beta" were independent options in the ZSH completion UI, which didn't make sense for this use case.
2020-08-05 11:49:05 -05:00
Nate Weaver 5323d56ea9 Escape backslash and square brackets in addition to single quotes (#222)
* Escape backslash and square brackets as well as single quotes (#218 and #221)

- Escape appropriate chars in subcommand abstracts as well.

* Add test for escaped zsh characters
2020-08-04 22:51:32 -05:00
Stuart Carnie 163211e2e4 fix: Improve zsh completion script generator (#219)
* `shellCommand` stores output in a local array that is passed
  to `_describe` to handle spaces and other punctuation in
  the shell command output

* elide the help abstract if it is empty, as it confuses
  the zsh completion system

* set the `_<commandName>_commandname` to `$words[1]`, which
  is the full name of the command used to invoke the completion.
  This ensures invocations like `./build/debug/math` ...
  as passed on to the `_custom_completion` command.
2020-08-03 14:26:25 -05:00
Nate Cook 280700d361 Add completion script generation (#123)
Support for generating shell completion scripts for `ParsableCommand`
types, with customization points for `ExpressibleByArgument` types and
individual arguments and options. Zsh and Bash are supported in this
initial release.
2020-07-29 17:58:44 -05:00