|
9 | 9 | //
|
10 | 10 | //===----------------------------------------------------------------------===//
|
11 | 11 |
|
12 |
| -/// The type of completion to use for an argument or option. |
| 12 | +/// The type of completion to use for an argument or option value. |
| 13 | +/// |
| 14 | +/// For all `CompletionKind`s, the completion shell script is configured with |
| 15 | +/// the following settings, which will not affect the requesting shell outside |
| 16 | +/// the completion script: |
| 17 | +/// |
| 18 | +/// ### bash |
| 19 | +/// |
| 20 | +/// ```shell |
| 21 | +/// shopt -s extglob |
| 22 | +/// set +o history +o posix |
| 23 | +/// ``` |
| 24 | +/// |
| 25 | +/// ### fish |
| 26 | +/// |
| 27 | +/// no settings |
| 28 | +/// |
| 29 | +/// ### zsh |
| 30 | +/// |
| 31 | +/// ```shell |
| 32 | +/// emulate -RL zsh -G |
| 33 | +/// setopt extendedglob nullglob numericglobsort |
| 34 | +/// unsetopt aliases banghist |
| 35 | +/// ``` |
13 | 36 | public struct CompletionKind {
|
14 | 37 | internal enum Kind {
|
15 |
| - /// Use the default completion kind for the value's type. |
16 | 38 | case `default`
|
17 |
| - |
18 |
| - /// Use the specified list of completion strings. |
19 | 39 | case list([String])
|
20 |
| - |
21 |
| - /// Complete file names with the specified extensions. |
22 | 40 | case file(extensions: [String])
|
23 |
| - |
24 |
| - /// Complete directory names that match the specified pattern. |
25 | 41 | case directory
|
26 |
| - |
27 |
| - /// Call the given shell command to generate completions. |
28 | 42 | case shellCommand(String)
|
29 |
| - |
30 |
| - /// Generate completions using the given closure. |
31 | 43 | case custom(@Sendable ([String]) -> [String])
|
32 | 44 | }
|
33 | 45 |
|
34 | 46 | internal var kind: Kind
|
35 | 47 |
|
36 |
| - /// Use the default completion kind for the value's type. |
| 48 | + /// Use the default completion kind for the argument's or option value's type. |
37 | 49 | public static var `default`: CompletionKind {
|
38 | 50 | CompletionKind(kind: .default)
|
39 | 51 | }
|
40 | 52 |
|
41 |
| - /// Use the specified list of completion strings. |
| 53 | + /// The completion candidates are the strings in the given array. |
| 54 | + /// |
| 55 | + /// Completion candidates are interpreted by the requesting shell as literals. |
| 56 | + /// They must be neither escaped nor quoted; Swift Argument Parser escapes or |
| 57 | + /// quotes them as necessary for the requesting shell. |
| 58 | + /// |
| 59 | + /// The completion candidates are included in a completion script when it is |
| 60 | + /// generated. |
42 | 61 | public static func list(_ words: [String]) -> CompletionKind {
|
43 | 62 | CompletionKind(kind: .list(words))
|
44 | 63 | }
|
45 | 64 |
|
46 |
| - /// Complete file names. |
| 65 | + /// The completion candidates include directory and file names, the latter |
| 66 | + /// filtered by the given list of extensions. |
| 67 | + /// |
| 68 | + /// If the given list of extensions is empty, then file names are not |
| 69 | + /// filtered. |
| 70 | + /// |
| 71 | + /// Given file extensions must not include the `.` initial extension |
| 72 | + /// separator. |
| 73 | + /// |
| 74 | + /// Given file extensions are parsed by the requesting shell as globs; Swift |
| 75 | + /// Argument Parser does not perform any escaping or quoting. |
| 76 | + /// |
| 77 | + /// The directory/file filter and the given list of extensions are included in |
| 78 | + /// a completion script when it is generated. |
47 | 79 | public static func file(extensions: [String] = []) -> CompletionKind {
|
48 | 80 | CompletionKind(kind: .file(extensions: extensions))
|
49 | 81 | }
|
50 | 82 |
|
51 |
| - /// Complete directory names. |
| 83 | + /// The completion candidates are directory names. |
| 84 | + /// |
| 85 | + /// The directory filter is included in a completion script when it is |
| 86 | + /// generated. |
52 | 87 | public static var directory: CompletionKind {
|
53 | 88 | CompletionKind(kind: .directory)
|
54 | 89 | }
|
55 | 90 |
|
56 |
| - /// Call the given shell command to generate completions. |
| 91 | + /// The completion candidates are specified by the `stdout` output of the |
| 92 | + /// given string run as a shell command when a user requests completions. |
| 93 | + /// |
| 94 | + /// Swift Argument Parser does not perform any escaping or quoting on the |
| 95 | + /// given shell command. |
| 96 | + /// |
| 97 | + /// The given shell command is included in a completion script when it is |
| 98 | + /// generated. |
57 | 99 | public static func shellCommand(_ command: String) -> CompletionKind {
|
58 | 100 | CompletionKind(kind: .shellCommand(command))
|
59 | 101 | }
|
60 | 102 |
|
61 |
| - /// Generate completions using the given closure. |
| 103 | + /// The completion candidates are the strings in the array returned by the |
| 104 | + /// given closure when it is executed in response to a user's request for |
| 105 | + /// completions. |
| 106 | + /// |
| 107 | + /// Completion candidates are interpreted by the requesting shell as literals. |
| 108 | + /// They must be neither escaped nor quoted; Swift Argument Parser escapes or |
| 109 | + /// quotes them as necessary for the requesting shell. |
| 110 | + /// |
| 111 | + /// The given closure is evaluated after a user invokes completion in their |
| 112 | + /// shell (normally by pressing TAB); it is not evaluated when a completion |
| 113 | + /// script is generated. |
| 114 | + /// |
| 115 | + /// The array of strings passed to the given closure contains all the shell |
| 116 | + /// words in the command line for the current command at completion |
| 117 | + /// invocation; this is exclusive of words for prior or subsequent commands or |
| 118 | + /// pipes, but inclusive of redirects and any other command line elements. |
| 119 | + /// Each word is its own element in the argument array; they appear in the |
| 120 | + /// same order as in the command line. Note that shell words may contain |
| 121 | + /// spaces if they are escaped or quoted. |
| 122 | + /// |
| 123 | + /// Shell words are passed to Swift verbatim, without processing or removing |
| 124 | + /// any quotes or escapes. For example, the shell word `"abc\\""def"` would be |
| 125 | + /// passed to Swift as `"abc\\""def"` (i.e. the Swift String's contents would |
| 126 | + /// include all 4 of the double quotes and the 2 consecutive backslashes). |
| 127 | + /// |
| 128 | + /// ### bash |
| 129 | + /// |
| 130 | + /// In bash 3-, a process substitution (`<(…)`) in the command line prevents |
| 131 | + /// Swift custom completion functions from being called. |
| 132 | + /// |
| 133 | + /// In bash 4+, a process substitution (`<(…)`) is split into multiple |
| 134 | + /// elements in the argument array: one for the starting `<(`, and one for |
| 135 | + /// each unescaped/unquoted-space-separated token through the closing `)`. |
| 136 | + /// |
| 137 | + /// In bash, if the cursor is between the backslash and the single quote for |
| 138 | + /// the last escaped single quote in a word, all subsequent pipes or other |
| 139 | + /// commands are included in the words passed to Swift. This oddity might |
| 140 | + /// occur only when additional constraints are met. This or similar oddities |
| 141 | + /// might occur in other circumstances. |
| 142 | + /// |
| 143 | + /// ### fish |
| 144 | + /// |
| 145 | + /// In fish 3-, due to a bug, the argument array includes the fish words only |
| 146 | + /// through the word being completed. This is fixed in fish 4+. |
| 147 | + /// |
| 148 | + /// In fish, a redirect's symbol is not included, but its source/target is. |
| 149 | + /// |
| 150 | + /// In fish 3-, due to limitations, words are passed to Swift unquoted. For |
| 151 | + /// example, the shell word `"abc\\""def"` would be passed to Swift as |
| 152 | + /// `abc\def`. This is fixed in fish 4+. |
| 153 | + /// |
| 154 | + /// ### zsh |
| 155 | + /// |
| 156 | + /// In zsh, redirects (both their symbol and source/target) are omitted. |
62 | 157 | @preconcurrency
|
63 | 158 | public static func custom(
|
64 | 159 | _ completion: @Sendable @escaping ([String]) -> [String]
|
|
0 commit comments