mirror of https://github.com/Hilbis/Hilbish
Compare commits
11 Commits
3cafbe8c4f
...
df70082a81
Author | SHA1 | Date |
---|---|---|
sammyette | df70082a81 | |
sammyette | 4dd6db54fe | |
sammyette | afd999a7b0 | |
sammyette | 54635072f6 | |
sammyette | bd3e9fdca6 | |
sammyette | 784e611272 | |
sammyette | 77b3dac1b1 | |
sammyette | 3b97b22f10 | |
sammyette | 20acfad2c2 | |
sammyette | 539a39f83a | |
sammyette | 452335d84a |
2
Makefile
2
Makefile
|
@ -15,7 +15,7 @@ hilbiline:
|
||||||
install:
|
install:
|
||||||
@install -v -d "$(DESTDIR)$(BINDIR)/" && install -m 0755 -v hilbish "$(DESTDIR)$(BINDIR)/hilbish"
|
@install -v -d "$(DESTDIR)$(BINDIR)/" && install -m 0755 -v hilbish "$(DESTDIR)$(BINDIR)/hilbish"
|
||||||
@mkdir -p "$(DESTDIR)$(LIBDIR)"
|
@mkdir -p "$(DESTDIR)$(LIBDIR)"
|
||||||
@cp libs preload.lua .hilbishrc.lua "$(DESTDIR)$(LIBDIR)" -r
|
@cp libs docs preload.lua .hilbishrc.lua "$(DESTDIR)$(LIBDIR)" -r
|
||||||
@grep "$(DESTDIR)$(BINDIR)/hilbish" -qxF /etc/shells || echo "$(DESTDIR)$(BINDIR)/hilbish" >> /etc/shells
|
@grep "$(DESTDIR)$(BINDIR)/hilbish" -qxF /etc/shells || echo "$(DESTDIR)$(BINDIR)/hilbish" >> /etc/shells
|
||||||
@echo "Hilbish Installed"
|
@echo "Hilbish Installed"
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ func main() {
|
||||||
|
|
||||||
for mod, v := range docs {
|
for mod, v := range docs {
|
||||||
if mod == "main" { mod = "global" }
|
if mod == "main" { mod = "global" }
|
||||||
os.Mkdir("docs", 0744)
|
os.Mkdir("docs", 0777)
|
||||||
f, _ := os.Create("docs/" + mod + ".txt")
|
f, _ := os.Create("docs/" + mod + ".txt")
|
||||||
f.WriteString(strings.Join(v, "\n") + "\n")
|
f.WriteString(strings.Join(v, "\n") + "\n")
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
catch(name, cb) > Catches a hook with `name`. Runs the `cb` when it is thrown
|
||||||
|
|
||||||
|
throw(name, ...args) > Throws a hook with `name` with the provided `args`
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
deregister(name) > Deregisters any command registered with `name`
|
||||||
|
|
||||||
|
register(name, cb) > Register a command with `name` that runs `cb` when ran
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
cd(dir) > Changes directory to `dir`
|
||||||
|
|
||||||
|
mkdir(name, recursive) > Makes a directory called `name`. If `recursive` is true, it will create its parent directories.
|
||||||
|
|
||||||
|
readdir(dir) > Returns a table of files in `dir`
|
||||||
|
|
||||||
|
stat(path) > Returns info about `path`
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
alias(cmd, orig) > Sets an alias of `orig` to `cmd`
|
||||||
|
|
||||||
|
appendPath(dir) > Appends `dir` to $PATH
|
||||||
|
|
||||||
|
exec(cmd) > Replaces running hilbish with `cmd`
|
||||||
|
|
||||||
|
goro(fn) > Puts `fn` in a goroutine
|
||||||
|
|
||||||
|
interval(cb, time) > Runs the `cb` function every `time` milliseconds
|
||||||
|
|
||||||
|
multiprompt(str) > Changes the continued line prompt to `str`
|
||||||
|
|
||||||
|
prompt(str) > Changes the shell prompt to `str`
|
||||||
|
There are a few verbs that can be used in the prompt text.
|
||||||
|
These will be formatted and replaced with the appropriate values.
|
||||||
|
`%d` - Current working directory
|
||||||
|
`%u` - Name of current user
|
||||||
|
`%h` - Hostname of device
|
||||||
|
|
||||||
|
timeout(cb, time) > Runs the `cb` function after `time` in milliseconds
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
cwd() > Returns the current directory of the shell
|
||||||
|
|
||||||
|
flag(f) > Checks if the `f` flag has been passed to Hilbish.
|
||||||
|
|
||||||
|
run(cmd) > Runs `cmd` in Hilbish's sh interpreter
|
||||||
|
|
|
@ -23,8 +23,12 @@ func (b *Bait) Loader(L *lua.LState) int {
|
||||||
L.SetField(mod, "throw", luar.New(L, b.bthrow))
|
L.SetField(mod, "throw", luar.New(L, b.bthrow))
|
||||||
L.SetField(mod, "catch", luar.New(L, b.bcatch))
|
L.SetField(mod, "catch", luar.New(L, b.bcatch))
|
||||||
|
|
||||||
util.Document(L, mod, `Bait is the event emitter for Hilbish. Why name it bait? Because it throws hooks that you can catch. (emits events that you can listen to) and because why not, fun naming is fun.
|
util.Document(L, mod, `Bait is the event emitter for Hilbish. Why name it bait?
|
||||||
This is what you will use if you want to listen in on hooks to know when certain things have happened, like when you've changed directory, a command has failed, etc.`)
|
Because it throws hooks that you can catch
|
||||||
|
(emits events that you can listen to) and because why not,
|
||||||
|
fun naming is fun. This is what you will use if you want to
|
||||||
|
listen in on hooks to know when certain things have happened,
|
||||||
|
like when you've changed directory, a command has failed, etc.`)
|
||||||
L.Push(mod)
|
L.Push(mod)
|
||||||
|
|
||||||
return 1
|
return 1
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
package fs
|
package fs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
@ -15,22 +14,23 @@ import (
|
||||||
func Loader(L *lua.LState) int {
|
func Loader(L *lua.LState) int {
|
||||||
mod := L.SetFuncs(L.NewTable(), exports)
|
mod := L.SetFuncs(L.NewTable(), exports)
|
||||||
|
|
||||||
util.Document(L, mod, `The fs module provides easy and simple access to filesystem functions and other
|
util.Document(L, mod, `The fs module provides easy and simple access to
|
||||||
things, and acts an addition to the Lua standard library's I/O and fs functions.`)
|
filesystem functions and other things, and acts an
|
||||||
|
addition to the Lua standard library's I/O and fs functions.`)
|
||||||
|
|
||||||
L.Push(mod)
|
L.Push(mod)
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
func luaErr(L *lua.LState, code int) {
|
func luaErr(L *lua.LState, msg string) {
|
||||||
// TODO: Error with a table, with path and error code
|
L.Error(lua.LString(msg), 2)
|
||||||
L.Error(lua.LNumber(code), 2)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var exports = map[string]lua.LGFunction{
|
var exports = map[string]lua.LGFunction{
|
||||||
"cd": fcd,
|
"cd": fcd,
|
||||||
"mkdir": fmkdir,
|
"mkdir": fmkdir,
|
||||||
"stat": fstat,
|
"stat": fstat,
|
||||||
|
"readdir": freaddir,
|
||||||
}
|
}
|
||||||
|
|
||||||
// cd(dir)
|
// cd(dir)
|
||||||
|
@ -40,16 +40,8 @@ func fcd(L *lua.LState) int {
|
||||||
|
|
||||||
err := os.Chdir(strings.TrimSpace(path))
|
err := os.Chdir(strings.TrimSpace(path))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
switch e := err.(*os.PathError).Err.Error(); e {
|
e := err.(*os.PathError).Err.Error()
|
||||||
case "no such file or directory":
|
luaErr(L, e)
|
||||||
luaErr(L, 1)
|
|
||||||
case "not a directory":
|
|
||||||
luaErr(L, 2)
|
|
||||||
default:
|
|
||||||
fmt.Printf("Found unhandled error case: %s\n", e)
|
|
||||||
fmt.Printf("Report this at https://github.com/Rosettea/Hilbish/issues with the title being: \"fs: unhandled error case %s\", and show what caused it.\n", e)
|
|
||||||
luaErr(L, 213)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
@ -61,12 +53,15 @@ func fmkdir(L *lua.LState) int {
|
||||||
dirname := L.CheckString(1)
|
dirname := L.CheckString(1)
|
||||||
recursive := L.ToBool(2)
|
recursive := L.ToBool(2)
|
||||||
path := strings.TrimSpace(dirname)
|
path := strings.TrimSpace(dirname)
|
||||||
|
var err error
|
||||||
|
|
||||||
// TODO: handle error here
|
|
||||||
if recursive {
|
if recursive {
|
||||||
os.MkdirAll(path, 0744)
|
err = os.MkdirAll(path, 0744)
|
||||||
} else {
|
} else {
|
||||||
os.Mkdir(path, 0744)
|
err = os.Mkdir(path, 0744)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
luaErr(L, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
|
@ -78,8 +73,32 @@ func fstat(L *lua.LState) int {
|
||||||
path := L.CheckString(1)
|
path := L.CheckString(1)
|
||||||
|
|
||||||
// TODO: handle error here
|
// TODO: handle error here
|
||||||
pathinfo, _ := os.Stat(path)
|
pathinfo, err := os.Stat(path)
|
||||||
|
if err != nil {
|
||||||
|
luaErr(L, err.Error())
|
||||||
|
return 0
|
||||||
|
}
|
||||||
L.Push(luar.New(L, pathinfo))
|
L.Push(luar.New(L, pathinfo))
|
||||||
|
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// readdir(dir)
|
||||||
|
// Returns a table of files in `dir`
|
||||||
|
func freaddir(L *lua.LState) int {
|
||||||
|
dir := L.CheckString(1)
|
||||||
|
names := []string{}
|
||||||
|
|
||||||
|
dirEntries, err := os.ReadDir(dir)
|
||||||
|
if err != nil {
|
||||||
|
luaErr(L, err.Error())
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
for _, entry := range dirEntries {
|
||||||
|
names = append(names, entry.Name())
|
||||||
|
}
|
||||||
|
|
||||||
|
L.Push(luar.New(L, names))
|
||||||
|
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
17
hilbish.go
17
hilbish.go
|
@ -8,6 +8,8 @@ import (
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"hilbish/util"
|
||||||
|
|
||||||
"github.com/pborman/getopt"
|
"github.com/pborman/getopt"
|
||||||
"github.com/yuin/gopher-lua"
|
"github.com/yuin/gopher-lua"
|
||||||
"mvdan.cc/sh/v3/interp"
|
"mvdan.cc/sh/v3/interp"
|
||||||
|
@ -29,16 +31,17 @@ func HilbishLoader(L *lua.LState) int {
|
||||||
username = strings.Split(username, "\\")[1] // for some reason Username includes the hostname on windows
|
username = strings.Split(username, "\\")[1] // for some reason Username includes the hostname on windows
|
||||||
}
|
}
|
||||||
|
|
||||||
setField(L, mod, "ver", lua.LString(version), "The version of Hilbish")
|
L.SetField(mod, "ver", lua.LString(version))
|
||||||
setField(L, mod, "user", lua.LString(username), "Current user's username")
|
L.SetField(mod, "user", lua.LString(username))
|
||||||
setField(L, mod, "host", lua.LString(host), "Hostname of the system")
|
L.SetField(mod, "host", lua.LString(host))
|
||||||
setField(L, mod, "home", lua.LString(homedir), "Path of home directory")
|
L.SetField(mod, "home", lua.LString(homedir))
|
||||||
|
|
||||||
xdg := L.NewTable()
|
xdg := L.NewTable()
|
||||||
setField(L, xdg, "config", lua.LString(confDir), "XDG config directory")
|
L.SetField(xdg, "config", lua.LString(confDir))
|
||||||
setField(L, xdg, "data", lua.LString(getenv("XDG_DATA_HOME", homedir + "/.local/share/")), "XDG data directory")
|
L.SetField(xdg, "data", lua.LString(getenv("XDG_DATA_HOME", homedir + "/.local/share/")))
|
||||||
setField(L, mod, "xdg", xdg, "XDG values for Linux")
|
L.SetField(mod, "xdg", xdg)
|
||||||
|
|
||||||
|
util.Document(L, mod, "A miscellaneous sort of \"core\" API for things that relate to the shell itself and others.")
|
||||||
L.Push(mod)
|
L.Push(mod)
|
||||||
|
|
||||||
return 1
|
return 1
|
||||||
|
|
8
lua.go
8
lua.go
|
@ -8,7 +8,6 @@ import (
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"hilbish/util"
|
|
||||||
"hilbish/golibs/bait"
|
"hilbish/golibs/bait"
|
||||||
"hilbish/golibs/commander"
|
"hilbish/golibs/commander"
|
||||||
"hilbish/golibs/fs"
|
"hilbish/golibs/fs"
|
||||||
|
@ -96,13 +95,6 @@ func RunLogin() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func setField(L *lua.LState, module lua.LValue, name string, val lua.LValue, doc string) {
|
|
||||||
if val.Type() == lua.LTTable {
|
|
||||||
util.Document(L, module, doc)
|
|
||||||
}
|
|
||||||
L.SetField(module, name, val)
|
|
||||||
}
|
|
||||||
|
|
||||||
/* prompt(str)
|
/* prompt(str)
|
||||||
Changes the shell prompt to `str`
|
Changes the shell prompt to `str`
|
||||||
There are a few verbs that can be used in the prompt text.
|
There are a few verbs that can be used in the prompt text.
|
||||||
|
|
51
preload.lua
51
preload.lua
|
@ -44,6 +44,57 @@ commander.register('exit', function()
|
||||||
os.exit(0)
|
os.exit(0)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
commander.register('doc', function(args)
|
||||||
|
local moddocPath = hilbish.dataDir .. '/docs/'
|
||||||
|
local globalDesc = [[
|
||||||
|
These are the global Hilbish functions that are always available and not part of a module.]]
|
||||||
|
if #args > 0 then
|
||||||
|
local mod = ''
|
||||||
|
for i = 1, #args do
|
||||||
|
mod = mod .. tostring(args[i]) .. ' '
|
||||||
|
end
|
||||||
|
mod = mod:gsub('^%s*(.-)%s*$', '%1')
|
||||||
|
|
||||||
|
local f = io.open(moddocPath .. mod .. '.txt', 'rb')
|
||||||
|
if not f then
|
||||||
|
print('Could not find docs for module named ' .. mod .. '.')
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
|
||||||
|
local desc = (mod == 'global' and globalDesc or getmetatable(require(mod)).__doc)
|
||||||
|
local funcdocs = f:read '*a'
|
||||||
|
local backtickOccurence = 0
|
||||||
|
print(desc .. '\n\n' .. lunacolors.format(funcdocs:sub(1, #funcdocs - 1):gsub('`', function()
|
||||||
|
backtickOccurence = backtickOccurence + 1
|
||||||
|
if backtickOccurence % 2 == 0 then
|
||||||
|
return '{reset}'
|
||||||
|
else
|
||||||
|
return '{invert}'
|
||||||
|
end
|
||||||
|
end)))
|
||||||
|
f:close()
|
||||||
|
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local modules = fs.readdir(moddocPath)
|
||||||
|
|
||||||
|
io.write [[
|
||||||
|
Welcome to Hilbish's doc tool! Here you can find documentation for builtin
|
||||||
|
functions and other things.
|
||||||
|
|
||||||
|
Usage: doc <module>
|
||||||
|
|
||||||
|
Available modules: ]]
|
||||||
|
|
||||||
|
local mods = ''
|
||||||
|
for i = 1, #modules do
|
||||||
|
mods = mods .. tostring(modules[i]):gsub('.txt', '') .. ', '
|
||||||
|
end
|
||||||
|
print(mods)
|
||||||
|
|
||||||
|
return
|
||||||
|
end)
|
||||||
|
|
||||||
do
|
do
|
||||||
local virt_G = { }
|
local virt_G = { }
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue