142 lines
2.9 KiB
Go
142 lines
2.9 KiB
Go
package input_parser
|
|
|
|
import (
|
|
"bbash/environment"
|
|
"bufio"
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
|
|
"golang.org/x/term"
|
|
)
|
|
|
|
type Input struct {
|
|
// The instruction a.k.a first argument
|
|
Instruction string
|
|
|
|
// The args, currently just the string after the instruction
|
|
Args []string
|
|
Args_raw string
|
|
Flags []string
|
|
}
|
|
|
|
func Parse(env *environment.Env) Input {
|
|
input := input_str(env)
|
|
return parse_input(input)
|
|
}
|
|
func parse_input(input string) Input {
|
|
split := strings.Split(string(input), " ")
|
|
instruction := strings.TrimSpace(split[0])
|
|
|
|
args_raw := ""
|
|
if len(split) > 1 {
|
|
args_raw = split[1]
|
|
}
|
|
|
|
var flags []string
|
|
var args []string
|
|
for _, arg := range split[1:] {
|
|
if len(arg) == 0 {
|
|
continue
|
|
} else if len(arg) == 1 {
|
|
if arg[0] == '-' {
|
|
continue
|
|
} else {
|
|
args = append(args, strings.TrimSpace(arg))
|
|
}
|
|
} else if arg[0:2] == "--" {
|
|
var result = strings.TrimSpace(arg)
|
|
flags = append(flags, string(result[2:]))
|
|
continue
|
|
} else if arg[0] == '-' {
|
|
var result = strings.TrimSpace(arg)
|
|
for _, c := range result[1:] {
|
|
flags = append(flags, string(c))
|
|
}
|
|
continue
|
|
} else {
|
|
args = append(args, strings.TrimSpace(arg))
|
|
}
|
|
|
|
}
|
|
return Input{
|
|
Instruction: instruction,
|
|
Args: args,
|
|
Flags: flags,
|
|
Args_raw: args_raw,
|
|
}
|
|
}
|
|
func input_str(env *environment.Env) string {
|
|
std_fd := os.Stdin.Fd()
|
|
term_restore, err := term.MakeRaw(int(std_fd))
|
|
if err != nil {
|
|
fmt.Println(fmt.Sprintf("Error opening terminal: %s", err.Error()))
|
|
panic(err.Error())
|
|
}
|
|
reader := bufio.NewReader(os.Stdin)
|
|
var input string
|
|
history_index := len(env.History) // not -1 since we start at the new one
|
|
env.History = append(env.History, input)
|
|
|
|
env.History[len(env.History)-1] = input
|
|
fmt.Print("\r\033[K")
|
|
fmt.Print(env.Path)
|
|
fmt.Print(" > ")
|
|
fmt.Print(input)
|
|
|
|
for {
|
|
r_rune, _, err := reader.ReadRune()
|
|
if err != nil {
|
|
fmt.Print(fmt.Sprintf("Error reading user input: ", err.Error()))
|
|
}
|
|
switch r_rune {
|
|
case 3: // ^C
|
|
fmt.Println("^C")
|
|
input = ""
|
|
case 4: // ^D
|
|
input = "exit"
|
|
goto loop_exit
|
|
case 9: // Tab
|
|
input = AutoComplete(input)
|
|
case 91:
|
|
if r, _, _ := reader.ReadRune(); r == 65 { // UPP
|
|
if history_index > 0 {
|
|
history_index--
|
|
input = env.History[history_index]
|
|
}
|
|
break
|
|
|
|
}
|
|
if r, _, _ := reader.ReadRune(); r != 66 { //DOWN
|
|
if history_index < len(env.History)-2 {
|
|
history_index++
|
|
input = env.History[history_index]
|
|
} else {
|
|
input = ""
|
|
}
|
|
break
|
|
}
|
|
|
|
case 127: //packspace
|
|
if len(input) > 0 {
|
|
input = input[:len(input)-1]
|
|
}
|
|
case 13: // Enter
|
|
goto loop_exit
|
|
default:
|
|
input = input + string(r_rune)
|
|
}
|
|
env.History[len(env.History)-1] = input
|
|
fmt.Print("\r")
|
|
fmt.Print("\r\033[K")
|
|
fmt.Print(env.Path)
|
|
fmt.Print(" > ")
|
|
fmt.Print("\033[K")
|
|
fmt.Print(input)
|
|
}
|
|
loop_exit:
|
|
term.Restore(int(std_fd), term_restore)
|
|
fmt.Println()
|
|
return input
|
|
}
|