diff --git a/go.mod b/go.mod index 74914a0..c5ae81d 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,8 @@ module github.com/Alexandre1a/GoSH go 1.23.5 + +require ( + github.com/chzyer/readline v1.5.1 // indirect + golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..2de3a80 --- /dev/null +++ b/go.sum @@ -0,0 +1,6 @@ +github.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ= +github.com/chzyer/readline v1.5.1 h1:upd/6fQk4src78LMRzh5vItIt361/o4uq553V8B5sGI= +github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk= +github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8= +golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5 h1:y/woIyUBFbpQGKS0u1aHF/40WUDnek3fPOyD08H5Vng= +golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/main.go b/main.go index 5f67638..0c44a14 100644 --- a/main.go +++ b/main.go @@ -1,48 +1,62 @@ package main import ( - "bufio" - "errors" "fmt" "os" "os/exec" "strings" + + "github.com/chzyer/readline" ) func main() { - reader := bufio.NewReader(os.Stdin) + // Chargement de l'historique au démarrage + homeDir, _ := os.UserHomeDir() + historyFile := homeDir + "/.gosh_history" + + // Configuration du shell interactif + rl, err := readline.NewEx(&readline.Config{ + Prompt: "> ", + HistoryFile: historyFile, // Permet de sauvegarder et charger l'historique + AutoComplete: nil, // Peut être amélioré avec l'autocomplétion + }) + if err != nil { + fmt.Fprintln(os.Stderr, "Erreur readline:", err) + return + } + defer rl.Close() + for { - fmt.Print("> ") - // Read the keyboard input. - input, err := reader.ReadString('\n') - if err != nil { - fmt.Fprintln(os.Stderr, err) + // Lecture de l'entrée utilisateur avec édition et historique + input, err := rl.Readline() + if err != nil { // EOF ou Ctrl+D + break } - // Handle the execution of the input. - if err = execInput(input); err != nil { + // Suppression des espaces inutiles + input = strings.TrimSpace(input) + if input == "" { + continue + } + + // Exécute la commande + if err := execInput(input); err != nil { fmt.Fprintln(os.Stderr, err) } } } func execInput(input string) error { - // Remove the newline character. input = strings.TrimSuffix(input, "\n") - - // Split the input to separate the command and the arguments. args := strings.Split(input, " ") - // Sauvegarde l'historique avant de traiter la commande - checkHistoryAndWrite(input) - - // Check for built-in commands. + // Gérer les commandes intégrées switch args[0] { case "cd": if len(args) < 2 || args[1] == "" { homeDir, err := os.UserHomeDir() if err != nil { - return errors.New("Unable to get home directory") + return fmt.Errorf("Impossible de trouver le home") } return os.Chdir(homeDir) } @@ -50,46 +64,13 @@ func execInput(input string) error { case "exit": os.Exit(0) case "version": - println("GoShell Version 0.2.0") + fmt.Println("GoShell Version 0.2.0") return nil } - // Pass the program and the arguments separately. + // Exécuter la commande système cmd := exec.Command(args[0], args[1:]...) - - // Set the correct output device. cmd.Stderr = os.Stderr cmd.Stdout = os.Stdout - - // Execute the command and return the error. return cmd.Run() } - -func fileExists(filename string) bool { - info, err := os.Stat(filename) - if os.IsNotExist(err) { - return false - } - return !info.IsDir() -} - -func checkHistoryAndWrite(text string) error { - homeDir, err := os.UserHomeDir() - if err != nil { - return errors.New("Unable to get home directory") - } - filePath := homeDir + "/.gosh_history" - - // Ouvre le fichier en mode append et avec les bons droits - file, err := os.OpenFile(filePath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644) - if err != nil { - return fmt.Errorf("Can't open history file: %v", err) - } - defer file.Close() - - _, err = file.WriteString(text + "\n") - if err != nil { - return fmt.Errorf("Can't write to history: %v", err) - } - return nil -}