mirror of https://github.com/Hilbis/Hilbish
Compare commits
No commits in common. "802f444ba6ebb7e1e642d25762c89da7090f8f04" and "96c1487bfa5f74183107e467ea728922d56b7a03" have entirely different histories.
802f444ba6
...
96c1487bfa
33
api.go
33
api.go
|
@ -26,7 +26,6 @@ var exports = map[string]lua.LGFunction {
|
||||||
"complete": hlcomplete,
|
"complete": hlcomplete,
|
||||||
"cwd": hlcwd,
|
"cwd": hlcwd,
|
||||||
"exec": hlexec,
|
"exec": hlexec,
|
||||||
"runnerMode": hlrunnerMode,
|
|
||||||
"goro": hlgoro,
|
"goro": hlgoro,
|
||||||
"multiprompt": hlmlprompt,
|
"multiprompt": hlmlprompt,
|
||||||
"prependPath": hlprependPath,
|
"prependPath": hlprependPath,
|
||||||
|
@ -107,10 +106,6 @@ Check out the {blue}{bold}guide{reset} command to get started.
|
||||||
util.Document(L, hshcomp, "Completions interface for Hilbish.")
|
util.Document(L, hshcomp, "Completions interface for Hilbish.")
|
||||||
L.SetField(mod, "completion", hshcomp)
|
L.SetField(mod, "completion", hshcomp)
|
||||||
|
|
||||||
runnerModule := runnerModeLoader(L)
|
|
||||||
util.Document(L, runnerModule, "Runner/exec interface for Hilbish.")
|
|
||||||
L.SetField(mod, "runner", runnerModule)
|
|
||||||
|
|
||||||
jobs = newJobHandler()
|
jobs = newJobHandler()
|
||||||
|
|
||||||
L.Push(mod)
|
L.Push(mod)
|
||||||
|
@ -177,7 +172,7 @@ func unsetVimMode() {
|
||||||
func hlrun(L *lua.LState) int {
|
func hlrun(L *lua.LState) int {
|
||||||
var exitcode uint8
|
var exitcode uint8
|
||||||
cmd := L.CheckString(1)
|
cmd := L.CheckString(1)
|
||||||
err := execCommand(cmd)
|
err := execCommand(cmd, true)
|
||||||
|
|
||||||
if code, ok := interp.IsExitStatus(err); ok {
|
if code, ok := interp.IsExitStatus(err); ok {
|
||||||
exitcode = code
|
exitcode = code
|
||||||
|
@ -471,29 +466,3 @@ func hlinputMode(L *lua.LState) int {
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// runnerMode(mode)
|
|
||||||
// Sets the execution/runner mode for interactive Hilbish. This determines whether
|
|
||||||
// Hilbish wll try to run input as Lua and/or sh or only do one of either.
|
|
||||||
// Accepted values for mode are hybrid (the default), hybridRev (sh first then Lua),
|
|
||||||
// sh, and lua. It also accepts a function, to which if it is passed one
|
|
||||||
// will call it to execute user input instead.
|
|
||||||
func hlrunnerMode(L *lua.LState) int {
|
|
||||||
mode := L.CheckAny(1)
|
|
||||||
switch mode.Type() {
|
|
||||||
case lua.LTString:
|
|
||||||
switch mode.String() {
|
|
||||||
// no fallthrough doesnt work so eh
|
|
||||||
case "hybrid": fallthrough
|
|
||||||
case "hybridRev": fallthrough
|
|
||||||
case "lua": fallthrough
|
|
||||||
case "sh":
|
|
||||||
runnerMode = mode
|
|
||||||
default: L.RaiseError("execMode: expected either a function or hybrid, hybridRev, lua, sh. Received %v", mode)
|
|
||||||
}
|
|
||||||
case lua.LTFunction: runnerMode = mode
|
|
||||||
default: L.RaiseError("execMode: expected either a function or hybrid, hybridRev, lua, sh. Received %v", mode)
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
|
@ -37,12 +37,6 @@ Returns `input`, will be nil if ctrl + d is pressed, or an error occurs (which s
|
||||||
|
|
||||||
run(cmd) > Runs `cmd` in Hilbish's sh interpreter.
|
run(cmd) > Runs `cmd` in Hilbish's sh interpreter.
|
||||||
|
|
||||||
runnerMode(mode) > Sets the execution/runner mode for interactive Hilbish. This determines whether
|
|
||||||
Hilbish wll try to run input as Lua and/or sh or only do one of either.
|
|
||||||
Accepted values for mode are hybrid (the default), hybridRev (sh first then Lua),
|
|
||||||
sh, and lua. It also accepts a function, to which if it is passed one
|
|
||||||
will call it to execute user input instead.
|
|
||||||
|
|
||||||
timeout(cb, time) > Runs the `cb` function after `time` in milliseconds
|
timeout(cb, time) > Runs the `cb` function after `time` in milliseconds
|
||||||
|
|
||||||
which(binName) > Searches for an executable called `binName` in the directories of $PATH
|
which(binName) > Searches for an executable called `binName` in the directories of $PATH
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
Hilbish is *unique,* when interactive it first attempts to run input as
|
|
||||||
Lua and then tries shell script. But if you're normal, you wouldn't
|
|
||||||
really be using Hilbish anyway but you'd also not want this
|
|
||||||
(or maybe want Lua only in some cases.)
|
|
||||||
|
|
||||||
The "runner mode" of Hilbish is customizable via `hilbish.runnerMode`,
|
|
||||||
which determines how Hilbish will run user input. By default, this is
|
|
||||||
set to `hybrid` which is the previously mentioned behaviour of running Lua
|
|
||||||
first then going to shell script. If you want the reverse order, you can
|
|
||||||
set it to `hybridRev` and for isolated modes there is `sh` and `lua`
|
|
||||||
respectively.
|
|
||||||
|
|
||||||
You can also set it to a function, which will be called everytime Hilbish
|
|
||||||
needs to run interactive input. For example, you can set this to a simple
|
|
||||||
function to compile and evaluate Fennel, and now you can run Fennel.
|
|
||||||
You can even mix it with sh to make a hybrid mode with Lua replaced by
|
|
||||||
Fennel.
|
|
||||||
|
|
||||||
An example:
|
|
||||||
hilbish.runnerMode(function(input)
|
|
||||||
local ok = pcall(fennel.eval, input)
|
|
||||||
if ok then
|
|
||||||
return 0, nil
|
|
||||||
end
|
|
||||||
|
|
||||||
return hilbish.runner.sh(input)
|
|
||||||
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.
|
|
||||||
The exit code has to be a number, it will be 0 otherwise and the error can be
|
|
||||||
`nil` to indicate no error.
|
|
|
@ -69,13 +69,6 @@ function hilbish.read(prompt) end
|
||||||
--- @param cmd string
|
--- @param cmd string
|
||||||
function hilbish.run(cmd) end
|
function hilbish.run(cmd) end
|
||||||
|
|
||||||
--- Sets the execution/runner mode for interactive Hilbish. This determines whether
|
|
||||||
--- Hilbish wll try to run input as Lua and/or sh or only do one of either.
|
|
||||||
--- Accepted values for mode are hybrid (the default), hybridRev (sh first then Lua),
|
|
||||||
--- sh, and lua. It also accepts a function, to which if it is passed one
|
|
||||||
--- will call it to execute user input instead.
|
|
||||||
function hilbish.runnerMode() end
|
|
||||||
|
|
||||||
--- Runs the `cb` function after `time` in milliseconds
|
--- Runs the `cb` function after `time` in milliseconds
|
||||||
--- @param cb function
|
--- @param cb function
|
||||||
--- @param time number
|
--- @param time number
|
||||||
|
|
105
exec.go
105
exec.go
|
@ -24,80 +24,13 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var errNotExec = errors.New("not executable")
|
var errNotExec = errors.New("not executable")
|
||||||
var runnerMode lua.LValue = lua.LString("hybrid")
|
|
||||||
|
|
||||||
func runInput(input string, priv bool) {
|
func runInput(input string, priv bool) {
|
||||||
running = true
|
running = true
|
||||||
cmdString := aliases.Resolve(input)
|
cmdString := aliases.Resolve(input)
|
||||||
|
|
||||||
hooks.Em.Emit("command.preexec", input, cmdString)
|
hooks.Em.Emit("command.preexec", input, cmdString)
|
||||||
|
|
||||||
if runnerMode.Type() == lua.LTString {
|
|
||||||
switch runnerMode.String() {
|
|
||||||
case "hybrid":
|
|
||||||
_, err := handleLua(cmdString)
|
|
||||||
if err == nil {
|
|
||||||
cmdFinish(0, cmdString, priv)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
exitCode, err := handleSh(cmdString)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintln(os.Stderr, err)
|
|
||||||
}
|
|
||||||
cmdFinish(exitCode, cmdString, priv)
|
|
||||||
case "hybridRev":
|
|
||||||
_, err := handleSh(cmdString)
|
|
||||||
if err == nil {
|
|
||||||
cmdFinish(0, cmdString, priv)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
exitCode, err := handleLua(cmdString)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintln(os.Stderr, err)
|
|
||||||
}
|
|
||||||
cmdFinish(exitCode, cmdString, priv)
|
|
||||||
case "lua":
|
|
||||||
exitCode, err := handleLua(cmdString)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintln(os.Stderr, err)
|
|
||||||
}
|
|
||||||
cmdFinish(exitCode, cmdString, priv)
|
|
||||||
case "sh":
|
|
||||||
exitCode, err := handleSh(cmdString)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintln(os.Stderr, err)
|
|
||||||
}
|
|
||||||
cmdFinish(exitCode, cmdString, priv)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// can only be a string or function so
|
|
||||||
err := l.CallByParam(lua.P{
|
|
||||||
Fn: runnerMode,
|
|
||||||
NRet: 2,
|
|
||||||
Protect: true,
|
|
||||||
}, lua.LString(cmdString))
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintln(os.Stderr, err)
|
|
||||||
cmdFinish(124, cmdString, priv)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
luaexitcode := l.Get(-2) // first return value (makes sense right i love stacks)
|
|
||||||
runErr := l.Get(-1)
|
|
||||||
l.Pop(2)
|
|
||||||
|
|
||||||
var exitCode uint8
|
|
||||||
if code, ok := luaexitcode.(lua.LNumber); luaexitcode != lua.LNil && ok {
|
|
||||||
exitCode = uint8(code)
|
|
||||||
}
|
|
||||||
|
|
||||||
if runErr != lua.LNil {
|
|
||||||
fmt.Fprintln(os.Stderr, runErr)
|
|
||||||
}
|
|
||||||
cmdFinish(exitCode, cmdString, priv)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func handleLua(cmdString string) (uint8, error) {
|
|
||||||
// First try to load input, essentially compiling to bytecode
|
// First try to load input, essentially compiling to bytecode
|
||||||
fn, err := l.LoadString(cmdString)
|
fn, err := l.LoadString(cmdString)
|
||||||
if err != nil && noexecute {
|
if err != nil && noexecute {
|
||||||
|
@ -108,7 +41,7 @@ func handleLua(cmdString string) (uint8, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
return 125, err
|
return
|
||||||
}
|
}
|
||||||
// And if there's no syntax errors and -n isnt provided, run
|
// And if there's no syntax errors and -n isnt provided, run
|
||||||
if !noexecute {
|
if !noexecute {
|
||||||
|
@ -116,14 +49,12 @@ func handleLua(cmdString string) (uint8, error) {
|
||||||
err = l.PCall(0, lua.MultRet, nil)
|
err = l.PCall(0, lua.MultRet, nil)
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return 0, nil
|
cmdFinish(0, cmdString, priv)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
return 125, err
|
// Last option: use sh interpreter
|
||||||
}
|
err = execCommand(cmdString, priv)
|
||||||
|
|
||||||
func handleSh(cmdString string) (uint8, error) {
|
|
||||||
err := execCommand(cmdString)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// If input is incomplete, start multiline prompting
|
// If input is incomplete, start multiline prompting
|
||||||
if syntax.IsIncomplete(err) {
|
if syntax.IsIncomplete(err) {
|
||||||
|
@ -132,31 +63,34 @@ func handleSh(cmdString string) (uint8, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
err = execCommand(cmdString)
|
err = execCommand(cmdString, priv)
|
||||||
if syntax.IsIncomplete(err) || strings.HasSuffix(cmdString, "\\") {
|
if syntax.IsIncomplete(err) || strings.HasSuffix(input, "\\") {
|
||||||
continue
|
continue
|
||||||
} else if code, ok := interp.IsExitStatus(err); ok {
|
} else if code, ok := interp.IsExitStatus(err); ok {
|
||||||
return code, nil
|
cmdFinish(code, cmdString, priv)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return 126, err
|
cmdFinish(1, cmdString, priv)
|
||||||
|
fmt.Fprintln(os.Stderr, err)
|
||||||
} else {
|
} else {
|
||||||
return 0, nil
|
cmdFinish(0, cmdString, priv)
|
||||||
}
|
}
|
||||||
|
break
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if code, ok := interp.IsExitStatus(err); ok {
|
if code, ok := interp.IsExitStatus(err); ok {
|
||||||
return code, nil
|
cmdFinish(code, cmdString, priv)
|
||||||
} else {
|
} else {
|
||||||
return 126, err
|
cmdFinish(126, cmdString, priv)
|
||||||
|
fmt.Fprintln(os.Stderr, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
cmdFinish(0, cmdString, priv)
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run command in sh interpreter
|
// Run command in sh interpreter
|
||||||
func execCommand(cmd string) error {
|
func execCommand(cmd string, priv bool) error {
|
||||||
file, err := syntax.NewParser().Parse(strings.NewReader(cmd), "")
|
file, err := syntax.NewParser().Parse(strings.NewReader(cmd), "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -207,6 +141,7 @@ func execCommand(cmd string) error {
|
||||||
exitcode = uint8(code)
|
exitcode = uint8(code)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cmdFinish(exitcode, argstring, priv)
|
||||||
return interp.NewExitStatus(exitcode)
|
return interp.NewExitStatus(exitcode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,46 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/yuin/gopher-lua"
|
|
||||||
)
|
|
||||||
|
|
||||||
func runnerModeLoader(L *lua.LState) *lua.LTable {
|
|
||||||
exports := map[string]lua.LGFunction{
|
|
||||||
"sh": shRunner,
|
|
||||||
"lua": luaRunner,
|
|
||||||
"setMode": hlrunnerMode,
|
|
||||||
}
|
|
||||||
|
|
||||||
mod := L.SetFuncs(L.NewTable(), exports)
|
|
||||||
L.SetField(mod, "mode", runnerMode)
|
|
||||||
|
|
||||||
return mod
|
|
||||||
}
|
|
||||||
|
|
||||||
func shRunner(L *lua.LState) int {
|
|
||||||
cmd := L.CheckString(1)
|
|
||||||
exitCode, err := handleSh(cmd)
|
|
||||||
var luaErr lua.LValue = lua.LNil
|
|
||||||
if err != nil {
|
|
||||||
luaErr = lua.LString(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
L.Push(lua.LNumber(exitCode))
|
|
||||||
L.Push(luaErr)
|
|
||||||
|
|
||||||
return 2
|
|
||||||
}
|
|
||||||
|
|
||||||
func luaRunner(L *lua.LState) int {
|
|
||||||
cmd := L.CheckString(1)
|
|
||||||
exitCode, err := handleLua(cmd)
|
|
||||||
var luaErr lua.LValue = lua.LNil
|
|
||||||
if err != nil {
|
|
||||||
luaErr = lua.LString(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
L.Push(lua.LNumber(exitCode))
|
|
||||||
L.Push(luaErr)
|
|
||||||
|
|
||||||
return 2
|
|
||||||
}
|
|
Loading…
Reference in New Issue