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) } func parse(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) == 1 && arg[0] == '-' { continue } 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 65: // UPP if history_index > 0 { history_index-- input = env.History[history_index] } case 66: // DOWN if history_index < len(env.History)-2 { history_index++ input = env.History[history_index] } else { history_index = len(env.History)-1 input = "" } case 67: // LEFT case 68: // RIGHT 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\033[K") fmt.Print(env.Path) fmt.Print(" > ") fmt.Print(input) } loop_exit: term.Restore(int(std_fd), term_restore) fmt.Println() return input }