vendor/github.com/spf13/cobra/completions.go
author Mikael Berthe <mikael@lilotux.net>
Sat, 04 Feb 2023 12:58:35 +0100
changeset 265 05c40b36d3b2
parent 260 445e01aede7e
permissions -rw-r--r--
Bump to version 3.0.0-dev, using madon v3
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
265
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents: 260
diff changeset
     1
// Copyright 2013-2022 The Cobra Authors
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents: 260
diff changeset
     2
//
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents: 260
diff changeset
     3
// Licensed under the Apache License, Version 2.0 (the "License");
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents: 260
diff changeset
     4
// you may not use this file except in compliance with the License.
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents: 260
diff changeset
     5
// You may obtain a copy of the License at
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents: 260
diff changeset
     6
//
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents: 260
diff changeset
     7
//      http://www.apache.org/licenses/LICENSE-2.0
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents: 260
diff changeset
     8
//
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents: 260
diff changeset
     9
// Unless required by applicable law or agreed to in writing, software
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents: 260
diff changeset
    10
// distributed under the License is distributed on an "AS IS" BASIS,
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents: 260
diff changeset
    11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents: 260
diff changeset
    12
// See the License for the specific language governing permissions and
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents: 260
diff changeset
    13
// limitations under the License.
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents: 260
diff changeset
    14
