Compare commits

..

6 Commits

Author SHA1 Message Date
TorchedSammy db437905e0
fix: implicitly expand tilde on args to all fs functions 2022-05-01 00:49:59 -04:00
TorchedSammy c890b86e08
feat: add hilbish.opts and autocd opt
this adds `hilbish.opts`, a table to set
simple options akin to shopt or setopt on
other shells. this commit specifically also
includes the autocd opt, which functions the
way you expect it to

to set opts, simply do `hilbish.opts.name = val`,
where `name` is the opt you want to set and `val`
being the opt setting.

ie: `hilbish.opts.autocd = true` to turn on autocd
2022-04-30 21:22:37 -04:00
TorchedSammy a8406657f9
fix: remove nature hook handles
since it was only for command exec errors,
and theyre handled runner side now, we dont
have to handle it via hooks anymore
2022-04-30 21:05:21 -04:00
TorchedSammy 4178b78341
fix: return other errors from sh runner
makes it so that the sh runner function will return
command not found and not executable errors,
which makes them able to be handled via lua properly
2022-04-30 21:02:36 -04:00
TorchedSammy c4eb3ad368
chore: change lua init errors to make more sense 2022-04-30 20:31:37 -04:00
TorchedSammy 0642ddda36
fix: push home dir to recent dirs with correct function 2022-04-30 20:28:47 -04:00
11 changed files with 156 additions and 54 deletions

View File

