cmd

package module
v1.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 11, 2023 License: MIT Imports: 18 Imported by: 12

README

cmd

A library to create shell-like command processors, slightly inspired by the Python cmd/cmd2 package

Installation

$ go get github.com/gobs/cmd

Documentation

http://godoc.org/github.com/gobs/cmd

Example

import "github.com/gobs/cmd"

// return true to stop command loop
func Exit(line string) (stop bool) {
      fmt.Println("goodbye!")
      return true
}
  
// change the prompt
func (cmd *Cmd) SetPrompt(line string) (stop bool) {
      cmd.Prompt = line
      return
}

// initialize Cmd structure
commander := &cmd.Cmd{Prompt: "> ",}
commander.Init()

// add inline method
commander.Add(cmd.Command{
      "ls",
      `list stuff`,
      func(line string) (stop bool) {
          fmt.Println("listing stuff")
          return
  }})

// add another command
commander.Add(cmd.Command{
      Name: "prompt",
      Help: `Set prompt`,
      Call: commander.SetPrompt
      })

// and one more
commander.Add(cmd.Command{
      "exit",
      `terminate example`,
      Exit
  })

// start command loop
commander.CmdLoop()

Available commands

The command processor predefines a few useful commands, including function definitions and conditionals.

Use the help command to see the list of available commands.

Function definition is similart to bash functions:

function test {
    echo Function name: $0
    echo Number of arguments: $#
    echo First argument: $1
    echo All arguments: $*
}

but you can also define a very short function (one-liner):

function oneliner echo "very short function"

Variables can be set/listed using the var command:

> var catch 22

> var catch
    catch: 22

> echo $catch
    22

To unset/remove a variable use:

> var -r catch
> var -rm catch
> var --remove catch

