mirror of https://github.com/Hilbis/Hilbish
feat: use custom exec handler for sh interpreter
so, here we use a custom function for the sh interpreter to run individual commands now. what does this mean? 1. aliases will work not only on the 1st command, since it was replaced in the beginning before. want to run `cmd; alias`? now you can! 2. custom error message when a command isnt found :} i can also add the command.not-found hook (will do in next commit) 3. sh and lua can be mixed (not in this commit, but itll work) this means all code for handling commands is in the single `execCommand` function in shell.go and will probably able to clean things up soon, ditching the `RunInput` function entirelypull/59/head
parent
aa7de15997
commit
a655ff00ce
93
shell.go
93
shell.go
|
@ -5,6 +5,7 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
// "github.com/bobappleyard/readline"
|
||||
"github.com/yuin/gopher-lua"
|
||||
|
@ -15,18 +16,7 @@ import (
|
|||
)
|
||||
|
||||
func RunInput(input string) {
|
||||
cmdArgs, cmdString := splitInput(input)
|
||||
|
||||
// If alias was found, use command alias
|
||||
for aliases[cmdArgs[0]] != "" {
|
||||
alias := aliases[cmdArgs[0]]
|
||||
cmdString = alias + strings.TrimPrefix(cmdString, cmdArgs[0])
|
||||
cmdArgs, cmdString = splitInput(cmdString)
|
||||
|
||||
if aliases[cmdArgs[0]] != "" {
|
||||
continue
|
||||
}
|
||||
}
|
||||
_, cmdString := splitInput(input)
|
||||
|
||||
// First try to load input, essentially compiling to bytecode
|
||||
fn, err := l.LoadString(cmdString)
|
||||
|
@ -49,33 +39,6 @@ func RunInput(input string) {
|
|||
return
|
||||
}
|
||||
|
||||
// If command is defined in Lua then run it
|
||||
if commands[cmdArgs[0]] {
|
||||
err := l.CallByParam(lua.P{
|
||||
Fn: l.GetField(
|
||||
l.GetTable(
|
||||
l.GetGlobal("commanding"),
|
||||
lua.LString("__commands")),
|
||||
cmdArgs[0]),
|
||||
NRet: 1,
|
||||
Protect: true,
|
||||
}, luar.New(l, cmdArgs[1:]))
|
||||
luaexitcode := l.Get(-1)
|
||||
exitcode := lua.LNumber(0)
|
||||
|
||||
l.Pop(1)
|
||||
|
||||
if code, ok := luaexitcode.(lua.LNumber); luaexitcode != lua.LNil && ok {
|
||||
exitcode = code
|
||||
}
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr,
|
||||
"Error in command:\n\n" + err.Error())
|
||||
}
|
||||
hooks.Em.Emit("command.exit", exitcode)
|
||||
return
|
||||
}
|
||||
|
||||
// Last option: use sh interpreter
|
||||
err = execCommand(cmdString)
|
||||
if err != nil {
|
||||
|
@ -115,8 +78,60 @@ func execCommand(cmd string) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
exechandle := func(ctx context.Context, args []string) error {
|
||||
hc := interp.HandlerCtx(ctx)
|
||||
args, argstring := splitInput(strings.Join(args, " "))
|
||||
|
||||
// If alias was found, use command alias
|
||||
for aliases[args[0]] != "" {
|
||||
alias := aliases[args[0]]
|
||||
argstring = alias + strings.TrimPrefix(argstring, args[0])
|
||||
args, argstring = splitInput(argstring)
|
||||
|
||||
if aliases[args[0]] != "" {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// If command is defined in Lua then run it
|
||||
if commands[args[0]] {
|
||||
err := l.CallByParam(lua.P{
|
||||
Fn: l.GetField(
|
||||
l.GetTable(
|
||||
l.GetGlobal("commanding"),
|
||||
lua.LString("__commands")),
|
||||
args[0]),
|
||||
NRet: 1,
|
||||
Protect: true,
|
||||
}, luar.New(l, args[1:]))
|
||||
luaexitcode := l.Get(-1)
|
||||
var exitcode uint8 = 0
|
||||
|
||||
l.Pop(1)
|
||||
|
||||
if code, ok := luaexitcode.(lua.LNumber); luaexitcode != lua.LNil && ok {
|
||||
exitcode = uint8(code)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr,
|
||||
"Error in command:\n\n" + err.Error())
|
||||
}
|
||||
hooks.Em.Emit("command.exit", exitcode)
|
||||
return interp.NewExitStatus(exitcode)
|
||||
}
|
||||
|
||||
if _, err := interp.LookPathDir(hc.Dir, hc.Env, args[0]); err != nil {
|
||||
fmt.Printf("hilbish: %s not found\n", args[0])
|
||||
return interp.NewExitStatus(127)
|
||||
}
|
||||
|
||||
return interp.DefaultExecHandler(2*time.Second)(ctx, args)
|
||||
}
|
||||
runner, _ := interp.New(
|
||||
interp.StdIO(os.Stdin, os.Stdout, os.Stderr),
|
||||
interp.ExecHandler(exechandle),
|
||||
)
|
||||
err = runner.Run(context.TODO(), file)
|
||||
|
||||
|
|
Loading…
Reference in New Issue