@ -24,7 +24,7 @@ func binaryComplete(query, ctx string, fields []string) ([]string, string) {
fileCompletions, filePref := matchPath(query)
if len(fileCompletions) != 0 {
for _, f := range fileCompletions {
fullPath, _ := filepath.Abs(expandHome(query + strings.TrimPrefix(f, filePref)))
fullPath, _ := filepath.Abs(util.ExpandHome(query + strings.TrimPrefix(f, filePref)))
if err := findExecutable(fullPath, false, true); err != nil {
continue
}
@ -71,7 +71,7 @@ func matchPath(query string) ([]string, string) {
var entries []string
var baseName string
path, _ := filepath.Abs(expandHome(filepath.Dir(query)))
path, _ := filepath.Abs(util.ExpandHome(filepath.Dir(query)))
if string(query) == "" {
// filepath base below would give us "."
// which would cause a match of only dotfiles

106
exec.go
View File

@ -25,8 +25,63 @@ import (
)
var errNotExec = errors.New("not executable")
var errNotFound = errors.New("not found")
var runnerMode rt.Value = rt.StringValue("hybrid")
type execError struct{
typ string
cmd string
code int
colon bool
err error
}
func (e execError) Error() string {
return fmt.Sprintf("%s: %s", e.cmd, e.typ)
}
func (e execError) sprint() error {
sep := " "
if e.colon {
sep = ": "
}
return fmt.Errorf("hilbish: %s%s%s", e.cmd, sep, e.err.Error())
}
func isExecError(err error) (execError, bool) {
if exErr, ok := err.(execError); ok {
return exErr, true
}
fields := strings.Split(err.Error(), ": ")
knownTypes := []string{
"not-found",
"not-executable",
}
if len(fields) > 1 && contains(knownTypes, fields[1]) {
var colon bool
var e error
switch fields[1] {
case "not-found":
e = errNotFound
case "not-executable":
colon = true
e = errNotExec
}
return execError{
cmd: fields[0],
typ: fields[1],
colon: colon,
err: e,
}, true
}
return execError{}, false
}
func runInput(input string, priv bool) {
running = true
cmdString := aliases.Resolve(input)
@ -43,10 +98,6 @@ func runInput(input string, priv bool) {
return
}
input, exitCode, err = handleSh(input)
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
cmdFinish(exitCode, input, priv)
case "hybridRev":
_, _, err = handleSh(input)
if err == nil {
@ -54,27 +105,15 @@ func runInput(input string, priv bool) {
return
}
input, exitCode, err = handleLua(cmdString)
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
cmdFinish(exitCode, input, priv)
case "lua":
input, exitCode, err = handleLua(cmdString)
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
cmdFinish(exitCode, input, priv)
case "sh":
input, exitCode, err = handleSh(input)
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
cmdFinish(exitCode, input, priv)
}
} else {
// can only be a string or function so
term := rt.NewTerminationWith(l.MainThread().CurrentCont(), 3, false)
err := rt.Call(l.MainThread(), runnerMode, []rt.Value{rt.StringValue(cmdString)}, term)
err = rt.Call(l.MainThread(), runnerMode, []rt.Value{rt.StringValue(cmdString)}, term)
if err != nil {
fmt.Fprintln(os.Stderr, err)
cmdFinish(124, input, priv)
@ -85,7 +124,6 @@ func runInput(input string, priv bool) {
luaexitcode := term.Get(1)
runErr := term.Get(2)
var exitCode uint8
if code, ok := luaexitcode.TryInt(); ok {
exitCode = uint8(code)
}
@ -94,11 +132,19 @@ func runInput(input string, priv bool) {
input = inp
}
if runErr != rt.NilValue {
fmt.Fprintln(os.Stderr, runErr)
if errStr, ok := runErr.TryString(); ok {
err = fmt.Errorf("%s", errStr)
}
}
if err != nil {
if exErr, ok := isExecError(err); ok {
hooks.Em.Emit("command." + exErr.typ, exErr.cmd)
err = exErr.sprint()
}
fmt.Fprintln(os.Stderr, err)
}
cmdFinish(exitCode, input, priv)
}
}
func handleLua(cmdString string) (string, uint8, error) {
@ -255,12 +301,20 @@ func execHandle(bg bool) interp.ExecHandlerFunc {
err := lookpath(args[0])
if err == errNotExec {
hooks.Em.Emit("command.no-perm", args[0])
hooks.Em.Emit("command.not-executable", args[0])
return interp.NewExitStatus(126)
return execError{
typ: "not-executable",
cmd: args[0],
code: 126,
colon: true,
err: errNotExec,
}
} else if err != nil {
hooks.Em.Emit("command.not-found", args[0])
return interp.NewExitStatus(127)
return execError{
typ: "not-found",
cmd: args[0],
code: 127,
err: errNotFound,
}
}
killTimeout := 2 * time.Second

View File

@ -30,7 +30,7 @@ func loaderFunc(rtm *rt.Runtime) (rt.Value, func()) {
util.Document(mod, `The fs module provides easy and simple access to
filesystem functions and other things, and acts an
addition to the Lua standard library's I/O and fs functions.`)
addition to the Lua standard library's I/O and filesystem functions.`)
return rt.TableValue(mod), nil
}
@ -46,8 +46,9 @@ func fcd(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err != nil {
return nil, err
}
path = util.ExpandHome(strings.TrimSpace(path))
err = os.Chdir(strings.TrimSpace(path))
err = os.Chdir(path)
if err != nil {
return nil, err
}
@ -63,7 +64,7 @@ func fmkdir(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err := c.CheckNArgs(2); err != nil {
return nil, err
}
dirname, err := c.StringArg(0)
path, err := c.StringArg(0)
if err != nil {
return nil, err
}
@ -71,7 +72,7 @@ func fmkdir(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err != nil {
return nil, err
}
path := strings.TrimSpace(dirname)
path = util.ExpandHome(strings.TrimSpace(path))
if recursive {
err = os.MkdirAll(path, 0744)
@ -96,6 +97,7 @@ func fstat(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err != nil {
return nil, err
}
path = util.ExpandHome(path)
pathinfo, err := os.Stat(path)
if err != nil {
@ -122,6 +124,7 @@ func freaddir(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err != nil {
return nil, err
}
dir = util.ExpandHome(dir)
names := rt.NewTable()
dirEntries, err := os.ReadDir(dir)
@ -143,6 +146,7 @@ func fabs(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err != nil {
return nil, err
}
path = util.ExpandHome(path)
abspath, err := filepath.Abs(path)
if err != nil {

4
lua.go
View File

@ -51,14 +51,14 @@ func luaInit() {
// Add more paths that Lua can require from
err := util.DoString(l, "package.path = package.path .. " + requirePaths)
if err != nil {
fmt.Fprintln(os.Stderr, "Could not add preload paths! Libraries will be missing. This shouldn't happen.")
fmt.Fprintln(os.Stderr, "Could not add Hilbish require paths! Libraries will be missing. This shouldn't happen.")
}
err = util.DoFile(l, "nature/init.lua")
if err != nil {
err = util.DoFile(l, preloadPath)
if err != nil {
fmt.Fprintln(os.Stderr, "Missing preload file, builtins may be missing.")
fmt.Fprintln(os.Stderr, "Missing nature module, some functionality and builtins will be missing.")
}
}
}

View File

@ -56,13 +56,13 @@ func main() {
defaultConfDir = filepath.Join(confDir, "hilbish")
} else {
// else do ~ substitution
defaultConfDir = filepath.Join(expandHome(defaultConfDir), "hilbish")
defaultConfDir = filepath.Join(util.ExpandHome(defaultConfDir), "hilbish")
}
defaultConfPath = filepath.Join(defaultConfDir, "init.lua")
if defaultHistDir == "" {
defaultHistDir = filepath.Join(userDataDir, "hilbish")
} else {
defaultHistDir = filepath.Join(expandHome(defaultHistDir), "hilbish")
defaultHistDir = filepath.Join(util.ExpandHome(defaultHistDir), "hilbish")
}
defaultHistPath = filepath.Join(defaultHistDir, ".hilbish-history")
helpflag := getopt.BoolLong("help", 'h', "Prints Hilbish flags")
@ -273,11 +273,6 @@ func handleHistory(cmd string) {
// TODO: load history again (history shared between sessions like this ye)
}
func expandHome(path string) string {
homedir := curuser.HomeDir
return strings.Replace(path, "~", homedir, 1)
}
func removeDupes(slice []string) []string {
all := make(map[string]bool)
newSlice := []string{}

View File

@ -31,5 +31,5 @@ commander.register('cd', function (args)
fs.cd(hilbish.home)
bait.throw('cd', hilbish.home)
dirs.addRecent(hilbish.home)
dirs.push(hilbish.home)
end)

View File

@ -1,11 +0,0 @@
local bait = require 'bait'
-- Hook handles
bait.catch('command.not-found', function(cmd)
print(string.format('hilbish: %s not found', cmd))
end)
bait.catch('command.not-executable', function(cmd)
print(string.format('hilbish: %s: not executable', cmd))
end)

View File

@ -4,9 +4,9 @@ local _ = require 'succulent' -- Function additions
package.path = package.path .. ';' .. hilbish.dataDir .. '/?/init.lua'
.. ';' .. hilbish.dataDir .. '/?/?.lua'
require 'nature.hooks'
require 'nature.commands'
require 'nature.completions'
require 'nature.opts'
local shlvl = tonumber(os.getenv 'SHLVL')
if shlvl ~= nil then

View File

@ -0,0 +1,23 @@
local fs = require 'fs'
function cdHandle(inp)
local input, exit, err = hilbish.runner.lua(inp)
if not err then
return input, exit, err
end
input, exit, err = hilbish.runner.sh(inp)
if exit ~= 0 and hilbish.opts.autocd then
local ok, stat = pcall(fs.stat, input)
if ok and stat.isDir then
-- discard here to not append the cd, which will be in history
_, exit, err = hilbish.runner.sh('cd ' .. input)
end
end
return input, exit, err
end
hilbish.runner.setMode(cdHandle)

View File

@ -0,0 +1,28 @@
local opts = {}
hilbish.opts = {}
setmetatable(hilbish.opts, {
__newindex = function(_, k, v)
if opts[k] == nil then
error(string.format('opt %s does not exist', k))
end
opts[k] = v
end,
__index = function(_, k)
return opts[k]
end
})
local function setupOpt(name, default)
opts[name] = default
require('nature.opts.' .. name)
end
local defaultOpts = {
autocd = false
}
for optsName, default in pairs(defaultOpts) do
setupOpt(optsName, default)
end

View File

@ -3,7 +3,9 @@ package util
import (
"bufio"
"io"
"strings"
"os"
"os/user"
rt "github.com/arnodel/golua/runtime"
)
@ -150,3 +152,10 @@ func ForEach(tbl *rt.Table, cb func(key rt.Value, val rt.Value)) {
cb(key, val)
}
}
func ExpandHome(path string) string {
curuser, _ := user.Current()
homedir := curuser.HomeDir
return strings.Replace(path, "~", homedir, 1)
}