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)
if len(fileCompletions) != 0 {
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 {
continue
}
@ -71,7 +71,7 @@ func matchPath(query string) ([]string, string) {
var entries []string
var baseName string
path, _ := filepath.Abs(util.ExpandHome(filepath.Dir(query)))
path, _ := filepath.Abs(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,63 +25,8 @@ 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)
@ -98,6 +43,10 @@ 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 {
@ -105,15 +54,27 @@ 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)
@ -124,6 +85,7 @@ 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)
}
@ -132,20 +94,12 @@ func runInput(input string, priv bool) {
input = inp
}
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)
if runErr != rt.NilValue {
fmt.Fprintln(os.Stderr, runErr)
}
cmdFinish(exitCode, input, priv)
}
}
func handleLua(cmdString string) (string, uint8, error) {
// First try to load input, essentially compiling to bytecode
@ -301,20 +255,12 @@ func execHandle(bg bool) interp.ExecHandlerFunc {
err := lookpath(args[0])
if err == errNotExec {
return execError{
typ: "not-executable",
cmd: args[0],
code: 126,
colon: true,
err: errNotExec,
}
hooks.Em.Emit("command.no-perm", args[0])
hooks.Em.Emit("command.not-executable", args[0])
return interp.NewExitStatus(126)
} else if err != nil {
return execError{
typ: "not-found",
cmd: args[0],
code: 127,
err: errNotFound,
}
hooks.Em.Emit("command.not-found", args[0])
return interp.NewExitStatus(127)
}
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 filesystem functions.`)
addition to the Lua standard library's I/O and fs functions.`)
return rt.TableValue(mod), nil
}
@ -46,9 +46,8 @@ 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(path)
err = os.Chdir(strings.TrimSpace(path))
if err != nil {
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 {
return nil, err
}
path, err := c.StringArg(0)
dirname, err := c.StringArg(0)
if err != nil {
return nil, err
}
@ -72,7 +71,7 @@ func fmkdir(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err != nil {
return nil, err
}
path = util.ExpandHome(strings.TrimSpace(path))
path := strings.TrimSpace(dirname)
if recursive {
err = os.MkdirAll(path, 0744)
@ -97,7 +96,6 @@ 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 {
@ -124,7 +122,6 @@ 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)
@ -146,7 +143,6 @@ 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 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")
if err != nil {
err = util.DoFile(l, preloadPath)
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")
} else {
// else do ~ substitution
defaultConfDir = filepath.Join(util.ExpandHome(defaultConfDir), "hilbish")
defaultConfDir = filepath.Join(expandHome(defaultConfDir), "hilbish")
}
defaultConfPath = filepath.Join(defaultConfDir, "init.lua")
if defaultHistDir == "" {
defaultHistDir = filepath.Join(userDataDir, "hilbish")
} else {
defaultHistDir = filepath.Join(util.ExpandHome(defaultHistDir), "hilbish")
defaultHistDir = filepath.Join(expandHome(defaultHistDir), "hilbish")
}
defaultHistPath = filepath.Join(defaultHistDir, ".hilbish-history")
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)
}
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.push(hilbish.home)
dirs.addRecent(hilbish.home)
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'
.. ';' .. 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

@ -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 (
"bufio"
"io"
"strings"
"os"
"os/user"
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)
}
}
func ExpandHome(path string) string {
curuser, _ := user.Current()
homedir := curuser.HomeDir
return strings.Replace(path, "~", homedir, 1)
}