git.sr.ht/~pingoo/stdx@v0.0.0-20240218134121-094174641f6e/cobra/user_guide.md (about)

     1  # User Guide
     2  
     3  While you are welcome to provide your own organization, typically a Cobra-based
     4  application will follow the following organizational structure:
     5  
     6  ```
     7    ▾ appName/
     8      ▾ cmd/
     9          add.go
    10          your.go
    11          commands.go
    12          here.go
    13        main.go
    14  ```
    15  
    16  In a Cobra app, typically the main.go file is very bare. It serves one purpose: initializing Cobra.
    17  
    18  ```go
    19  package main
    20  
    21  import (
    22    "{pathToYourApp}/cmd"
    23  )
    24  
    25  func main() {
    26    cmd.Execute()
    27  }
    28  ```
    29  
    30  ## Using the Cobra Generator
    31  
    32  Cobra-CLI is its own program that will create your application and add any
    33  commands you want. It's the easiest way to incorporate Cobra into your application.
    34  
    35  For complete details on using the Cobra generator, please refer to [The Cobra-CLI Generator README](https://github.com/spf13/cobra-cli/blob/main/README.md)
    36  
    37  ## Using the Cobra Library
    38  
    39  To manually implement Cobra you need to create a bare main.go file and a rootCmd file.
    40  You will optionally provide additional commands as you see fit.
    41  
    42  ### Create rootCmd
    43  
    44  Cobra doesn't require any special constructors. Simply create your commands.
    45  
    46  Ideally you place this in app/cmd/root.go:
    47  
    48  ```go
    49  var rootCmd = &cobra.Command{
    50    Use:   "hugo",
    51    Short: "Hugo is a very fast static site generator",
    52    Long: `A Fast and Flexible Static Site Generator built with
    53                  love by spf13 and friends in Go.
    54                  Complete documentation is available at https://gohugo.io/documentation/`,
    55    Run: func(cmd *cobra.Command, args []string) {
    56      // Do Stuff Here
    57    },
    58  }
    59  
    60  func Execute() {
    61    if err := rootCmd.Execute(); err != nil {
    62      fmt.Fprintln(os.Stderr, err)
    63      os.Exit(1)
    64    }
    65  }
    66  ```
    67  
    68  You will additionally define flags and handle configuration in your init() function.
    69  
    70  For example cmd/root.go:
    71  
    72  ```go
    73  package cmd
    74  
    75  import (
    76  	"fmt"
    77  	"os"
    78  
    79  	"github.com/spf13/cobra"
    80  	"github.com/spf13/viper"
    81  )
    82  
    83  var (
    84  	// Used for flags.
    85  	cfgFile     string
    86  	userLicense string
    87  
    88  	rootCmd = &cobra.Command{
    89  		Use:   "cobra-cli",
    90  		Short: "A generator for Cobra based Applications",
    91  		Long: `Cobra is a CLI library for Go that empowers applications.
    92  This application is a tool to generate the needed files
    93  to quickly create a Cobra application.`,
    94  	}
    95  )
    96  
    97  // Execute executes the root command.
    98  func Execute() error {
    99  	return rootCmd.Execute()
   100  }
   101  
   102  func init() {
   103  	cobra.OnInitialize(initConfig)
   104  
   105  	rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.cobra.yaml)")
   106  	rootCmd.PersistentFlags().StringP("author", "a", "YOUR NAME", "author name for copyright attribution")
   107  	rootCmd.PersistentFlags().StringVarP(&userLicense, "license", "l", "", "name of license for the project")
   108  	rootCmd.PersistentFlags().Bool("viper", true, "use Viper for configuration")
   109  	viper.BindPFlag("author", rootCmd.PersistentFlags().Lookup("author"))
   110  	viper.BindPFlag("useViper", rootCmd.PersistentFlags().Lookup("viper"))
   111  	viper.SetDefault("author", "NAME HERE <EMAIL ADDRESS>")
   112  	viper.SetDefault("license", "apache")
   113  
   114  	rootCmd.AddCommand(addCmd)
   115  	rootCmd.AddCommand(initCmd)
   116  }
   117  
   118  func initConfig() {
   119  	if cfgFile != "" {
   120  		// Use config file from the flag.
   121  		viper.SetConfigFile(cfgFile)
   122  	} else {
   123  		// Find home directory.
   124  		home, err := os.UserHomeDir()
   125  		cobra.CheckErr(err)
   126  
   127  		// Search config in home directory with name ".cobra" (without extension).
   128  		viper.AddConfigPath(home)
   129  		viper.SetConfigType("yaml")
   130  		viper.SetConfigName(".cobra")
   131  	}
   132  
   133  	viper.AutomaticEnv()
   134  
   135  	if err := viper.ReadInConfig(); err == nil {
   136  		fmt.Println("Using config file:", viper.ConfigFileUsed())
   137  	}
   138  }
   139  ```
   140  
   141  ### Create your main.go
   142  
   143  With the root command you need to have your main function execute it.
   144  Execute should be run on the root for clarity, though it can be called on any command.
   145  
   146  In a Cobra app, typically the main.go file is very bare. It serves one purpose: to initialize Cobra.
   147  
   148  ```go
   149  package main
   150  
   151  import (
   152    "{pathToYourApp}/cmd"
   153  )
   154  
   155  func main() {
   156    cmd.Execute()
   157  }
   158  ```
   159  
   160  ### Create additional commands
   161  
   162  Additional commands can be defined and typically are each given their own file
   163  inside of the cmd/ directory.
   164  
   165  If you wanted to create a version command you would create cmd/version.go and
   166  populate it with the following:
   167  
   168  ```go
   169  package cmd
   170  
   171  import (
   172    "fmt"
   173  
   174    "github.com/spf13/cobra"
   175  )
   176  
   177  func init() {
   178    rootCmd.AddCommand(versionCmd)
   179  }
   180  
   181  var versionCmd = &cobra.Command{
   182    Use:   "version",
   183    Short: "Print the version number of Hugo",
   184    Long:  `All software has versions. This is Hugo's`,
   185    Run: func(cmd *cobra.Command, args []string) {
   186      fmt.Println("Hugo Static Site Generator v0.9 -- HEAD")
   187    },
   188  }
   189  ```
   190  
   191  ### Returning and handling errors
   192  
   193  If you wish to return an error to the caller of a command, `RunE` can be used.
   194  
   195  ```go
   196  package cmd
   197  
   198  import (
   199    "fmt"
   200  
   201    "github.com/spf13/cobra"
   202  )
   203  
   204  func init() {
   205    rootCmd.AddCommand(tryCmd)
   206  }
   207  
   208  var tryCmd = &cobra.Command{
   209    Use:   "try",
   210    Short: "Try and possibly fail at something",
   211    RunE: func(cmd *cobra.Command, args []string) error {
   212      if err := someFunc(); err != nil {
   213  	return err
   214      }
   215      return nil
   216    },
   217  }
   218  ```
   219  
   220  The error can then be caught at the execute function call.
   221  
   222  ## Working with Flags
   223  
   224  Flags provide modifiers to control how the action command operates.
   225  
   226  ### Assign flags to a command
   227  
   228  Since the flags are defined and used in different locations, we need to
   229  define a variable outside with the correct scope to assign the flag to
   230  work with.
   231  
   232  ```go
   233  var Verbose bool
   234  var Source string
   235  ```
   236  
   237  There are two different approaches to assign a flag.
   238  
   239  ### Persistent Flags
   240  
   241  A flag can be 'persistent', meaning that this flag will be available to the
   242  command it's assigned to as well as every command under that command. For
   243  global flags, assign a flag as a persistent flag on the root.
   244  
   245  ```go
   246  rootCmd.PersistentFlags().BoolVarP(&Verbose, "verbose", "v", false, "verbose output")
   247  ```
   248  
   249  ### Local Flags
   250  
   251  A flag can also be assigned locally, which will only apply to that specific command.
   252  
   253  ```go
   254  localCmd.Flags().StringVarP(&Source, "source", "s", "", "Source directory to read from")
   255  ```
   256  
   257  ### Local Flag on Parent Commands
   258  
   259  By default, Cobra only parses local flags on the target command, and any local flags on
   260  parent commands are ignored. By enabling `Command.TraverseChildren`, Cobra will
   261  parse local flags on each command before executing the target command.
   262  
   263  ```go
   264  command := cobra.Command{
   265    Use: "print [OPTIONS] [COMMANDS]",
   266    TraverseChildren: true,
   267  }
   268  ```
   269  
   270  ### Bind Flags with Config
   271  
   272  You can also bind your flags with [viper](https://github.com/spf13/viper):
   273  ```go
   274  var author string
   275  
   276  func init() {
   277    rootCmd.PersistentFlags().StringVar(&author, "author", "YOUR NAME", "Author name for copyright attribution")
   278    viper.BindPFlag("author", rootCmd.PersistentFlags().Lookup("author"))
   279  }
   280  ```
   281  
   282  In this example, the persistent flag `author` is bound with `viper`.
   283  **Note**: the variable `author` will not be set to the value from config,
   284  when the `--author` flag is provided by user.
   285  
   286  More in [viper documentation](https://github.com/spf13/viper#working-with-flags).
   287  
   288  ### Required flags
   289  
   290  Flags are optional by default. If instead you wish your command to report an error
   291  when a flag has not been set, mark it as required:
   292  ```go
   293  rootCmd.Flags().StringVarP(&Region, "region", "r", "", "AWS region (required)")
   294  rootCmd.MarkFlagRequired("region")
   295  ```
   296  
   297  Or, for persistent flags:
   298  ```go
   299  rootCmd.PersistentFlags().StringVarP(&Region, "region", "r", "", "AWS region (required)")
   300  rootCmd.MarkPersistentFlagRequired("region")
   301  ```
   302  
   303  ### Flag Groups
   304  
   305  If you have different flags that must be provided together (e.g. if they provide the `--username` flag they MUST provide the `--password` flag as well) then
   306  Cobra can enforce that requirement:
   307  ```go
   308  rootCmd.Flags().StringVarP(&u, "username", "u", "", "Username (required if password is set)")
   309  rootCmd.Flags().StringVarP(&pw, "password", "p", "", "Password (required if username is set)")
   310  rootCmd.MarkFlagsRequiredTogether("username", "password")
   311  ```
   312  
   313  You can also prevent different flags from being provided together if they represent mutually
   314  exclusive options such as specifying an output format as either `--json` or `--yaml` but never both:
   315  ```go
   316  rootCmd.Flags().BoolVar(&u, "json", false, "Output in JSON")
   317  rootCmd.Flags().BoolVar(&pw, "yaml", false, "Output in YAML")
   318  rootCmd.MarkFlagsMutuallyExclusive("json", "yaml")
   319  ```
   320  
   321  In both of these cases:
   322    - both local and persistent flags can be used
   323      - **NOTE:** the group is only enforced on commands where every flag is defined
   324    - a flag may appear in multiple groups
   325    - a group may contain any number of flags
   326  
   327  ## Positional and Custom Arguments
   328  
   329  Validation of positional arguments can be specified using the `Args` field of `Command`.
   330  The following validators are built in:
   331  
   332  - Number of arguments:
   333    - `NoArgs` - report an error if there are any positional args.
   334    - `ArbitraryArgs` - accept any number of args.
   335    - `MinimumNArgs(int)` - report an error if less than N positional args are provided.
   336    - `MaximumNArgs(int)` - report an error if more than N positional args are provided.
   337    - `ExactArgs(int)` - report an error if there are not exactly N positional args.
   338    - `RangeArgs(min, max)` - report an error if the number of args is not between `min` and `max`.
   339  - Content of the arguments:
   340    - `OnlyValidArgs` - report an error if there are any positional args not specified in the `ValidArgs` field of `Command`, which can optionally be set to a list of valid values for positional args.
   341  
   342  If `Args` is undefined or `nil`, it defaults to `ArbitraryArgs`.
   343  
   344  Moreover, `MatchAll(pargs ...PositionalArgs)` enables combining existing checks with arbitrary other checks.
   345  For instance, if you want to report an error if there are not exactly N positional args OR if there are any positional
   346  args that are not in the `ValidArgs` field of `Command`, you can call `MatchAll` on `ExactArgs` and `OnlyValidArgs`, as
   347  shown below:
   348  
   349  ```go
   350  var cmd = &cobra.Command{
   351    Short: "hello",
   352    Args: MatchAll(ExactArgs(2), OnlyValidArgs),
   353    Run: func(cmd *cobra.Command, args []string) {
   354      fmt.Println("Hello, World!")
   355    },
   356  }
   357  ```
   358  
   359  It is possible to set any custom validator that satisfies `func(cmd *cobra.Command, args []string) error`.
   360  For example:
   361  
   362  ```go
   363  var cmd = &cobra.Command{
   364    Short: "hello",
   365    Args: func(cmd *cobra.Command, args []string) error {
   366      // Optionally run one of the validators provided by cobra
   367      if err := cobra.MinimumNArgs(1)(cmd, args); err != nil {
   368          return err
   369      }
   370      // Run the custom validation logic
   371      if myapp.IsValidColor(args[0]) {
   372        return nil
   373      }
   374      return fmt.Errorf("invalid color specified: %s", args[0])
   375    },
   376    Run: func(cmd *cobra.Command, args []string) {
   377      fmt.Println("Hello, World!")
   378    },
   379  }
   380  ```
   381  
   382  ## Example
   383  
   384  In the example below, we have defined three commands. Two are at the top level
   385  and one (cmdTimes) is a child of one of the top commands. In this case the root
   386  is not executable, meaning that a subcommand is required. This is accomplished
   387  by not providing a 'Run' for the 'rootCmd'.
   388  
   389  We have only defined one flag for a single command.
   390  
   391  More documentation about flags is available at https://github.com/spf13/pflag
   392  
   393  ```go
   394  package main
   395  
   396  import (
   397    "fmt"
   398    "strings"
   399  
   400    "github.com/spf13/cobra"
   401  )
   402  
   403  func main() {
   404    var echoTimes int
   405  
   406    var cmdPrint = &cobra.Command{
   407      Use:   "print [string to print]",
   408      Short: "Print anything to the screen",
   409      Long: `print is for printing anything back to the screen.
   410  For many years people have printed back to the screen.`,
   411      Args: cobra.MinimumNArgs(1),
   412      Run: func(cmd *cobra.Command, args []string) {
   413        fmt.Println("Print: " + strings.Join(args, " "))
   414      },
   415    }
   416  
   417    var cmdEcho = &cobra.Command{
   418      Use:   "echo [string to echo]",
   419      Short: "Echo anything to the screen",
   420      Long: `echo is for echoing anything back.
   421  Echo works a lot like print, except it has a child command.`,
   422      Args: cobra.MinimumNArgs(1),
   423      Run: func(cmd *cobra.Command, args []string) {
   424        fmt.Println("Echo: " + strings.Join(args, " "))
   425      },
   426    }
   427  
   428    var cmdTimes = &cobra.Command{
   429      Use:   "times [string to echo]",
   430      Short: "Echo anything to the screen more times",
   431      Long: `echo things multiple times back to the user by providing
   432  a count and a string.`,
   433      Args: cobra.MinimumNArgs(1),
   434      Run: func(cmd *cobra.Command, args []string) {
   435        for i := 0; i < echoTimes; i++ {
   436          fmt.Println("Echo: " + strings.Join(args, " "))
   437        }
   438      },
   439    }
   440  
   441    cmdTimes.Flags().IntVarP(&echoTimes, "times", "t", 1, "times to echo the input")
   442  
   443    var rootCmd = &cobra.Command{Use: "app"}
   444    rootCmd.AddCommand(cmdPrint, cmdEcho)
   445    cmdEcho.AddCommand(cmdTimes)
   446    rootCmd.Execute()
   447  }
   448  ```
   449  
   450  For a more complete example of a larger application, please checkout [Hugo](https://gohugo.io/).
   451  
   452  ## Help Command
   453  
   454  Cobra automatically adds a help command to your application when you have subcommands.
   455  This will be called when a user runs 'app help'. Additionally, help will also
   456  support all other commands as input. Say, for instance, you have a command called
   457  'create' without any additional configuration; Cobra will work when 'app help
   458  create' is called.  Every command will automatically have the '--help' flag added.
   459  
   460  ### Example
   461  
   462  The following output is automatically generated by Cobra. Nothing beyond the
   463  command and flag definitions are needed.
   464  
   465      $ cobra-cli help
   466  
   467      Cobra is a CLI library for Go that empowers applications.
   468      This application is a tool to generate the needed files
   469      to quickly create a Cobra application.
   470  
   471      Usage:
   472        cobra-cli [command]
   473  
   474      Available Commands:
   475        add         Add a command to a Cobra Application
   476        completion  Generate the autocompletion script for the specified shell
   477        help        Help about any command
   478        init        Initialize a Cobra Application
   479  
   480      Flags:
   481        -a, --author string    author name for copyright attribution (default "YOUR NAME")
   482            --config string    config file (default is $HOME/.cobra.yaml)
   483        -h, --help             help for cobra-cli
   484        -l, --license string   name of license for the project
   485            --viper            use Viper for configuration
   486  
   487      Use "cobra-cli [command] --help" for more information about a command.
   488  
   489  
   490  Help is just a command like any other. There is no special logic or behavior
   491  around it. In fact, you can provide your own if you want.
   492  
   493  ### Defining your own help
   494  
   495  You can provide your own Help command or your own template for the default command to use
   496  with the following functions:
   497  
   498  ```go
   499  cmd.SetHelpCommand(cmd *Command)
   500  cmd.SetHelpFunc(f func(*Command, []string))
   501  cmd.SetHelpTemplate(s string)
   502  ```
   503  
   504  The latter two will also apply to any children commands.
   505  
   506  ## Usage Message
   507  
   508  When the user provides an invalid flag or invalid command, Cobra responds by
   509  showing the user the 'usage'.
   510  
   511  ### Example
   512  You may recognize this from the help above. That's because the default help
   513  embeds the usage as part of its output.
   514  
   515      $ cobra-cli --invalid
   516      Error: unknown flag: --invalid
   517      Usage:
   518        cobra-cli [command]
   519  
   520      Available Commands:
   521        add         Add a command to a Cobra Application
   522        completion  Generate the autocompletion script for the specified shell
   523        help        Help about any command
   524        init        Initialize a Cobra Application
   525  
   526      Flags:
   527        -a, --author string    author name for copyright attribution (default "YOUR NAME")
   528            --config string    config file (default is $HOME/.cobra.yaml)
   529        -h, --help             help for cobra-cli
   530        -l, --license string   name of license for the project
   531            --viper            use Viper for configuration
   532  
   533      Use "cobra [command] --help" for more information about a command.
   534  
   535  ### Defining your own usage
   536  You can provide your own usage function or template for Cobra to use.
   537  Like help, the function and template are overridable through public methods:
   538  
   539  ```go
   540  cmd.SetUsageFunc(f func(*Command) error)
   541  cmd.SetUsageTemplate(s string)
   542  ```
   543  
   544  ## Version Flag
   545  
   546  Cobra adds a top-level '--version' flag if the Version field is set on the root command.
   547  Running an application with the '--version' flag will print the version to stdout using
   548  the version template. The template can be customized using the
   549  `cmd.SetVersionTemplate(s string)` function.
   550  
   551  ## PreRun and PostRun Hooks
   552  
   553  It is possible to run functions before or after the main `Run` function of your command. The `PersistentPreRun` and `PreRun` functions will be executed before `Run`. `PersistentPostRun` and `PostRun` will be executed after `Run`.  The `Persistent*Run` functions will be inherited by children if they do not declare their own.  These functions are run in the following order:
   554  
   555  - `PersistentPreRun`
   556  - `PreRun`
   557  - `Run`
   558  - `PostRun`
   559  - `PersistentPostRun`
   560  
   561  An example of two commands which use all of these features is below.  When the subcommand is executed, it will run the root command's `PersistentPreRun` but not the root command's `PersistentPostRun`:
   562  
   563  ```go
   564  package main
   565  
   566  import (
   567    "fmt"
   568  
   569    "github.com/spf13/cobra"
   570  )
   571  
   572  func main() {
   573  
   574    var rootCmd = &cobra.Command{
   575      Use:   "root [sub]",
   576      Short: "My root command",
   577      PersistentPreRun: func(cmd *cobra.Command, args []string) {
   578        fmt.Printf("Inside rootCmd PersistentPreRun with args: %v\n", args)
   579      },
   580      PreRun: func(cmd *cobra.Command, args []string) {
   581        fmt.Printf("Inside rootCmd PreRun with args: %v\n", args)
   582      },
   583      Run: func(cmd *cobra.Command, args []string) {
   584        fmt.Printf("Inside rootCmd Run with args: %v\n", args)
   585      },
   586      PostRun: func(cmd *cobra.Command, args []string) {
   587        fmt.Printf("Inside rootCmd PostRun with args: %v\n", args)
   588      },
   589      PersistentPostRun: func(cmd *cobra.Command, args []string) {
   590        fmt.Printf("Inside rootCmd PersistentPostRun with args: %v\n", args)
   591      },
   592    }
   593  
   594    var subCmd = &cobra.Command{
   595      Use:   "sub [no options!]",
   596      Short: "My subcommand",
   597      PreRun: func(cmd *cobra.Command, args []string) {
   598        fmt.Printf("Inside subCmd PreRun with args: %v\n", args)
   599      },
   600      Run: func(cmd *cobra.Command, args []string) {
   601        fmt.Printf("Inside subCmd Run with args: %v\n", args)
   602      },
   603      PostRun: func(cmd *cobra.Command, args []string) {
   604        fmt.Printf("Inside subCmd PostRun with args: %v\n", args)
   605      },
   606      PersistentPostRun: func(cmd *cobra.Command, args []string) {
   607        fmt.Printf("Inside subCmd PersistentPostRun with args: %v\n", args)
   608      },
   609    }
   610  
   611    rootCmd.AddCommand(subCmd)
   612  
   613    rootCmd.SetArgs([]string{""})
   614    rootCmd.Execute()
   615    fmt.Println()
   616    rootCmd.SetArgs([]string{"sub", "arg1", "arg2"})
   617    rootCmd.Execute()
   618  }
   619  ```
   620  
   621  Output:
   622  ```
   623  Inside rootCmd PersistentPreRun with args: []
   624  Inside rootCmd PreRun with args: []
   625  Inside rootCmd Run with args: []
   626  Inside rootCmd PostRun with args: []
   627  Inside rootCmd PersistentPostRun with args: []
   628  
   629  Inside rootCmd PersistentPreRun with args: [arg1 arg2]
   630  Inside subCmd PreRun with args: [arg1 arg2]
   631  Inside subCmd Run with args: [arg1 arg2]
   632  Inside subCmd PostRun with args: [arg1 arg2]
   633  Inside subCmd PersistentPostRun with args: [arg1 arg2]
   634  ```
   635  
   636  ## Suggestions when "unknown command" happens
   637  
   638  Cobra will print automatic suggestions when "unknown command" errors happen. This allows Cobra to behave similarly to the `git` command when a typo happens. For example:
   639  
   640  ```
   641  $ hugo srever
   642  Error: unknown command "srever" for "hugo"
   643  
   644  Did you mean this?
   645          server
   646  
   647  Run 'hugo --help' for usage.
   648  ```
   649  
   650  Suggestions are automatically generated based on existing subcommands and use an implementation of [Levenshtein distance](https://en.wikipedia.org/wiki/Levenshtein_distance). Every registered command that matches a minimum distance of 2 (ignoring case) will be displayed as a suggestion.
   651  
   652  If you need to disable suggestions or tweak the string distance in your command, use:
   653  
   654  ```go
   655  command.DisableSuggestions = true
   656  ```
   657  
   658  or
   659  
   660  ```go
   661  command.SuggestionsMinimumDistance = 1
   662  ```
   663  
   664  You can also explicitly set names for which a given command will be suggested using the `SuggestFor` attribute. This allows suggestions for strings that are not close in terms of string distance, but make sense in your set of commands but for which
   665  you don't want aliases. Example:
   666  
   667  ```
   668  $ kubectl remove
   669  Error: unknown command "remove" for "kubectl"
   670  
   671  Did you mean this?
   672          delete
   673  
   674  Run 'kubectl help' for usage.
   675  ```
   676  
   677  ## Generating documentation for your command
   678  
   679  Cobra can generate documentation based on subcommands, flags, etc. Read more about it in the [docs generation documentation](doc/README.md).
   680  
   681  ## Generating shell completions
   682  
   683  Cobra can generate a shell-completion file for the following shells: bash, zsh, fish, PowerShell. If you add more information to your commands, these completions can be amazingly powerful and flexible.  Read more about it in [Shell Completions](shell_completions.md).
   684  
   685  ## Providing Active Help
   686  
   687  Cobra makes use of the shell-completion system to define a framework allowing you to provide Active Help to your users.  Active Help are messages (hints, warnings, etc) printed as the program is being used.  Read more about it in [Active Help](active_help.md).