initCompleteCmd adds a special hidden command that can be used to request custom completions.
(args []string)
| 229 | |
| 230 | // initCompleteCmd adds a special hidden command that can be used to request custom completions. |
| 231 | func (c *Command) initCompleteCmd(args []string) { |
| 232 | completeCmd := &Command{ |
| 233 | Use: fmt.Sprintf("%s [command-line]", ShellCompRequestCmd), |
| 234 | Aliases: []string{ShellCompNoDescRequestCmd}, |
| 235 | DisableFlagsInUseLine: true, |
| 236 | Hidden: true, |
| 237 | DisableFlagParsing: true, |
| 238 | Args: MinimumNArgs(1), |
| 239 | Short: "Request shell completion choices for the specified command-line", |
| 240 | Long: fmt.Sprintf("%[2]s is a special command that is used by the shell completion logic\n%[1]s", |
| 241 | "to request completion choices for the specified command-line.", ShellCompRequestCmd), |
| 242 | Run: func(cmd *Command, args []string) { |
| 243 | finalCmd, completions, directive, err := cmd.getCompletions(args) |
| 244 | if err != nil { |
| 245 | CompErrorln(err.Error()) |
| 246 | // Keep going for multiple reasons: |
| 247 | // 1- There could be some valid completions even though there was an error |
| 248 | // 2- Even without completions, we need to print the directive |
| 249 | } |
| 250 | |
| 251 | noDescriptions := cmd.CalledAs() == ShellCompNoDescRequestCmd |
| 252 | if !noDescriptions { |
| 253 | if doDescriptions, err := strconv.ParseBool(getEnvConfig(cmd, configEnvVarSuffixDescriptions)); err == nil { |
| 254 | noDescriptions = !doDescriptions |
| 255 | } |
| 256 | } |
| 257 | noActiveHelp := GetActiveHelpConfig(finalCmd) == activeHelpGlobalDisable |
| 258 | out := finalCmd.OutOrStdout() |
| 259 | for _, comp := range completions { |
| 260 | if noActiveHelp && strings.HasPrefix(comp, activeHelpMarker) { |
| 261 | // Remove all activeHelp entries if it's disabled. |
| 262 | continue |
| 263 | } |
| 264 | if noDescriptions { |
| 265 | // Remove any description that may be included following a tab character. |
| 266 | comp = strings.SplitN(comp, "\t", 2)[0] |
| 267 | } |
| 268 | |
| 269 | // Make sure we only write the first line to the output. |
| 270 | // This is needed if a description contains a linebreak. |
| 271 | // Otherwise the shell scripts will interpret the other lines as new flags |
| 272 | // and could therefore provide a wrong completion. |
| 273 | comp = strings.SplitN(comp, "\n", 2)[0] |
| 274 | |
| 275 | // Finally trim the completion. This is especially important to get rid |
| 276 | // of a trailing tab when there are no description following it. |
| 277 | // For example, a sub-command without a description should not be completed |
| 278 | // with a tab at the end (or else zsh will show a -- following it |
| 279 | // although there is no description). |
| 280 | comp = strings.TrimSpace(comp) |
| 281 | |
| 282 | // Print each possible completion to the output for the completion script to consume. |
| 283 | fmt.Fprintln(out, comp) |
| 284 | } |
| 285 | |
| 286 | // As the last printout, print the completion directive for the completion script to parse. |
| 287 | // The directive integer must be that last character following a single colon (:). |
| 288 | // The completion script expects :<directive> |