note that currently only "string" values are supported (i.e. var x 1 is the same as `var x "1"1)

Conditional flow with if and else commands:

if (condition) {
    # true path
} else {
    # false path
}

The else block is optional:

if (condition) {
    # only the truth
}

And the short test:

if (condition) echo "yes!"

Conditions:

The simplest condition is the "non empty argument":

if true echo "yes, it's true"

But if you are using a variable you need to quote it:

if "$nonempty" echo "nonempty is not empty"

All other conditionals are in the form: (cond arguments...):

(z $var)        # $var is empty

(n $var)        # $var is not empty

(t $var)        # $var is true (true, 1, not-empty var)

(f $var)        # $var is false (false, 0, empty empty)

(eq $var val)   # $var == val

(ne $var val)   # $var != val

(gt $var val)   # $var > val

(gte $var val)  # $var >= val

(lt $var val)   # $var < val

(lte $var val)  # $var <= val

(startswith $var val) # $var starts with val
(endswith $var val)   # $var ends with val
(contains $var val)   # $var contains val

Conditions can also be negated with the "!" operator:

if !true echo "not true"
if !(contains $var val) echo val not in $var

As for variables, for now only string comparisons are supported.

Documentation

Overview

 This package is used to implement a "line oriented command interpreter", inspired by the python package with
 the same name http://docs.python.org/2/library/cmd.html

 Usage:

	 commander := &Cmd{...}
	 commander.Init()

	 commander.Add(Command{...})
	 commander.Add(Command{...})

	 commander.CmdLoop()

Index

Constants

This section is empty.

Variables

View Source
var (

	// NoVar is passed to Command.OnChange to indicate that the variable is not set or needs to be deleted
	NoVar = &struct{}{}
)

Functions

This section is empty.

Types

type Cmd

type Cmd struct {
	// the prompt string
	Prompt string

	// the continuation prompt string
	ContinuationPrompt string

	// the history file
	HistoryFile string

	// this function is called to fetch the current prompt
	// so it can be overridden to provide a dynamic prompt
	GetPrompt func(bool) string

	// this function is called before starting the command loop
	PreLoop func()

	// this function is called before terminating the command loop
	PostLoop func()

	// this function is called before executing the selected command
	PreCmd func(string)

	// this function is called after a command has been executed
	// return true to terminate the interpreter, false to continue
	PostCmd func(string, bool) bool

	// this function is called to execute one command
	OneCmd func(string) bool

	// this function is called if the last typed command was an empty line
	EmptyLine func()

	// this function is called if the command line doesn't match any existing command
	// by default it displays an error message
	Default func(string)

	// this function is called when the user types the "help" command.
	// It is implemented so that it can be overwritten, mainly to support plugins.
	Help func(string) bool

	// this function is called to implement command completion.
	// it should return a list of words that match the input text
	Complete func(string, string) []string

	// this function is called when a variable change (via set/var command).
	// it should return the new value to set the variable to (to force type casting)
	//
	// oldv will be nil if a new varabile is being created
	//
	// newv will be nil if the variable is being deleted
	OnChange func(name string, oldv, newv interface{}) interface{}

	// this function is called when the user tries to interrupt a running
	// command. If it returns true, the application will be terminated.
	Interrupt func(os.Signal) bool

	// this function is called when recovering from a panic.
	// If it returns true, the application will be terminated.
	Recover func(interface{}) bool

	// if true, enable shell commands
	EnableShell bool

	// if true, print elapsed time
	Timing bool

	// if true, print command before executing
	Echo bool

	// if true, don't print result of some operations (stored in result variables)
	Silent bool

	// this is the list of available commands indexed by command name
	Commands map[string]Command

	sync.RWMutex
	// contains filtered or unexported fields
}

This the the "context" for the command interpreter

func (*Cmd) Add

func (cmd *Cmd) Add(command Command)

Add a command to the command interpreter. Overrides a command with the same name, if there was one

func (*Cmd) AddCompleter

func (cmd *Cmd) AddCompleter(name string, c Completer)

func (*Cmd) ChangeVar

func (cmd *Cmd) ChangeVar(k string, v interface{})

ChangeVar sets a variable in the current scope and calls the OnChange method

func (*Cmd) CmdLoop

func (cmd *Cmd) CmdLoop()

This is the command interpreter entry point. It displays a prompt, waits for a command and executes it until the selected command returns true

func (*Cmd) GetBoolVar

func (cmd *Cmd) GetBoolVar(name string) (val bool)

GetBoolVar returns the value of the variable as boolean

func (*Cmd) GetCompleter

func (cmd *Cmd) GetCompleter(name string) Completer

func (*Cmd) GetIntVar

func (cmd *Cmd) GetIntVar(name string) (val int)

GetIntVar returns the value of the variable as int

func (*Cmd) GetVar

func (cmd *Cmd) GetVar(k string) (string, bool)

GetVar return the value of the specified variable from the closest scope

func (*Cmd) Init

func (cmd *Cmd) Init(plugins ...Plugin)

Initialize the command interpreter context

func (*Cmd) Interrupted

func (cmd *Cmd) Interrupted() (interrupted bool)

func (*Cmd) RunBlock

func (cmd *Cmd) RunBlock(name string, body []string, args []string, newscope bool) (stop bool)

RunBlock runs a block of code.

Note: this is public because it's needed by the ControlFlow plugin (and can't be in interal because of circular dependencies). It shouldn't be used by end-user applications.

func (*Cmd) SetPrompt

func (cmd *Cmd) SetPrompt(prompt string, max int)

func (*Cmd) SetVar

func (cmd *Cmd) SetVar(k string, v interface{})

SetVar sets a variable in the current scope

func (*Cmd) SilentResult

func (cmd *Cmd) SilentResult() bool

SilentResult returns true if the command should be silent (not print results to the console, but only store in return variable)

func (*Cmd) UnsetVar

func (cmd *Cmd) UnsetVar(k string)

UnsetVar removes a variable from the current scope

func (*Cmd) UpdateVar

func (cmd *Cmd) UpdateVar(k string, update func(string) interface{}) string

UpdateVar allows to atomically change the valua of a variable. The `update` callback receives the current value and should returns the new value.

type Command

type Command struct {
	// command name
	Name string
	// command description
	Help string
	// the function to call to execute the command
	Call func(string) bool
	// the function to call to print the help string
	HelpFunc func()
}

This is used to describe a new command

func (*Command) DefaultHelp

func (c *Command) DefaultHelp()

type Completer

type Completer interface {
	Complete(string, string) []string // Complete(start, full-line) returns matches
}

type CompleterCond

type CompleterCond func(start, line string) bool

type CompleterWords

type CompleterWords func() []string

type GoRunner

type GoRunner interface {
	Run(task func())
	Wait()
}

func GroupRunner

func GroupRunner(workers int) GoRunner

func PoolRunner

func PoolRunner(workers, capacity int, options ...pond.Option) GoRunner

type Plugin

type Plugin interface {
	PluginInit(cmd *Cmd, ctx *internal.Context) error
}

Plugin is the interface implemented by plugins

type WordCompleter

type WordCompleter struct {
	// a function that returns the list of words to match on
	Words CompleterWords
	// a function that returns true if this completer should be executed
	Cond CompleterCond
}

The context for command completion

func NewWordCompleter

func NewWordCompleter(words CompleterWords, cond CompleterCond) *WordCompleter

Create a WordCompleter and initialize with list of words

func (*WordCompleter) Complete

func (c *WordCompleter) Complete(start, line string) (matches []string)

Directories

Path Synopsis
plugins
json
Package json add some json-related commands to the command loop.
Package json add some json-related commands to the command loop.
stats
Package stats add some statistics-related commands to the command loop.
Package stats add some statistics-related commands to the command loop.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL