Compare commits

..

No commits in common. "db437905e07ea268e879000dddf97179e7b1f9e1" and "b210378380e9e56f3d012647dc667e3f8207dd8e" have entirely different histories.

11 changed files with 54 additions and 156 deletions

View File

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

106
exec.go
View File

@ -25,63 +25,8 @@ import (
) )
var errNotExec = errors.New("not executable") var errNotExec = errors.New("not executable")
var errNotFound = errors.New("not found")
var runnerMode rt.Value = rt.StringValue("hybrid") 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) { func runInput(input string, priv bool) {
running = true running = true
cmdString := aliases.Resolve(input) cmdString := aliases.Resolve(input)
@ -98,6 +43,10 @@ func runInput(input string, priv bool) {
return return
} }
input, exitCode, err = handleSh(input) input, exitCode, err = handleSh(input)
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
cmdFinish(exitCode, input, priv)
case "hybridRev": case "hybridRev":
_, _, err = handleSh(input) _, _, err = handleSh(input)
if err == nil { if err == nil {
@ -105,15 +54,27 @@ func runInput(input string, priv bool) {
return return
} }
input, exitCode, err = handleLua(cmdString) input, exitCode, err = handleLua(cmdString)
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
cmdFinish(exitCode, input, priv)
case "lua": case "lua":
input, exitCode, err = handleLua(cmdString) input, exitCode, err = handleLua(cmdString)
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
cmdFinish(exitCode, input, priv)
case "sh": case "sh":
input, exitCode, err = handleSh(input) input, exitCode, err = handleSh(input)
if err != nil {
fmt.Fprintln(os.Stderr, err)
}
cmdFinish(exitCode, input, priv)
} }
} else { } else {
// can only be a string or function so // can only be a string or function so
term := rt.NewTerminationWith(l.MainThread().CurrentCont(), 3, false) 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 { if err != nil {
fmt.Fprintln(os.Stderr, err) fmt.Fprintln(os.Stderr, err)
cmdFinish(124, input, priv) cmdFinish(124, input, priv)
@ -124,6 +85,7 @@ func runInput(input string, priv bool) {
luaexitcode := term.Get(1) luaexitcode := term.Get(1)
runErr := term.Get(2) runErr := term.Get(2)
var exitCode uint8
if code, ok := luaexitcode.TryInt(); ok { if code, ok := luaexitcode.TryInt(); ok {
exitCode = uint8(code) exitCode = uint8(code)
} }
@ -132,20 +94,12 @@ func runInput(input string, priv bool) {
input = inp input = inp
} }
if errStr, ok := runErr.TryString(); ok { if runErr != rt.NilValue {
err = fmt.Errorf("%s", errStr) fmt.Fprintln(os.Stderr, runErr)
}
}
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) cmdFinish(exitCode, input, priv)
} }
}
func handleLua(cmdString string) (string, uint8, error) { func handleLua(cmdString string) (string, uint8, error) {
// First try to load input, essentially compiling to bytecode // First try to load input, essentially compiling to bytecode
@ -301,20 +255,12 @@ func execHandle(bg bool) interp.ExecHandlerFunc {
err := lookpath(args[0]) err := lookpath(args[0])
if err == errNotExec { if err == errNotExec {
return execError{ hooks.Em.Emit("command.no-perm", args[0])
typ: "not-executable", hooks.Em.Emit("command.not-executable", args[0])
cmd: args[0], return interp.NewExitStatus(126)
code: 126,
colon: true,
err: errNotExec,
}
} else if err != nil { } else if err != nil {
return execError{ hooks.Em.Emit("command.not-found", args[0])
typ: "not-found", return interp.NewExitStatus(127)
cmd: args[0],
code: 127,
err: errNotFound,
}
} }
killTimeout := 2 * time.Second 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 util.Document(mod, `The fs module provides easy and simple access to
filesystem functions and other things, and acts an filesystem functions and other things, and acts an
addition to the Lua standard library's I/O and filesystem functions.`) addition to the Lua standard library's I/O and fs functions.`)
return rt.TableValue(mod), nil return rt.TableValue(mod), nil
} }
@ -46,9 +46,8 @@ func fcd(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
path = util.ExpandHome(strings.TrimSpace(path))
err = os.Chdir(path) err = os.Chdir(strings.TrimSpace(path))
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -64,7 +63,7 @@ func fmkdir(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err := c.CheckNArgs(2); err != nil { if err := c.CheckNArgs(2); err != nil {
return nil, err return nil, err
} }
path, err := c.StringArg(0) dirname, err := c.StringArg(0)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -72,7 +71,7 @@ func fmkdir(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
path = util.ExpandHome(strings.TrimSpace(path)) path := strings.TrimSpace(dirname)
if recursive { if recursive {
err = os.MkdirAll(path, 0744) err = os.MkdirAll(path, 0744)
@ -97,7 +96,6 @@ func fstat(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
path = util.ExpandHome(path)
pathinfo, err := os.Stat(path) pathinfo, err := os.Stat(path)
if err != nil { if err != nil {
@ -124,7 +122,6 @@ func freaddir(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
dir = util.ExpandHome(dir)
names := rt.NewTable() names := rt.NewTable()
dirEntries, err := os.ReadDir(dir) dirEntries, err := os.ReadDir(dir)
@ -146,7 +143,6 @@ func fabs(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
path = util.ExpandHome(path)
abspath, err := filepath.Abs(path) abspath, err := filepath.Abs(path)
if err != nil { if err != nil {

4
lua.go
View File

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

View File

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

View File

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

11
nature/hooks.lua 100644
View File

@ -0,0 +1,11 @@
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' package.path = package.path .. ';' .. hilbish.dataDir .. '/?/init.lua'
.. ';' .. hilbish.dataDir .. '/?/?.lua' .. ';' .. hilbish.dataDir .. '/?/?.lua'
require 'nature.hooks'
require 'nature.commands' require 'nature.commands'
require 'nature.completions' require 'nature.completions'
require 'nature.opts'
local shlvl = tonumber(os.getenv 'SHLVL') local shlvl = tonumber(os.getenv 'SHLVL')
if shlvl ~= nil then if shlvl ~= nil then

View File

@ -1,23 +0,0 @@
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

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