Compare commits

..

23 Commits

Author SHA1 Message Date
Tobias P.L Wennberg
2a594eac1d Fix merge 2025-01-14 13:31:39 +01:00
Lo
9bbaae1d11 fixade autocomplete 2025-01-14 13:22:09 +01:00
Tobias P.L Wennberg
ed3067a9a0 Better input, now with ctrl 2025-01-14 10:39:22 +01:00
Tobias P.L Wennberg
ada7fa9d9e fix cursor 2025-01-14 09:24:56 +01:00
Tobias P.L Wennberg
3f1b876f68 Fix merge with autocomplete, still a few quirks 2025-01-14 09:15:35 +01:00
b071d3dd78 implemened cursor control and better escape char handling 2025-01-14 09:04:38 +01:00
Tobias P.L Wennberg
78fb97a860 Nvim works! 2025-01-14 09:02:59 +01:00
Tobias P.L Wennberg
e37798dd82 merge conflict 2025-01-13 18:05:13 +01:00
Tobias P.L Wennberg
a227e3e106 remove api key 2025-01-13 18:03:45 +01:00
Lo
2f6f75b3a4 Mindre fixar med auto slut 2025-01-13 17:46:40 +01:00
Tobias P.L Wennberg
0216b72d65 Accidentally disabled tab-complete 2025-01-13 17:12:54 +01:00
Tobias P.L Wennberg
35af0423a7 merge flodman 2025-01-13 17:04:15 +01:00
Tobias P.L Wennberg
3c166dda98 Merge branch 'Flodman' 2025-01-13 17:02:51 +01:00
In_the_Thick_of_It
e6e223b6a7 implemented some brainrot for y'all :):):):):):) 2025-01-13 16:59:09 +01:00
Tobias P.L Wennberg
d4757c154b Fix 2025-01-13 15:45:26 +01:00
Tobias P.L Wennberg
45cf77ed2a Merge fix 2025-01-13 15:39:04 +01:00
Lo
45f50a95ce History auto komplett :D 2025-01-13 15:28:58 +01:00
Laukka
0525f346b4 Merge remote-tracking branch 'origin/laukkasBranch' into laukkasBranch 2025-01-13 15:01:43 +01:00
Laukka
15da22bc16 added fritiofscommando och att man kan ha " " innan komandon 2025-01-13 15:01:38 +01:00
Laukka
642d1780b6 added fritiofscommando och att man kan ha " " innan komandon 2025-01-13 14:37:35 +01:00
Laukka
2932f9bf43 added fritiofscommando och att man kan ha " " innan komandon 2025-01-13 14:28:15 +01:00
Laukka
6c63fc7122 Merge branch 'refs/heads/master' into laukkasBranch
# Conflicts:
#	input_parser/input_parser.go
2025-01-13 14:25:54 +01:00
Laukka
aad4da3077 fixed len 1 and 0 args and flags 2025-01-13 10:55:44 +01:00
10 changed files with 554 additions and 54 deletions

2
.gitignore vendored
View File

@ -1 +1 @@
/api/api.go ./api/api.go

View File

@ -1,7 +1,6 @@
package api package api
func Api() string { func Api() string {
apiString := "" apiString := "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"
return apiString return apiString
} }

View File

@ -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
} }

View 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
}

View 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!")
}

18
hello Normal file
View File

@ -0,0 +1,18 @@
a
b
c
1
2
3
4
5
6
7
8
9
9
9
9
9
9
9

View File

@ -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
} }

View 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
}

View 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
}

View File

@ -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)