diff --git a/docs/runner-mode.txt b/docs/runner-mode.txt index 41e0912..9df1095 100644 --- a/docs/runner-mode.txt +++ b/docs/runner-mode.txt @@ -20,7 +20,7 @@ An example: hilbish.runnerMode(function(input) local ok = pcall(fennel.eval, input) if ok then - return 0, nil + return input, 0, nil end return hilbish.runner.sh(input) @@ -28,7 +28,9 @@ end) The `hilbish.runner` interface is an alternative to using `hilbish.runnerMode` and also provides the sh and Lua runner functions that Hilbish itself uses. -A runner function is expected to return 2 values: the exit code, and an error. +A runner function is expected to return 3 values: the input, exit code, and an error. +The input return is there incase you need to prompt for more input. +If you don't, just return the input passed to the runner function. The exit code has to be a number, it will be 0 otherwise and the error can be `nil` to indicate no error. @@ -36,5 +38,5 @@ The exit code has to be a number, it will be 0 otherwise and the error can be These are the functions for the `hilbish.runner` interface + setMode(mode) > The same as `hilbish.runnerMode` -+ sh(input) -> code, err > Runs `input` in Hilbish's sh interpreter -+ lua(input) -> code, err > Evals `input` as Lua code ++ sh(input) -> input, code, err > Runs `input` in Hilbish's sh interpreter ++ lua(input) -> input, code, err > Evals `input` as Lua code diff --git a/exec.go b/exec.go index d2ff6cd..62c40f3 100644 --- a/exec.go +++ b/exec.go @@ -32,38 +32,40 @@ func runInput(input string, priv bool) { cmdString := aliases.Resolve(input) hooks.Em.Emit("command.preexec", input, cmdString) + var exitCode uint8 + var err error if runnerMode.Type() == rt.StringType { switch runnerMode.AsString() { case "hybrid": - _, err := handleLua(cmdString) + _, _, err = handleLua(cmdString) if err == nil { cmdFinish(0, input, priv) return } - exitCode, err := handleSh(cmdString) + input, exitCode, err = handleSh(cmdString) if err != nil { fmt.Fprintln(os.Stderr, err) } cmdFinish(exitCode, input, priv) case "hybridRev": - _, err := handleSh(cmdString) + _, _, err = handleSh(cmdString) if err == nil { cmdFinish(0, input, priv) return } - exitCode, err := handleLua(cmdString) + input, exitCode, err = handleLua(cmdString) if err != nil { fmt.Fprintln(os.Stderr, err) } cmdFinish(exitCode, input, priv) case "lua": - exitCode, err := handleLua(cmdString) + input, exitCode, err = handleLua(cmdString) if err != nil { fmt.Fprintln(os.Stderr, err) } cmdFinish(exitCode, input, priv) case "sh": - exitCode, err := handleSh(cmdString) + input, exitCode, err = handleSh(cmdString) if err != nil { fmt.Fprintln(os.Stderr, err) } @@ -79,13 +81,18 @@ func runInput(input string, priv bool) { return } - luaexitcode := term.Get(0) // first return value (makes sense right i love stacks) + luaexitcode := term.Get(0) runErr := term.Get(1) + luaInput := term.Get(1) var exitCode uint8 if code, ok := luaexitcode.TryInt(); ok { exitCode = uint8(code) } + + if inp, ok := luaInput.TryString(); ok { + input = inp + } if runErr != rt.NilValue { fmt.Fprintln(os.Stderr, runErr) @@ -94,7 +101,7 @@ func runInput(input string, priv bool) { } } -func handleLua(cmdString string) (uint8, error) { +func handleLua(cmdString string) (string, uint8, error) { // First try to load input, essentially compiling to bytecode chunk, err := l.CompileAndLoadLuaChunk("", []byte(cmdString), rt.TableValue(l.GlobalEnv())) if err != nil && noexecute { @@ -105,7 +112,7 @@ func handleLua(cmdString string) (uint8, error) { } } */ - return 125, err + return cmdString, 125, err } // And if there's no syntax errors and -n isnt provided, run if !noexecute { @@ -114,19 +121,19 @@ func handleLua(cmdString string) (uint8, error) { } } if err == nil { - return 0, nil + return cmdString, 0, nil } - return 125, err + return cmdString, 125, err } -func handleSh(cmdString string) (uint8, error) { +func handleSh(cmdString string) (string, uint8, error) { _, _, err := execCommand(cmdString, true) if err != nil { // If input is incomplete, start multiline prompting if syntax.IsIncomplete(err) { if !interactive { - return 126, err + return cmdString, 126, err } for { cmdString, err = continuePrompt(strings.TrimSuffix(cmdString, "\\")) @@ -137,23 +144,23 @@ func handleSh(cmdString string) (uint8, error) { if syntax.IsIncomplete(err) || strings.HasSuffix(cmdString, "\\") { continue } else if code, ok := interp.IsExitStatus(err); ok { - return code, nil + return cmdString, code, nil } else if err != nil { - return 126, err + return cmdString, 126, err } else { - return 0, nil + return cmdString, 0, nil } } } else { if code, ok := interp.IsExitStatus(err); ok { - return code, nil + return cmdString, code, nil } else { - return 126, err + return cmdString, 126, err } } } - return 0, nil + return cmdString, 0, nil } // Run command in sh interpreter diff --git a/runnermode.go b/runnermode.go index 7b682b4..4285142 100644 --- a/runnermode.go +++ b/runnermode.go @@ -28,13 +28,13 @@ func shRunner(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { return nil, err } - exitCode, err := handleSh(cmd) + input, exitCode, err := handleSh(cmd) var luaErr rt.Value = rt.NilValue if err != nil { luaErr = rt.StringValue(err.Error()) } - return c.PushingNext(t.Runtime, rt.IntValue(int64(exitCode)), luaErr), nil + return c.PushingNext(t.Runtime, rt.StringValue(input), rt.IntValue(int64(exitCode)), luaErr), nil } func luaRunner(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { @@ -46,11 +46,11 @@ func luaRunner(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { return nil, err } - exitCode, err := handleLua(cmd) + input, exitCode, err := handleLua(cmd) var luaErr rt.Value = rt.NilValue if err != nil { luaErr = rt.StringValue(err.Error()) } - return c.PushingNext(t.Runtime, rt.IntValue(int64(exitCode)), luaErr), nil + return c.PushingNext(t.Runtime, rt.StringValue(input), rt.IntValue(int64(exitCode)), luaErr), nil }