Compare commits

...

11 Commits

Author SHA1 Message Date
sammyette df70082a81
feat: add doc command (closes #76)
the `doc` command is a way to see hilbish documentation from
in the shell. for usage, just run the command
2021-10-16 15:42:55 -04:00
sammyette 4dd6db54fe
fix: stop using setField wrapper 2021-10-16 15:40:16 -04:00
sammyette afd999a7b0
docs: add docs for functions 2021-10-16 15:38:49 -04:00
sammyette 54635072f6
fix(docgen): use better perm mask for output files and folder 2021-10-16 15:38:17 -04:00
sammyette bd3e9fdca6
docs: make linebreaks to descriptions for better alignment 2021-10-16 15:36:30 -04:00
sammyette 784e611272
chore: remove unused setField func 2021-10-16 15:33:57 -04:00
sammyette 77b3dac1b1
build: add docs folder to makefile 2021-10-16 15:33:22 -04:00
sammyette 3b97b22f10
feat: add hilbish.dataDir var 2021-10-16 13:51:09 -04:00
sammyette 20acfad2c2
fix(fs)!: handle mkdir error, change error return for cd
breaking change: cd now returns a message instead of a code to indicate the error.
any error in mkdir is now handled
2021-10-16 13:49:01 -04:00
sammyette 539a39f83a
feat: add fs.readdir function
it takes 1 argument: the directory to read.
2021-10-16 13:47:39 -04:00
sammyette 452335d84a
fix: change luaErr to return string instead of code 2021-10-16 13:47:09 -04:00
12 changed files with 151 additions and 39 deletions

View File

@ -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"

View File

@ -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")
} }

4
docs/bait.txt 100644
View File

@ -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`

View File

@ -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

8
docs/fs.txt 100644
View File

@ -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`

21
docs/global.txt 100644
View File

@ -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

6
docs/hilbish.txt 100644
View File

@ -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

View File

@ -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

View File

@ -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
}

View File

@ -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
View File

@ -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.

View File

@ -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 = { }