Compare commits
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2a594eac1d | ||
| 9bbaae1d11 | |||
|
|
ed3067a9a0 | ||
|
|
ada7fa9d9e | ||
|
|
3f1b876f68 | ||
| b071d3dd78 | |||
|
|
78fb97a860 | ||
|
|
e37798dd82 | ||
|
|
a227e3e106 | ||
| 2f6f75b3a4 | |||
|
|
0216b72d65 | ||
|
|
35af0423a7 | ||
|
|
3c166dda98 | ||
|
|
e6e223b6a7 | ||
|
|
d4757c154b | ||
|
|
45cf77ed2a | ||
| 45f50a95ce | |||
|
|
0525f346b4 | ||
|
|
15da22bc16 | ||
|
|
642d1780b6 | ||
|
|
2932f9bf43 | ||
|
|
6c63fc7122 | ||
|
|
aad4da3077 |
@ -1,6 +0,0 @@
|
|||||||
package api
|
|
||||||
|
|
||||||
func Api() string {
|
|
||||||
apiString := <api_key>
|
|
||||||
return apiString
|
|
||||||
}
|
|
||||||
@ -6,6 +6,7 @@ import (
|
|||||||
"bbash/command/cd"
|
"bbash/command/cd"
|
||||||
"bbash/command/cp"
|
"bbash/command/cp"
|
||||||
"bbash/command/echo"
|
"bbash/command/echo"
|
||||||
|
"bbash/command/fritiofcommand"
|
||||||
"bbash/command/head"
|
"bbash/command/head"
|
||||||
"bbash/command/help"
|
"bbash/command/help"
|
||||||
"bbash/command/ls"
|
"bbash/command/ls"
|
||||||
@ -15,6 +16,7 @@ import (
|
|||||||
"bbash/command/rm"
|
"bbash/command/rm"
|
||||||
"bbash/command/tail"
|
"bbash/command/tail"
|
||||||
"bbash/command/touch"
|
"bbash/command/touch"
|
||||||
|
"bbash/command/whereareyou"
|
||||||
"bbash/environment"
|
"bbash/environment"
|
||||||
"bbash/input_parser"
|
"bbash/input_parser"
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -34,6 +36,8 @@ func Init(env *environment.Env) {
|
|||||||
|
|
||||||
func Run_command(in input_parser.Input, env *environment.Env) {
|
func Run_command(in input_parser.Input, env *environment.Env) {
|
||||||
switch in.Instruction {
|
switch in.Instruction {
|
||||||
|
case "fritiofcommand":
|
||||||
|
fritiofcommand.Fritiof(in, env)
|
||||||
case "pwd":
|
case "pwd":
|
||||||
pwd.Pwd(in, env)
|
pwd.Pwd(in, env)
|
||||||
case "echo":
|
case "echo":
|
||||||
@ -60,6 +64,8 @@ func Run_command(in input_parser.Input, env *environment.Env) {
|
|||||||
help.Help(in, env)
|
help.Help(in, env)
|
||||||
case "tail":
|
case "tail":
|
||||||
tail.Tail(in, env)
|
tail.Tail(in, env)
|
||||||
|
case "whereareyou":
|
||||||
|
whereareyou.Whereareyou(in, env)
|
||||||
case "brainrot":
|
case "brainrot":
|
||||||
brainrot.Brainrot(in, env)
|
brainrot.Brainrot(in, env)
|
||||||
default:
|
default:
|
||||||
@ -76,8 +82,13 @@ func run_by_path(in input_parser.Input, env *environment.Env) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
cmd := exec.Command(instr, strings.Fields(in.Args_raw)...)
|
cmd := exec.Command(instr, strings.Fields(in.Args_raw)...)
|
||||||
output, _ := cmd.CombinedOutput()
|
cmd.Stdin = os.Stdin
|
||||||
print(string(output))
|
cmd.Stdout = os.Stdout
|
||||||
|
if err := cmd.Run(); err != nil {
|
||||||
|
fmt.Println(err.Error())
|
||||||
|
}
|
||||||
|
//output, _ := cmd.CombinedOutput()
|
||||||
|
//print(string(output))
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
12
command/fritiofcommand/fritiof.go
Normal file
12
command/fritiofcommand/fritiof.go
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package fritiofcommand
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bbash/environment"
|
||||||
|
"bbash/input_parser"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Fritiof(in input_parser.Input, _ *environment.Env) {
|
||||||
|
fmt.Print("Sannolikheten för läkarlinjen är mycket hög!")
|
||||||
|
// fritiof
|
||||||
|
}
|
||||||
11
command/whereareyou/whereareyou.go
Normal file
11
command/whereareyou/whereareyou.go
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package whereareyou
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bbash/environment"
|
||||||
|
"bbash/input_parser"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Whereareyou(in input_parser.Input, env *environment.Env) {
|
||||||
|
fmt.Println("You're in the thick of it everybody knows!")
|
||||||
|
}
|
||||||
@ -1,24 +1,41 @@
|
|||||||
package input_parser
|
package input_parser
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bbash/environment"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
var commandsTab []string
|
var commandsTab []string
|
||||||
var prevInput string
|
var prevInput string
|
||||||
var tabIndex int
|
var tabIndex int
|
||||||
|
var skipCurrent bool
|
||||||
|
|
||||||
func AutoComplete(input string) string {
|
func AutoComplete(input string, env environment.Env) string {
|
||||||
|
|
||||||
|
rawInput := input
|
||||||
inputLength := len(input)
|
inputLength := len(input)
|
||||||
|
|
||||||
if inputLength == 0 {
|
if inputLength == 0 {
|
||||||
return input
|
return input
|
||||||
}
|
}
|
||||||
|
|
||||||
if tabIndex+2 > len(commandsTab) {
|
|
||||||
tabIndex = -1
|
|
||||||
}
|
|
||||||
|
|
||||||
if prevInput == input {
|
if prevInput == input {
|
||||||
|
|
||||||
|
if skipCurrent {
|
||||||
|
return input
|
||||||
|
}
|
||||||
|
|
||||||
tabIndex = tabIndex + 1
|
tabIndex = tabIndex + 1
|
||||||
|
|
||||||
|
if len(commandsTab) == 0 && tabIndex > 0 {
|
||||||
|
return input
|
||||||
|
}
|
||||||
|
|
||||||
|
if tabIndex > len(commandsTab)-1 {
|
||||||
|
tabIndex = 0
|
||||||
|
}
|
||||||
|
|
||||||
prevInput = commandsTab[tabIndex]
|
prevInput = commandsTab[tabIndex]
|
||||||
return commandsTab[tabIndex]
|
return commandsTab[tabIndex]
|
||||||
}
|
}
|
||||||
@ -26,11 +43,15 @@ func AutoComplete(input string) string {
|
|||||||
prevInput = input
|
prevInput = input
|
||||||
tabIndex = 0
|
tabIndex = 0
|
||||||
|
|
||||||
currentCommands := []string{
|
var flagsDictionary []string
|
||||||
|
|
||||||
|
baseCommands := []string{
|
||||||
"cat",
|
"cat",
|
||||||
"cd",
|
"cd",
|
||||||
"cp",
|
"cp",
|
||||||
"echo",
|
"echo",
|
||||||
|
"exit",
|
||||||
|
"fritiofcommand",
|
||||||
"head",
|
"head",
|
||||||
"help",
|
"help",
|
||||||
"ls",
|
"ls",
|
||||||
@ -40,31 +61,270 @@ func AutoComplete(input string) string {
|
|||||||
"rm",
|
"rm",
|
||||||
"tail",
|
"tail",
|
||||||
"touch",
|
"touch",
|
||||||
|
"whereareyou",
|
||||||
|
}
|
||||||
|
|
||||||
|
var paths []string
|
||||||
|
|
||||||
|
fs, err := os.ReadDir(env.Path)
|
||||||
|
if err != nil {
|
||||||
|
// fmt.Print(fmt.Sprintf("Error opening directory %s", env.Path))
|
||||||
|
}
|
||||||
|
for _, f := range fs {
|
||||||
|
// if (f.Name()[0] == '.') && !(slices.Contains(in.Flags, "a")) {
|
||||||
|
// continue
|
||||||
|
// } // allows for hidden directories
|
||||||
|
// fmt.Print(f.Name())
|
||||||
|
// fmt.Println()
|
||||||
|
paths = append(paths, f.Name())
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
skipCurrent = false
|
||||||
|
acceptAll := false
|
||||||
|
|
||||||
|
var autoCompleteCommands []string
|
||||||
|
indexField0 := ""
|
||||||
|
var currentIndexFields int
|
||||||
|
var nextAutoCompleteCommands []string
|
||||||
|
noMoreFlags := false
|
||||||
|
|
||||||
|
for indexFields, currentField := range strings.Fields(input) {
|
||||||
|
|
||||||
|
// print("noMoreFlags", noMoreFlags)
|
||||||
|
|
||||||
|
currentIndexFields = indexFields
|
||||||
|
|
||||||
|
if currentIndexFields == 0 {
|
||||||
|
autoCompleteCommands = baseCommands
|
||||||
|
indexField0 = currentField
|
||||||
|
|
||||||
|
// println("len(strings.Fields(input))", len(strings.Fields(input)))
|
||||||
|
// println("input[1:]k", input[len(input)-1:], "khej")
|
||||||
|
if len(strings.Fields(input)) == 1 && input[len(input)-1:] == " " {
|
||||||
|
currentIndexFields += 1
|
||||||
|
// println("den hittade mellanslag :D")
|
||||||
|
acceptAll = true
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if currentIndexFields > 0 {
|
||||||
|
// autoCompleteCommands = baseFunctions
|
||||||
|
// println("currentField 1 :D", currentField)
|
||||||
|
|
||||||
|
switch indexField0 {
|
||||||
|
case "fritiofcommand":
|
||||||
|
skipCurrent = true
|
||||||
|
case "pwd":
|
||||||
|
skipCurrent = true
|
||||||
|
case "echo":
|
||||||
|
skipCurrent = true
|
||||||
|
case "ls":
|
||||||
|
autoCompleteCommands = paths
|
||||||
|
flagsDictionary = []string{
|
||||||
|
"-a", "-help",
|
||||||
|
}
|
||||||
|
case "cd":
|
||||||
|
autoCompleteCommands = paths
|
||||||
|
case "man":
|
||||||
|
autoCompleteCommands = baseCommands
|
||||||
|
case "cat":
|
||||||
|
autoCompleteCommands = paths
|
||||||
|
case "head":
|
||||||
|
autoCompleteCommands = paths
|
||||||
|
flagsDictionary = []string{
|
||||||
|
"-n", "-help",
|
||||||
|
}
|
||||||
|
case "touch":
|
||||||
|
autoCompleteCommands = paths
|
||||||
|
case "rm":
|
||||||
|
autoCompleteCommands = paths
|
||||||
|
case "cp":
|
||||||
|
autoCompleteCommands = paths
|
||||||
|
nextAutoCompleteCommands = paths
|
||||||
|
case "mv":
|
||||||
|
autoCompleteCommands = paths
|
||||||
|
nextAutoCompleteCommands = paths
|
||||||
|
case "help":
|
||||||
|
skipCurrent = true
|
||||||
|
case "tail":
|
||||||
|
autoCompleteCommands = paths
|
||||||
|
flagsDictionary = []string{
|
||||||
|
"-n", "-help",
|
||||||
|
}
|
||||||
|
case "whereareyou":
|
||||||
|
skipCurrent = true
|
||||||
|
default:
|
||||||
|
skipCurrent = true
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if skipCurrent {
|
||||||
|
return rawInput
|
||||||
|
}
|
||||||
|
|
||||||
|
if currentIndexFields == 1 {
|
||||||
|
// print("currentFieldhär om den har - :D", currentField)
|
||||||
|
if strings.ContainsAny(currentField, "-") {
|
||||||
|
noMoreFlags = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(strings.Fields(input)) == 2 && input[len(input)-1:] == " " {
|
||||||
|
// currentIndexFields += 1
|
||||||
|
// println("den hittade mellanslag 2 :D")
|
||||||
|
acceptAll = true
|
||||||
|
autoCompleteCommands = nil
|
||||||
|
|
||||||
|
if noMoreFlags {
|
||||||
|
skipCurrent = true
|
||||||
|
return rawInput
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if currentIndexFields > 2 {
|
||||||
|
skipCurrent = true
|
||||||
|
return rawInput
|
||||||
|
}
|
||||||
|
|
||||||
|
if currentIndexFields == 2 && noMoreFlags {
|
||||||
|
skipCurrent = true
|
||||||
|
return rawInput
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(strings.Fields(input)) == 2 && input[len(input)-1:] == "-" {
|
||||||
|
autoCompleteCommands = flagsDictionary
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if currentIndexFields > 0 && len(autoCompleteCommands) == 0 || currentIndexFields > 0 && strings.ContainsAny(rawInput, "-") {
|
||||||
|
// println("currentIdexFields är 2!!")
|
||||||
|
|
||||||
|
// if len(flagsDictionary) == 0 {
|
||||||
|
// skipCurrent = true
|
||||||
|
// return rawInput
|
||||||
|
// }
|
||||||
|
|
||||||
|
// } else {
|
||||||
|
// println("input", input, "test", input[len(input)-1:], "slut")
|
||||||
|
// if input[len(input)-1:] == " " {
|
||||||
|
// println("acceptAll")
|
||||||
|
// acceptAll = true
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// println("currentField 2 :D", currentField)
|
||||||
|
autoCompleteCommands = nextAutoCompleteCommands
|
||||||
|
// println("nextAutoCompleteCommands", nextAutoCompleteCommands)
|
||||||
|
// println("autoCompleteCommands", autoCompleteCommands)
|
||||||
|
if len(nextAutoCompleteCommands) == 0 {
|
||||||
|
// println("currentField 100 :D", currentField)
|
||||||
|
// if strings.ContainsAny(rawInput, "-") {
|
||||||
|
autoCompleteCommands = flagsDictionary
|
||||||
|
// print("autoCompleteCommands", autoCompleteCommands)
|
||||||
|
|
||||||
|
// if currentIndexFields == 1 {
|
||||||
|
// noMoreFlags = true
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// if len(autoCompleteCommands) == 0 {
|
||||||
|
// skipCurrent = true
|
||||||
|
// return rawInput
|
||||||
|
// }
|
||||||
|
// break
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if currentIndexFields > 0 {
|
||||||
|
input = currentField
|
||||||
|
}
|
||||||
|
|
||||||
|
// println("loop", indexFields)
|
||||||
|
|
||||||
|
// if strings.ContainsAny(currentField, "-") {
|
||||||
|
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
// println("autoCompleteCOmmands", autoCompleteCommands)
|
||||||
|
// println("autoCompleteCOmmands", autoCompleteCommands[0])
|
||||||
|
|
||||||
|
if autoCompleteCommands == nil {
|
||||||
|
skipCurrent = true
|
||||||
|
return rawInput
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var commandsWorking []string
|
var commandsWorking []string
|
||||||
|
|
||||||
for _, currentCommand := range currentCommands {
|
// println(commandsWorking)
|
||||||
|
|
||||||
if len(currentCommand) < inputLength {
|
inputLength = len(input)
|
||||||
|
|
||||||
|
aLength := 0
|
||||||
|
|
||||||
|
foundAutoComplete := false
|
||||||
|
|
||||||
|
for _, currentCommand := range autoCompleteCommands {
|
||||||
|
// println("currentCommand")
|
||||||
|
// println(currentCommand)
|
||||||
|
|
||||||
|
if len(currentCommand) < inputLength && !acceptAll {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
currentCommandWithoutEnd := currentCommand[:inputLength]
|
if !acceptAll {
|
||||||
|
currentCommandWithoutEnd := currentCommand[:inputLength]
|
||||||
if currentCommandWithoutEnd != input {
|
if currentCommandWithoutEnd != input {
|
||||||
continue
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foundAutoComplete = true
|
||||||
|
|
||||||
|
aLength = len(currentCommand) - len(input)
|
||||||
|
aLength = len(currentCommand) - aLength
|
||||||
|
|
||||||
|
// println("aLength")
|
||||||
|
// println(aLength)
|
||||||
|
|
||||||
|
// println("currentCommand")
|
||||||
|
// println(currentCommand)
|
||||||
|
|
||||||
|
// println("rawInput")
|
||||||
|
// println(rawInput)
|
||||||
|
|
||||||
|
if acceptAll {
|
||||||
|
commandsWorking = append(commandsWorking, rawInput+currentCommand)
|
||||||
|
} else {
|
||||||
|
commandsWorking = append(commandsWorking, rawInput+currentCommand[aLength:])
|
||||||
}
|
}
|
||||||
|
|
||||||
commandsWorking = append(commandsWorking, currentCommand)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !foundAutoComplete {
|
||||||
|
skipCurrent = true
|
||||||
|
return rawInput
|
||||||
|
}
|
||||||
|
|
||||||
|
// println("commandsWorking")
|
||||||
|
// println(commandsWorking[0])
|
||||||
|
// println(commandsWorking[1])
|
||||||
|
|
||||||
commandsTab = commandsWorking
|
commandsTab = commandsWorking
|
||||||
|
|
||||||
if len(commandsTab) == 0 {
|
if len(commandsTab) == 0 {
|
||||||
return input
|
return input
|
||||||
}
|
}
|
||||||
|
|
||||||
prevInput = commandsTab[0]
|
removedStart := commandsTab[0]
|
||||||
return commandsTab[0]
|
// removedStart := commandsTab[0][inputLength:]
|
||||||
|
|
||||||
|
prevInput = removedStart
|
||||||
|
return prevInput
|
||||||
}
|
}
|
||||||
|
|||||||
55
input_parser/auto_complete_history.go
Normal file
55
input_parser/auto_complete_history.go
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
package input_parser
|
||||||
|
|
||||||
|
import "bbash/environment"
|
||||||
|
|
||||||
|
func AutoCompleteHistory(input string, env environment.Env) string {
|
||||||
|
|
||||||
|
inputLength := len(input)
|
||||||
|
|
||||||
|
if inputLength == 0 {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// tabIndex = 0
|
||||||
|
|
||||||
|
// currentCommands := []string{
|
||||||
|
// "cat",
|
||||||
|
// "cd",
|
||||||
|
// "cp",
|
||||||
|
// "echo",
|
||||||
|
// "head",
|
||||||
|
// "help",
|
||||||
|
// "ls",
|
||||||
|
// "man",
|
||||||
|
// "mv",
|
||||||
|
// "pwd",
|
||||||
|
// "rm",
|
||||||
|
// "tail",
|
||||||
|
// "touch",
|
||||||
|
// }
|
||||||
|
|
||||||
|
historyWorking := ""
|
||||||
|
|
||||||
|
for _, currentHistory := range env.History[:len(env.History)-1] {
|
||||||
|
// println("currentHistory", currentHistory)
|
||||||
|
|
||||||
|
if len(currentHistory) < inputLength {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
currentCommandWithoutEnd := currentHistory[:inputLength]
|
||||||
|
|
||||||
|
if currentCommandWithoutEnd != input {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
historyWorking = currentHistory
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(historyWorking) != 0 {
|
||||||
|
historyWorking = historyWorking[inputLength:]
|
||||||
|
}
|
||||||
|
|
||||||
|
return historyWorking
|
||||||
|
}
|
||||||
105
input_parser/escape_handler.go
Normal file
105
input_parser/escape_handler.go
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
package input_parser
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bbash/environment"
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Escape_handler(reader *bufio.Reader, history_index int, input string, env environment.Env, cursor int) (string, int, int) {
|
||||||
|
next_rune, _, _ := reader.ReadRune()
|
||||||
|
if next_rune == 59 {
|
||||||
|
}
|
||||||
|
if next_rune != 91 { // not "["
|
||||||
|
return "", history_index, cursor
|
||||||
|
}
|
||||||
|
next_rune, _, _ = reader.ReadRune()
|
||||||
|
|
||||||
|
switch next_rune {
|
||||||
|
case 65: //A
|
||||||
|
if history_index > 0 {
|
||||||
|
history_index--
|
||||||
|
input = env.History[history_index]
|
||||||
|
cursor = len(input)
|
||||||
|
}
|
||||||
|
case 66: //B
|
||||||
|
if history_index < len(env.History)-1 {
|
||||||
|
history_index++
|
||||||
|
input = env.History[history_index]
|
||||||
|
}
|
||||||
|
if history_index == len(env.History)-1 {
|
||||||
|
input = ""
|
||||||
|
cursor = 0
|
||||||
|
}
|
||||||
|
cursor = len(input)
|
||||||
|
case 68: //D
|
||||||
|
if cursor > 0 {
|
||||||
|
cursor--
|
||||||
|
}
|
||||||
|
|
||||||
|
case 67: //C
|
||||||
|
if prevGhostString != "" {
|
||||||
|
input = input + prevGhostString
|
||||||
|
cursor = len(input)
|
||||||
|
}
|
||||||
|
if cursor < len(input) {
|
||||||
|
cursor++
|
||||||
|
}
|
||||||
|
case 49:
|
||||||
|
cursor = ctrl(reader, input, cursor)
|
||||||
|
return input, history_index, cursor
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return input, history_index, cursor
|
||||||
|
}
|
||||||
|
func ctrl(reader *bufio.Reader, input string, cursor int) int {
|
||||||
|
next_rune, _, err := reader.ReadRune()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err.Error())
|
||||||
|
return cursor
|
||||||
|
}
|
||||||
|
if next_rune != 59 {
|
||||||
|
return cursor
|
||||||
|
}
|
||||||
|
next_rune, _, err = reader.ReadRune()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err.Error())
|
||||||
|
return cursor
|
||||||
|
}
|
||||||
|
if next_rune != 53 {
|
||||||
|
return cursor
|
||||||
|
}
|
||||||
|
next_rune, _, err = reader.ReadRune()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err.Error())
|
||||||
|
return cursor
|
||||||
|
}
|
||||||
|
switch next_rune {
|
||||||
|
case 68: // ctrl left
|
||||||
|
input_at := input[:cursor]
|
||||||
|
last_index := strings.LastIndex(input_at, " ")
|
||||||
|
if last_index == -1 {
|
||||||
|
cursor = 0
|
||||||
|
} else {
|
||||||
|
input_at = input_at[:last_index]
|
||||||
|
cursor = len(input_at)
|
||||||
|
}
|
||||||
|
case 67: // ctrl right
|
||||||
|
input_next := input[cursor:]
|
||||||
|
next_trimmed := strings.TrimLeft(input_next, " ")
|
||||||
|
last_index := strings.Index(next_trimmed, " ")
|
||||||
|
if last_index == -1 {
|
||||||
|
cursor = len(input)
|
||||||
|
} else {
|
||||||
|
cursor = cursor + last_index + (len(input_next) - len(next_trimmed))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cursor
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@ -10,6 +10,8 @@ import (
|
|||||||
"golang.org/x/term"
|
"golang.org/x/term"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var prevGhostString string
|
||||||
|
|
||||||
type Input struct {
|
type Input struct {
|
||||||
// The instruction a.k.a first argument
|
// The instruction a.k.a first argument
|
||||||
Instruction string
|
Instruction string
|
||||||
@ -22,10 +24,10 @@ type Input struct {
|
|||||||
|
|
||||||
func Parse(env *environment.Env) Input {
|
func Parse(env *environment.Env) Input {
|
||||||
input := input_str(env)
|
input := input_str(env)
|
||||||
return parse_input(input)
|
return Parse_input(input)
|
||||||
}
|
}
|
||||||
func parse_input(input string) Input {
|
func Parse_input(input string) Input {
|
||||||
split := strings.Split(string(input), " ")
|
split := strings.Split(strings.TrimSpace(string(input)), " ")
|
||||||
instruction := strings.TrimSpace(split[0])
|
instruction := strings.TrimSpace(split[0])
|
||||||
|
|
||||||
args_raw := ""
|
args_raw := ""
|
||||||
@ -36,14 +38,11 @@ func parse_input(input string) Input {
|
|||||||
var flags []string
|
var flags []string
|
||||||
var args []string
|
var args []string
|
||||||
for _, arg := range split[1:] {
|
for _, arg := range split[1:] {
|
||||||
if len(arg) == 0 {
|
if len(arg) == 1 {
|
||||||
continue
|
|
||||||
} else if len(arg) == 1 {
|
|
||||||
if arg[0] == '-' {
|
if arg[0] == '-' {
|
||||||
continue
|
continue
|
||||||
} else {
|
|
||||||
args = append(args, strings.TrimSpace(arg))
|
|
||||||
}
|
}
|
||||||
|
_ = append(args, string(arg[0]))
|
||||||
} else if arg[0:2] == "--" {
|
} else if arg[0:2] == "--" {
|
||||||
var result = strings.TrimSpace(arg)
|
var result = strings.TrimSpace(arg)
|
||||||
flags = append(flags, string(result[2:]))
|
flags = append(flags, string(result[2:]))
|
||||||
@ -78,6 +77,8 @@ func input_str(env *environment.Env) string {
|
|||||||
history_index := len(env.History) // not -1 since we start at the new one
|
history_index := len(env.History) // not -1 since we start at the new one
|
||||||
env.History = append(env.History, input)
|
env.History = append(env.History, input)
|
||||||
|
|
||||||
|
cursor := 0
|
||||||
|
|
||||||
env.History[len(env.History)-1] = input
|
env.History[len(env.History)-1] = input
|
||||||
fmt.Print("\r\033[K")
|
fmt.Print("\r\033[K")
|
||||||
fmt.Print(env.Path)
|
fmt.Print(env.Path)
|
||||||
@ -85,54 +86,82 @@ func input_str(env *environment.Env) string {
|
|||||||
fmt.Print(input)
|
fmt.Print(input)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
|
if cursor > len(input) {
|
||||||
|
cursor = len(input)
|
||||||
|
}
|
||||||
|
if cursor < 0 {
|
||||||
|
cursor = 0
|
||||||
|
}
|
||||||
r_rune, _, err := reader.ReadRune()
|
r_rune, _, err := reader.ReadRune()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Print(fmt.Sprintf("Error reading user input: ", err.Error()))
|
fmt.Print(fmt.Sprintf("Error reading user input: %s", err.Error()))
|
||||||
}
|
}
|
||||||
switch r_rune {
|
switch r_rune {
|
||||||
case 3: // ^C
|
case 3: // ^C
|
||||||
fmt.Println("^C")
|
fmt.Println("^C")
|
||||||
|
cursor = 0
|
||||||
input = ""
|
input = ""
|
||||||
case 4: // ^D
|
case 4: // ^D
|
||||||
input = "exit"
|
input = "exit"
|
||||||
goto loop_exit
|
goto loop_exit
|
||||||
case 9: // Tab
|
case 8: // <CTR><BACKSPACE>
|
||||||
input = AutoComplete(input)
|
input_at := input[:cursor]
|
||||||
case 91:
|
input_after := input[cursor:]
|
||||||
if r, _, _ := reader.ReadRune(); r == 65 { // UPP
|
last_index := strings.LastIndex(input_at, " ")
|
||||||
if history_index > 0 {
|
if last_index == -1 {
|
||||||
history_index--
|
input_at = ""
|
||||||
input = env.History[history_index]
|
cursor = 0
|
||||||
}
|
} else {
|
||||||
break
|
input_at = input_at[:last_index]
|
||||||
|
cursor = len(input_at)
|
||||||
}
|
|
||||||
if r, _, _ := reader.ReadRune(); r != 66 { //DOWN
|
|
||||||
if history_index < len(env.History)-2 {
|
|
||||||
history_index++
|
|
||||||
input = env.History[history_index]
|
|
||||||
} else {
|
|
||||||
input = ""
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
|
input = input_at+input_after
|
||||||
|
|
||||||
|
case 9: // TAB
|
||||||
|
input = AutoComplete(input, *env)
|
||||||
|
cursor = len(input)
|
||||||
|
case 27: // Escape
|
||||||
|
input, history_index, cursor = Escape_handler(reader, history_index, input, *env, cursor)
|
||||||
case 127: //packspace
|
case 127: //packspace
|
||||||
|
input_at := input[:cursor]
|
||||||
|
input_after := input[cursor:]
|
||||||
if len(input) > 0 {
|
if len(input) > 0 {
|
||||||
input = input[:len(input)-1]
|
input_at = input_at[:len(input_at)-1]
|
||||||
|
cursor--
|
||||||
}
|
}
|
||||||
|
input=input_at+input_after
|
||||||
case 13: // Enter
|
case 13: // Enter
|
||||||
goto loop_exit
|
goto loop_exit
|
||||||
default:
|
default:
|
||||||
input = input + string(r_rune)
|
input_at := input[:cursor]
|
||||||
|
input_after := input[cursor:]
|
||||||
|
input_at += string(r_rune)
|
||||||
|
input = input_at+input_after
|
||||||
|
cursor++
|
||||||
}
|
}
|
||||||
|
ghost_input := AutoCompleteHistory(input, *env)
|
||||||
|
|
||||||
env.History[len(env.History)-1] = input
|
env.History[len(env.History)-1] = input
|
||||||
fmt.Print("\r")
|
fmt.Print("\r")
|
||||||
fmt.Print("\r\033[K")
|
fmt.Print(env.Path)
|
||||||
|
fmt.Print(" > \033[K")
|
||||||
|
fmt.Print(input)
|
||||||
|
fmt.Print("\033[2m", ghost_input, "\033[0m")
|
||||||
|
|
||||||
|
prevGhostString = ""
|
||||||
|
|
||||||
|
backwardSteps := len(ghost_input)
|
||||||
|
if backwardSteps != 0 {
|
||||||
|
fmt.Printf("\033[%dD", backwardSteps)
|
||||||
|
prevGhostString = ghost_input
|
||||||
|
}
|
||||||
|
fmt.Print("\r")
|
||||||
fmt.Print(env.Path)
|
fmt.Print(env.Path)
|
||||||
fmt.Print(" > ")
|
fmt.Print(" > ")
|
||||||
fmt.Print("\033[K")
|
for i := 0; i < cursor; i++ {
|
||||||
fmt.Print(input)
|
fmt.Print("\033[C")
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
loop_exit:
|
loop_exit:
|
||||||
term.Restore(int(std_fd), term_restore)
|
term.Restore(int(std_fd), term_restore)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user