mirror of https://github.com/Bios-Marcel/cordless
113 lines
3.0 KiB
Go
113 lines
3.0 KiB
Go
package commands
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"strings"
|
|
|
|
"github.com/Bios-Marcel/cordless/config"
|
|
"github.com/Bios-Marcel/cordless/ui/tviewutil"
|
|
)
|
|
|
|
// Command represents a command that is executable by the user.
|
|
type Command interface {
|
|
// Execute runs the command piping its output into the supplied writer.
|
|
Execute(writer io.Writer, parameters []string)
|
|
|
|
// PrintHelp prints a static help page for this command
|
|
PrintHelp(writer io.Writer)
|
|
|
|
// Name returns the primary name for this command. This name will also be
|
|
// used for listing the command in the commandlist.
|
|
Name() string
|
|
|
|
// Aliases are a list of aliases for this command. There might be none.
|
|
Aliases() []string
|
|
}
|
|
|
|
// ParseCommand takes an arbitrary input string and splits it into parameters.
|
|
// The first parameter (index 0) will always be the command itself.
|
|
func ParseCommand(input string) []string {
|
|
if len(input) == 0 || len(strings.TrimSpace(input)) == 0 {
|
|
return nil
|
|
}
|
|
|
|
if !strings.ContainsRune(input, ' ') {
|
|
return []string{input}
|
|
}
|
|
|
|
parameters := make([]string, 0)
|
|
|
|
trimmedWhiteSpace := []rune(strings.TrimSpace(input))
|
|
length := len(trimmedWhiteSpace)
|
|
|
|
lastArgument := make([]rune, 0)
|
|
|
|
OUTER_LOOP:
|
|
for index := 0; index < length; index++ {
|
|
char := trimmedWhiteSpace[index]
|
|
if char == ' ' {
|
|
if len(lastArgument) > 0 {
|
|
parameters = append(parameters, string(lastArgument))
|
|
lastArgument = make([]rune, 0)
|
|
}
|
|
} else if char == '\\' {
|
|
if index == length-1 {
|
|
lastArgument = append(lastArgument, char)
|
|
} else if trimmedWhiteSpace[index+1] == '"' {
|
|
lastArgument = append(lastArgument, '"')
|
|
index++
|
|
continue OUTER_LOOP
|
|
}
|
|
} else if char == '"' {
|
|
if index == 0 || trimmedWhiteSpace[index] != '\\' {
|
|
for index2 := index + 1; index2 < length; index2++ {
|
|
nextChar := trimmedWhiteSpace[index2]
|
|
if nextChar == '"' && trimmedWhiteSpace[index2-1] != '\\' {
|
|
lastArgument = trimmedWhiteSpace[index+1 : index2]
|
|
replacedEscapedQuotes := strings.Replace(string(lastArgument), "\\\"", "\"", -1)
|
|
parameters = append(parameters, replacedEscapedQuotes)
|
|
lastArgument = make([]rune, 0)
|
|
index = index2
|
|
continue OUTER_LOOP
|
|
}
|
|
}
|
|
|
|
//No quoting end found
|
|
lastArgument = append(lastArgument, char)
|
|
}
|
|
} else {
|
|
lastArgument = append(lastArgument, char)
|
|
}
|
|
}
|
|
|
|
if len(lastArgument) > 0 {
|
|
parameters = append(parameters, string(lastArgument))
|
|
}
|
|
|
|
return parameters
|
|
}
|
|
|
|
// PrintError message writes an error to the given io.Writer in the
|
|
// default format, using the correct colors and punctuation.
|
|
func PrintError(writer io.Writer, error, reason string) {
|
|
errorColor := tviewutil.ColorToHex(config.GetTheme().ErrorColor)
|
|
fmt.Fprintf(writer, "[%s]%s:\n\t[%s]%s\n", errorColor, error, errorColor, reason)
|
|
}
|
|
|
|
// CommandEquals checks whether the text given matches either the name of the
|
|
// given command or one of it's aliases.
|
|
func CommandEquals(cmd Command, text string) bool {
|
|
if cmd.Name() == text {
|
|
return true
|
|
}
|
|
|
|
for _, alias := range cmd.Aliases() {
|
|
if alias == text {
|
|
return true
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|