256
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    15
package cobra
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    16
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    17
import (
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    18
	"fmt"
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    19
	"os"
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    20
	"strings"
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    21
	"sync"
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    22
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    23
	"github.com/spf13/pflag"
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    24
)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    25
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    26
const (
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    27
	// ShellCompRequestCmd is the name of the hidden command that is used to request
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    28
	// completion results from the program.  It is used by the shell completion scripts.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    29
	ShellCompRequestCmd = "__complete"
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    30
	// ShellCompNoDescRequestCmd is the name of the hidden command that is used to request
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    31
	// completion results without their description.  It is used by the shell completion scripts.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    32
	ShellCompNoDescRequestCmd = "__completeNoDesc"
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    33
)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    34
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    35
// Global map of flag completion functions. Make sure to use flagCompletionMutex before you try to read and write from it.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    36
var flagCompletionFunctions = map[*pflag.Flag]func(cmd *Command, args []string, toComplete string) ([]string, ShellCompDirective){}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    37
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    38
// lock for reading and writing from flagCompletionFunctions
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    39
var flagCompletionMutex = &sync.RWMutex{}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    40
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    41
// ShellCompDirective is a bit map representing the different behaviors the shell
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    42
// can be instructed to have once completions have been provided.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    43
type ShellCompDirective int
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    44
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    45
type flagCompError struct {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    46
	subCommand string
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    47
	flagName   string
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    48
}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    49
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    50
func (e *flagCompError) Error() string {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    51
	return "Subcommand '" + e.subCommand + "' does not support flag '" + e.flagName + "'"
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    52
}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    53
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    54
const (
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    55
	// ShellCompDirectiveError indicates an error occurred and completions should be ignored.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    56
	ShellCompDirectiveError ShellCompDirective = 1 << iota
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    57
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    58
	// ShellCompDirectiveNoSpace indicates that the shell should not add a space
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    59
	// after the completion even if there is a single completion provided.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    60
	ShellCompDirectiveNoSpace
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    61
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    62
	// ShellCompDirectiveNoFileComp indicates that the shell should not provide
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    63
	// file completion even when no completion is provided.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    64
	ShellCompDirectiveNoFileComp
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    65
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    66
	// ShellCompDirectiveFilterFileExt indicates that the provided completions
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    67
	// should be used as file extension filters.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    68
	// For flags, using Command.MarkFlagFilename() and Command.MarkPersistentFlagFilename()
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    69
	// is a shortcut to using this directive explicitly.  The BashCompFilenameExt
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    70
	// annotation can also be used to obtain the same behavior for flags.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    71
	ShellCompDirectiveFilterFileExt
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    72
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    73
	// ShellCompDirectiveFilterDirs indicates that only directory names should
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    74
	// be provided in file completion.  To request directory names within another
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    75
	// directory, the returned completions should specify the directory within
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    76
	// which to search.  The BashCompSubdirsInDir annotation can be used to
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    77
	// obtain the same behavior but only for flags.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    78
	ShellCompDirectiveFilterDirs
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    79
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    80
	// ===========================================================================
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    81
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    82
	// All directives using iota should be above this one.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    83
	// For internal use.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    84
	shellCompDirectiveMaxValue
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    85
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    86
	// ShellCompDirectiveDefault indicates to let the shell perform its default
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    87
	// behavior after completions have been provided.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    88
	// This one must be last to avoid messing up the iota count.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    89
	ShellCompDirectiveDefault ShellCompDirective = 0
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    90
)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    91
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    92
const (
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    93
	// Constants for the completion command
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    94
	compCmdName              = "completion"
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    95
	compCmdNoDescFlagName    = "no-descriptions"
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    96
	compCmdNoDescFlagDesc    = "disable completion descriptions"
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    97
	compCmdNoDescFlagDefault = false
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    98
)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    99
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   100
// CompletionOptions are the options to control shell completion
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   101
type CompletionOptions struct {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   102
	// DisableDefaultCmd prevents Cobra from creating a default 'completion' command
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   103
	DisableDefaultCmd bool
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   104
	// DisableNoDescFlag prevents Cobra from creating the '--no-descriptions' flag
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   105
	// for shells that support completion descriptions
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   106
	DisableNoDescFlag bool
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   107
	// DisableDescriptions turns off all completion descriptions for shells
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   108
	// that support them
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   109
	DisableDescriptions bool
260
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   110
	// HiddenDefaultCmd makes the default 'completion' command hidden
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   111
	HiddenDefaultCmd bool
256
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   112
}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   113
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   114
// NoFileCompletions can be used to disable file completion for commands that should
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   115
// not trigger file completions.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   116
func NoFileCompletions(cmd *Command, args []string, toComplete string) ([]string, ShellCompDirective) {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   117
	return nil, ShellCompDirectiveNoFileComp
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   118
}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   119
260
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   120
// FixedCompletions can be used to create a completion function which always
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   121
// returns the same results.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   122
func FixedCompletions(choices []string, directive ShellCompDirective) func(cmd *Command, args []string, toComplete string) ([]string, ShellCompDirective) {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   123
	return func(cmd *Command, args []string, toComplete string) ([]string, ShellCompDirective) {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   124
		return choices, directive
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   125
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   126
}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   127
256
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   128
// RegisterFlagCompletionFunc should be called to register a function to provide completion for a flag.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   129
func (c *Command) RegisterFlagCompletionFunc(flagName string, f func(cmd *Command, args []string, toComplete string) ([]string, ShellCompDirective)) error {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   130
	flag := c.Flag(flagName)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   131
	if flag == nil {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   132
		return fmt.Errorf("RegisterFlagCompletionFunc: flag '%s' does not exist", flagName)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   133
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   134
	flagCompletionMutex.Lock()
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   135
	defer flagCompletionMutex.Unlock()
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   136
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   137
	if _, exists := flagCompletionFunctions[flag]; exists {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   138
		return fmt.Errorf("RegisterFlagCompletionFunc: flag '%s' already registered", flagName)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   139
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   140
	flagCompletionFunctions[flag] = f
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   141
	return nil
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   142
}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   143
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   144
// Returns a string listing the different directive enabled in the specified parameter
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   145
func (d ShellCompDirective) string() string {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   146
	var directives []string
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   147
	if d&ShellCompDirectiveError != 0 {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   148
		directives = append(directives, "ShellCompDirectiveError")
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   149
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   150
	if d&ShellCompDirectiveNoSpace != 0 {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   151
		directives = append(directives, "ShellCompDirectiveNoSpace")
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   152
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   153
	if d&ShellCompDirectiveNoFileComp != 0 {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   154
		directives = append(directives, "ShellCompDirectiveNoFileComp")
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   155
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   156
	if d&ShellCompDirectiveFilterFileExt != 0 {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   157
		directives = append(directives, "ShellCompDirectiveFilterFileExt")
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   158
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   159
	if d&ShellCompDirectiveFilterDirs != 0 {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   160
		directives = append(directives, "ShellCompDirectiveFilterDirs")
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   161
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   162
	if len(directives) == 0 {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   163
		directives = append(directives, "ShellCompDirectiveDefault")
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   164
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   165
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   166
	if d >= shellCompDirectiveMaxValue {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   167
		return fmt.Sprintf("ERROR: unexpected ShellCompDirective value: %d", d)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   168
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   169
	return strings.Join(directives, ", ")
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   170
}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   171
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   172
// Adds a special hidden command that can be used to request custom completions.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   173
func (c *Command) initCompleteCmd(args []string) {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   174
	completeCmd := &Command{
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   175
		Use:                   fmt.Sprintf("%s [command-line]", ShellCompRequestCmd),
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   176
		Aliases:               []string{ShellCompNoDescRequestCmd},
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   177
		DisableFlagsInUseLine: true,
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   178
		Hidden:                true,
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   179
		DisableFlagParsing:    true,
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   180
		Args:                  MinimumNArgs(1),
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   181
		Short:                 "Request shell completion choices for the specified command-line",
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   182
		Long: fmt.Sprintf("%[2]s is a special command that is used by the shell completion logic\n%[1]s",
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   183
			"to request completion choices for the specified command-line.", ShellCompRequestCmd),
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   184
		Run: func(cmd *Command, args []string) {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   185
			finalCmd, completions, directive, err := cmd.getCompletions(args)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   186
			if err != nil {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   187
				CompErrorln(err.Error())
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   188
				// Keep going for multiple reasons:
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   189
				// 1- There could be some valid completions even though there was an error
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   190
				// 2- Even without completions, we need to print the directive
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   191
			}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   192
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   193
			noDescriptions := (cmd.CalledAs() == ShellCompNoDescRequestCmd)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   194
			for _, comp := range completions {
260
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   195
				if GetActiveHelpConfig(finalCmd) == activeHelpGlobalDisable {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   196
					// Remove all activeHelp entries in this case
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   197
					if strings.HasPrefix(comp, activeHelpMarker) {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   198
						continue
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   199
					}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   200
				}
256
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   201
				if noDescriptions {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   202
					// Remove any description that may be included following a tab character.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   203
					comp = strings.Split(comp, "\t")[0]
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   204
				}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   205
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   206
				// Make sure we only write the first line to the output.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   207
				// This is needed if a description contains a linebreak.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   208
				// Otherwise the shell scripts will interpret the other lines as new flags
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   209
				// and could therefore provide a wrong completion.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   210
				comp = strings.Split(comp, "\n")[0]
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   211
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   212
				// Finally trim the completion.  This is especially important to get rid
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   213
				// of a trailing tab when there are no description following it.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   214
				// For example, a sub-command without a description should not be completed
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   215
				// with a tab at the end (or else zsh will show a -- following it
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   216
				// although there is no description).
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   217
				comp = strings.TrimSpace(comp)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   218
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   219
				// Print each possible completion to stdout for the completion script to consume.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   220
				fmt.Fprintln(finalCmd.OutOrStdout(), comp)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   221
			}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   222
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   223
			// As the last printout, print the completion directive for the completion script to parse.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   224
			// The directive integer must be that last character following a single colon (:).
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   225
			// The completion script expects :<directive>
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   226
			fmt.Fprintf(finalCmd.OutOrStdout(), ":%d\n", directive)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   227
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   228
			// Print some helpful info to stderr for the user to understand.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   229
			// Output from stderr must be ignored by the completion script.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   230
			fmt.Fprintf(finalCmd.ErrOrStderr(), "Completion ended with directive: %s\n", directive.string())
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   231
		},
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   232
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   233
	c.AddCommand(completeCmd)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   234
	subCmd, _, err := c.Find(args)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   235
	if err != nil || subCmd.Name() != ShellCompRequestCmd {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   236
		// Only create this special command if it is actually being called.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   237
		// This reduces possible side-effects of creating such a command;
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   238
		// for example, having this command would cause problems to a
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   239
		// cobra program that only consists of the root command, since this
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   240
		// command would cause the root command to suddenly have a subcommand.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   241
		c.RemoveCommand(completeCmd)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   242
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   243
}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   244
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   245
func (c *Command) getCompletions(args []string) (*Command, []string, ShellCompDirective, error) {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   246
	// The last argument, which is not completely typed by the user,
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   247
	// should not be part of the list of arguments
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   248
	toComplete := args[len(args)-1]
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   249
	trimmedArgs := args[:len(args)-1]
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   250
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   251
	var finalCmd *Command
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   252
	var finalArgs []string
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   253
	var err error
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   254
	// Find the real command for which completion must be performed
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   255
	// check if we need to traverse here to parse local flags on parent commands
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   256
	if c.Root().TraverseChildren {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   257
		finalCmd, finalArgs, err = c.Root().Traverse(trimmedArgs)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   258
	} else {
260
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   259
		// For Root commands that don't specify any value for their Args fields, when we call
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   260
		// Find(), if those Root commands don't have any sub-commands, they will accept arguments.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   261
		// However, because we have added the __complete sub-command in the current code path, the
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   262
		// call to Find() -> legacyArgs() will return an error if there are any arguments.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   263
		// To avoid this, we first remove the __complete command to get back to having no sub-commands.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   264
		rootCmd := c.Root()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   265
		if len(rootCmd.Commands()) == 1 {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   266
			rootCmd.RemoveCommand(c)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   267
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   268
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   269
		finalCmd, finalArgs, err = rootCmd.Find(trimmedArgs)
256
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   270
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   271
	if err != nil {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   272
		// Unable to find the real command. E.g., <program> someInvalidCmd <TAB>
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   273
		return c, []string{}, ShellCompDirectiveDefault, fmt.Errorf("Unable to find a command for arguments: %v", trimmedArgs)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   274
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   275
	finalCmd.ctx = c.ctx
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   276
265
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents: 260
diff changeset
   277
	// These flags are normally added when `execute()` is called on `finalCmd`,
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents: 260
diff changeset
   278
	// however, when doing completion, we don't call `finalCmd.execute()`.
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents: 260
diff changeset
   279
	// Let's add the --help and --version flag ourselves.
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents: 260
diff changeset
   280
	finalCmd.InitDefaultHelpFlag()
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents: 260
diff changeset
   281
	finalCmd.InitDefaultVersionFlag()
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents: 260
diff changeset
   282
256
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   283
	// Check if we are doing flag value completion before parsing the flags.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   284
	// This is important because if we are completing a flag value, we need to also
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   285
	// remove the flag name argument from the list of finalArgs or else the parsing
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   286
	// could fail due to an invalid value (incomplete) for the flag.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   287
	flag, finalArgs, toComplete, flagErr := checkIfFlagCompletion(finalCmd, finalArgs, toComplete)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   288
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   289
	// Check if interspersed is false or -- was set on a previous arg.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   290
	// This works by counting the arguments. Normally -- is not counted as arg but
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   291
	// if -- was already set or interspersed is false and there is already one arg then
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   292
	// the extra added -- is counted as arg.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   293
	flagCompletion := true
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   294
	_ = finalCmd.ParseFlags(append(finalArgs, "--"))
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   295
	newArgCount := finalCmd.Flags().NArg()
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   296
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   297
	// Parse the flags early so we can check if required flags are set
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   298
	if err = finalCmd.ParseFlags(finalArgs); err != nil {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   299
		return finalCmd, []string{}, ShellCompDirectiveDefault, fmt.Errorf("Error while parsing flags from args %v: %s", finalArgs, err.Error())
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   300
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   301
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   302
	realArgCount := finalCmd.Flags().NArg()
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   303
	if newArgCount > realArgCount {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   304
		// don't do flag completion (see above)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   305
		flagCompletion = false
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   306
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   307
	// Error while attempting to parse flags
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   308
	if flagErr != nil {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   309
		// If error type is flagCompError and we don't want flagCompletion we should ignore the error
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   310
		if _, ok := flagErr.(*flagCompError); !(ok && !flagCompletion) {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   311
			return finalCmd, []string{}, ShellCompDirectiveDefault, flagErr
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   312
		}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   313
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   314
265
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents: 260
diff changeset
   315
	// Look for the --help or --version flags.  If they are present,
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents: 260
diff changeset
   316
	// there should be no further completions.
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents: 260
diff changeset
   317
	if helpOrVersionFlagPresent(finalCmd) {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents: 260
diff changeset
   318
		return finalCmd, []string{}, ShellCompDirectiveNoFileComp, nil
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents: 260
diff changeset
   319
	}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents: 260
diff changeset
   320
260
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   321
	// We only remove the flags from the arguments if DisableFlagParsing is not set.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   322
	// This is important for commands which have requested to do their own flag completion.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   323
	if !finalCmd.DisableFlagParsing {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   324
		finalArgs = finalCmd.Flags().Args()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   325
	}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   326
256
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   327
	if flag != nil && flagCompletion {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   328
		// Check if we are completing a flag value subject to annotations
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   329
		if validExts, present := flag.Annotations[BashCompFilenameExt]; present {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   330
			if len(validExts) != 0 {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   331
				// File completion filtered by extensions
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   332
				return finalCmd, validExts, ShellCompDirectiveFilterFileExt, nil
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   333
			}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   334
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   335
			// The annotation requests simple file completion.  There is no reason to do
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   336
			// that since it is the default behavior anyway.  Let's ignore this annotation
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   337
			// in case the program also registered a completion function for this flag.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   338
			// Even though it is a mistake on the program's side, let's be nice when we can.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   339
		}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   340
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   341
		if subDir, present := flag.Annotations[BashCompSubdirsInDir]; present {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   342
			if len(subDir) == 1 {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   343
				// Directory completion from within a directory
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   344
				return finalCmd, subDir, ShellCompDirectiveFilterDirs, nil
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   345
			}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   346
			// Directory completion
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   347
			return finalCmd, []string{}, ShellCompDirectiveFilterDirs, nil
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   348
		}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   349
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   350
260
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   351
	var completions []string
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   352
	var directive ShellCompDirective
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   353
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   354
	// Enforce flag groups before doing flag completions
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   355
	finalCmd.enforceFlagGroupsForCompletion()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   356
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   357
	// Note that we want to perform flagname completion even if finalCmd.DisableFlagParsing==true;
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   358
	// doing this allows for completion of persistent flag names even for commands that disable flag parsing.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   359
	//
256
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   360
	// When doing completion of a flag name, as soon as an argument starts with
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   361
	// a '-' we know it is a flag.  We cannot use isFlagArg() here as it requires
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   362
	// the flag name to be complete
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   363
	if flag == nil && len(toComplete) > 0 && toComplete[0] == '-' && !strings.Contains(toComplete, "=") && flagCompletion {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   364
		// First check for required flags
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   365
		completions = completeRequireFlags(finalCmd, toComplete)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   366
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   367
		// If we have not found any required flags, only then can we show regular flags
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   368
		if len(completions) == 0 {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   369
			doCompleteFlags := func(flag *pflag.Flag) {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   370
				if !flag.Changed ||
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   371
					strings.Contains(flag.Value.Type(), "Slice") ||
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   372
					strings.Contains(flag.Value.Type(), "Array") {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   373
					// If the flag is not already present, or if it can be specified multiple times (Array or Slice)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   374
					// we suggest it as a completion
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   375
					completions = append(completions, getFlagNameCompletions(flag, toComplete)...)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   376
				}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   377
			}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   378
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   379
			// We cannot use finalCmd.Flags() because we may not have called ParsedFlags() for commands
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   380
			// that have set DisableFlagParsing; it is ParseFlags() that merges the inherited and
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   381
			// non-inherited flags.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   382
			finalCmd.InheritedFlags().VisitAll(func(flag *pflag.Flag) {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   383
				doCompleteFlags(flag)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   384
			})
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   385
			finalCmd.NonInheritedFlags().VisitAll(func(flag *pflag.Flag) {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   386
				doCompleteFlags(flag)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   387
			})
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   388
		}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   389
260
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   390
		directive = ShellCompDirectiveNoFileComp
256
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   391
		if len(completions) == 1 && strings.HasSuffix(completions[0], "=") {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   392
			// If there is a single completion, the shell usually adds a space
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   393
			// after the completion.  We don't want that if the flag ends with an =
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   394
			directive = ShellCompDirectiveNoSpace
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   395
		}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   396
260
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   397
		if !finalCmd.DisableFlagParsing {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   398
			// If DisableFlagParsing==false, we have completed the flags as known by Cobra;
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   399
			// we can return what we found.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   400
			// If DisableFlagParsing==true, Cobra may not be aware of all flags, so we
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   401
			// let the logic continue to see if ValidArgsFunction needs to be called.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   402
			return finalCmd, completions, directive, nil
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   403
		}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   404
	} else {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   405
		directive = ShellCompDirectiveDefault
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   406
		if flag == nil {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   407
			foundLocalNonPersistentFlag := false
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   408
			// If TraverseChildren is true on the root command we don't check for
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   409
			// local flags because we can use a local flag on a parent command
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   410
			if !finalCmd.Root().TraverseChildren {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   411
				// Check if there are any local, non-persistent flags on the command-line
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   412
				localNonPersistentFlags := finalCmd.LocalNonPersistentFlags()
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   413
				finalCmd.NonInheritedFlags().VisitAll(func(flag *pflag.Flag) {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   414
					if localNonPersistentFlags.Lookup(flag.Name) != nil && flag.Changed {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   415
						foundLocalNonPersistentFlag = true
256
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   416
					}
260
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   417
				})
256
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   418
			}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   419
260
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   420
			// Complete subcommand names, including the help command
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   421
			if len(finalArgs) == 0 && !foundLocalNonPersistentFlag {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   422
				// We only complete sub-commands if:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   423
				// - there are no arguments on the command-line and
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   424
				// - there are no local, non-persistent flags on the command-line or TraverseChildren is true
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   425
				for _, subCmd := range finalCmd.Commands() {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   426
					if subCmd.IsAvailableCommand() || subCmd == finalCmd.helpCommand {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   427
						if strings.HasPrefix(subCmd.Name(), toComplete) {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   428
							completions = append(completions, fmt.Sprintf("%s\t%s", subCmd.Name(), subCmd.Short))
256
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   429
						}
260
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   430
						directive = ShellCompDirectiveNoFileComp
256
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   431
					}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   432
				}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   433
			}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   434
260
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   435
			// Complete required flags even without the '-' prefix
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   436
			completions = append(completions, completeRequireFlags(finalCmd, toComplete)...)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   437
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   438
			// Always complete ValidArgs, even if we are completing a subcommand name.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   439
			// This is for commands that have both subcommands and ValidArgs.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   440
			if len(finalCmd.ValidArgs) > 0 {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   441
				if len(finalArgs) == 0 {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   442
					// ValidArgs are only for the first argument
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   443
					for _, validArg := range finalCmd.ValidArgs {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   444
						if strings.HasPrefix(validArg, toComplete) {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   445
							completions = append(completions, validArg)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   446
						}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   447
					}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   448
					directive = ShellCompDirectiveNoFileComp
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   449
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   450
					// If no completions were found within commands or ValidArgs,
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   451
					// see if there are any ArgAliases that should be completed.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   452
					if len(completions) == 0 {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   453
						for _, argAlias := range finalCmd.ArgAliases {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   454
							if strings.HasPrefix(argAlias, toComplete) {
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   455
								completions = append(completions, argAlias)
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   456
							}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   457
						}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   458
					}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   459
				}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   460
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   461
				// If there are ValidArgs specified (even if they don't match), we stop completion.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   462
				// Only one of ValidArgs or ValidArgsFunction can be used for a single command.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   463
				return finalCmd, completions, directive, nil
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   464
			}
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   465
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   466
			// Let the logic continue so as to add any ValidArgsFunction completions,
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   467
			// even if we already found sub-commands.
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   468
			// This is for commands that have subcommands but also specify a ValidArgsFunction.
256
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   469
		}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   470
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   471
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   472
	// Find the completion function for the flag or command
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   473
	var completionFn func(cmd *Command, args []string, toComplete string) ([]string, ShellCompDirective)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   474
	if flag != nil && flagCompletion {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   475
		flagCompletionMutex.RLock()
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   476
		completionFn = flagCompletionFunctions[flag]
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   477
		flagCompletionMutex.RUnlock()
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   478
	} else {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   479
		completionFn = finalCmd.ValidArgsFunction
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   480
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   481
	if completionFn != nil {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   482
		// Go custom completion defined for this flag or command.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   483
		// Call the registered completion function to get the completions.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   484
		var comps []string
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   485
		comps, directive = completionFn(finalCmd, finalArgs, toComplete)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   486
		completions = append(completions, comps...)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   487
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   488
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   489
	return finalCmd, completions, directive, nil
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   490
}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   491
265
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents: 260
diff changeset
   492
func helpOrVersionFlagPresent(cmd *Command) bool {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents: 260
diff changeset
   493
	if versionFlag := cmd.Flags().Lookup("version"); versionFlag != nil &&
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents: 260
diff changeset
   494
		len(versionFlag.Annotations[FlagSetByCobraAnnotation]) > 0 && versionFlag.Changed {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents: 260
diff changeset
   495
		return true
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents: 260
diff changeset
   496
	}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents: 260
diff changeset
   497
	if helpFlag := cmd.Flags().Lookup("help"); helpFlag != nil &&
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents: 260
diff changeset
   498
		len(helpFlag.Annotations[FlagSetByCobraAnnotation]) > 0 && helpFlag.Changed {
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents: 260
diff changeset
   499
		return true
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents: 260
diff changeset
   500
	}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents: 260
diff changeset
   501
	return false
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents: 260
diff changeset
   502
}
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents: 260
diff changeset
   503
256
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   504
func getFlagNameCompletions(flag *pflag.Flag, toComplete string) []string {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   505
	if nonCompletableFlag(flag) {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   506
		return []string{}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   507
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   508
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   509
	var completions []string
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   510
	flagName := "--" + flag.Name
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   511
	if strings.HasPrefix(flagName, toComplete) {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   512
		// Flag without the =
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   513
		completions = append(completions, fmt.Sprintf("%s\t%s", flagName, flag.Usage))
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   514
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   515
		// Why suggest both long forms: --flag and --flag= ?
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   516
		// This forces the user to *always* have to type either an = or a space after the flag name.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   517
		// Let's be nice and avoid making users have to do that.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   518
		// Since boolean flags and shortname flags don't show the = form, let's go that route and never show it.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   519
		// The = form will still work, we just won't suggest it.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   520
		// This also makes the list of suggested flags shorter as we avoid all the = forms.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   521
		//
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   522
		// if len(flag.NoOptDefVal) == 0 {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   523
		// 	// Flag requires a value, so it can be suffixed with =
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   524
		// 	flagName += "="
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   525
		// 	completions = append(completions, fmt.Sprintf("%s\t%s", flagName, flag.Usage))
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   526
		// }
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   527
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   528
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   529
	flagName = "-" + flag.Shorthand
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   530
	if len(flag.Shorthand) > 0 && strings.HasPrefix(flagName, toComplete) {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   531
		completions = append(completions, fmt.Sprintf("%s\t%s", flagName, flag.Usage))
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   532
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   533
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   534
	return completions
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   535
}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   536
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   537
func completeRequireFlags(finalCmd *Command, toComplete string) []string {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   538
	var completions []string
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   539
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   540
	doCompleteRequiredFlags := func(flag *pflag.Flag) {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   541
		if _, present := flag.Annotations[BashCompOneRequiredFlag]; present {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   542
			if !flag.Changed {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   543
				// If the flag is not already present, we suggest it as a completion
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   544
				completions = append(completions, getFlagNameCompletions(flag, toComplete)...)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   545
			}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   546
		}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   547
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   548
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   549
	// We cannot use finalCmd.Flags() because we may not have called ParsedFlags() for commands
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   550
	// that have set DisableFlagParsing; it is ParseFlags() that merges the inherited and
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   551
	// non-inherited flags.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   552
	finalCmd.InheritedFlags().VisitAll(func(flag *pflag.Flag) {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   553
		doCompleteRequiredFlags(flag)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   554
	})
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   555
	finalCmd.NonInheritedFlags().VisitAll(func(flag *pflag.Flag) {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   556
		doCompleteRequiredFlags(flag)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   557
	})
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   558
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   559
	return completions
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   560
}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   561
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   562
func checkIfFlagCompletion(finalCmd *Command, args []string, lastArg string) (*pflag.Flag, []string, string, error) {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   563
	if finalCmd.DisableFlagParsing {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   564
		// We only do flag completion if we are allowed to parse flags
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   565
		// This is important for commands which have requested to do their own flag completion.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   566
		return nil, args, lastArg, nil
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   567
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   568
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   569
	var flagName string
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   570
	trimmedArgs := args
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   571
	flagWithEqual := false
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   572
	orgLastArg := lastArg
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   573
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   574
	// When doing completion of a flag name, as soon as an argument starts with
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   575
	// a '-' we know it is a flag.  We cannot use isFlagArg() here as that function
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   576
	// requires the flag name to be complete
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   577
	if len(lastArg) > 0 && lastArg[0] == '-' {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   578
		if index := strings.Index(lastArg, "="); index >= 0 {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   579
			// Flag with an =
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   580
			if strings.HasPrefix(lastArg[:index], "--") {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   581
				// Flag has full name
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   582
				flagName = lastArg[2:index]
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   583
			} else {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   584
				// Flag is shorthand
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   585
				// We have to get the last shorthand flag name
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   586
				// e.g. `-asd` => d to provide the correct completion
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   587
				// https://github.com/spf13/cobra/issues/1257
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   588
				flagName = lastArg[index-1 : index]
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   589
			}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   590
			lastArg = lastArg[index+1:]
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   591
			flagWithEqual = true
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   592
		} else {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   593
			// Normal flag completion
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   594
			return nil, args, lastArg, nil
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   595
		}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   596
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   597
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   598
	if len(flagName) == 0 {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   599
		if len(args) > 0 {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   600
			prevArg := args[len(args)-1]
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   601
			if isFlagArg(prevArg) {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   602
				// Only consider the case where the flag does not contain an =.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   603
				// If the flag contains an = it means it has already been fully processed,
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   604
				// so we don't need to deal with it here.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   605
				if index := strings.Index(prevArg, "="); index < 0 {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   606
					if strings.HasPrefix(prevArg, "--") {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   607
						// Flag has full name
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   608
						flagName = prevArg[2:]
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   609
					} else {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   610
						// Flag is shorthand
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   611
						// We have to get the last shorthand flag name
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   612
						// e.g. `-asd` => d to provide the correct completion
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   613
						// https://github.com/spf13/cobra/issues/1257
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   614
						flagName = prevArg[len(prevArg)-1:]
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   615
					}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   616
					// Remove the uncompleted flag or else there could be an error created
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   617
					// for an invalid value for that flag
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   618
					trimmedArgs = args[:len(args)-1]
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   619
				}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   620
			}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   621
		}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   622
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   623
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   624
	if len(flagName) == 0 {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   625
		// Not doing flag completion
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   626
		return nil, trimmedArgs, lastArg, nil
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   627
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   628
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   629
	flag := findFlag(finalCmd, flagName)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   630
	if flag == nil {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   631
		// Flag not supported by this command, the interspersed option might be set so return the original args
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   632
		return nil, args, orgLastArg, &flagCompError{subCommand: finalCmd.Name(), flagName: flagName}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   633
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   634
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   635
	if !flagWithEqual {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   636
		if len(flag.NoOptDefVal) != 0 {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   637
			// We had assumed dealing with a two-word flag but the flag is a boolean flag.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   638
			// In that case, there is no value following it, so we are not really doing flag completion.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   639
			// Reset everything to do noun completion.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   640
			trimmedArgs = args
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   641
			flag = nil
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   642
		}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   643
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   644
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   645
	return flag, trimmedArgs, lastArg, nil
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   646
}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   647
265
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents: 260
diff changeset
   648
// InitDefaultCompletionCmd adds a default 'completion' command to c.
256
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   649
// This function will do nothing if any of the following is true:
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   650
// 1- the feature has been explicitly disabled by the program,
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   651
// 2- c has no subcommands (to avoid creating one),
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   652
// 3- c already has a 'completion' command provided by the program.
265
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents: 260
diff changeset
   653
func (c *Command) InitDefaultCompletionCmd() {
256
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   654
	if c.CompletionOptions.DisableDefaultCmd || !c.HasSubCommands() {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   655
		return
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   656
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   657
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   658
	for _, cmd := range c.commands {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   659
		if cmd.Name() == compCmdName || cmd.HasAlias(compCmdName) {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   660
			// A completion command is already available
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   661
			return
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   662
		}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   663
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   664
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   665
	haveNoDescFlag := !c.CompletionOptions.DisableNoDescFlag && !c.CompletionOptions.DisableDescriptions
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   666
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   667
	completionCmd := &Command{
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   668
		Use:   compCmdName,
260
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   669
		Short: "Generate the autocompletion script for the specified shell",
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   670
		Long: fmt.Sprintf(`Generate the autocompletion script for %[1]s for the specified shell.
256
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   671
See each sub-command's help for details on how to use the generated script.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   672
`, c.Root().Name()),
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   673
		Args:              NoArgs,
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   674
		ValidArgsFunction: NoFileCompletions,
260
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   675
		Hidden:            c.CompletionOptions.HiddenDefaultCmd,
265
05c40b36d3b2 Bump to version 3.0.0-dev, using madon v3
Mikael Berthe <mikael@lilotux.net>
parents: 260
diff changeset
   676
		GroupID:           c.completionCommandGroupID,
256
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   677
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   678
	c.AddCommand(completionCmd)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   679
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   680
	out := c.OutOrStdout()
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   681
	noDesc := c.CompletionOptions.DisableDescriptions
260
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   682
	shortDesc := "Generate the autocompletion script for %s"
256
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   683
	bash := &Command{
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   684
		Use:   "bash",
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   685
		Short: fmt.Sprintf(shortDesc, "bash"),
260
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   686
		Long: fmt.Sprintf(`Generate the autocompletion script for the bash shell.
256
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   687
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   688
This script depends on the 'bash-completion' package.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   689
If it is not installed already, you can install it via your OS's package manager.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   690
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   691
To load completions in your current shell session:
260
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   692
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   693
	source <(%[1]s completion bash)
256
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   694
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   695
To load completions for every new session, execute once:
260
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   696
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   697
#### Linux:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   698
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   699
	%[1]s completion bash > /etc/bash_completion.d/%[1]s
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   700
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   701
#### macOS:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   702
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   703
	%[1]s completion bash > $(brew --prefix)/etc/bash_completion.d/%[1]s
256
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   704
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   705
You will need to start a new shell for this setup to take effect.
260
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   706
`, c.Root().Name()),
256
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   707
		Args:                  NoArgs,
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   708
		DisableFlagsInUseLine: true,
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   709
		ValidArgsFunction:     NoFileCompletions,
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   710
		RunE: func(cmd *Command, args []string) error {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   711
			return cmd.Root().GenBashCompletionV2(out, !noDesc)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   712
		},
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   713
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   714
	if haveNoDescFlag {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   715
		bash.Flags().BoolVar(&noDesc, compCmdNoDescFlagName, compCmdNoDescFlagDefault, compCmdNoDescFlagDesc)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   716
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   717
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   718
	zsh := &Command{
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   719
		Use:   "zsh",
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   720
		Short: fmt.Sprintf(shortDesc, "zsh"),
260
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   721
		Long: fmt.Sprintf(`Generate the autocompletion script for the zsh shell.
256
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   722
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   723
If shell completion is not already enabled in your environment you will need
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   724
to enable it.  You can execute the following once:
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   725
260
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   726
	echo "autoload -U compinit; compinit" >> ~/.zshrc
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   727
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   728
To load completions in your current shell session:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   729
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   730
	source <(%[1]s completion zsh); compdef _%[1]s %[1]s
256
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   731
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   732
To load completions for every new session, execute once:
260
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   733
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   734
#### Linux:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   735
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   736
	%[1]s completion zsh > "${fpath[1]}/_%[1]s"
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   737
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   738
#### macOS:
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   739
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   740
	%[1]s completion zsh > $(brew --prefix)/share/zsh/site-functions/_%[1]s
256
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   741
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   742
You will need to start a new shell for this setup to take effect.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   743
`, c.Root().Name()),
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   744
		Args:              NoArgs,
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   745
		ValidArgsFunction: NoFileCompletions,
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   746
		RunE: func(cmd *Command, args []string) error {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   747
			if noDesc {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   748
				return cmd.Root().GenZshCompletionNoDesc(out)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   749
			}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   750
			return cmd.Root().GenZshCompletion(out)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   751
		},
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   752
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   753
	if haveNoDescFlag {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   754
		zsh.Flags().BoolVar(&noDesc, compCmdNoDescFlagName, compCmdNoDescFlagDefault, compCmdNoDescFlagDesc)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   755
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   756
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   757
	fish := &Command{
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   758
		Use:   "fish",
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   759
		Short: fmt.Sprintf(shortDesc, "fish"),
260
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   760
		Long: fmt.Sprintf(`Generate the autocompletion script for the fish shell.
256
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   761
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   762
To load completions in your current shell session:
260
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   763
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   764
	%[1]s completion fish | source
256
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   765
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   766
To load completions for every new session, execute once:
260
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   767
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   768
	%[1]s completion fish > ~/.config/fish/completions/%[1]s.fish
256
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   769
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   770
You will need to start a new shell for this setup to take effect.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   771
`, c.Root().Name()),
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   772
		Args:              NoArgs,
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   773
		ValidArgsFunction: NoFileCompletions,
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   774
		RunE: func(cmd *Command, args []string) error {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   775
			return cmd.Root().GenFishCompletion(out, !noDesc)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   776
		},
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   777
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   778
	if haveNoDescFlag {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   779
		fish.Flags().BoolVar(&noDesc, compCmdNoDescFlagName, compCmdNoDescFlagDefault, compCmdNoDescFlagDesc)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   780
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   781
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   782
	powershell := &Command{
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   783
		Use:   "powershell",
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   784
		Short: fmt.Sprintf(shortDesc, "powershell"),
260
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   785
		Long: fmt.Sprintf(`Generate the autocompletion script for powershell.
256
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   786
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   787
To load completions in your current shell session:
260
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   788
445e01aede7e Update vendor directory
Mikael Berthe <mikael@lilotux.net>
parents: 256
diff changeset
   789
	%[1]s completion powershell | Out-String | Invoke-Expression
256
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   790
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   791
To load completions for every new session, add the output of the above command
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   792
to your powershell profile.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   793
`, c.Root().Name()),
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   794
		Args:              NoArgs,
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   795
		ValidArgsFunction: NoFileCompletions,
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   796
		RunE: func(cmd *Command, args []string) error {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   797
			if noDesc {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   798
				return cmd.Root().GenPowerShellCompletion(out)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   799
			}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   800
			return cmd.Root().GenPowerShellCompletionWithDesc(out)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   801
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   802
		},
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   803
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   804
	if haveNoDescFlag {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   805
		powershell.Flags().BoolVar(&noDesc, compCmdNoDescFlagName, compCmdNoDescFlagDefault, compCmdNoDescFlagDesc)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   806
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   807
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   808
	completionCmd.AddCommand(bash, zsh, fish, powershell)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   809
}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   810
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   811
func findFlag(cmd *Command, name string) *pflag.Flag {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   812
	flagSet := cmd.Flags()
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   813
	if len(name) == 1 {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   814
		// First convert the short flag into a long flag
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   815
		// as the cmd.Flag() search only accepts long flags
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   816
		if short := flagSet.ShorthandLookup(name); short != nil {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   817
			name = short.Name
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   818
		} else {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   819
			set := cmd.InheritedFlags()
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   820
			if short = set.ShorthandLookup(name); short != nil {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   821
				name = short.Name
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   822
			} else {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   823
				return nil
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   824
			}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   825
		}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   826
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   827
	return cmd.Flag(name)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   828
}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   829
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   830
// CompDebug prints the specified string to the same file as where the
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   831
// completion script prints its logs.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   832
// Note that completion printouts should never be on stdout as they would
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   833
// be wrongly interpreted as actual completion choices by the completion script.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   834
func CompDebug(msg string, printToStdErr bool) {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   835
	msg = fmt.Sprintf("[Debug] %s", msg)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   836
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   837
	// Such logs are only printed when the user has set the environment
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   838
	// variable BASH_COMP_DEBUG_FILE to the path of some file to be used.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   839
	if path := os.Getenv("BASH_COMP_DEBUG_FILE"); path != "" {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   840
		f, err := os.OpenFile(path,
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   841
			os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   842
		if err == nil {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   843
			defer f.Close()
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   844
			WriteStringAndCheck(f, msg)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   845
		}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   846
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   847
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   848
	if printToStdErr {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   849
		// Must print to stderr for this not to be read by the completion script.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   850
		fmt.Fprint(os.Stderr, msg)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   851
	}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   852
}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   853
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   854
// CompDebugln prints the specified string with a newline at the end
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   855
// to the same file as where the completion script prints its logs.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   856
// Such logs are only printed when the user has set the environment
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   857
// variable BASH_COMP_DEBUG_FILE to the path of some file to be used.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   858
func CompDebugln(msg string, printToStdErr bool) {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   859
	CompDebug(fmt.Sprintf("%s\n", msg), printToStdErr)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   860
}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   861
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   862
// CompError prints the specified completion message to stderr.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   863
func CompError(msg string) {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   864
	msg = fmt.Sprintf("[Error] %s", msg)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   865
	CompDebug(msg, true)
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   866
}
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   867
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   868
// CompErrorln prints the specified completion message to stderr with a newline at the end.
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   869
func CompErrorln(msg string) {
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   870
	CompError(fmt.Sprintf("%s\n", msg))
6d9efbef00a9 Update dependencies
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   871
}