Hilbish/exec.go

215 lines
5.2 KiB
Go
Raw Normal View History

2021-04-03 17:13:45 +00:00
package main
import (
"errors"
2021-04-19 02:09:27 +00:00
"fmt"
refactor!: support lua 5.4 (#129) major rewrite which changes the library hilbish uses for it's lua vm this one implements lua 5.4, and since that's a major version bump, it's a breaking change. introduced here also is a fix for `hilbish.login` not being the right value * refactor: start work on lua 5.4 lots of commented out code ive found a go lua library which implements lua 5.4 and found an opportunity to start working on it. this commit basically removes everything and just leaves enough for the shell to be "usable" and able to start. there are no builtins or libraries (besides the `hilbish` global) * fix: call cont next in prompt function this continues execution of lua, very obvious fixes an issue with code stopping at the prompt function * fix: handle errors in user config * fix: handle panic in lua input if it is incorrect * feat: implement bait * refactor: use util funcs to run lua where possible * refactor: move arg handle function to util * feat: implement commander * feat: implement fs * feat: add hilbish module functions used by prelude * chore: use custom fork of golua * fix: make sure args to setenv are strings in prelude * feat: implement completions * chore: remove comment * feat: implement terminal * feat: implement hilbish.interval * chore: update lunacolors * chore: update golua * feat: implement aliases * feat: add input mode * feat: implement runner mode * style: use comma separated cases instead of fallthrough * feat: implement syntax highlight and hints * chore: add comments to document util functions * chore: fix dofile comment doc * refactor: make loader functions for go modules unexported * feat: implement job management * feat: add hilbish properties * feat: implement all hilbish module functions * feat: implement history interface * feat: add completion interface * feat: add module description docs * feat: implement os interface * refactor: use hlalias for add function in hilbish.alias interface * feat: make it so hilbish.run can return command output * fix: set hilbish.exitCode to last command exit code * fix(ansikit): flush on io.write * fix: deregister commander if return isnt number * feat: run script when provided path * fix: read file manually in DoFile to avoid shebang * chore: add comment for reason of unreading byte * fix: remove prelude error printing * fix: add names at chunk load for context in errors * fix: add newline at the beginning of file buffer when there is shebang this makes the line count in error messages line up properly * fix: remove extra newline after error
2022-04-04 10:40:02 +00:00
"io"
2021-04-19 02:09:27 +00:00
"os"
2021-04-03 17:13:45 +00:00
"strings"
2022-03-06 17:31:50 +00:00
"hilbish/util"
2024-12-29 05:12:06 +00:00
//herror "hilbish/errors"
refactor!: support lua 5.4 (#129) major rewrite which changes the library hilbish uses for it's lua vm this one implements lua 5.4, and since that's a major version bump, it's a breaking change. introduced here also is a fix for `hilbish.login` not being the right value * refactor: start work on lua 5.4 lots of commented out code ive found a go lua library which implements lua 5.4 and found an opportunity to start working on it. this commit basically removes everything and just leaves enough for the shell to be "usable" and able to start. there are no builtins or libraries (besides the `hilbish` global) * fix: call cont next in prompt function this continues execution of lua, very obvious fixes an issue with code stopping at the prompt function * fix: handle errors in user config * fix: handle panic in lua input if it is incorrect * feat: implement bait * refactor: use util funcs to run lua where possible * refactor: move arg handle function to util * feat: implement commander * feat: implement fs * feat: add hilbish module functions used by prelude * chore: use custom fork of golua * fix: make sure args to setenv are strings in prelude * feat: implement completions * chore: remove comment * feat: implement terminal * feat: implement hilbish.interval * chore: update lunacolors * chore: update golua * feat: implement aliases * feat: add input mode * feat: implement runner mode * style: use comma separated cases instead of fallthrough * feat: implement syntax highlight and hints * chore: add comments to document util functions * chore: fix dofile comment doc * refactor: make loader functions for go modules unexported * feat: implement job management * feat: add hilbish properties * feat: implement all hilbish module functions * feat: implement history interface * feat: add completion interface * feat: add module description docs * feat: implement os interface * refactor: use hlalias for add function in hilbish.alias interface * feat: make it so hilbish.run can return command output * fix: set hilbish.exitCode to last command exit code * fix(ansikit): flush on io.write * fix: deregister commander if return isnt number * feat: run script when provided path * fix: read file manually in DoFile to avoid shebang * chore: add comment for reason of unreading byte * fix: remove prelude error printing * fix: add names at chunk load for context in errors * fix: add newline at the beginning of file buffer when there is shebang this makes the line count in error messages line up properly * fix: remove extra newline after error
2022-04-04 10:40:02 +00:00
rt "github.com/arnodel/golua/runtime"
2021-11-21 23:50:35 +00:00
//"github.com/yuin/gopher-lua/parse"
2021-04-03 17:13:45 +00:00
)
var errNotExec = errors.New("not executable")
var errNotFound = errors.New("not found")
2024-12-29 05:35:01 +00:00
var runnerMode rt.Value = rt.NilValue
func runInput(input string, priv bool) {
running = true
cmdString := aliases.Resolve(input)
hooks.Emit("command.preexec", input, cmdString)
2024-12-29 05:12:06 +00:00
currentRunner := runnerMode
rerun:
var exitCode uint8
var cont bool
var newline bool
// save incase it changes while prompting (For some reason)
2024-12-29 05:12:06 +00:00
input, exitCode, cont, newline, runnerErr, err := runLuaRunner(currentRunner, input)
if err != nil {
fmt.Fprintln(os.Stderr, err)
cmdFinish(124, input, priv)
return
}
2024-12-29 05:12:06 +00:00
// we only use `err` to check for lua eval error
// our actual error should only be a runner provided error at this point
// command not found type, etc
err = runnerErr
if cont {
input, err = continuePrompt(input, newline)
if err == nil {
goto rerun
} else if err == io.EOF {
lr.SetPrompt(fmtPrompt(prompt))
}
}
if err != nil && err != io.EOF {
2024-12-29 05:12:06 +00:00
if exErr, ok := util.IsExecError(err); ok {
hooks.Emit("command." + exErr.Typ, exErr.Cmd)
} else {
fmt.Fprintln(os.Stderr, err)
}
}
cmdFinish(exitCode, input, priv)
}
func reprompt(input string, newline bool) (string, error) {
for {
/*
if strings.HasSuffix(input, "\\") {
input = strings.TrimSuffix(input, "\\") + "\n"
}
*/
in, err := continuePrompt(input, newline)
if err != nil {
lr.SetPrompt(fmtPrompt(prompt))
return input, err
}
return in, nil
}
}
func runLuaRunner(runr rt.Value, userInput string) (input string, exitCode uint8, continued bool, newline bool, runnerErr, err error) {
term := rt.NewTerminationWith(l.MainThread().CurrentCont(), 3, false)
err = rt.Call(l.MainThread(), runr, []rt.Value{rt.StringValue(userInput)}, term)
if err != nil {
return "", 124, false, false, nil, err
}
var runner *rt.Table
var ok bool
runnerRet := term.Get(0)
if runner, ok = runnerRet.TryTable(); !ok {
fmt.Fprintln(os.Stderr, "runner did not return a table")
exitCode = 125
input = userInput
return
}
if code, ok := runner.Get(rt.StringValue("exitCode")).TryInt(); ok {
exitCode = uint8(code)
}
if inp, ok := runner.Get(rt.StringValue("input")).TryString(); ok {
input = inp
}
if errStr, ok := runner.Get(rt.StringValue("err")).TryString(); ok {
runnerErr = fmt.Errorf("%s", errStr)
}
if c, ok := runner.Get(rt.StringValue("continue")).TryBool(); ok {
continued = c
}
if nl, ok := runner.Get(rt.StringValue("newline")).TryBool(); ok {
newline = nl
}
return
}
func handleLua(input string) (string, uint8, error) {
cmdString := aliases.Resolve(input)
2021-05-08 12:56:24 +00:00
// First try to load input, essentially compiling to bytecode
refactor!: support lua 5.4 (#129) major rewrite which changes the library hilbish uses for it's lua vm this one implements lua 5.4, and since that's a major version bump, it's a breaking change. introduced here also is a fix for `hilbish.login` not being the right value * refactor: start work on lua 5.4 lots of commented out code ive found a go lua library which implements lua 5.4 and found an opportunity to start working on it. this commit basically removes everything and just leaves enough for the shell to be "usable" and able to start. there are no builtins or libraries (besides the `hilbish` global) * fix: call cont next in prompt function this continues execution of lua, very obvious fixes an issue with code stopping at the prompt function * fix: handle errors in user config * fix: handle panic in lua input if it is incorrect * feat: implement bait * refactor: use util funcs to run lua where possible * refactor: move arg handle function to util * feat: implement commander * feat: implement fs * feat: add hilbish module functions used by prelude * chore: use custom fork of golua * fix: make sure args to setenv are strings in prelude * feat: implement completions * chore: remove comment * feat: implement terminal * feat: implement hilbish.interval * chore: update lunacolors * chore: update golua * feat: implement aliases * feat: add input mode * feat: implement runner mode * style: use comma separated cases instead of fallthrough * feat: implement syntax highlight and hints * chore: add comments to document util functions * chore: fix dofile comment doc * refactor: make loader functions for go modules unexported * feat: implement job management * feat: add hilbish properties * feat: implement all hilbish module functions * feat: implement history interface * feat: add completion interface * feat: add module description docs * feat: implement os interface * refactor: use hlalias for add function in hilbish.alias interface * feat: make it so hilbish.run can return command output * fix: set hilbish.exitCode to last command exit code * fix(ansikit): flush on io.write * fix: deregister commander if return isnt number * feat: run script when provided path * fix: read file manually in DoFile to avoid shebang * chore: add comment for reason of unreading byte * fix: remove prelude error printing * fix: add names at chunk load for context in errors * fix: add newline at the beginning of file buffer when there is shebang this makes the line count in error messages line up properly * fix: remove extra newline after error
2022-04-04 10:40:02 +00:00
chunk, err := l.CompileAndLoadLuaChunk("", []byte(cmdString), rt.TableValue(l.GlobalEnv()))
2021-05-08 12:56:24 +00:00
if err != nil && noexecute {
fmt.Println(err)
2021-06-12 14:41:51 +00:00
/* if lerr, ok := err.(*lua.ApiError); ok {
if perr, ok := lerr.Cause.(*parse.Error); ok {
print(perr.Pos.Line == parse.EOF)
}
}
2021-06-12 14:41:51 +00:00
*/
return cmdString, 125, err
2021-05-08 12:56:24 +00:00
}
// And if there's no syntax errors and -n isnt provided, run
if !noexecute {
refactor!: support lua 5.4 (#129) major rewrite which changes the library hilbish uses for it's lua vm this one implements lua 5.4, and since that's a major version bump, it's a breaking change. introduced here also is a fix for `hilbish.login` not being the right value * refactor: start work on lua 5.4 lots of commented out code ive found a go lua library which implements lua 5.4 and found an opportunity to start working on it. this commit basically removes everything and just leaves enough for the shell to be "usable" and able to start. there are no builtins or libraries (besides the `hilbish` global) * fix: call cont next in prompt function this continues execution of lua, very obvious fixes an issue with code stopping at the prompt function * fix: handle errors in user config * fix: handle panic in lua input if it is incorrect * feat: implement bait * refactor: use util funcs to run lua where possible * refactor: move arg handle function to util * feat: implement commander * feat: implement fs * feat: add hilbish module functions used by prelude * chore: use custom fork of golua * fix: make sure args to setenv are strings in prelude * feat: implement completions * chore: remove comment * feat: implement terminal * feat: implement hilbish.interval * chore: update lunacolors * chore: update golua * feat: implement aliases * feat: add input mode * feat: implement runner mode * style: use comma separated cases instead of fallthrough * feat: implement syntax highlight and hints * chore: add comments to document util functions * chore: fix dofile comment doc * refactor: make loader functions for go modules unexported * feat: implement job management * feat: add hilbish properties * feat: implement all hilbish module functions * feat: implement history interface * feat: add completion interface * feat: add module description docs * feat: implement os interface * refactor: use hlalias for add function in hilbish.alias interface * feat: make it so hilbish.run can return command output * fix: set hilbish.exitCode to last command exit code * fix(ansikit): flush on io.write * fix: deregister commander if return isnt number * feat: run script when provided path * fix: read file manually in DoFile to avoid shebang * chore: add comment for reason of unreading byte * fix: remove prelude error printing * fix: add names at chunk load for context in errors * fix: add newline at the beginning of file buffer when there is shebang this makes the line count in error messages line up properly * fix: remove extra newline after error
2022-04-04 10:40:02 +00:00
if chunk != nil {
_, err = rt.Call1(l.MainThread(), rt.FunctionValue(chunk))
}
2021-05-08 12:56:24 +00:00
}
2021-04-03 17:13:45 +00:00
if err == nil {
return cmdString, 0, nil
}
return cmdString, 125, err
}
2024-12-29 05:12:06 +00:00
/*
func execSh(cmdString string) (input string, exitcode uint8, cont bool, newline bool, e error) {
_, _, err := execCommand(cmdString, nil)
if err != nil {
// If input is incomplete, start multiline prompting
if syntax.IsIncomplete(err) {
if !interactive {
return cmdString, 126, false, false, err
}
newline := false
if strings.Contains(err.Error(), "unclosed here-document") {
newline = true
}
return cmdString, 126, true, newline, err
} else {
if code, ok := interp.IsExitStatus(err); ok {
return cmdString, code, false, false, nil
2021-04-19 02:09:27 +00:00
} else {
return cmdString, 126, false, false, err
2021-04-19 02:09:27 +00:00
}
}
}
return cmdString, 0, false, false, nil
2021-04-03 17:13:45 +00:00
}
2024-12-29 05:12:06 +00:00
*/
2022-01-29 21:43:12 +00:00
2021-04-03 17:13:45 +00:00
func splitInput(input string) ([]string, string) {
// end my suffering
// TODO: refactor this garbage
quoted := false
cmdArgs := []string{}
2021-04-03 17:13:45 +00:00
sb := &strings.Builder{}
cmdstr := &strings.Builder{}
for _, r := range input {
if r == '"' {
// start quoted input
// this determines if other runes are replaced
quoted = !quoted
// dont add back quotes
//sb.WriteRune(r)
} else if !quoted && r == '~' {
// if not in quotes and ~ is found then make it $HOME
sb.WriteString(os.Getenv("HOME"))
} else if !quoted && r == ' ' {
// if not quoted and there's a space then add to cmdargs
cmdArgs = append(cmdArgs, sb.String())
sb.Reset()
} else {
sb.WriteRune(r)
}
cmdstr.WriteRune(r)
}
if sb.Len() > 0 {
cmdArgs = append(cmdArgs, sb.String())
}
return cmdArgs, cmdstr.String()
}
func cmdFinish(code uint8, cmdstr string, private bool) {
util.SetField(l, hshMod, "exitCode", rt.IntValue(int64(code)))
refactor!: support lua 5.4 (#129) major rewrite which changes the library hilbish uses for it's lua vm this one implements lua 5.4, and since that's a major version bump, it's a breaking change. introduced here also is a fix for `hilbish.login` not being the right value * refactor: start work on lua 5.4 lots of commented out code ive found a go lua library which implements lua 5.4 and found an opportunity to start working on it. this commit basically removes everything and just leaves enough for the shell to be "usable" and able to start. there are no builtins or libraries (besides the `hilbish` global) * fix: call cont next in prompt function this continues execution of lua, very obvious fixes an issue with code stopping at the prompt function * fix: handle errors in user config * fix: handle panic in lua input if it is incorrect * feat: implement bait * refactor: use util funcs to run lua where possible * refactor: move arg handle function to util * feat: implement commander * feat: implement fs * feat: add hilbish module functions used by prelude * chore: use custom fork of golua * fix: make sure args to setenv are strings in prelude * feat: implement completions * chore: remove comment * feat: implement terminal * feat: implement hilbish.interval * chore: update lunacolors * chore: update golua * feat: implement aliases * feat: add input mode * feat: implement runner mode * style: use comma separated cases instead of fallthrough * feat: implement syntax highlight and hints * chore: add comments to document util functions * chore: fix dofile comment doc * refactor: make loader functions for go modules unexported * feat: implement job management * feat: add hilbish properties * feat: implement all hilbish module functions * feat: implement history interface * feat: add completion interface * feat: add module description docs * feat: implement os interface * refactor: use hlalias for add function in hilbish.alias interface * feat: make it so hilbish.run can return command output * fix: set hilbish.exitCode to last command exit code * fix(ansikit): flush on io.write * fix: deregister commander if return isnt number * feat: run script when provided path * fix: read file manually in DoFile to avoid shebang * chore: add comment for reason of unreading byte * fix: remove prelude error printing * fix: add names at chunk load for context in errors * fix: add newline at the beginning of file buffer when there is shebang this makes the line count in error messages line up properly * fix: remove extra newline after error
2022-04-04 10:40:02 +00:00
// using AsValue (to convert to lua type) on an interface which is an int
// results in it being unknown in lua .... ????
// so we allow the hook handler to take lua runtime Values
hooks.Emit("command.exit", rt.IntValue(int64(code)), cmdstr, private)
}