9 Commits
Author SHA1 Message Date
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
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 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
Lev Walkin 511a72aea8 Add Sendable conformance (#582)
This change adds conditional `Sendable` conformance to all
property wrapper types when their `Value` is `Sendable`, enabling
commands to be used in concurrent contexts. Some notes on
the implementation:

* Fix flag exclusivity issues

This derives the `hasUpdated` check from the parsed values data type,
rather than storing it in the closure (which breaks sendability) or
passing it through the closure invocation (which wasn't finished
enough to actually work).

* Mark all `transform` methods as `@Sendable`

This allows for a stronger, compiler-supported guarantee of
sendability when a compound `ParsableArguments` or `ParsableCommand`
type is marked `Sendable`. Most transformations shouldn't be a
problem, since the general case is that these are pure string ->
value transformations.

In cases where making such a transformation sendable is impossible,
an author can always change the property to be just a string and
perform the transformation within the context of the command's
execution, in either the `run()` or `validate()` methods.

* Add `@preconcurrency` to Sendable closure APIs

This adds the `@preconcurrency` attribute to all public APIs that
have changed to take a `@Sendable` closure. This will ease the
migration path for sendable adoption for ArgumentParser users, since
a warning will only appear for using these APIs (like the `transform`
parameter in an @Option or @Argument) once they've turned on strict
concurrency checking.

I'm also backing out changes that avoided those warnings in the tests
and examples, since in most cases those warnings are spurious;
unapplied functions don't capture state. See
https://forums.swift.org/t/pitch-inferring-sendable-for-methods-and-key-path-literals/68011
for more on this and hopefully an upcoming fix for these issues.

* Raise minimum Swift version to 5.7

In order to provide `@preconcurrency` support, the package needs to
have a minimum Swift requirement of 5.7. This makes that change and
updates the README to indicate this for the next version.
2023-11-17 10:06:47 -06:00
Gwynne Raskind c10af98655 Respect the COLUMNS and LINES environment variables when present (#596)
* Respect the `COLUMNS` and `LINES` environment variables, if set, when determining screen size.
* Add test for COLUMNS environment override
* Make columns test idempotent against there being a COLUMNS value already set in the environment
* Make help tests be more explicit about screen widths.
2023-11-14 21:17:06 -08:00
Nate Cook 5535a95838 Fix some Swift 5.6 compatibility issues (#516)
* Use existential CodingKey parameters consistently

Swift 5.7 supports implicit opening for existentials, so these
conversions from `CodingKey` parameters to pass to methods that
are generic over `CodingKey` work fine. Prior to Swift 5.7, however,
these don't compile, with the message that `CodingKey` doesn't conform
to itself.

* Bump the required Swift version for the count-lines test

The overload resolution for the `static func main()` in an `@main`
type still had issues in Swift 5.6, such that a package with a min.
platform below that which works for concurrency backdeployment doesn't
properly resolve the AsyncParsableCommand `main()` function. In
Swift 5.7, this is properly resolved, so just the availability on
the main type is sufficient.

This change just skips the test of `count-lines` prior to Swift 5.7,
so that we can maintain the open platform minimum for the package
as a whole.
2022-11-04 16:18:24 -05:00
Rauhul Varma 607021b737 Unify @Argument and @Option initialization paths (#477)
- Fixes #466.
- Adds initializers to ArgumentDefinition generic over a Container type.
  The Container type must conform to a new internal protocol
  ArgumentDefinitionContainer which describes functionality like default
  set of help options for the argument defined by the property wrapper,
  etc.
- Adds overloads for Optional @Arguments and @Options with default
  values which emit deprecation warning to guide users towards using the
  non-Optional versions.
2022-09-10 18:40:31 -05:00
Nate Cook 1141ed1e1b Support an async entry point for commands (#404)
Adds a new `AsyncParsableCommand` protocol, which provides a
`static func main() async` entry point and can call through to the root
command's or a subcommand's asynchronous `run()` method. For this
asynchronous execution, the root command must conform to `AsyncParsableCommand`,
but its subcommands can be a mix of asynchronous and synchronous commands.

Due to an issue in Swift 5.5, you can only use `@main` on an
`AsyncParsableCommand` root command starting in Swift 5.6.
This change also includes a workaround for clients that are using Swift 5.5.
Declare a separate type that conforms to `AsyncMainProtocol` and add the `@main`
attribute to that type.

```
@main enum Main: AsyncMain {
    typealias Command = <#command#>
}
```
2022-03-14 18:14:09 -05:00