mirror of https://github.com/Hilbis/Hilbish
181 lines
5.8 KiB
Go
181 lines
5.8 KiB
Go
package completers
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"github.com/jessevdk/go-flags"
|
|
|
|
"github.com/maxlandon/readline"
|
|
)
|
|
|
|
// HintCompleter - Entrypoint to all hints in the Wiregost console
|
|
func (c *CommandCompleter) HintCompleter(line []rune, pos int) (hint []rune) {
|
|
|
|
// Format and sanitize input
|
|
// @args => All items of the input line
|
|
// @last => The last word detected in input line as []rune
|
|
// @lastWord => The last word detected in input as string
|
|
args, last, lastWord := formatInput(line)
|
|
|
|
// Detect base command automatically
|
|
var command = c.detectedCommand(args)
|
|
|
|
// Menu hints (command line is empty, or nothing recognized)
|
|
if noCommandOrEmpty(args, last, command) {
|
|
hint = MenuHint(args, last)
|
|
}
|
|
|
|
// Check environment variables
|
|
if envVarAsked(args, lastWord) {
|
|
return envVarHint(args, last)
|
|
}
|
|
|
|
// Command Hint
|
|
if commandFound(command) {
|
|
|
|
// Command hint by default (no space between cursor and last command character)
|
|
hint = CommandHint(command)
|
|
|
|
// Check environment variables
|
|
if envVarAsked(args, lastWord) {
|
|
return envVarHint(args, last)
|
|
}
|
|
|
|
// If options are asked for root command, return commpletions.
|
|
if len(command.Groups()) > 0 {
|
|
for _, grp := range command.Groups() {
|
|
if opt, yes := optionArgRequired(args, last, grp); yes {
|
|
hint = OptionArgumentHint(args, last, opt)
|
|
}
|
|
}
|
|
}
|
|
|
|
// If command has args, hint for args
|
|
if arg, yes := commandArgumentRequired(lastWord, args, command); yes {
|
|
hint = []rune(CommandArgumentHints(args, last, command, arg))
|
|
}
|
|
|
|
// Brief subcommand hint
|
|
if lastIsSubCommand(lastWord, command) {
|
|
hint = []rune(commandHint + command.Find(string(last)).ShortDescription)
|
|
}
|
|
|
|
// Handle subcommand if found
|
|
if sub, ok := subCommandFound(lastWord, args, command); ok {
|
|
return HandleSubcommandHints(args, last, sub)
|
|
}
|
|
|
|
}
|
|
|
|
// Handle system binaries, shell commands, etc...
|
|
if commandFoundInPath(args[0]) {
|
|
// hint = []rune(exeHint + util.ParseSummary(util.GetManPages(args[0])))
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// CommandHint - Yields the hint of a Wiregost command
|
|
func CommandHint(command *flags.Command) (hint []rune) {
|
|
return []rune(commandHint + command.ShortDescription)
|
|
}
|
|
|
|
// HandleSubcommandHints - Handles hints for a subcommand and its arguments, options, etc.
|
|
func HandleSubcommandHints(args []string, last []rune, command *flags.Command) (hint []rune) {
|
|
|
|
// If command has args, hint for args
|
|
if arg, yes := commandArgumentRequired(string(last), args, command); yes {
|
|
hint = []rune(CommandArgumentHints(args, last, command, arg))
|
|
return
|
|
}
|
|
|
|
// Environment variables
|
|
if envVarAsked(args, string(last)) {
|
|
hint = envVarHint(args, last)
|
|
}
|
|
|
|
// If the last word in input is an option --name, yield argument hint if needed
|
|
if len(command.Groups()) > 0 {
|
|
for _, grp := range command.Groups() {
|
|
if opt, yes := optionArgRequired(args, last, grp); yes {
|
|
hint = OptionArgumentHint(args, last, opt)
|
|
}
|
|
}
|
|
}
|
|
|
|
// If user asks for completions with "-" or "--".
|
|
// (Note: This takes precedence on any argument hints, as it is evaluated after them)
|
|
if commandOptionsAsked(args, string(last), command) {
|
|
return OptionHints(args, last, command)
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// CommandArgumentHints - Yields hints for arguments to commands if they have some
|
|
func CommandArgumentHints(args []string, last []rune, command *flags.Command, arg string) (hint []rune) {
|
|
|
|
found := argumentByName(command, arg)
|
|
// Base Hint is just a description of the command argument
|
|
hint = []rune(argHint + found.Description)
|
|
|
|
return
|
|
}
|
|
|
|
// ModuleOptionHints - If the option being set has a description, show it
|
|
func ModuleOptionHints(opt string) (hint []rune) {
|
|
return
|
|
}
|
|
|
|
// OptionHints - Yields hints for proposed options lists/groups
|
|
func OptionHints(args []string, last []rune, command *flags.Command) (hint []rune) {
|
|
return
|
|
}
|
|
|
|
// OptionArgumentHint - Yields hints for arguments to an option (generally the last word in input)
|
|
func OptionArgumentHint(args []string, last []rune, opt *flags.Option) (hint []rune) {
|
|
return []rune(valueHint + opt.Description)
|
|
}
|
|
|
|
// MenuHint - Returns the Hint for a given menu context
|
|
func MenuHint(args []string, current []rune) (hint []rune) {
|
|
return
|
|
}
|
|
|
|
// SpecialCommandHint - Shows hints for Wiregost special commands
|
|
func SpecialCommandHint(args []string, current []rune) (hint []rune) {
|
|
return current
|
|
}
|
|
|
|
// envVarHint - Yields hints for environment variables
|
|
func envVarHint(args []string, last []rune) (hint []rune) {
|
|
// Trim last in case its a path with multiple vars
|
|
allVars := strings.Split(string(last), "/")
|
|
lastVar := allVars[len(allVars)-1]
|
|
|
|
// Base hint
|
|
hint = []rune(envHint + lastVar)
|
|
|
|
envVar := strings.TrimPrefix(lastVar, "$")
|
|
|
|
if v, ok := clientEnv[envVar]; ok {
|
|
if v != "" {
|
|
hintStr := string(hint) + " => " + clientEnv[envVar]
|
|
hint = []rune(hintStr)
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
var (
|
|
// Hint signs
|
|
menuHint = readline.RESET + readline.DIM + readline.BOLD + " menu " + readline.RESET // Dim
|
|
envHint = readline.RESET + readline.GREEN + readline.BOLD + " env " + readline.RESET + readline.DIM + readline.GREEN // Green
|
|
commandHint = readline.RESET + readline.DIM + readline.BOLD + " command " + readline.RESET + readline.DIM + "\033[38;5;244m" // Cream
|
|
exeHint = readline.RESET + readline.DIM + readline.BOLD + " shell " + readline.RESET + readline.DIM // Dim
|
|
optionHint = "\033[38;5;222m" + readline.BOLD + " options " + readline.RESET + readline.DIM + "\033[38;5;222m" // Cream-Yellow
|
|
valueHint = readline.RESET + readline.DIM + readline.BOLD + " value " + readline.RESET + readline.DIM + "\033[38;5;244m" // Pink-Cream
|
|
// valueHint = "\033[38;5;217m" + readline.BOLD + " Value " + readline.RESET + readline.DIM + "\033[38;5;244m" // Pink-Cream
|
|
argHint = readline.DIM + "\033[38;5;217m" + readline.BOLD + " arg " + readline.RESET + readline.DIM + "\033[38;5;244m" // Pink-Cream
|
|
)
|