Compare commits

...

29 Commits

Author SHA1 Message Date
sammyette 3cbf80a3e5
Merge 3065cdd62d into a0513c0a05 2023-12-12 01:35:14 -07:00
sammyette 3065cdd62d
chore: update branch 2023-12-03 20:56:30 -04:00
sammyette 90ef8f7a9c
refactor: update documentation for everything 2023-12-03 20:54:00 -04:00
sammyette 7cd1170e41
chore: reorder hilbish.completion functions 2023-12-02 13:06:42 -04:00
sammyette 93c0645d12
docs: update hilbish.completion 2023-12-02 13:03:19 -04:00
sammyette 1f7f8e5104
docs: update api docs, make others show up on site 2023-12-02 10:49:50 -04:00
sammyette f40ce3c8f7
chore: update docs 2023-12-02 08:23:49 -04:00
sammyette be526c15d1
doc(fs): rewrite docs 2023-12-02 08:23:40 -04:00
sammyette 393b2009bf
fix(docgen): add double space after line of text 2023-12-02 08:22:40 -04:00
sammyette 77979dca19
website: set highlighter options to guess syntax 2023-12-02 08:22:09 -04:00
sammyette bb8d072b8c
website(docs/commander): rewrite commander docs 2023-11-30 22:19:13 -04:00
sammyette 068ef7a376
website(docs/bait): add example for throw function 2023-11-30 22:09:07 -04:00
sammyette d921d3f752
website(docs/bait): complete documentation 2023-11-30 22:07:48 -04:00
sammyette f516e1bb87
website(docs): setup custom syntax highlighting, add line numbers 2023-11-30 22:00:47 -04:00
sammyette e81384e42c
refactor(bait): reorder functions alphabetically 2023-11-30 18:32:28 -04:00
sammyette 2363e6ff2f
website(docs): add example 2023-11-30 18:30:54 -04:00
sammyette e8ea79b5ec
website(docs): remove unused header 2023-11-30 17:37:08 -04:00
sammyette 5be470521f
refactor: move misc docs for use in hilbish and website 2023-11-11 22:28:18 -04:00
sammyette 0607a90c30
fix: clear before setting statusline 2023-11-11 22:27:50 -04:00
sammyette 0f923a6f80
chore: merge from master 2023-11-11 21:57:15 -04:00
sammyette 726082ba03
docs: fix duplicate functions header 2023-09-09 13:38:54 -04:00
sammyette 95ac2e280d
docs: fix description of exitCode prop 2023-09-02 16:24:35 -04:00
sammyette 7fd2ed391b
docs: add separators for types, make object properties into tables 2023-09-02 16:11:57 -04:00
sammyette 0900284304
docs: turn properties list into a table
also fix member functions causing a spam of separators
2023-09-02 16:01:57 -04:00
sammyette eda4fda972
docs(commander): remove note about input sink being unimplemented 2023-09-02 15:32:53 -04:00
sammyette 22cf0fcb49
docs: change colors for syntax highlight and function jump highlight 2023-09-02 14:30:31 -04:00
sammyette aa7e899db4
docs: make various style changes
- add a table that lists module functions
- add highlight when jumping to a function
- separators
2023-09-02 14:18:40 -04:00
sammyette 81b7e20cbf
docs: add better introduction for bait module
also highlights codeblocks better
2023-09-02 12:57:13 -04:00
sammyette 7c1984135b
docs: add detailed parameter listing, change interface to modules
there are a few changes here
- documentation of each parameter separately has been added
to the generated text docs
- interfaces have been renamed to modules. this was honestly a pointless
and confusing distinction (interfaces are tables for modules that are
lua modules). it also makes it so that (formerly) interfaces and
modules line up with each other on the doc list

im not sure what else i did, these are old changes
2023-08-26 11:30:51 -04:00
62 changed files with 2592 additions and 924 deletions

View File

@ -111,15 +111,23 @@ func (a *aliasModule) Loader(rtm *rt.Runtime) *rt.Table {
// #interface aliases // #interface aliases
// add(alias, cmd) // add(alias, cmd)
// This is an alias (ha) for the `hilbish.alias` function. // This is an alias (ha) for the [hilbish.alias](../#alias) function.
// --- @param alias string // --- @param alias string
// --- @param cmd string // --- @param cmd string
func _hlalias() {} func _hlalias() {}
// #interface aliases // #interface aliases
// list() -> table<string, string> // list() -> table[string, string]
// Get a table of all aliases, with string keys as the alias and the value as the command. // Get a table of all aliases, with string keys as the alias and the value as the command.
// --- @returns table<string, string> // #returns table[string, string]
/*
#example
hilbish.aliases.add('hi', 'echo hi')
local aliases = hilbish.aliases.list()
-- -> {hi = 'echo hi'}
#example
*/
func (a *aliasModule) luaList(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { func (a *aliasModule) luaList(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
aliasesList := rt.NewTable() aliasesList := rt.NewTable()
for k, v := range a.All() { for k, v := range a.All() {
@ -132,7 +140,7 @@ func (a *aliasModule) luaList(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
// #interface aliases // #interface aliases
// delete(name) // delete(name)
// Removes an alias. // Removes an alias.
// --- @param name string // #param name string
func (a *aliasModule) luaDelete(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { func (a *aliasModule) luaDelete(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err := c.Check1Arg(); err != nil { if err := c.Check1Arg(); err != nil {
return nil, err return nil, err
@ -147,10 +155,10 @@ func (a *aliasModule) luaDelete(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
} }
// #interface aliases // #interface aliases
// resolve(alias) -> command (string) // resolve(alias) -> string?
// Tries to resolve an alias to its command. // Resolves an alias to its original command. Will thrown an error if the alias doesn't exist.
// --- @param alias string // #param alias string
// --- @returns string // #returns string
func (a *aliasModule) luaResolve(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { func (a *aliasModule) luaResolve(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err := c.Check1Arg(); err != nil { if err := c.Check1Arg(); err != nil {
return nil, err return nil, err

169
api.go
View File

@ -9,7 +9,7 @@
// #field interactive Is Hilbish in an interactive shell? // #field interactive Is Hilbish in an interactive shell?
// #field login Is Hilbish the login shell? // #field login Is Hilbish the login shell?
// #field vimMode Current Vim input mode of Hilbish (will be nil if not in Vim input mode) // #field vimMode Current Vim input mode of Hilbish (will be nil if not in Vim input mode)
// #field exitCode xit code of the last executed command // #field exitCode Exit code of the last executed command
package main package main
import ( import (
@ -192,12 +192,10 @@ func unsetVimMode() {
} }
// run(cmd, returnOut) -> exitCode (number), stdout (string), stderr (string) // run(cmd, returnOut) -> exitCode (number), stdout (string), stderr (string)
// Runs `cmd` in Hilbish's sh interpreter. // Runs `cmd` in Hilbish's shell script interpreter.
// If returnOut is true, the outputs of `cmd` will be returned as the 2nd and // #param cmd string
// 3rd values instead of being outputted to the terminal. // #param returnOut boolean If this is true, the function will return the standard output and error of the command instead of printing it.
// --- @param cmd string // #returns number, string, string
// --- @param returnOut boolean
// --- @returns number, string, string
func hlrun(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { func hlrun(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err := c.Check1Arg(); err != nil { if err := c.Check1Arg(); err != nil {
return nil, err return nil, err
@ -240,7 +238,7 @@ func hlrun(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
// cwd() -> string // cwd() -> string
// Returns the current directory of the shell // Returns the current directory of the shell
// --- @returns string // #returns string
func hlcwd(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { func hlcwd(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
cwd, _ := os.Getwd() cwd, _ := os.Getwd()
@ -251,9 +249,9 @@ func hlcwd(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
// read(prompt) -> input (string) // read(prompt) -> input (string)
// Read input from the user, using Hilbish's line editor/input reader. // Read input from the user, using Hilbish's line editor/input reader.
// This is a separate instance from the one Hilbish actually uses. // This is a separate instance from the one Hilbish actually uses.
// Returns `input`, will be nil if ctrl + d is pressed, or an error occurs (which shouldn't happen) // Returns `input`, will be nil if ctrl + d is pressed, or an error occurs (which shouldn't happen).
// --- @param prompt? string // #param prompt? string
// --- @returns string|nil // #returns string|nil
func hlread(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { func hlread(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
luaprompt := c.Arg(0) luaprompt := c.Arg(0)
if typ := luaprompt.Type(); typ != rt.StringType && typ != rt.NilType { if typ := luaprompt.Type(); typ != rt.StringType && typ != rt.NilType {
@ -281,14 +279,21 @@ func hlread(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
/* /*
prompt(str, typ) prompt(str, typ)
Changes the shell prompt to `str` Changes the shell prompt to the provided string.
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.
These will be formatted and replaced with the appropriate values. These will be formatted and replaced with the appropriate values.
`%d` - Current working directory `%d` - Current working directory
`%u` - Name of current user `%u` - Name of current user
`%h` - Hostname of device `%h` - Hostname of device
--- @param str string #param str string
--- @param typ? string Type of prompt, being left or right. Left by default. #param typ? string Type of prompt, being left or right. Left by default.
#example
-- the default hilbish prompt without color
hilbish.prompt '%u %d '
-- or something of old:
hilbish.prompt '%u@%h :%d $'
-- prompt: user@hostname: ~/directory $
#example
*/ */
func hlprompt(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { func hlprompt(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
err := c.Check1Arg() err := c.Check1Arg()
@ -322,8 +327,28 @@ func hlprompt(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
} }
// multiprompt(str) // multiprompt(str)
// Changes the continued line prompt to `str` // Changes the text prompt when Hilbish asks for more input.
// --- @param str string // This will show up when text is incomplete, like a missing quote
// #param str string
/*
#example
--[[
imagine this is your text input:
user ~ echo "hey
but there's a missing quote! hilbish will now prompt you so the terminal
will look like:
user ~ echo "hey
--> ...!"
so then you get
user ~ echo "hey
--> ...!"
hey ...!
]]--
hilbish.multiprompt '-->'
#example
*/
func hlmultiprompt(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { func hlmultiprompt(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err := c.Check1Arg(); err != nil { if err := c.Check1Arg(); err != nil {
return nil, err return nil, err
@ -338,9 +363,19 @@ func hlmultiprompt(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
} }
// alias(cmd, orig) // alias(cmd, orig)
// Sets an alias of `cmd` to `orig` // Sets an alias, with a name of `cmd` to another command.
// --- @param cmd string // #param cmd string Name of the alias
// --- @param orig string // #param orig string Command that will be aliased
/*
#example
-- With this, "ga file" will turn into "git add file"
hilbish.alias('ga', 'git add')
-- Numbered substitutions are supported here!
hilbish.alias('dircount', 'ls %1 | wc -l')
-- "dircount ~" would count how many files are in ~ (home directory).
#example
*/
func hlalias(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { func hlalias(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
@ -360,8 +395,20 @@ func hlalias(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
} }
// appendPath(dir) // appendPath(dir)
// Appends `dir` to $PATH // Appends the provided dir to the command path (`$PATH`)
// --- @param dir string|table // #param dir string|table Directory (or directories) to append to path
/*
#example
hilbish.appendPath '~/go/bin'
-- Will add ~/go/bin to the command path.
-- Or do multiple:
hilbush.appendPath {
'~/go/bin',
'~/.local/bin'
}
#example
*/
func hlappendPath(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { func hlappendPath(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err := c.Check1Arg(); err != nil { if err := c.Check1Arg(); err != nil {
return nil, err return nil, err
@ -395,8 +442,9 @@ func appendPath(dir string) {
} }
// exec(cmd) // exec(cmd)
// Replaces running hilbish with `cmd` // Replaces the currently running Hilbish instance with the supplied command.
// --- @param cmd string // This can be used to do an in-place restart.
// #param cmd string
func hlexec(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { func hlexec(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err := c.Check1Arg(); err != nil { if err := c.Check1Arg(); err != nil {
return nil, err return nil, err
@ -430,8 +478,10 @@ func hlexec(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
} }
// goro(fn) // goro(fn)
// Puts `fn` in a goroutine // Puts `fn` in a Goroutine.
// --- @param fn function // This can be used to run any function in another thread.
// **NOTE: THIS FUNCTION MAY CRASH HILBISH IF OUTSIDE VARIABLES ARE ACCESSED.**
// #param fn function
func hlgoro(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { func hlgoro(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err := c.Check1Arg(); err != nil { if err := c.Check1Arg(); err != nil {
return nil, err return nil, err
@ -454,10 +504,10 @@ func hlgoro(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
// timeout(cb, time) -> @Timer // timeout(cb, time) -> @Timer
// Runs the `cb` function after `time` in milliseconds. // Runs the `cb` function after `time` in milliseconds.
// This creates a timer that starts immediately. // This creates a Timer that starts immediately.
// --- @param cb function // #param cb function
// --- @param time number // #param time number
// --- @returns Timer // #returns Timer
func hltimeout(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { func hltimeout(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
@ -481,9 +531,9 @@ func hltimeout(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
// interval(cb, time) -> @Timer // interval(cb, time) -> @Timer
// Runs the `cb` function every `time` milliseconds. // Runs the `cb` function every `time` milliseconds.
// This creates a timer that starts immediately. // This creates a timer that starts immediately.
// --- @param cb function // #param cb function
// --- @param time number // #param time number
// --- @return Timer // #return Timer
func hlinterval(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { func hlinterval(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
@ -505,13 +555,13 @@ func hlinterval(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
} }
// complete(scope, cb) // complete(scope, cb)
// Registers a completion handler for `scope`. // Registers a completion handler for the specified scope.
// A `scope` is currently only expected to be `command.<cmd>`, // A `scope` is currently only expected to be `command.<cmd>`,
// replacing <cmd> with the name of the command (for example `command.git`). // replacing <cmd> with the name of the command (for example `command.git`).
// `cb` must be a function that returns a table of "completion groups." // The documentation for completions, under Features/Completions or `doc completions`
// Check `doc completions` for more information. // provides more details.
// --- @param scope string // #param scope string
// --- @param cb function // #param cb function
func hlcomplete(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { func hlcomplete(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
scope, cb, err := util.HandleStrCallback(t, c) scope, cb, err := util.HandleStrCallback(t, c)
if err != nil { if err != nil {
@ -523,8 +573,8 @@ func hlcomplete(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
} }
// prependPath(dir) // prependPath(dir)
// Prepends `dir` to $PATH // Prepends `dir` to $PATH.
// --- @param dir string // #param dir string
func hlprependPath(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { func hlprependPath(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err := c.Check1Arg(); err != nil { if err := c.Check1Arg(); err != nil {
return nil, err return nil, err
@ -547,8 +597,8 @@ func hlprependPath(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
// which(name) -> string // which(name) -> string
// Checks if `name` is a valid command. // Checks if `name` is a valid command.
// Will return the path of the binary, or a basename if it's a commander. // Will return the path of the binary, or a basename if it's a commander.
// --- @param name string // #param name string
// --- @returns string // #returns string
func hlwhich(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { func hlwhich(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err := c.Check1Arg(); err != nil { if err := c.Check1Arg(); err != nil {
return nil, err return nil, err
@ -578,8 +628,10 @@ func hlwhich(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
} }
// inputMode(mode) // inputMode(mode)
// Sets the input mode for Hilbish's line reader. Accepts either emacs or vim // Sets the input mode for Hilbish's line reader. Accepts either emacs or vim.
// --- @param mode string // `emacs` is the default. Setting it to `vim` changes behavior of input to be
// Vim-like with modes and Vim keybinds.
// #param mode string
func hlinputMode(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { func hlinputMode(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err := c.Check1Arg(); err != nil { if err := c.Check1Arg(); err != nil {
return nil, err return nil, err
@ -609,7 +661,7 @@ func hlinputMode(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
// Accepted values for mode are hybrid (the default), hybridRev (sh first then Lua), // Accepted values for mode are hybrid (the default), hybridRev (sh first then Lua),
// sh, and lua. It also accepts a function, to which if it is passed one // sh, and lua. It also accepts a function, to which if it is passed one
// will call it to execute user input instead. // will call it to execute user input instead.
// --- @param mode string|function // #param mode string|function
func hlrunnerMode(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { func hlrunnerMode(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err := c.Check1Arg(); err != nil { if err := c.Check1Arg(); err != nil {
return nil, err return nil, err
@ -635,26 +687,33 @@ func hlrunnerMode(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
// line and cursor position. It is expected to return a string which is used // line and cursor position. It is expected to return a string which is used
// as the text for the hint. This is by default a shim. To set hints, // as the text for the hint. This is by default a shim. To set hints,
// override this function with your custom handler. // override this function with your custom handler.
// --- @param line string // #param line string
// --- @param pos number // #param pos number
/*
#example
-- this will display "hi" after the cursor in a dimmed color.
function hilbish.hinter(line, pos)
return 'hi'
end
#example
*/
func hlhinter(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { func hlhinter(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
return c.Next(), nil return c.Next(), nil
} }
// highlighter(line) // highlighter(line)
// Line highlighter handler. This is mainly for syntax highlighting, but in // Line highlighter handler.
// reality could set the input of the prompt to *display* anything. The // This is mainly for syntax highlighting, but in reality could set the input
// callback is passed the current line and is expected to return a line that // of the prompt to *display* anything. The callback is passed the current line
// will be used as the input display. // and is expected to return a line that will be used as the input display.
// Note that to set a highlighter, one has to override this function. // Note that to set a highlighter, one has to override this function.
// Example: // #example
// ``` // --This code will highlight all double quoted strings in green.
// function hilbish.highlighter(line) // function hilbish.highlighter(line)
// return line:gsub('"%w+"', function(c) return lunacolors.green(c) end) // return line:gsub('"%w+"', function(c) return lunacolors.green(c) end)
// end // end
// ``` // #example
// This code will highlight all double quoted strings in green. // #param line string
// --- @param line string
func hlhighlighter(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { func hlhighlighter(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
return c.Next(), nil return c.Next(), nil
} }

View File

@ -11,6 +11,8 @@ import (
"strings" "strings"
"os" "os"
"sync" "sync"
md "github.com/atsushinee/go-markdown-generator/doc"
) )
var header = `--- var header = `---
@ -43,6 +45,12 @@ type module struct {
HasTypes bool HasTypes bool
} }
type param struct{
Name string
Type string
Doc []string
}
type docPiece struct { type docPiece struct {
Doc []string Doc []string
FuncSig string FuncSig string
@ -55,11 +63,14 @@ type docPiece struct {
IsType bool IsType bool
Fields []docPiece Fields []docPiece
Properties []docPiece Properties []docPiece
Params []param
Tags map[string][]tag
} }
type tag struct { type tag struct {
id string id string
fields []string fields []string
startIdx int
} }
var docs = make(map[string]module) var docs = make(map[string]module)
@ -80,7 +91,7 @@ func getTagsAndDocs(docs string) (map[string][]tag, []string) {
parts := []string{} parts := []string{}
tags := make(map[string][]tag) tags := make(map[string][]tag)
for _, part := range pts { for idx, part := range pts {
if strings.HasPrefix(part, "#") { if strings.HasPrefix(part, "#") {
tagParts := strings.Split(strings.TrimPrefix(part, "#"), " ") tagParts := strings.Split(strings.TrimPrefix(part, "#"), " ")
if tags[tagParts[0]] == nil { if tags[tagParts[0]] == nil {
@ -89,12 +100,21 @@ func getTagsAndDocs(docs string) (map[string][]tag, []string) {
id = tagParts[1] id = tagParts[1]
} }
tags[tagParts[0]] = []tag{ tags[tagParts[0]] = []tag{
{id: id}, {id: id, startIdx: idx},
} }
if len(tagParts) >= 2 { if len(tagParts) >= 2 {
tags[tagParts[0]][0].fields = tagParts[2:] tags[tagParts[0]][0].fields = tagParts[2:]
} }
} else { } else {
if tagParts[0] == "example" {
exampleIdx := tags["example"][0].startIdx
exampleCode := pts[exampleIdx+1:idx]
tags["example"][0].fields = exampleCode
parts = strings.Split(strings.Replace(strings.Join(parts, "\n"), strings.TrimPrefix(strings.Join(exampleCode, "\n"), "#example\n"), "", -1), "\n")
continue
}
fleds := []string{} fleds := []string{}
if len(tagParts) >= 2 { if len(tagParts) >= 2 {
fleds = tagParts[2:] fleds = tagParts[2:]
@ -179,6 +199,7 @@ func setupDocType(mod string, typ *doc.Type) *docPiece {
ParentModule: parentMod, ParentModule: parentMod,
Fields: fields, Fields: fields,
Properties: properties, Properties: properties,
Tags: tags,
} }
typeTable[strings.ToLower(typeName)] = []string{parentMod, interfaces} typeTable[strings.ToLower(typeName)] = []string{parentMod, interfaces}
@ -215,6 +236,17 @@ start:
fields := docPieceTag("field", tags) fields := docPieceTag("field", tags)
properties := docPieceTag("property", tags) properties := docPieceTag("property", tags)
var params []param
if paramsRaw := tags["param"]; paramsRaw != nil {
params = make([]param, len(paramsRaw))
for i, p := range paramsRaw {
params[i] = param{
Name: p.id,
Type: p.fields[0],
Doc: p.fields[1:],
}
}
}
for _, d := range doc { for _, d := range doc {
if strings.HasPrefix(d, "---") { if strings.HasPrefix(d, "---") {
@ -252,6 +284,8 @@ start:
ParentModule: parentMod, ParentModule: parentMod,
Fields: fields, Fields: fields,
Properties: properties, Properties: properties,
Params: params,
Tags: tags,
} }
if strings.HasSuffix(dps.GoFuncName, strings.ToLower("loader")) { if strings.HasSuffix(dps.GoFuncName, strings.ToLower("loader")) {
dps.Doc = parts dps.Doc = parts
@ -412,13 +446,14 @@ func main() {
defer wg.Done() defer wg.Done()
modOrIface := "Module" modOrIface := "Module"
if modu.ParentModule != "" { if modu.ParentModule != "" {
modOrIface = "Interface" modOrIface = "Module"
} }
lastHeader := ""
f, _ := os.Create(docPath) f, _ := os.Create(docPath)
f.WriteString(fmt.Sprintf(header, modOrIface, modname, modu.ShortDescription)) f.WriteString(fmt.Sprintf(header, modOrIface, modname, modu.ShortDescription))
typeTag, _ := regexp.Compile(`\B@\w+`) typeTag, _ := regexp.Compile(`\B@\w+`)
modDescription := typeTag.ReplaceAllStringFunc(strings.Replace(modu.Description, "<", `\<`, -1), func(typ string) string { modDescription := typeTag.ReplaceAllStringFunc(strings.Replace(strings.Replace(modu.Description, "<", `\<`, -1), "{{\\<", "{{<", -1), func(typ string) string {
typName := typ[1:] typName := typ[1:]
typLookup := typeTable[strings.ToLower(typName)] typLookup := typeTable[strings.ToLower(typName)]
ifaces := typLookup[0] + "." + typLookup[1] + "/" ifaces := typLookup[0] + "." + typLookup[1] + "/"
@ -429,32 +464,77 @@ func main() {
return fmt.Sprintf(`<a href="%s" style="text-decoration: none;">%s</a>`, linkedTyp, typName) return fmt.Sprintf(`<a href="%s" style="text-decoration: none;">%s</a>`, linkedTyp, typName)
}) })
f.WriteString(fmt.Sprintf("## Introduction\n%s\n\n", modDescription)) f.WriteString(fmt.Sprintf("## Introduction\n%s\n\n", modDescription))
if len(modu.Fields) != 0 {
f.WriteString("## Interface fields\n")
for _, dps := range modu.Fields {
f.WriteString(fmt.Sprintf("- `%s`: ", dps.FuncName))
f.WriteString(strings.Join(dps.Doc, " "))
f.WriteString("\n")
}
f.WriteString("\n")
}
if len(modu.Properties) != 0 {
f.WriteString("## Object properties\n")
for _, dps := range modu.Properties {
f.WriteString(fmt.Sprintf("- `%s`: ", dps.FuncName))
f.WriteString(strings.Join(dps.Doc, " "))
f.WriteString("\n")
}
f.WriteString("\n")
}
if len(modu.Docs) != 0 { if len(modu.Docs) != 0 {
f.WriteString("## Functions\n") funcCount := 0
for _, dps := range modu.Docs { for _, dps := range modu.Docs {
if dps.IsMember { if dps.IsMember {
continue continue
} }
htmlSig := typeTag.ReplaceAllStringFunc(strings.Replace(dps.FuncSig, "<", `\<`, -1), func(typ string) string { funcCount++
}
f.WriteString("## Functions\n")
lastHeader = "functions"
mdTable := md.NewTable(funcCount, 2)
mdTable.SetTitle(0, "")
mdTable.SetTitle(1, "")
diff := 0
for i, dps := range modu.Docs {
if dps.IsMember {
diff++
continue
}
mdTable.SetContent(i - diff, 0, fmt.Sprintf(`<a href="#%s">%s</a>`, dps.FuncName, dps.FuncSig))
mdTable.SetContent(i - diff, 1, dps.Doc[0])
}
f.WriteString(mdTable.String())
f.WriteString("\n")
}
if len(modu.Fields) != 0 {
f.WriteString("## Static module fields\n")
mdTable := md.NewTable(len(modu.Fields), 2)
mdTable.SetTitle(0, "")
mdTable.SetTitle(1, "")
for i, dps := range modu.Fields {
mdTable.SetContent(i, 0, dps.FuncName)
mdTable.SetContent(i, 1, strings.Join(dps.Doc, " "))
}
f.WriteString(mdTable.String())
f.WriteString("\n")
}
if len(modu.Properties) != 0 {
f.WriteString("## Object properties\n")
mdTable := md.NewTable(len(modu.Fields), 2)
mdTable.SetTitle(0, "")
mdTable.SetTitle(1, "")
for i, dps := range modu.Properties {
mdTable.SetContent(i, 0, dps.FuncName)
mdTable.SetContent(i, 1, strings.Join(dps.Doc, " "))
}
f.WriteString(mdTable.String())
f.WriteString("\n")
}
if len(modu.Docs) != 0 {
if lastHeader != "functions" {
f.WriteString("## Functions\n")
}
for _, dps := range modu.Docs {
if dps.IsMember {
continue
}
f.WriteString(fmt.Sprintf("<hr><div id='%s'>", dps.FuncName))
htmlSig := typeTag.ReplaceAllStringFunc(strings.Replace(modname + "." + dps.FuncSig, "<", `\<`, -1), func(typ string) string {
typName := typ[1:] typName := typ[1:]
typLookup := typeTable[strings.ToLower(typName)] typLookup := typeTable[strings.ToLower(typName)]
ifaces := typLookup[0] + "." + typLookup[1] + "/" ifaces := typLookup[0] + "." + typLookup[1] + "/"
@ -462,21 +542,55 @@ func main() {
ifaces = "" ifaces = ""
} }
linkedTyp := fmt.Sprintf("/Hilbish/docs/api/%s/%s#%s", typLookup[0], ifaces, strings.ToLower(typName)) linkedTyp := fmt.Sprintf("/Hilbish/docs/api/%s/%s#%s", typLookup[0], ifaces, strings.ToLower(typName))
return fmt.Sprintf(`<a href="%s" style="text-decoration: none;">%s</a>`, linkedTyp, typName) return fmt.Sprintf(`<a href="%s" style="text-decoration: none;" id="lol">%s</a>`, linkedTyp, typName)
}) })
f.WriteString(fmt.Sprintf("### %s\n", htmlSig)) f.WriteString(fmt.Sprintf(`
<h4 class='heading'>
%s
<a href="#%s" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
`, htmlSig, dps.FuncName))
for _, doc := range dps.Doc { for _, doc := range dps.Doc {
if !strings.HasPrefix(doc, "---") { if !strings.HasPrefix(doc, "---") {
f.WriteString(doc + "\n") f.WriteString(doc + " \n")
} }
} }
f.WriteString("\n") f.WriteString("#### Parameters\n")
if len(dps.Params) == 0 {
f.WriteString("This function has no parameters. \n")
}
for _, p := range dps.Params {
isVariadic := false
typ := p.Type
if strings.HasPrefix(p.Type, "...") {
isVariadic = true
typ = p.Type[3:]
}
f.WriteString(fmt.Sprintf("`%s` **`%s`**", typ, p.Name))
if isVariadic {
f.WriteString(" (This type is variadic. You can pass an infinite amount of parameters with this type.)")
}
f.WriteString(" \n")
f.WriteString(strings.Join(p.Doc, " "))
f.WriteString("\n\n")
}
if codeExample := dps.Tags["example"]; codeExample != nil {
f.WriteString("#### Example\n")
f.WriteString(fmt.Sprintf("```lua\n%s\n````\n", strings.Join(codeExample[0].fields, "\n")))
}
f.WriteString("</div>")
f.WriteString("\n\n")
} }
} }
if len(modu.Types) != 0 { if len(modu.Types) != 0 {
f.WriteString("## Types\n") f.WriteString("## Types\n")
for _, dps := range modu.Types { for _, dps := range modu.Types {
f.WriteString("<hr>\n\n")
f.WriteString(fmt.Sprintf("## %s\n", dps.FuncName)) f.WriteString(fmt.Sprintf("## %s\n", dps.FuncName))
for _, doc := range dps.Doc { for _, doc := range dps.Doc {
if !strings.HasPrefix(doc, "---") { if !strings.HasPrefix(doc, "---") {
@ -484,12 +598,18 @@ func main() {
} }
} }
if len(dps.Properties) != 0 { if len(dps.Properties) != 0 {
f.WriteString("### Properties\n") f.WriteString("## Object properties\n")
for _, dps := range dps.Properties {
f.WriteString(fmt.Sprintf("- `%s`: ", dps.FuncName)) mdTable := md.NewTable(len(dps.Properties), 2)
f.WriteString(strings.Join(dps.Doc, " ")) mdTable.SetTitle(0, "")
f.WriteString("\n") mdTable.SetTitle(1, "")
for i, d := range dps.Properties {
mdTable.SetContent(i, 0, d.FuncName)
mdTable.SetContent(i, 1, strings.Join(d.Doc, " "))
} }
f.WriteString(mdTable.String())
f.WriteString("\n")
} }
f.WriteString("\n") f.WriteString("\n")
f.WriteString("### Methods\n") f.WriteString("### Methods\n")

View File

@ -193,10 +193,10 @@ func escapeFilename(fname string) string {
// The completions interface deals with tab completions. // The completions interface deals with tab completions.
func completionLoader(rtm *rt.Runtime) *rt.Table { func completionLoader(rtm *rt.Runtime) *rt.Table {
exports := map[string]util.LuaExport{ exports := map[string]util.LuaExport{
"files": {luaFileComplete, 3, false}, "bins": {hcmpBins, 3, false},
"bins": {luaBinaryComplete, 3, false}, "call": {hcmpCall, 4, false},
"call": {callLuaCompleter, 4, false}, "files": {hcmpFiles, 3, false},
"handler": {completionHandler, 2, false}, "handler": {hcmpHandler, 2, false},
} }
mod := rt.NewTable() mod := rt.NewTable()
@ -206,26 +206,57 @@ func completionLoader(rtm *rt.Runtime) *rt.Table {
} }
// #interface completion // #interface completion
// handler(line, pos) // bins(query, ctx, fields) -> entries (table), prefix (string)
// The handler function is the callback for tab completion in Hilbish. // Return binaries/executables based on the provided parameters.
// You can check the completions doc for more info. // This function is meant to be used as a helper in a command completion handler.
// --- @param line string // #param query string
// --- @param pos string // #param ctx string
func completionHandler(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { // #param fields table
return c.Next(), nil /*
#example
-- an extremely simple completer for sudo.
hilbish.complete('command.sudo', function(query, ctx, fields)
table.remove(fields, 1)
if #fields[1] then
-- return commands because sudo runs a command as root..!
local entries, pfx = hilbish.completion.bins(query, ctx, fields)
return {
type = 'grid',
items = entries
}, pfx
end
-- ... else suggest files or anything else ..
end)
#example
*/
func hcmpBins(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
query, ctx, fds, err := getCompleteParams(t, c)
if err != nil {
return nil, err
}
completions, pfx := binaryComplete(query, ctx, fds)
luaComps := rt.NewTable()
for i, comp := range completions {
luaComps.Set(rt.IntValue(int64(i + 1)), rt.StringValue(comp))
}
return c.PushingNext(t.Runtime, rt.TableValue(luaComps), rt.StringValue(pfx)), nil
} }
// #interface completion // #interface completion
// call(name, query, ctx, fields) -> completionGroups (table), prefix (string) // call(name, query, ctx, fields) -> completionGroups (table), prefix (string)
// Calls a completer function. This is mainly used to call // Calls a completer function. This is mainly used to call a command completer, which will have a `name`
// a command completer, which will have a `name` in the form // in the form of `command.name`, example: `command.git`.
// of `command.name`, example: `command.git`. // You can check the Completions doc or `doc completions` for info on the `completionGroups` return value.
// You can check `doc completions` for info on the `completionGroups` return value. // #param name string
// --- @param name string // #param query string
// --- @param query string // #param ctx string
// --- @param ctx string // #param fields table
// --- @param fields table func hcmpCall(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
func callLuaCompleter(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err := c.CheckNArgs(4); err != nil { if err := c.CheckNArgs(4); err != nil {
return nil, err return nil, err
} }
@ -267,11 +298,12 @@ func callLuaCompleter(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
// #interface completion // #interface completion
// files(query, ctx, fields) -> entries (table), prefix (string) // files(query, ctx, fields) -> entries (table), prefix (string)
// Returns file completion candidates based on the provided query. // Returns file matches based on the provided parameters.
// --- @param query string // This function is meant to be used as a helper in a command completion handler.
// --- @param ctx string // #param query string
// --- @param fields table // #param ctx string
func luaFileComplete(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { // #param fields table
func hcmpFiles(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
query, ctx, fds, err := getCompleteParams(t, c) query, ctx, fds, err := getCompleteParams(t, c)
if err != nil { if err != nil {
return nil, err return nil, err
@ -288,27 +320,31 @@ func luaFileComplete(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
} }
// #interface completion // #interface completion
// bins(query, ctx, fields) -> entries (table), prefix (string) // handler(line, pos)
// Returns binary/executale completion candidates based on the provided query. // This function contains the general completion handler for Hilbish. This function handles
// --- @param query string // completion of everything, which includes calling other command handlers, binaries, and files.
// --- @param ctx string // This function can be overriden to supply a custom handler. Note that alias resolution is required to be done in this function.
// --- @param fields table // #param line string The current Hilbish command line
func luaBinaryComplete(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { // #param pos number Numerical position of the cursor
query, ctx, fds, err := getCompleteParams(t, c) /*
if err != nil { #example
return nil, err -- stripped down version of the default implementation
} function hilbish.completion.handler(line, pos)
local query = fields[#fields]
completions, pfx := binaryComplete(query, ctx, fds) if #fields == 1 then
luaComps := rt.NewTable() -- call bins handler here
else
for i, comp := range completions { -- call command completer or files completer here
luaComps.Set(rt.IntValue(int64(i + 1)), rt.StringValue(comp)) end
} end
#example
return c.PushingNext(t.Runtime, rt.TableValue(luaComps), rt.StringValue(pfx)), nil */
func hcmpHandler(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
return c.Next(), nil
} }
func getCompleteParams(t *rt.Thread, c *rt.GoCont) (string, string, []string, error) { func getCompleteParams(t *rt.Thread, c *rt.GoCont) (string, string, []string, error) {
if err := c.CheckNArgs(3); err != nil { if err := c.CheckNArgs(3); err != nil {
return "", "", []string{}, err return "", "", []string{}, err

View File

@ -1,7 +1,7 @@
--- ---
title: API title: API
layout: doc layout: doc
weight: -50 weight: -100
menu: docs menu: docs
--- ---

View File

@ -8,27 +8,156 @@ menu:
--- ---
## Introduction ## Introduction
Bait is the event emitter for Hilbish. Why name it bait? Why not.
It throws hooks that you can catch. This is what you will use if Bait is the event emitter for Hilbish. Much like Node.js and
you want to listen in on hooks to know when certain things have its `events` system, many actions in Hilbish emit events.
happened, like when you've changed directory, a command has failed, Unlike Node.js, Hilbish events are global. So make sure to
etc. To find all available hooks thrown by Hilbish, see doc hooks. pick a unique name!
Usage of the Bait module consists of userstanding
event-driven architecture, but it's pretty simple:
If you want to act on a certain event, you can `catch` it.
You can act on events via callback functions.
Examples of this are in the Hilbish default config!
Consider this part of it:
```lua
bait.catch('command.exit', function(code)
running = false
doPrompt(code ~= 0)
doNotifyPrompt()
end)
```
What this does is, whenever the `command.exit` event is thrown,
this function will set the user prompt.
## Functions ## Functions
### catch(name, cb) |||
Catches a hook with `name`. Runs the `cb` when it is thrown |----|----|
|<a href="#catch">catch(name, cb)</a>|Catches an event. This function can be used to act on events.|
|<a href="#catchOnce">catchOnce(name, cb)</a>|Catches an event, but only once. This will remove the hook immediately after it runs for the first time.|
|<a href="#hooks">hooks(name) -> table</a>|Returns a list of callbacks that are hooked on an event with the corresponding `name`.|
|<a href="#release">release(name, catcher)</a>|Removes the `catcher` for the event with `name`.|
|<a href="#throw">throw(name, ...args)</a>|Throws a hook with `name` with the provided `args`.|
### catchOnce(name, cb) <hr><div id='catch'>
Same as catch, but only runs the `cb` once and then removes the hook <h4 class='heading'>
bait.catch(name, cb)
<a href="#catch" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
### hooks(name) -> table Catches an event. This function can be used to act on events.
Returns a table with hooks (callback functions) on the event with `name`.
#### Parameters
`string` **`name`**
The name of the hook.
`function` **`cb`**
The function that will be called when the hook is thrown.
#### Example
```lua
bait.catch('hilbish.exit', function()
print 'Goodbye Hilbish!'
end)
````
</div>
<hr><div id='catchOnce'>
<h4 class='heading'>
bait.catchOnce(name, cb)
<a href="#catchOnce" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
Catches an event, but only once. This will remove the hook immediately after it runs for the first time.
#### Parameters
`string` **`name`**
The name of the event
`function` **`cb`**
The function that will be called when the event is thrown.
</div>
<hr><div id='hooks'>
<h4 class='heading'>
bait.hooks(name) -> table
<a href="#hooks" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
Returns a list of callbacks that are hooked on an event with the corresponding `name`.
#### Parameters
`string` **`name`**
The name of the function
</div>
<hr><div id='release'>
<h4 class='heading'>
bait.release(name, catcher)
<a href="#release" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
### release(name, catcher)
Removes the `catcher` for the event with `name`. Removes the `catcher` for the event with `name`.
For this to work, `catcher` has to be the same function used to catch For this to work, `catcher` has to be the same function used to catch
an event, like one saved to a variable. an event, like one saved to a variable.
### throw(name, ...args)
Throws a hook with `name` with the provided `args` #### Parameters
`string` **`name`**
Name of the event the hook is on
`function` **`catcher`**
Hook function to remove
#### Example
```lua
local hookCallback = function() print 'hi' end
bait.catch('event', hookCallback)
-- a little while later....
bait.release('event', hookCallback)
-- and now hookCallback will no longer be ran for the event.
````
</div>
<hr><div id='throw'>
<h4 class='heading'>
bait.throw(name, ...args)
<a href="#throw" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
Throws a hook with `name` with the provided `args`.
#### Parameters
`string` **`name`**
The name of the hook.
`any` **`args`** (This type is variadic. You can pass an infinite amount of parameters with this type.)
The arguments to pass to the hook.
#### Example
```lua
bait.throw('greeting', 'world')
-- This can then be listened to via
bait.catch('gretting', function(greetTo)
print('Hello ' .. greetTo)
end)
````
</div>

View File

@ -9,11 +9,10 @@ menu:
## Introduction ## Introduction
Commander is a library for writing custom commands in Lua. Commander is the library which handles Hilbish commands. This makes
In order to make it easier to write commands for Hilbish, the user able to add Lua-written commands to their shell without making
not require separate scripts and to be able to use in a config, a separate script in a bin folder. Instead, you may simply use the Commander
the Commander library exists. This is like a very simple wrapper library in your Hilbish config.
that works with Hilbish for writing commands. Example:
```lua ```lua
local commander = require 'commander' local commander = require 'commander'
@ -28,19 +27,65 @@ that will print `Hello world!` to output. One question you may
have is: What is the `sinks` parameter? have is: What is the `sinks` parameter?
The `sinks` parameter is a table with 3 keys: `in`, `out`, The `sinks` parameter is a table with 3 keys: `in`, `out`,
and `err`. The values of these is a <a href="/Hilbish/docs/api/hilbish/#sink" style="text-decoration: none;">Sink</a>. and `err`. All of them are a <a href="/Hilbish/docs/api/hilbish/#sink" style="text-decoration: none;">Sink</a>.
- `in` is the standard input. You can read from this sink - `in` is the standard input.
to get user input. (**This is currently unimplemented.**) You may use the read functions on this sink to get input from the user.
- `out` is standard output. This is usually where text meant for - `out` is standard output.
output should go. This is usually where command output should go.
- `err` is standard error. This sink is for writing errors, as the - `err` is standard error.
name would suggest. This sink is for writing errors, as the name would suggest.
## Functions ## Functions
### deregister(name) |||
Deregisters any command registered with `name` |----|----|
|<a href="#deregister">deregister(name)</a>|Removes the named command. Note that this will only remove Commander-registered commands.|
|<a href="#register">register(name, cb)</a>|Adds a new command with the given `name`. When Hilbish has to run a command with a name,|
### register(name, cb) <hr><div id='deregister'>
Register a command with `name` that runs `cb` when ran <h4 class='heading'>
commander.deregister(name)
<a href="#deregister" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
Removes the named command. Note that this will only remove Commander-registered commands.
#### Parameters
`string` **`name`**
Name of the command to remove.
</div>
<hr><div id='register'>
<h4 class='heading'>
commander.register(name, cb)
<a href="#register" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
Adds a new command with the given `name`. When Hilbish has to run a command with a name,
it will run the function providing the arguments and sinks.
#### Parameters
`string` **`name`**
Name of the command
`function` **`cb`**
Callback to handle command invocation
#### Example
```lua
-- When you run the command `hello` in the shell, it will print `Hello world`.
-- If you run it with, for example, `hello Hilbish`, it will print 'Hello Hilbish'
commander.register('hello', function(args, sinks)
local name = 'world'
if #args > 0 then name = args[1] end
sinks.out:writeln('Hello ' .. name)
end)
````
</div>

View File

@ -8,44 +8,223 @@ menu:
--- ---
## Introduction ## Introduction
The fs module provides easy and simple access to filesystem functions
and other things, and acts an addition to the Lua standard library's The fs module provides filesystem functions to Hilbish. While Lua's standard
I/O and filesystem functions. library has some I/O functions, they're missing a lot of the basics. The `fs`
library offers more functions and will work on any operating system Hilbish does.
## Functions ## Functions
### abs(path) -> string |||
Gives an absolute version of `path`. |----|----|
|<a href="#abs">abs(path) -> string</a>|Returns an absolute version of the `path`.|
|<a href="#basename">basename(path) -> string</a>|Returns the "basename," or the last part of the provided `path`. If path is empty,|
|<a href="#cd">cd(dir)</a>|Changes Hilbish's directory to `dir`.|
|<a href="#dir">dir(path) -> string</a>|Returns the directory part of `path`. If a file path like|
|<a href="#glob">glob(pattern) -> matches (table)</a>|Match all files based on the provided `pattern`.|
|<a href="#join">join(...path) -> string</a>|Takes any list of paths and joins them based on the operating system's path separator.|
|<a href="#mkdir">mkdir(name, recursive)</a>|Creates a new directory with the provided `name`.|
|<a href="#readdir">readdir(path) -> table[string]</a>|Returns a list of all files and directories in the provided path.|
|<a href="#stat">stat(path) -> {}</a>|Returns the information about a given `path`.|
### basename(path) -> string ## Static module fields
Gives the basename of `path`. For the rules, |||
see Go's filepath.Base |----|----|
|pathSep|The operating system's path separator.|
### cd(dir) <hr><div id='abs'>
Changes directory to `dir` <h4 class='heading'>
fs.abs(path) -> string
<a href="#abs" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
### dir(path) -> string Returns an absolute version of the `path`.
Returns the directory part of `path`. For the rules, see Go's This can be used to resolve short paths like `..` to `/home/user`.
filepath.Dir #### Parameters
`string` **`path`**
### glob(pattern) -> matches (table)
Glob all files and directories that match the pattern.
For the rules, see Go's filepath.Glob
### join(...) -> string </div>
Takes paths and joins them together with the OS's
directory separator (forward or backward slash).
### mkdir(name, recursive) <hr><div id='basename'>
Makes a directory called `name`. If `recursive` is true, it will create its parent directories. <h4 class='heading'>
fs.basename(path) -> string
<a href="#basename" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
### readdir(dir) -> {} Returns the "basename," or the last part of the provided `path`. If path is empty,
Returns a table of files in `dir`. `.` will be returned.
#### Parameters
`string` **`path`**
Path to get the base name of.
### stat(path) -> {} </div>
Returns a table of info about the `path`.
It contains the following keys: <hr><div id='cd'>
<h4 class='heading'>
fs.cd(dir)
<a href="#cd" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
Changes Hilbish's directory to `dir`.
#### Parameters
`string` **`dir`**
Path to change directory to.
</div>
<hr><div id='dir'>
<h4 class='heading'>
fs.dir(path) -> string
<a href="#dir" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
Returns the directory part of `path`. If a file path like
`~/Documents/doc.txt` then this function will return `~/Documents`.
#### Parameters
`string` **`path`**
Path to get the directory for.
</div>
<hr><div id='glob'>
<h4 class='heading'>
fs.glob(pattern) -> matches (table)
<a href="#glob" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
Match all files based on the provided `pattern`.
For the syntax' refer to Go's filepath.Match function: https://pkg.go.dev/path/filepath#Match
#### Parameters
`string` **`pattern`**
Pattern to compare files with.
#### Example
```lua
--[[
Within a folder that contains the following files:
a.txt
init.lua
code.lua
doc.pdf
]]--
local matches = fs.glob './*.lua'
print(matches)
-- -> {'init.lua', 'code.lua'}
````
</div>
<hr><div id='join'>
<h4 class='heading'>
fs.join(...path) -> string
<a href="#join" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
Takes any list of paths and joins them based on the operating system's path separator.
#### Parameters
`string` **`path`** (This type is variadic. You can pass an infinite amount of parameters with this type.)
Paths to join together
#### Example
```lua
-- This prints the directory for Hilbish's config!
print(fs.join(hilbish.userDir.config, 'hilbish'))
-- -> '/home/user/.config/hilbish' on Linux
````
</div>
<hr><div id='mkdir'>
<h4 class='heading'>
fs.mkdir(name, recursive)
<a href="#mkdir" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
Creates a new directory with the provided `name`.
With `recursive`, mkdir will create parent directories.
-- This will create the directory foo, then create the directory bar in the
-- foo directory. If recursive is false in this case, it will fail.
fs.mkdir('./foo/bar', true)
#### Parameters
`string` **`name`**
Name of the directory
`boolean` **`recursive`**
Whether to create parent directories for the provided name
#### Example
```lua
````
</div>
<hr><div id='readdir'>
<h4 class='heading'>
fs.readdir(path) -> table[string]
<a href="#readdir" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
Returns a list of all files and directories in the provided path.
#### Parameters
`string` **`dir`**
</div>
<hr><div id='stat'>
<h4 class='heading'>
fs.stat(path) -> {}
<a href="#stat" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
Returns the information about a given `path`.
The returned table contains the following values:
name (string) - Name of the path name (string) - Name of the path
size (number) - Size of the path size (number) - Size of the path in bytes
mode (string) - Permission mode in an octal format string (with leading 0) mode (string) - Unix permission mode in an octal format string (with leading 0)
isDir (boolean) - If the path is a directory isDir (boolean) - If the path is a directory
#### Parameters
`string` **`path`**
#### Example
```lua
local inspect = require 'inspect'
local stat = fs.stat '~'
print(inspect(stat))
--[[
Would print the following:
{
isDir = true,
mode = "0755",
name = "username",
size = 12288
}
]]--
````
</div>

View File

@ -11,108 +11,435 @@ menu:
The Hilbish module includes the core API, containing The Hilbish module includes the core API, containing
interfaces and functions which directly relate to shell functionality. interfaces and functions which directly relate to shell functionality.
## Interface fields
- `ver`: The version of Hilbish
- `goVersion`: The version of Go that Hilbish was compiled with
- `user`: Username of the user
- `host`: Hostname of the machine
- `dataDir`: Directory for Hilbish data files, including the docs and default modules
- `interactive`: Is Hilbish in an interactive shell?
- `login`: Is Hilbish the login shell?
- `vimMode`: Current Vim input mode of Hilbish (will be nil if not in Vim input mode)
- `exitCode`: xit code of the last executed command
## Functions ## Functions
### alias(cmd, orig) |||
Sets an alias of `cmd` to `orig` |----|----|
|<a href="#alias">alias(cmd, orig)</a>|Sets an alias, with a name of `cmd` to another command.|
|<a href="#appendPath">appendPath(dir)</a>|Appends the provided dir to the command path (`$PATH`)|
|<a href="#complete">complete(scope, cb)</a>|Registers a completion handler for the specified scope.|
|<a href="#cwd">cwd() -> string</a>|Returns the current directory of the shell|
|<a href="#exec">exec(cmd)</a>|Replaces the currently running Hilbish instance with the supplied command.|
|<a href="#goro">goro(fn)</a>|Puts `fn` in a Goroutine.|
|<a href="#highlighter">highlighter(line)</a>|Line highlighter handler.|
|<a href="#hinter">hinter(line, pos)</a>|The command line hint handler. It gets called on every key insert to|
|<a href="#inputMode">inputMode(mode)</a>|Sets the input mode for Hilbish's line reader. Accepts either emacs or vim.|
|<a href="#interval">interval(cb, time) -> @Timer</a>|Runs the `cb` function every `time` milliseconds.|
|<a href="#multiprompt">multiprompt(str)</a>|Changes the text prompt when Hilbish asks for more input.|
|<a href="#prependPath">prependPath(dir)</a>|Prepends `dir` to $PATH.|
|<a href="#prompt">prompt(str, typ)</a>|Changes the shell prompt to the provided string.|
|<a href="#read">read(prompt) -> input (string)</a>|Read input from the user, using Hilbish's line editor/input reader.|
|<a href="#run">run(cmd, returnOut) -> exitCode (number), stdout (string), stderr (string)</a>|Runs `cmd` in Hilbish's shell script interpreter.|
|<a href="#runnerMode">runnerMode(mode)</a>|Sets the execution/runner mode for interactive Hilbish. This determines whether|
|<a href="#timeout">timeout(cb, time) -> @Timer</a>|Runs the `cb` function after `time` in milliseconds.|
|<a href="#which">which(name) -> string</a>|Checks if `name` is a valid command.|
### appendPath(dir) ## Static module fields
Appends `dir` to $PATH |||
|----|----|
|ver|The version of Hilbish|
|goVersion|The version of Go that Hilbish was compiled with|
|user|Username of the user|
|host|Hostname of the machine|
|dataDir|Directory for Hilbish data files, including the docs and default modules|
|interactive|Is Hilbish in an interactive shell?|
|login|Is Hilbish the login shell?|
|vimMode|Current Vim input mode of Hilbish (will be nil if not in Vim input mode)|
|exitCode|Exit code of the last executed command|
### complete(scope, cb) <hr><div id='alias'>
Registers a completion handler for `scope`. <h4 class='heading'>
hilbish.alias(cmd, orig)
<a href="#alias" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
Sets an alias, with a name of `cmd` to another command.
#### Parameters
`string` **`cmd`**
Name of the alias
`string` **`orig`**
Command that will be aliased
#### Example
```lua
-- With this, "ga file" will turn into "git add file"
hilbish.alias('ga', 'git add')
-- Numbered substitutions are supported here!
hilbish.alias('dircount', 'ls %1 | wc -l')
-- "dircount ~" would count how many files are in ~ (home directory).
````
</div>
<hr><div id='appendPath'>
<h4 class='heading'>
hilbish.appendPath(dir)
<a href="#appendPath" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
Appends the provided dir to the command path (`$PATH`)
#### Parameters
`string|table` **`dir`**
Directory (or directories) to append to path
#### Example
```lua
hilbish.appendPath '~/go/bin'
-- Will add ~/go/bin to the command path.
-- Or do multiple:
hilbush.appendPath {
'~/go/bin',
'~/.local/bin'
}
````
</div>
<hr><div id='complete'>
<h4 class='heading'>
hilbish.complete(scope, cb)
<a href="#complete" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
Registers a completion handler for the specified scope.
A `scope` is currently only expected to be `command.<cmd>`, A `scope` is currently only expected to be `command.<cmd>`,
replacing <cmd> with the name of the command (for example `command.git`). replacing <cmd> with the name of the command (for example `command.git`).
`cb` must be a function that returns a table of "completion groups." The documentation for completions, under Features/Completions or `doc completions`
Check `doc completions` for more information. provides more details.
#### Parameters
`string` **`scope`**
`function` **`cb`**
</div>
<hr><div id='cwd'>
<h4 class='heading'>
hilbish.cwd() -> string
<a href="#cwd" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
### cwd() -> string
Returns the current directory of the shell Returns the current directory of the shell
#### Parameters
This function has no parameters.
</div>
### exec(cmd) <hr><div id='exec'>
Replaces running hilbish with `cmd` <h4 class='heading'>
hilbish.exec(cmd)
<a href="#exec" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
### goro(fn) Replaces the currently running Hilbish instance with the supplied command.
Puts `fn` in a goroutine This can be used to do an in-place restart.
#### Parameters
`string` **`cmd`**
### highlighter(line)
Line highlighter handler. This is mainly for syntax highlighting, but in </div>
reality could set the input of the prompt to *display* anything. The
callback is passed the current line and is expected to return a line that <hr><div id='goro'>
will be used as the input display. <h4 class='heading'>
hilbish.goro(fn)
<a href="#goro" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
Puts `fn` in a Goroutine.
This can be used to run any function in another thread.
**NOTE: THIS FUNCTION MAY CRASH HILBISH IF OUTSIDE VARIABLES ARE ACCESSED.**
#### Parameters
`function` **`fn`**
</div>
<hr><div id='highlighter'>
<h4 class='heading'>
hilbish.highlighter(line)
<a href="#highlighter" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
Line highlighter handler.
This is mainly for syntax highlighting, but in reality could set the input
of the prompt to *display* anything. The callback is passed the current line
and is expected to return a line that will be used as the input display.
Note that to set a highlighter, one has to override this function. Note that to set a highlighter, one has to override this function.
Example:
``` #### Parameters
`string` **`line`**
#### Example
```lua
--This code will highlight all double quoted strings in green.
function hilbish.highlighter(line) function hilbish.highlighter(line)
return line:gsub('"%w+"', function(c) return lunacolors.green(c) end) return line:gsub('"%w+"', function(c) return lunacolors.green(c) end)
end end
``` ````
This code will highlight all double quoted strings in green. </div>
<hr><div id='hinter'>
<h4 class='heading'>
hilbish.hinter(line, pos)
<a href="#hinter" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
### hinter(line, pos)
The command line hint handler. It gets called on every key insert to The command line hint handler. It gets called on every key insert to
determine what text to use as an inline hint. It is passed the current determine what text to use as an inline hint. It is passed the current
line and cursor position. It is expected to return a string which is used line and cursor position. It is expected to return a string which is used
as the text for the hint. This is by default a shim. To set hints, as the text for the hint. This is by default a shim. To set hints,
override this function with your custom handler. override this function with your custom handler.
### inputMode(mode)
Sets the input mode for Hilbish's line reader. Accepts either emacs or vim
### interval(cb, time) -> <a href="/Hilbish/docs/api/hilbish/hilbish.timers/#timer" style="text-decoration: none;">Timer</a> #### Parameters
`string` **`line`**
`number` **`pos`**
#### Example
```lua
-- this will display "hi" after the cursor in a dimmed color.
function hilbish.hinter(line, pos)
return 'hi'
end
````
</div>
<hr><div id='inputMode'>
<h4 class='heading'>
hilbish.inputMode(mode)
<a href="#inputMode" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
Sets the input mode for Hilbish's line reader. Accepts either emacs or vim.
`emacs` is the default. Setting it to `vim` changes behavior of input to be
Vim-like with modes and Vim keybinds.
#### Parameters
`string` **`mode`**
</div>
<hr><div id='interval'>
<h4 class='heading'>
hilbish.interval(cb, time) -> <a href="/Hilbish/docs/api/hilbish/hilbish.timers/#timer" style="text-decoration: none;" id="lol">Timer</a>
<a href="#interval" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
Runs the `cb` function every `time` milliseconds. Runs the `cb` function every `time` milliseconds.
This creates a timer that starts immediately. This creates a timer that starts immediately.
#### Parameters
`function` **`cb`**
### multiprompt(str)
Changes the continued line prompt to `str`
### prependPath(dir) `number` **`time`**
Prepends `dir` to $PATH
### prompt(str, typ)
Changes the shell prompt to `str` </div>
<hr><div id='multiprompt'>
<h4 class='heading'>
hilbish.multiprompt(str)
<a href="#multiprompt" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
Changes the text prompt when Hilbish asks for more input.
This will show up when text is incomplete, like a missing quote
#### Parameters
`string` **`str`**
#### Example
```lua
--[[
imagine this is your text input:
user ~ ∆ echo "hey
but there's a missing quote! hilbish will now prompt you so the terminal
will look like:
user ~ ∆ echo "hey
--> ...!"
so then you get
user ~ ∆ echo "hey
--> ...!"
hey ...!
]]--
hilbish.multiprompt '-->'
````
</div>
<hr><div id='prependPath'>
<h4 class='heading'>
hilbish.prependPath(dir)
<a href="#prependPath" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
Prepends `dir` to $PATH.
#### Parameters
`string` **`dir`**
</div>
<hr><div id='prompt'>
<h4 class='heading'>
hilbish.prompt(str, typ)
<a href="#prompt" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
Changes the shell prompt to the provided string.
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.
These will be formatted and replaced with the appropriate values. These will be formatted and replaced with the appropriate values.
`%d` - Current working directory `%d` - Current working directory
`%u` - Name of current user `%u` - Name of current user
`%h` - Hostname of device `%h` - Hostname of device
### read(prompt) -> input (string) #### Parameters
`string` **`str`**
`string` **`typ?`**
Type of prompt, being left or right. Left by default.
#### Example
```lua
-- the default hilbish prompt without color
hilbish.prompt '%u %d ∆'
-- or something of old:
hilbish.prompt '%u@%h :%d $'
-- prompt: user@hostname: ~/directory $
````
</div>
<hr><div id='read'>
<h4 class='heading'>
hilbish.read(prompt) -> input (string)
<a href="#read" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
Read input from the user, using Hilbish's line editor/input reader. Read input from the user, using Hilbish's line editor/input reader.
This is a separate instance from the one Hilbish actually uses. This is a separate instance from the one Hilbish actually uses.
Returns `input`, will be nil if ctrl + d is pressed, or an error occurs (which shouldn't happen) Returns `input`, will be nil if ctrl + d is pressed, or an error occurs (which shouldn't happen).
#### Parameters
`string` **`prompt?`**
### run(cmd, returnOut) -> exitCode (number), stdout (string), stderr (string)
Runs `cmd` in Hilbish's sh interpreter.
If returnOut is true, the outputs of `cmd` will be returned as the 2nd and
3rd values instead of being outputted to the terminal.
### runnerMode(mode) </div>
<hr><div id='run'>
<h4 class='heading'>
hilbish.run(cmd, returnOut) -> exitCode (number), stdout (string), stderr (string)
<a href="#run" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
Runs `cmd` in Hilbish's shell script interpreter.
#### Parameters
`string` **`cmd`**
`boolean` **`returnOut`**
If this is true, the function will return the standard output and error of the command instead of printing it.
</div>
<hr><div id='runnerMode'>
<h4 class='heading'>
hilbish.runnerMode(mode)
<a href="#runnerMode" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
Sets the execution/runner mode for interactive Hilbish. This determines whether Sets the execution/runner mode for interactive Hilbish. This determines whether
Hilbish wll try to run input as Lua and/or sh or only do one of either. Hilbish wll try to run input as Lua and/or sh or only do one of either.
Accepted values for mode are hybrid (the default), hybridRev (sh first then Lua), Accepted values for mode are hybrid (the default), hybridRev (sh first then Lua),
sh, and lua. It also accepts a function, to which if it is passed one sh, and lua. It also accepts a function, to which if it is passed one
will call it to execute user input instead. will call it to execute user input instead.
#### Parameters
`string|function` **`mode`**
</div>
<hr><div id='timeout'>
<h4 class='heading'>
hilbish.timeout(cb, time) -> <a href="/Hilbish/docs/api/hilbish/hilbish.timers/#timer" style="text-decoration: none;" id="lol">Timer</a>
<a href="#timeout" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
### timeout(cb, time) -> <a href="/Hilbish/docs/api/hilbish/hilbish.timers/#timer" style="text-decoration: none;">Timer</a>
Runs the `cb` function after `time` in milliseconds. Runs the `cb` function after `time` in milliseconds.
This creates a timer that starts immediately. This creates a Timer that starts immediately.
#### Parameters
`function` **`cb`**
`number` **`time`**
</div>
<hr><div id='which'>
<h4 class='heading'>
hilbish.which(name) -> string
<a href="#which" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
### which(name) -> string
Checks if `name` is a valid command. Checks if `name` is a valid command.
Will return the path of the binary, or a basename if it's a commander. Will return the path of the binary, or a basename if it's a commander.
#### Parameters
`string` **`name`**
</div>
## Types ## Types
<hr>
## Sink ## Sink
A sink is a structure that has input and/or output to/from A sink is a structure that has input and/or output to/from
a desination. a desination.

View File

@ -1,5 +1,5 @@
--- ---
title: Interface hilbish.aliases title: Module hilbish.aliases
description: command aliasing description: command aliasing
layout: doc layout: doc
menu: menu:
@ -11,15 +11,75 @@ menu:
The alias interface deals with all command aliases in Hilbish. The alias interface deals with all command aliases in Hilbish.
## Functions ## Functions
### add(alias, cmd) |||
This is an alias (ha) for the `hilbish.alias` function. |----|----|
|<a href="#aliases.add">add(alias, cmd)</a>|This is an alias (ha) for the [hilbish.alias](../#alias) function.|
|<a href="#aliases.delete">delete(name)</a>|Removes an alias.|
|<a href="#aliases.list">list() -> table[string, string]</a>|Get a table of all aliases, with string keys as the alias and the value as the command.|
|<a href="#aliases.resolve">resolve(alias) -> string?</a>|Resolves an alias to its original command. Will thrown an error if the alias doesn't exist.|
<hr><div id='aliases.add'>
<h4 class='heading'>
hilbish.aliases.add(alias, cmd)
<a href="#aliases.add" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
This is an alias (ha) for the [hilbish.alias](../#alias) function.
#### Parameters
This function has no parameters.
</div>
<hr><div id='aliases.delete'>
<h4 class='heading'>
hilbish.aliases.delete(name)
<a href="#aliases.delete" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
### delete(name)
Removes an alias. Removes an alias.
#### Parameters
`string` **`name`**
</div>
<hr><div id='aliases.list'>
<h4 class='heading'>
hilbish.aliases.list() -> table[string, string]
<a href="#aliases.list" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
### list() -> table\<string, string>
Get a table of all aliases, with string keys as the alias and the value as the command. Get a table of all aliases, with string keys as the alias and the value as the command.
### resolve(alias) -> command (string)
Tries to resolve an alias to its command. #### Parameters
This function has no parameters.
#### Example
```lua
hilbish.aliases.add('hi', 'echo hi')
local aliases = hilbish.aliases.list()
-- -> {hi = 'echo hi'}
````
</div>
<hr><div id='aliases.resolve'>
<h4 class='heading'>
hilbish.aliases.resolve(alias) -> string?
<a href="#aliases.resolve" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
Resolves an alias to its original command. Will thrown an error if the alias doesn't exist.
#### Parameters
`string` **`alias`**
</div>

View File

@ -1,5 +1,5 @@
--- ---
title: Interface hilbish.completion title: Module hilbish.completion
description: tab completions description: tab completions
layout: doc layout: doc
menu: menu:
@ -11,19 +11,135 @@ menu:
The completions interface deals with tab completions. The completions interface deals with tab completions.
## Functions ## Functions
### call(name, query, ctx, fields) -> completionGroups (table), prefix (string) |||
Calls a completer function. This is mainly used to call |----|----|
a command completer, which will have a `name` in the form |<a href="#completion.bins">bins(query, ctx, fields) -> entries (table), prefix (string)</a>|Return binaries/executables based on the provided parameters.|
of `command.name`, example: `command.git`. |<a href="#completion.call">call(name, query, ctx, fields) -> completionGroups (table), prefix (string)</a>|Calls a completer function. This is mainly used to call a command completer, which will have a `name`|
You can check `doc completions` for info on the `completionGroups` return value. |<a href="#completion.files">files(query, ctx, fields) -> entries (table), prefix (string)</a>|Returns file matches based on the provided parameters.|
|<a href="#completion.handler">handler(line, pos)</a>|This function contains the general completion handler for Hilbish. This function handles|
### handler(line, pos) <hr><div id='completion.bins'>
The handler function is the callback for tab completion in Hilbish. <h4 class='heading'>
You can check the completions doc for more info. hilbish.completion.bins(query, ctx, fields) -> entries (table), prefix (string)
<a href="#completion.bins" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
### bins(query, ctx, fields) -> entries (table), prefix (string) Return binaries/executables based on the provided parameters.
Returns binary/executale completion candidates based on the provided query. This function is meant to be used as a helper in a command completion handler.
### files(query, ctx, fields) -> entries (table), prefix (string)
Returns file completion candidates based on the provided query. #### Parameters
`string` **`query`**
`string` **`ctx`**
`table` **`fields`**
#### Example
```lua
-- an extremely simple completer for sudo.
hilbish.complete('command.sudo', function(query, ctx, fields)
table.remove(fields, 1)
if #fields[1] then
-- return commands because sudo runs a command as root..!
local entries, pfx = hilbish.completion.bins(query, ctx, fields)
return {
type = 'grid',
items = entries
}, pfx
end
-- ... else suggest files or anything else ..
end)
````
</div>
<hr><div id='completion.call'>
<h4 class='heading'>
hilbish.completion.call(name, query, ctx, fields) -> completionGroups (table), prefix (string)
<a href="#completion.call" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
Calls a completer function. This is mainly used to call a command completer, which will have a `name`
in the form of `command.name`, example: `command.git`.
You can check the Completions doc or `doc completions` for info on the `completionGroups` return value.
#### Parameters
`string` **`name`**
`string` **`query`**
`string` **`ctx`**
`table` **`fields`**
</div>
<hr><div id='completion.files'>
<h4 class='heading'>
hilbish.completion.files(query, ctx, fields) -> entries (table), prefix (string)
<a href="#completion.files" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
Returns file matches based on the provided parameters.
This function is meant to be used as a helper in a command completion handler.
#### Parameters
`string` **`query`**
`string` **`ctx`**
`table` **`fields`**
</div>
<hr><div id='completion.handler'>
<h4 class='heading'>
hilbish.completion.handler(line, pos)
<a href="#completion.handler" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
This function contains the general completion handler for Hilbish. This function handles
completion of everything, which includes calling other command handlers, binaries, and files.
This function can be overriden to supply a custom handler. Note that alias resolution is required to be done in this function.
#### Parameters
`string` **`line`**
The current Hilbish command line
`number` **`pos`**
Numerical position of the cursor
#### Example
```lua
-- stripped down version of the default implementation
function hilbish.completion.handler(line, pos)
local query = fields[#fields]
if #fields == 1 then
-- call bins handler here
else
-- call command completer or files completer here
end
end
````
</div>

View File

@ -1,29 +0,0 @@
---
title: Interface hilbish.completions
description: tab completions
layout: doc
menu:
docs:
parent: "API"
---
## Introduction
The completions interface deals with tab completions.
## Functions
### call(name, query, ctx, fields) -> completionGroups (table), prefix (string)
Calls a completer function. This is mainly used to call
a command completer, which will have a `name` in the form
of `command.name`, example: `command.git`.
You can check `doc completions` for info on the `completionGroups` return value.
### handler(line, pos)
The handler function is the callback for tab completion in Hilbish.
You can check the completions doc for more info.
### bins(query, ctx, fields) -> entries (table), prefix (string)
Returns binary/executale completion candidates based on the provided query.
### files(query, ctx, fields) -> entries (table), prefix (string)
Returns file completion candidates based on the provided query.

View File

@ -1,5 +1,5 @@
--- ---
title: Interface hilbish.editor title: Module hilbish.editor
description: interactions for Hilbish's line reader description: interactions for Hilbish's line reader
layout: doc layout: doc
menu: menu:
@ -12,19 +12,82 @@ The hilbish.editor interface provides functions to
directly interact with the line editor in use. directly interact with the line editor in use.
## Functions ## Functions
### getLine() -> string |||
|----|----|
|<a href="#editor.getLine">getLine() -> string</a>|Returns the current input line.|
|<a href="#editor.getVimRegister">getVimRegister(register) -> string</a>|Returns the text that is at the register.|
|<a href="#editor.insert">insert(text)</a>|Inserts text into the Hilbish command line.|
|<a href="#editor.getChar">getChar() -> string</a>|Reads a keystroke from the user. This is in a format of something like Ctrl-L.|
|<a href="#editor.setVimRegister">setVimRegister(register, text)</a>|Sets the vim register at `register` to hold the passed text.|
<hr><div id='editor.getLine'>
<h4 class='heading'>
hilbish.editor.getLine() -> string
<a href="#editor.getLine" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
Returns the current input line. Returns the current input line.
#### Parameters
This function has no parameters.
</div>
<hr><div id='editor.getVimRegister'>
<h4 class='heading'>
hilbish.editor.getVimRegister(register) -> string
<a href="#editor.getVimRegister" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
### getVimRegister(register) -> string
Returns the text that is at the register. Returns the text that is at the register.
#### Parameters
`string` **`register`**
### insert(text)
Inserts text into the line.
### getChar() -> string </div>
Reads a keystroke from the user. This is in a format
of something like Ctrl-L.. <hr><div id='editor.insert'>
<h4 class='heading'>
hilbish.editor.insert(text)
<a href="#editor.insert" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
Inserts text into the Hilbish command line.
#### Parameters
`string` **`text`**
</div>
<hr><div id='editor.getChar'>
<h4 class='heading'>
hilbish.editor.getChar() -> string
<a href="#editor.getChar" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
Reads a keystroke from the user. This is in a format of something like Ctrl-L.
#### Parameters
This function has no parameters.
</div>
<hr><div id='editor.setVimRegister'>
<h4 class='heading'>
hilbish.editor.setVimRegister(register, text)
<a href="#editor.setVimRegister" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
### setVimRegister(register, text)
Sets the vim register at `register` to hold the passed text. Sets the vim register at `register` to hold the passed text.
#### Parameters
`string` **`text`**
</div>

View File

@ -1,5 +1,5 @@
--- ---
title: Interface hilbish.history title: Module hilbish.history
description: command history description: command history
layout: doc layout: doc
menu: menu:
@ -13,18 +13,80 @@ This includes the ability to override functions to change the main
method of saving history. method of saving history.
## Functions ## Functions
### add(cmd) |||
|----|----|
|<a href="#history.add">add(cmd)</a>|Adds a command to the history.|
|<a href="#history.all">all() -> table</a>|Retrieves all history as a table.|
|<a href="#history.clear">clear()</a>|Deletes all commands from the history.|
|<a href="#history.get">get(index)</a>|Retrieves a command from the history based on the `index`.|
|<a href="#history.size">size() -> number</a>|Returns the amount of commands in the history.|
<hr><div id='history.add'>
<h4 class='heading'>
hilbish.history.add(cmd)
<a href="#history.add" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
Adds a command to the history. Adds a command to the history.
#### Parameters
`string` **`cmd`**
### all() -> table
Retrieves all history.
### clear() </div>
<hr><div id='history.all'>
<h4 class='heading'>
hilbish.history.all() -> table
<a href="#history.all" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
Retrieves all history as a table.
#### Parameters
This function has no parameters.
</div>
<hr><div id='history.clear'>
<h4 class='heading'>
hilbish.history.clear()
<a href="#history.clear" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
Deletes all commands from the history. Deletes all commands from the history.
#### Parameters
This function has no parameters.
</div>
### get(idx) <hr><div id='history.get'>
Retrieves a command from the history based on the `idx`. <h4 class='heading'>
hilbish.history.get(index)
<a href="#history.get" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
Retrieves a command from the history based on the `index`.
#### Parameters
`number` **`index`**
</div>
<hr><div id='history.size'>
<h4 class='heading'>
hilbish.history.size() -> number
<a href="#history.size" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
### size() -> number
Returns the amount of commands in the history. Returns the amount of commands in the history.
#### Parameters
This function has no parameters.
</div>

View File

@ -1,5 +1,5 @@
--- ---
title: Interface hilbish.jobs title: Module hilbish.jobs
description: background job management description: background job management
layout: doc layout: doc
menu: menu:
@ -15,32 +15,112 @@ Jobs are the name of background tasks/commands. A job can be started via
interactive usage or with the functions defined below for use in external runners. interactive usage or with the functions defined below for use in external runners.
## Functions ## Functions
### add(cmdstr, args, execPath) |||
Adds a new job to the job table. Note that this does not immediately run it. |----|----|
|<a href="#jobs.add">add(cmdstr, args, execPath)</a>|Creates a new job. This function does not run the job. This function is intended to be|
|<a href="#jobs.all">all() -> table[@Job]</a>|Returns a table of all job objects.|
|<a href="#jobs.disown">disown(id)</a>|Disowns a job. This simply deletes it from the list of jobs without stopping it.|
|<a href="#jobs.get">get(id) -> @Job</a>|Get a job object via its ID.|
|<a href="#jobs.last">last() -> @Job</a>|Returns the last added job to the table.|
<hr><div id='jobs.add'>
<h4 class='heading'>
hilbish.jobs.add(cmdstr, args, execPath)
<a href="#jobs.add" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
Creates a new job. This function does not run the job. This function is intended to be
used by runners, but can also be used to create jobs via Lua. Commanders cannot be ran as jobs.
#### Parameters
`string` **`cmdstr`**
String that a user would write for the job
`table` **`args`**
Arguments for the commands. Has to include the name of the command.
`string` **`execPath`**
Binary to use to run the command. Does not
#### Example
```lua
hilbish.jobs.add('go build', {'go', 'build'}, '/usr/bin/go')
````
</div>
<hr><div id='jobs.all'>
<h4 class='heading'>
hilbish.jobs.all() -> table[<a href="/Hilbish/docs/api/hilbish/hilbish.jobs/#job" style="text-decoration: none;" id="lol">Job</a>]
<a href="#jobs.all" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
### all() -> table\<<a href="/Hilbish/docs/api/hilbish/hilbish.jobs/#job" style="text-decoration: none;">Job</a>>
Returns a table of all job objects. Returns a table of all job objects.
#### Parameters
This function has no parameters.
</div>
### disown(id) <hr><div id='jobs.disown'>
Disowns a job. This deletes it from the job table. <h4 class='heading'>
hilbish.jobs.disown(id)
<a href="#jobs.disown" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
Disowns a job. This simply deletes it from the list of jobs without stopping it.
#### Parameters
`number` **`id`**
</div>
<hr><div id='jobs.get'>
<h4 class='heading'>
hilbish.jobs.get(id) -> <a href="/Hilbish/docs/api/hilbish/hilbish.jobs/#job" style="text-decoration: none;" id="lol">Job</a>
<a href="#jobs.get" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
### get(id) -> <a href="/Hilbish/docs/api/hilbish/hilbish.jobs/#job" style="text-decoration: none;">Job</a>
Get a job object via its ID. Get a job object via its ID.
#### Parameters
This function has no parameters.
</div>
### last() -> <a href="/Hilbish/docs/api/hilbish/hilbish.jobs/#job" style="text-decoration: none;">Job</a> <hr><div id='jobs.last'>
Returns the last added job from the table. <h4 class='heading'>
hilbish.jobs.last() -> <a href="/Hilbish/docs/api/hilbish/hilbish.jobs/#job" style="text-decoration: none;" id="lol">Job</a>
<a href="#jobs.last" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
Returns the last added job to the table.
#### Parameters
This function has no parameters.
</div>
## Types ## Types
<hr>
## Job ## Job
The Job type describes a Hilbish job. The Job type describes a Hilbish job.
### Properties ## Object properties
- `cmd`: The user entered command string for the job. |||
- `running`: Whether the job is running or not. |----|----|
- `id`: The ID of the job in the job table |cmd|The user entered command string for the job.|
- `pid`: The Process ID |running|Whether the job is running or not.|
- `exitCode`: The last exit code of the job. |id|The ID of the job in the job table|
- `stdout`: The standard output of the job. This just means the normal logs of the process. |pid|The Process ID|
- `stderr`: The standard error stream of the process. This (usually) includes error messages of the job. |exitCode|The last exit code of the job.|
|stdout|The standard output of the job. This just means the normal logs of the process.|
|stderr|The standard error stream of the process. This (usually) includes error messages of the job.|
### Methods ### Methods
#### background() #### background()

View File

@ -1,5 +1,5 @@
--- ---
title: Interface hilbish.module title: Module hilbish.module
description: native module loading description: native module loading
layout: doc layout: doc
menu: menu:
@ -43,11 +43,29 @@ func Loader(rtm *rt.Runtime) rt.Value {
This can be compiled with `go build -buildmode=plugin plugin.go`. This can be compiled with `go build -buildmode=plugin plugin.go`.
If you attempt to require and print the result (`print(require 'plugin')`), it will show "hello world!" If you attempt to require and print the result (`print(require 'plugin')`), it will show "hello world!"
## Interface fields
- `paths`: A list of paths to search when loading native modules. This is in the style of Lua search paths and will be used when requiring native modules. Example: `?.so;?/?.so`
## Functions ## Functions
### load(path) |||
|----|----|
|<a href="#module.load">load(path)</a>|Loads a module at the designated `path`.|
## Static module fields
|||
|----|----|
|paths|A list of paths to search when loading native modules. This is in the style of Lua search paths and will be used when requiring native modules. Example: `?.so;?/?.so`|
<hr><div id='module.load'>
<h4 class='heading'>
hilbish.module.load(path)
<a href="#module.load" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
Loads a module at the designated `path`. Loads a module at the designated `path`.
It will throw if any error occurs. It will throw if any error occurs.
#### Parameters
`string` **`path`**
</div>

View File

@ -1,6 +1,6 @@
--- ---
title: Interface hilbish.os title: Module hilbish.os
description: OS Info description: operating system info
layout: doc layout: doc
menu: menu:
docs: docs:
@ -8,12 +8,13 @@ menu:
--- ---
## Introduction ## Introduction
The `os` interface provides simple text information properties about Provides simple text information properties about the current operating system.
the current OS on the systen. This mainly includes the name and This mainly includes the name and version.
version.
## Interface fields ## Static module fields
- `family`: Family name of the current OS |||
- `name`: Pretty name of the current OS |----|----|
- `version`: Version of the current OS |family|Family name of the current OS|
|name|Pretty name of the current OS|
|version|Version of the current OS|

View File

@ -1,5 +1,5 @@
--- ---
title: Interface hilbish.runner title: Module hilbish.runner
description: interactive command runner customization description: interactive command runner customization
layout: doc layout: doc
menu: menu:
@ -15,17 +15,59 @@ language or script of their choosing. A good example is using it to
write command in Fennel. write command in Fennel.
## Functions ## Functions
### setMode(cb) |||
This is the same as the `hilbish.runnerMode` function. It takes a callback, |----|----|
which will be used to execute all interactive input. |<a href="#runner.setMode">setMode(cb)</a>|This is the same as the `hilbish.runnerMode` function.|
|<a href="#runner.lua">lua(cmd)</a>|Evaluates `cmd` as Lua input. This is the same as using `dofile`|
|<a href="#runner.sh">sh(cmd)</a>|Runs a command in Hilbish's shell script interpreter.|
<hr><div id='runner.setMode'>
<h4 class='heading'>
hilbish.runner.setMode(cb)
<a href="#runner.setMode" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
This is the same as the `hilbish.runnerMode` function.
It takes a callback, which will be used to execute all interactive input.
In normal cases, neither callbacks should be overrided by the user, In normal cases, neither callbacks should be overrided by the user,
as the higher level functions listed below this will handle it. as the higher level functions listed below this will handle it.
#### Parameters
`function` **`cb`**
</div>
<hr><div id='runner.lua'>
<h4 class='heading'>
hilbish.runner.lua(cmd)
<a href="#runner.lua" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
### lua(cmd)
Evaluates `cmd` as Lua input. This is the same as using `dofile` Evaluates `cmd` as Lua input. This is the same as using `dofile`
or `load`, but is appropriated for the runner interface. or `load`, but is appropriated for the runner interface.
#### Parameters
`string` **`cmd`**
</div>
<hr><div id='runner.sh'>
<h4 class='heading'>
hilbish.runner.sh(cmd)
<a href="#runner.sh" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
### sh(cmd)
Runs a command in Hilbish's shell script interpreter. Runs a command in Hilbish's shell script interpreter.
This is the equivalent of using `source`. This is the equivalent of using `source`.
#### Parameters
`string` **`cmd`**
</div>

View File

@ -1,5 +1,5 @@
--- ---
title: Interface hilbish.timers title: Module hilbish.timers
description: timeout and interval API description: timeout and interval API
layout: doc layout: doc
menu: menu:
@ -14,14 +14,10 @@ a few seconds, you don't have to rely on timing tricks, as Hilbish has a
timer API to set intervals and timeouts. timer API to set intervals and timeouts.
These are the simple functions `hilbish.interval` and `hilbish.timeout` (doc These are the simple functions `hilbish.interval` and `hilbish.timeout` (doc
accessible with `doc hilbish`). But if you want slightly more control over accessible with `doc hilbish`, or `Module hilbish` on the Website).
them, there is the `hilbish.timers` interface. It allows you to get
a timer via ID and control them.
All functions documented with the `Timer` type refer to a Timer object.
An example of usage: An example of usage:
``` ```lua
local t = hilbish.timers.create(hilbish.timers.TIMEOUT, 5000, function() local t = hilbish.timers.create(hilbish.timers.TIMEOUT, 5000, function()
print 'hello!' print 'hello!'
end) end)
@ -30,25 +26,66 @@ t:start()
print(t.running) // true print(t.running) // true
``` ```
## Interface fields
- `INTERVAL`: Constant for an interval timer type
- `TIMEOUT`: Constant for a timeout timer type
## Functions ## Functions
### create(type, time, callback) -> <a href="/Hilbish/docs/api/hilbish/hilbish.timers/#timer" style="text-decoration: none;">Timer</a> |||
Creates a timer that runs based on the specified `time` in milliseconds. |----|----|
The `type` can either be `hilbish.timers.INTERVAL` or `hilbish.timers.TIMEOUT` |<a href="#timers.create">create(type, time, callback) -> @Timer</a>|Creates a timer that runs based on the specified `time`.|
|<a href="#timers.get">get(id) -> @Timer</a>|Retrieves a timer via its ID.|
## Static module fields
|||
|----|----|
|INTERVAL|Constant for an interval timer type|
|TIMEOUT|Constant for a timeout timer type|
<hr><div id='timers.create'>
<h4 class='heading'>
hilbish.timers.create(type, time, callback) -> <a href="/Hilbish/docs/api/hilbish/hilbish.timers/#timer" style="text-decoration: none;" id="lol">Timer</a>
<a href="#timers.create" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
Creates a timer that runs based on the specified `time`.
#### Parameters
`number` **`type`**
What kind of timer to create, can either be `hilbish.timers.INTERVAL` or `hilbish.timers.TIMEOUT`
`number` **`time`**
The amount of time the function should run in milliseconds.
`function` **`callback`**
The function to run for the timer.
</div>
<hr><div id='timers.get'>
<h4 class='heading'>
hilbish.timers.get(id) -> <a href="/Hilbish/docs/api/hilbish/hilbish.timers/#timer" style="text-decoration: none;" id="lol">Timer</a>
<a href="#timers.get" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
### get(id) -> <a href="/Hilbish/docs/api/hilbish/hilbish.timers/#timer" style="text-decoration: none;">Timer</a>
Retrieves a timer via its ID. Retrieves a timer via its ID.
#### Parameters
`number` **`id`**
</div>
## Types ## Types
<hr>
## Timer ## Timer
The Job type describes a Hilbish timer. The Job type describes a Hilbish timer.
### Properties ## Object properties
- `type`: What type of timer it is |||
- `running`: If the timer is running |----|----|
- `duration`: The duration in milliseconds that the timer will run |type|What type of timer it is|
|running|If the timer is running|
|duration|The duration in milliseconds that the timer will run|
### Methods ### Methods
#### start() #### start()

View File

@ -1,5 +1,5 @@
--- ---
title: Interface hilbish.userDir title: Module hilbish.userDir
description: user-related directories description: user-related directories
layout: doc layout: doc
menu: menu:
@ -12,7 +12,9 @@ This interface just contains properties to know about certain user directories.
It is equivalent to XDG on Linux and gets the user's preferred directories It is equivalent to XDG on Linux and gets the user's preferred directories
for configs and data. for configs and data.
## Interface fields ## Static module fields
- `config`: The user's config directory |||
- `data`: The user's directory for program data |----|----|
|config|The user's config directory|
|data|The user's directory for program data|

View File

@ -11,16 +11,63 @@ menu:
The terminal library is a simple and lower level library for certain terminal interactions. The terminal library is a simple and lower level library for certain terminal interactions.
## Functions ## Functions
### restoreState() |||
|----|----|
|<a href="#restoreState">restoreState()</a>|Restores the last saved state of the terminal|
|<a href="#saveState">saveState()</a>|Saves the current state of the terminal.|
|<a href="#setRaw">setRaw()</a>|Puts the terminal into raw mode.|
|<a href="#size">size()</a>|Gets the dimensions of the terminal. Returns a table with `width` and `height`|
<hr><div id='restoreState'>
<h4 class='heading'>
terminal.restoreState()
<a href="#restoreState" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
Restores the last saved state of the terminal Restores the last saved state of the terminal
#### Parameters
This function has no parameters.
</div>
### saveState() <hr><div id='saveState'>
Saves the current state of the terminal <h4 class='heading'>
terminal.saveState()
<a href="#saveState" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
### setRaw() Saves the current state of the terminal.
Puts the terminal in raw mode #### Parameters
This function has no parameters.
</div>
<hr><div id='setRaw'>
<h4 class='heading'>
terminal.setRaw()
<a href="#setRaw" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
Puts the terminal into raw mode.
#### Parameters
This function has no parameters.
</div>
<hr><div id='size'>
<h4 class='heading'>
terminal.size()
<a href="#size" class='heading-link'>
<i class="fas fa-paperclip"></i>
</a>
</h4>
### size()
Gets the dimensions of the terminal. Returns a table with `width` and `height` Gets the dimensions of the terminal. Returns a table with `width` and `height`
Note: this is not the size in relation to the dimensions of the display NOTE: The size refers to the amount of columns and rows of text that can fit in the terminal.
#### Parameters
This function has no parameters.
</div>

View File

@ -1,3 +1,12 @@
---
title: Completions
description: Tab completion for commands.
layout: doc
menu:
docs:
parent: "Features"
---
Hilbish has a pretty good completion system. It has a nice looking Hilbish has a pretty good completion system. It has a nice looking
menu, with 2 types of menus: grid (like file completions) or menu, with 2 types of menus: grid (like file completions) or
list. list.

View File

@ -15,11 +15,12 @@ It compiles for Windows (CI ensures it does), but otherwise it is not
directly supported. If you'd like to improve this situation, directly supported. If you'd like to improve this situation,
checkout [the discussion](https://github.com/Rosettea/Hilbish/discussions/165). checkout [the discussion](https://github.com/Rosettea/Hilbish/discussions/165).
# Where is the API documentation?
The builtin `doc` command supplies all documentation of Hilbish provided
APIs. You can also check the sidebar.
# Why? # Why?
Hilbish emerged from the desire of a Lua configured shell. Hilbish emerged from the desire of a Lua configured shell.
It was the initial reason that it was created, but now it's more: It was the initial reason that it was created, but now it's more:
to be hyper extensible, simpler and more user friendly. to be hyper extensible, simpler and more user friendly.
# Does it have "autocompletion" or "tab completion"
Of course! This is a modern shell. Hilbish provides a way for users
to write tab completion for any command and/or the whole shell.
Inline hinting and syntax highlighting are also available.

View File

@ -1,13 +1,11 @@
Here is a list of bait hooks that are thrown by Hilbish. If a hook is related ---
to a command, it will have the `command` scope, as example. title: Hooks
description:
layout: doc
weight: -50
menu:
docs
---
Here is the format for a doc for a hook: Hooks are Hilbish's versions of events, which are used via the [Bait](../api/bait) module.
+ <hook name> -> <args> > <description> For more detail on how to act on these hooks, you may check the Bait page.
`<args>` just means the arguments of the hook. If a hook doc has the format
of `arg...`, it means the hook can take/recieve any number of `arg`.
+ error -> eventName, handler, err > Emitted when there is an error in
an event handler. The `eventName` is the name of the event the handler
is for, the `handler` is the callback function, and `err` is the error
message.

View File

@ -1,12 +1,21 @@
+ `command.preexec` -> input, cmdStr > Thrown before a command ---
title: Command
description:
layout: doc
menu:
docs:
parent: "Hooks"
---
- `command.preexec` -> input, cmdStr > Thrown before a command
is executed. The `input` is the user written command, while `cmdStr` is executed. The `input` is the user written command, while `cmdStr`
is what will be executed (`input` will have aliases while `cmdStr` is what will be executed (`input` will have aliases while `cmdStr`
will have alias resolved input). will have alias resolved input).
+ `command.exit` -> code, cmdStr > Thrown when a command exits. - `command.exit` -> code, cmdStr > Thrown when a command exits.
`code` is the exit code of the command, and `cmdStr` is the command that was run. `code` is the exit code of the command, and `cmdStr` is the command that was run.
+ `command.not-found` -> cmdStr > Thrown when a command is not found. - `command.not-found` -> cmdStr > Thrown when a command is not found.
+ `command.not-executable` -> cmdStr > Thrown when Hilbish attempts to run a file - `command.not-executable` -> cmdStr > Thrown when Hilbish attempts to run a file
that is not executable. that is not executable.

View File

@ -1,3 +1,12 @@
---
title: Hilbish
description:
layout: doc
menu:
docs:
parent: "Hooks"
---
+ `hilbish.exit` > Sent when Hilbish is about to exit. + `hilbish.exit` > Sent when Hilbish is about to exit.
+ `hilbish.vimMode` -> modeName > Sent when Hilbish's Vim mode is changed (example insert to normal mode), + `hilbish.vimMode` -> modeName > Sent when Hilbish's Vim mode is changed (example insert to normal mode),

View File

@ -1,3 +1,12 @@
---
title: Signal
description:
layout: doc
menu:
docs:
parent: "Hooks"
---
+ `signal.sigint` > Sent when Hilbish receives SIGINT (on Ctrl-C). + `signal.sigint` > Sent when Hilbish receives SIGINT (on Ctrl-C).
+ `signal.resize` > Sent when the terminal is resized. + `signal.resize` > Sent when the terminal is resized.

View File

@ -1,3 +1,12 @@
---
title: Jobs
description: Controls for background commands in Hilbish.
layout: doc
menu:
docs:
parent: "Features"
---
Hilbish has pretty standard job control. It's missing one or two things, Hilbish has pretty standard job control. It's missing one or two things,
but works well. One thing which is different from other shells but works well. One thing which is different from other shells
(besides Hilbish) itself is the API for jobs, and of course it's in Lua. (besides Hilbish) itself is the API for jobs, and of course it's in Lua.

View File

@ -1,3 +1,10 @@
---
title: Lunacolors
layout: doc
weight: -60
menu: docs
---
Lunacolors is an ANSI color/styling library for Lua. It is included Lunacolors is an ANSI color/styling library for Lua. It is included
by default in standard Hilbish distributions to provide easy styling by default in standard Hilbish distributions to provide easy styling
for things like prompts and text. for things like prompts and text.

View File

@ -1,3 +1,10 @@
---
title: Nature
layout: doc
weight: -90
menu: docs
---
A bit after creation, we have the outside nature. Little plants, seeds, A bit after creation, we have the outside nature. Little plants, seeds,
growing to their final phase: a full plant. A lot of Hilbish itself is growing to their final phase: a full plant. A lot of Hilbish itself is
written in Go, but there are parts made in Lua, being most builtins written in Go, but there are parts made in Lua, being most builtins

View File

@ -1,7 +1,15 @@
Hilbish is *unique,* when interactive it first attempts to run input as Hilbish allows you to change how interactive text can be interpreted.
Lua and then tries shell script. But if you're normal, you wouldn't This is mainly due to the fact that the default method Hilbish uses
really be using Hilbish anyway but you'd also not want this is that it runs Lua first and then falls back to shell script.
(or maybe want Lua only in some cases.)
In some cases, someone might want to switch to just shell script to avoid
it while interactive but still have a Lua config, or go full Lua to use
Hilbish as a REPL. This also allows users to add alternative languages like
Fennel as the interactive script runner.
Runner mode can also be used to handle specific kinds of input before
evaluating like normal, which is how [Link.hsh](https://github.com/TorchedSammy/Link.hsh)
handles links.
The "runner mode" of Hilbish is customizable via `hilbish.runnerMode`, The "runner mode" of Hilbish is customizable via `hilbish.runnerMode`,
which determines how Hilbish will run user input. By default, this is which determines how Hilbish will run user input. By default, this is
@ -27,12 +35,20 @@ hilbish.runnerMode(function(input)
end) end)
The `hilbish.runner` interface is an alternative to using `hilbish.runnerMode` The `hilbish.runner` interface is an alternative to using `hilbish.runnerMode`
and also provides the sh and Lua runner functions that Hilbish itself uses. and also provides the shell script and Lua runner functions that Hilbish itself uses.
A runner function is expected to return 3 values: the input, exit code, and an error.
The input return is there incase you need to prompt for more input. A runner function is expected to return a table with the following values:
If you don't, just return the input passed to the runner function. - `exitCode` (number): Exit code of the command
The exit code has to be a number, it will be 0 otherwise and the error can be - `input` (string): The text input of the user. This is used by Hilbish to append extra input, in case
`nil` to indicate no error. more is requested.
- `err` (string): A string that represents an error from the runner.
This should only be set when, for example, there is a syntax error.
It can be set to a few special values for Hilbish to throw the right
hooks and have a better looking message.
- `<command>: not-found` will throw a `command.not-found` hook
based on what `<command>` is.
- `<command>: not-executable` will throw a `command.not-executable` hook.
- `continue` (boolean): Whether Hilbish should prompt the user for no input
## Functions ## Functions
These are the "low level" functions for the `hilbish.runner` interface. These are the "low level" functions for the `hilbish.runner` interface.
@ -41,21 +57,6 @@ These are the "low level" functions for the `hilbish.runner` interface.
+ sh(input) -> table > Runs `input` in Hilbish's sh interpreter + sh(input) -> table > Runs `input` in Hilbish's sh interpreter
+ lua(input) -> table > Evals `input` as Lua code + lua(input) -> table > Evals `input` as Lua code
The table value that runners return can have at least 4 values:
+ input (string): The full input text.
+ exitCode (number): Exit code (usually from a command)
+ continue (boolean): Whether to prompt the user for more input
(in the case of incomplete syntax)
+ err (string): A string that represents an error from the runner.
This should only be set when, for example, there is a syntax error.
It can be set to a few special values for Hilbish to throw the right
hooks and have a better looking message.
+ `<command>: not-found` will throw a `command.not-found` hook
based on what `<command>` is.
+ `<command>: not-executable` will throw a `command.not-executable` hook.
The others here are defined in Lua and have EmmyLua documentation.
These functions should be preferred over the previous ones. These functions should be preferred over the previous ones.
+ setCurrent(mode) > The same as `setMode`, but works with runners managed + setCurrent(mode) > The same as `setMode`, but works with runners managed
via the functions below. via the functions below.

View File

@ -1,3 +1,10 @@
---
title: Vim Mode
layout: doc
weight: -90
menu: docs
---
Hilbish has a Vim binding input mode accessible for use. Hilbish has a Vim binding input mode accessible for use.
It can be enabled with the `hilbish.inputMode` function (check `doc hilbish`). It can be enabled with the `hilbish.inputMode` function (check `doc hilbish`).

View File

@ -1,3 +1,12 @@
---
title: Actions
layout: doc
weight: -80
menu:
docs:
parent: "Vim Mode"
---
Vim actions are essentially just when a user uses a Vim keybind. Vim actions are essentially just when a user uses a Vim keybind.
Things like yanking and pasting are Vim actions. Things like yanking and pasting are Vim actions.
This is not an "offical Vim thing," just a Hilbish thing. This is not an "offical Vim thing," just a Hilbish thing.

View File

@ -27,7 +27,8 @@ func editorLoader(rtm *rt.Runtime) *rt.Table {
// #interface editor // #interface editor
// insert(text) // insert(text)
// Inserts text into the line. // Inserts text into the Hilbish command line.
// #param text string
func editorInsert(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { func editorInsert(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err := c.Check1Arg(); err != nil { if err := c.Check1Arg(); err != nil {
return nil, err return nil, err
@ -46,8 +47,8 @@ func editorInsert(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
// #interface editor // #interface editor
// setVimRegister(register, text) // setVimRegister(register, text)
// Sets the vim register at `register` to hold the passed text. // Sets the vim register at `register` to hold the passed text.
// --- @param register string // #aram register string
// --- @param text string // #param text string
func editorSetRegister(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { func editorSetRegister(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err := c.Check1Arg(); err != nil { if err := c.Check1Arg(); err != nil {
return nil, err return nil, err
@ -71,7 +72,7 @@ func editorSetRegister(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
// #interface editor // #interface editor
// getVimRegister(register) -> string // getVimRegister(register) -> string
// Returns the text that is at the register. // Returns the text that is at the register.
// --- @param register string // #param register string
func editorGetRegister(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { func editorGetRegister(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err := c.Check1Arg(); err != nil { if err := c.Check1Arg(); err != nil {
return nil, err return nil, err
@ -90,6 +91,7 @@ func editorGetRegister(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
// #interface editor // #interface editor
// getLine() -> string // getLine() -> string
// Returns the current input line. // Returns the current input line.
// #returns string
func editorGetLine(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { func editorGetLine(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
buf := lr.rl.GetLine() buf := lr.rl.GetLine()
@ -98,8 +100,7 @@ func editorGetLine(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
// #interface editor // #interface editor
// getChar() -> string // getChar() -> string
// Reads a keystroke from the user. This is in a format // Reads a keystroke from the user. This is in a format of something like Ctrl-L.
// of something like Ctrl-L..
func editorReadChar(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { func editorReadChar(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
buf := lr.rl.ReadChar() buf := lr.rl.ReadChar()

View File

@ -2,31 +2,27 @@
local bait = {} local bait = {}
--- Catches a hook with `name`. Runs the `cb` when it is thrown --- Catches an event. This function can be used to act on events.
--- @param name string ---
--- @param cb function ---
function bait.catch(name, cb) end function bait.catch(name, cb) end
--- Same as catch, but only runs the `cb` once and then removes the hook --- Catches an event, but only once. This will remove the hook immediately after it runs for the first time.
--- @param name string
--- @param cb function
function bait.catchOnce(name, cb) end function bait.catchOnce(name, cb) end
--- Returns a table with hooks (callback functions) on the event with `name`. --- Returns a list of callbacks that are hooked on an event with the corresponding `name`.
--- @param name string
--- @returns table<function>
function bait.hooks(name) end function bait.hooks(name) end
--- Removes the `catcher` for the event with `name`. --- Removes the `catcher` for the event with `name`.
--- For this to work, `catcher` has to be the same function used to catch --- For this to work, `catcher` has to be the same function used to catch
--- an event, like one saved to a variable. --- an event, like one saved to a variable.
--- @param name string ---
--- @param catcher function ---
function bait.release(name, catcher) end function bait.release(name, catcher) end
--- Throws a hook with `name` with the provided `args` --- Throws a hook with `name` with the provided `args`.
--- @param name string ---
--- @vararg any ---
function bait.throw(name, ...args) end function bait.throw(name, ...args) end
return bait return bait

View File

@ -2,13 +2,13 @@
local commander = {} local commander = {}
--- Deregisters any command registered with `name` --- Removes the named command. Note that this will only remove Commander-registered commands.
--- @param name string
function commander.deregister(name) end function commander.deregister(name) end
--- Register a command with `name` that runs `cb` when ran --- Adds a new command with the given `name`. When Hilbish has to run a command with a name,
--- @param name string --- it will run the function providing the arguments and sinks.
--- @param cb function ---
---
function commander.register(name, cb) end function commander.register(name, cb) end
return commander return commander

View File

@ -2,56 +2,51 @@
local fs = {} local fs = {}
--- Gives an absolute version of `path`. --- Returns an absolute version of the `path`.
--- @param path string --- This can be used to resolve short paths like `..` to `/home/user`.
--- @returns string
function fs.abs(path) end function fs.abs(path) end
--- Gives the basename of `path`. For the rules, --- Returns the "basename," or the last part of the provided `path`. If path is empty,
--- see Go's filepath.Base --- `.` will be returned.
--- @returns string
function fs.basename(path) end function fs.basename(path) end
--- Changes directory to `dir` --- Changes Hilbish's directory to `dir`.
--- @param dir string
function fs.cd(dir) end function fs.cd(dir) end
--- Returns the directory part of `path`. For the rules, see Go's --- Returns the directory part of `path`. If a file path like
--- filepath.Dir --- `~/Documents/doc.txt` then this function will return `~/Documents`.
--- @param path string
--- @returns string
function fs.dir(path) end function fs.dir(path) end
--- Glob all files and directories that match the pattern. --- Match all files based on the provided `pattern`.
--- For the rules, see Go's filepath.Glob --- For the syntax' refer to Go's filepath.Match function: https://pkg.go.dev/path/filepath#Match
--- @param pattern string ---
--- @returns table ---
function fs.glob(pattern) end function fs.glob(pattern) end
--- Takes paths and joins them together with the OS's --- Takes any list of paths and joins them based on the operating system's path separator.
--- directory separator (forward or backward slash). ---
--- @vararg string ---
--- @returns string function fs.join(...path) end
function fs.join(...) end
--- Makes a directory called `name`. If `recursive` is true, it will create its parent directories. --- Creates a new directory with the provided `name`.
--- @param name string --- With `recursive`, mkdir will create parent directories.
--- @param recursive boolean ---
--- -- This will create the directory foo, then create the directory bar in the
--- -- foo directory. If recursive is false in this case, it will fail.
--- fs.mkdir('./foo/bar', true)
function fs.mkdir(name, recursive) end function fs.mkdir(name, recursive) end
--- Returns a table of files in `dir`. --- Returns a list of all files and directories in the provided path.
--- @param dir string function fs.readdir(path) end
--- @return table
function fs.readdir(dir) end
--- Returns a table of info about the `path`. --- Returns the information about a given `path`.
--- It contains the following keys: --- The returned table contains the following values:
--- name (string) - Name of the path --- name (string) - Name of the path
--- size (number) - Size of the path --- size (number) - Size of the path in bytes
--- mode (string) - Permission mode in an octal format string (with leading 0) --- mode (string) - Unix permission mode in an octal format string (with leading 0)
--- isDir (boolean) - If the path is a directory --- isDir (boolean) - If the path is a directory
--- @param path string ---
--- @returns table ---
function fs.stat(path) end function fs.stat(path) end
return fs return fs

View File

@ -2,96 +2,89 @@
local hilbish = {} local hilbish = {}
--- This is an alias (ha) for the `hilbish.alias` function. --- This is an alias (ha) for the [hilbish.alias](../#alias) function.
--- @param alias string --- @param alias string
--- @param cmd string --- @param cmd string
function hilbish.aliases.add(alias, cmd) end function hilbish.aliases.add(alias, cmd) end
--- This is the same as the `hilbish.runnerMode` function. It takes a callback, --- This is the same as the `hilbish.runnerMode` function.
--- which will be used to execute all interactive input. --- It takes a callback, which will be used to execute all interactive input.
--- In normal cases, neither callbacks should be overrided by the user, --- In normal cases, neither callbacks should be overrided by the user,
--- as the higher level functions listed below this will handle it. --- as the higher level functions listed below this will handle it.
--- @param cb function
function hilbish.runner.setMode(cb) end function hilbish.runner.setMode(cb) end
--- Calls a completer function. This is mainly used to call
--- a command completer, which will have a `name` in the form
--- of `command.name`, example: `command.git`.
--- You can check `doc completions` for info on the `completionGroups` return value.
--- @param name string
--- @param query string
--- @param ctx string
--- @param fields table
function hilbish.completion.call(name, query, ctx, fields) end
--- The handler function is the callback for tab completion in Hilbish.
--- You can check the completions doc for more info.
--- @param line string
--- @param pos string
function hilbish.completion.handler(line, pos) end
--- Returns the current input line. --- Returns the current input line.
function hilbish.editor.getLine() end function hilbish.editor.getLine() end
--- Returns the text that is at the register. --- Returns the text that is at the register.
--- @param register string
function hilbish.editor.getVimRegister(register) end function hilbish.editor.getVimRegister(register) end
--- Inserts text into the line. --- Inserts text into the Hilbish command line.
function hilbish.editor.insert(text) end function hilbish.editor.insert(text) end
--- Reads a keystroke from the user. This is in a format --- Reads a keystroke from the user. This is in a format of something like Ctrl-L.
--- of something like Ctrl-L..
function hilbish.editor.getChar() end function hilbish.editor.getChar() end
--- Sets the vim register at `register` to hold the passed text. --- Sets the vim register at `register` to hold the passed text.
--- @param register string
--- @param text string
function hilbish.editor.setVimRegister(register, text) end function hilbish.editor.setVimRegister(register, text) end
--- Sets an alias of `cmd` to `orig` --- Return binaries/executables based on the provided parameters.
--- @param cmd string --- This function is meant to be used as a helper in a command completion handler.
--- @param orig string ---
---
function hilbish.completion.bins(query, ctx, fields) end
--- Calls a completer function. This is mainly used to call a command completer, which will have a `name`
--- in the form of `command.name`, example: `command.git`.
--- You can check the Completions doc or `doc completions` for info on the `completionGroups` return value.
function hilbish.completion.call(name, query, ctx, fields) end
--- Returns file matches based on the provided parameters.
--- This function is meant to be used as a helper in a command completion handler.
function hilbish.completion.files(query, ctx, fields) end
--- This function contains the general completion handler for Hilbish. This function handles
--- completion of everything, which includes calling other command handlers, binaries, and files.
--- This function can be overriden to supply a custom handler. Note that alias resolution is required to be done in this function.
---
---
function hilbish.completion.handler(line, pos) end
--- Sets an alias, with a name of `cmd` to another command.
---
---
function hilbish.alias(cmd, orig) end function hilbish.alias(cmd, orig) end
--- Appends `dir` to $PATH --- Appends the provided dir to the command path (`$PATH`)
--- @param dir string|table ---
---
function hilbish.appendPath(dir) end function hilbish.appendPath(dir) end
--- Registers a completion handler for `scope`. --- Registers a completion handler for the specified scope.
--- A `scope` is currently only expected to be `command.<cmd>`, --- A `scope` is currently only expected to be `command.<cmd>`,
--- replacing <cmd> with the name of the command (for example `command.git`). --- replacing <cmd> with the name of the command (for example `command.git`).
--- `cb` must be a function that returns a table of "completion groups." --- The documentation for completions, under Features/Completions or `doc completions`
--- Check `doc completions` for more information. --- provides more details.
--- @param scope string
--- @param cb function
function hilbish.complete(scope, cb) end function hilbish.complete(scope, cb) end
--- Returns the current directory of the shell --- Returns the current directory of the shell
--- @returns string
function hilbish.cwd() end function hilbish.cwd() end
--- Replaces running hilbish with `cmd` --- Replaces the currently running Hilbish instance with the supplied command.
--- @param cmd string --- This can be used to do an in-place restart.
function hilbish.exec(cmd) end function hilbish.exec(cmd) end
--- Puts `fn` in a goroutine --- Puts `fn` in a Goroutine.
--- @param fn function --- This can be used to run any function in another thread.
--- **NOTE: THIS FUNCTION MAY CRASH HILBISH IF OUTSIDE VARIABLES ARE ACCESSED.**
function hilbish.goro(fn) end function hilbish.goro(fn) end
--- Line highlighter handler. This is mainly for syntax highlighting, but in --- Line highlighter handler.
--- reality could set the input of the prompt to *display* anything. The --- This is mainly for syntax highlighting, but in reality could set the input
--- callback is passed the current line and is expected to return a line that --- of the prompt to *display* anything. The callback is passed the current line
--- will be used as the input display. --- and is expected to return a line that will be used as the input display.
--- Note that to set a highlighter, one has to override this function. --- Note that to set a highlighter, one has to override this function.
--- Example: ---
--- ```
--- function hilbish.highlighter(line)
--- return line:gsub('"%w+"', function(c) return lunacolors.green(c) end)
--- end
--- ```
--- This code will highlight all double quoted strings in green.
--- @param line string
function hilbish.highlighter(line) end function hilbish.highlighter(line) end
--- The command line hint handler. It gets called on every key insert to --- The command line hint handler. It gets called on every key insert to
@ -99,52 +92,43 @@ function hilbish.highlighter(line) end
--- line and cursor position. It is expected to return a string which is used --- line and cursor position. It is expected to return a string which is used
--- as the text for the hint. This is by default a shim. To set hints, --- as the text for the hint. This is by default a shim. To set hints,
--- override this function with your custom handler. --- override this function with your custom handler.
--- @param line string ---
--- @param pos number ---
function hilbish.hinter(line, pos) end function hilbish.hinter(line, pos) end
--- Sets the input mode for Hilbish's line reader. Accepts either emacs or vim --- Sets the input mode for Hilbish's line reader. Accepts either emacs or vim.
--- @param mode string --- `emacs` is the default. Setting it to `vim` changes behavior of input to be
--- Vim-like with modes and Vim keybinds.
function hilbish.inputMode(mode) end function hilbish.inputMode(mode) end
--- Runs the `cb` function every `time` milliseconds. --- Runs the `cb` function every `time` milliseconds.
--- This creates a timer that starts immediately. --- This creates a timer that starts immediately.
--- @param cb function
--- @param time number
--- @return Timer
function hilbish.interval(cb, time) end function hilbish.interval(cb, time) end
--- Changes the continued line prompt to `str` --- Changes the text prompt when Hilbish asks for more input.
--- @param str string --- This will show up when text is incomplete, like a missing quote
---
---
function hilbish.multiprompt(str) end function hilbish.multiprompt(str) end
--- Prepends `dir` to $PATH --- Prepends `dir` to $PATH.
--- @param dir string
function hilbish.prependPath(dir) end function hilbish.prependPath(dir) end
--- Changes the shell prompt to `str` --- Changes the shell prompt to the provided string.
--- 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.
--- These will be formatted and replaced with the appropriate values. --- These will be formatted and replaced with the appropriate values.
--- `%d` - Current working directory --- `%d` - Current working directory
--- `%u` - Name of current user --- `%u` - Name of current user
--- `%h` - Hostname of device --- `%h` - Hostname of device
--- @param str string ---
--- @param typ? string Type of prompt, being left or right. Left by default.
function hilbish.prompt(str, typ) end function hilbish.prompt(str, typ) end
--- Read input from the user, using Hilbish's line editor/input reader. --- Read input from the user, using Hilbish's line editor/input reader.
--- This is a separate instance from the one Hilbish actually uses. --- This is a separate instance from the one Hilbish actually uses.
--- Returns `input`, will be nil if ctrl + d is pressed, or an error occurs (which shouldn't happen) --- Returns `input`, will be nil if ctrl + d is pressed, or an error occurs (which shouldn't happen).
--- @param prompt? string
--- @returns string|nil
function hilbish.read(prompt) end function hilbish.read(prompt) end
--- Runs `cmd` in Hilbish's sh interpreter. --- Runs `cmd` in Hilbish's shell script interpreter.
--- If returnOut is true, the outputs of `cmd` will be returned as the 2nd and
--- 3rd values instead of being outputted to the terminal.
--- @param cmd string
--- @param returnOut boolean
--- @returns number, string, string
function hilbish.run(cmd, returnOut) end function hilbish.run(cmd, returnOut) end
--- Sets the execution/runner mode for interactive Hilbish. This determines whether --- Sets the execution/runner mode for interactive Hilbish. This determines whether
@ -152,44 +136,25 @@ function hilbish.run(cmd, returnOut) end
--- Accepted values for mode are hybrid (the default), hybridRev (sh first then Lua), --- Accepted values for mode are hybrid (the default), hybridRev (sh first then Lua),
--- sh, and lua. It also accepts a function, to which if it is passed one --- sh, and lua. It also accepts a function, to which if it is passed one
--- will call it to execute user input instead. --- will call it to execute user input instead.
--- @param mode string|function
function hilbish.runnerMode(mode) end function hilbish.runnerMode(mode) end
--- Runs the `cb` function after `time` in milliseconds. --- Runs the `cb` function after `time` in milliseconds.
--- This creates a timer that starts immediately. --- This creates a Timer that starts immediately.
--- @param cb function
--- @param time number
--- @returns Timer
function hilbish.timeout(cb, time) end function hilbish.timeout(cb, time) end
--- Checks if `name` is a valid command. --- Checks if `name` is a valid command.
--- Will return the path of the binary, or a basename if it's a commander. --- Will return the path of the binary, or a basename if it's a commander.
--- @param name string
--- @returns string
function hilbish.which(name) end function hilbish.which(name) end
--- Puts a job in the background. This acts the same as initially running a job. --- Puts a job in the background. This acts the same as initially running a job.
function hilbish.jobs:background() end function hilbish.jobs:background() end
--- Returns binary/executale completion candidates based on the provided query.
--- @param query string
--- @param ctx string
--- @param fields table
function hilbish.completion.bins(query, ctx, fields) end
--- Returns file completion candidates based on the provided query.
--- @param query string
--- @param ctx string
--- @param fields table
function hilbish.completion.files(query, ctx, fields) end
--- Puts a job in the foreground. This will cause it to run like it was --- Puts a job in the foreground. This will cause it to run like it was
--- executed normally and wait for it to complete. --- executed normally and wait for it to complete.
function hilbish.jobs:foreground() end function hilbish.jobs:foreground() end
--- Evaluates `cmd` as Lua input. This is the same as using `dofile` --- Evaluates `cmd` as Lua input. This is the same as using `dofile`
--- or `load`, but is appropriated for the runner interface. --- or `load`, but is appropriated for the runner interface.
--- @param cmd string
function hilbish.runner.lua(cmd) end function hilbish.runner.lua(cmd) end
--- Sets/toggles the option of automatically flushing output. --- Sets/toggles the option of automatically flushing output.
@ -226,7 +191,6 @@ function hilbish.module.load(path) end
--- Runs a command in Hilbish's shell script interpreter. --- Runs a command in Hilbish's shell script interpreter.
--- This is the equivalent of using `source`. --- This is the equivalent of using `source`.
--- @param cmd string
function hilbish.runner.sh(cmd) end function hilbish.runner.sh(cmd) end
--- Starts a timer. --- Starts a timer.
@ -236,30 +200,26 @@ function hilbish.timers:start() end
function hilbish.timers:stop() end function hilbish.timers:stop() end
--- Removes an alias. --- Removes an alias.
--- @param name string
function hilbish.aliases.delete(name) end function hilbish.aliases.delete(name) end
--- Get a table of all aliases, with string keys as the alias and the value as the command. --- Get a table of all aliases, with string keys as the alias and the value as the command.
--- @returns table<string, string> ---
---
function hilbish.aliases.list() end function hilbish.aliases.list() end
--- Tries to resolve an alias to its command. --- Resolves an alias to its original command. Will thrown an error if the alias doesn't exist.
--- @param alias string
--- @returns string
function hilbish.aliases.resolve(alias) end function hilbish.aliases.resolve(alias) end
--- Adds a new job to the job table. Note that this does not immediately run it. --- Creates a new job. This function does not run the job. This function is intended to be
--- @param cmdstr string --- used by runners, but can also be used to create jobs via Lua. Commanders cannot be ran as jobs.
--- @param args table ---
--- @param execPath string ---
function hilbish.jobs.add(cmdstr, args, execPath) end function hilbish.jobs.add(cmdstr, args, execPath) end
--- Returns a table of all job objects. --- Returns a table of all job objects.
--- @returns table<Job>
function hilbish.jobs.all() end function hilbish.jobs.all() end
--- Disowns a job. This deletes it from the job table. --- Disowns a job. This simply deletes it from the list of jobs without stopping it.
--- @param id number
function hilbish.jobs.disown(id) end function hilbish.jobs.disown(id) end
--- Get a job object via its ID. --- Get a job object via its ID.
@ -267,39 +227,28 @@ function hilbish.jobs.disown(id) end
--- @returns Job --- @returns Job
function hilbish.jobs.get(id) end function hilbish.jobs.get(id) end
--- Returns the last added job from the table. --- Returns the last added job to the table.
--- @returns Job
function hilbish.jobs.last() end function hilbish.jobs.last() end
--- Adds a command to the history. --- Adds a command to the history.
--- @param cmd string
function hilbish.history.add(cmd) end function hilbish.history.add(cmd) end
--- Retrieves all history. --- Retrieves all history as a table.
--- @returns table
function hilbish.history.all() end function hilbish.history.all() end
--- Deletes all commands from the history. --- Deletes all commands from the history.
function hilbish.history.clear() end function hilbish.history.clear() end
--- Retrieves a command from the history based on the `idx`. --- Retrieves a command from the history based on the `index`.
--- @param idx number function hilbish.history.get(index) end
function hilbish.history.get(idx) end
--- Returns the amount of commands in the history. --- Returns the amount of commands in the history.
--- @returns number
function hilbish.history.size() end function hilbish.history.size() end
--- Creates a timer that runs based on the specified `time` in milliseconds. --- Creates a timer that runs based on the specified `time`.
--- The `type` can either be `hilbish.timers.INTERVAL` or `hilbish.timers.TIMEOUT`
--- @param type number
--- @param time number
--- @param callback function
function hilbish.timers.create(type, time, callback) end function hilbish.timers.create(type, time, callback) end
--- Retrieves a timer via its ID. --- Retrieves a timer via its ID.
--- @param id number
--- @returns Timer
function hilbish.timers.get(id) end function hilbish.timers.get(id) end
return hilbish return hilbish

View File

@ -5,14 +5,14 @@ local terminal = {}
--- Restores the last saved state of the terminal --- Restores the last saved state of the terminal
function terminal.restoreState() end function terminal.restoreState() end
--- Saves the current state of the terminal --- Saves the current state of the terminal.
function terminal.saveState() end function terminal.saveState() end
--- Puts the terminal in raw mode --- Puts the terminal into raw mode.
function terminal.setRaw() end function terminal.setRaw() end
--- Gets the dimensions of the terminal. Returns a table with `width` and `height` --- Gets the dimensions of the terminal. Returns a table with `width` and `height`
--- Note: this is not the size in relation to the dimensions of the display --- NOTE: The size refers to the amount of columns and rows of text that can fit in the terminal.
function terminal.size() end function terminal.size() end
return terminal return terminal

1
go.mod
View File

@ -4,6 +4,7 @@ go 1.17
require ( require (
github.com/arnodel/golua v0.0.0-20220221163911-dfcf252b6f86 github.com/arnodel/golua v0.0.0-20220221163911-dfcf252b6f86
github.com/atsushinee/go-markdown-generator v0.0.0-20191121114853-83f9e1f68504
github.com/blackfireio/osinfo v1.0.3 github.com/blackfireio/osinfo v1.0.3
github.com/maxlandon/readline v0.1.0-beta.0.20211027085530-2b76cabb8036 github.com/maxlandon/readline v0.1.0-beta.0.20211027085530-2b76cabb8036
github.com/pborman/getopt v1.1.0 github.com/pborman/getopt v1.1.0

2
go.sum
View File

@ -8,6 +8,8 @@ github.com/arnodel/edit v0.0.0-20220202110212-dfc8d7a13890/go.mod h1:AcpttpuZBaL
github.com/arnodel/strftime v0.1.6 h1:0hc0pUvk8KhEMXE+htyaOUV42zNcf/csIbjzEFCJqsw= github.com/arnodel/strftime v0.1.6 h1:0hc0pUvk8KhEMXE+htyaOUV42zNcf/csIbjzEFCJqsw=
github.com/arnodel/strftime v0.1.6/go.mod h1:5NbK5XqYK8QpRZpqKNt4OlxLtIB8cotkLk4KTKzJfWs= github.com/arnodel/strftime v0.1.6/go.mod h1:5NbK5XqYK8QpRZpqKNt4OlxLtIB8cotkLk4KTKzJfWs=
github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
github.com/atsushinee/go-markdown-generator v0.0.0-20191121114853-83f9e1f68504 h1:R1/AOzdMbopSliUTTEHvHbyNmnZ3YxY5GvdhTkpPsSY=
github.com/atsushinee/go-markdown-generator v0.0.0-20191121114853-83f9e1f68504/go.mod h1:kHBCvAXJIatTX1pw6tLiOspjGc3MhUDRlog9yrCUS+k=
github.com/blackfireio/osinfo v1.0.3 h1:Yk2t2GTPjBcESv6nDSWZKO87bGMQgO+Hi9OoXPpxX8c= github.com/blackfireio/osinfo v1.0.3 h1:Yk2t2GTPjBcESv6nDSWZKO87bGMQgO+Hi9OoXPpxX8c=
github.com/blackfireio/osinfo v1.0.3/go.mod h1:Pd987poVNmd5Wsx6PRPw4+w7kLlf9iJxoRKPtPAjOrA= github.com/blackfireio/osinfo v1.0.3/go.mod h1:Pd987poVNmd5Wsx6PRPw4+w7kLlf9iJxoRKPtPAjOrA=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=

View File

@ -1,9 +1,28 @@
// the event emitter // the event emitter
// Bait is the event emitter for Hilbish. Why name it bait? Why not. /*
// It throws hooks that you can catch. This is what you will use if Bait is the event emitter for Hilbish. Much like Node.js and
// you want to listen in on hooks to know when certain things have its `events` system, many actions in Hilbish emit events.
// happened, like when you've changed directory, a command has failed, Unlike Node.js, Hilbish events are global. So make sure to
// etc. To find all available hooks thrown by Hilbish, see doc hooks. pick a unique name!
Usage of the Bait module consists of userstanding
event-driven architecture, but it's pretty simple:
If you want to act on a certain event, you can `catch` it.
You can act on events via callback functions.
Examples of this are in the Hilbish default config!
Consider this part of it:
```lua
bait.catch('command.exit', function(code)
running = false
doPrompt(code ~= 0)
doNotifyPrompt()
end)
```
What this does is, whenever the `command.exit` event is thrown,
this function will set the user prompt.
*/
package bait package bait
import ( import (
@ -228,31 +247,17 @@ func handleHook(t *rt.Thread, c *rt.GoCont, name string, catcher *rt.Closure, ar
} }
} }
// throw(name, ...args)
// Throws a hook with `name` with the provided `args`
// --- @param name string
// --- @vararg any
func (b *Bait) bthrow(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err := c.Check1Arg(); err != nil {
return nil, err
}
name, err := c.StringArg(0)
if err != nil {
return nil, err
}
ifaceSlice := make([]interface{}, len(c.Etc()))
for i, v := range c.Etc() {
ifaceSlice[i] = v
}
b.Emit(name, ifaceSlice...)
return c.Next(), nil
}
// catch(name, cb) // catch(name, cb)
// Catches a hook with `name`. Runs the `cb` when it is thrown // Catches an event. This function can be used to act on events.
// --- @param name string // #param name string The name of the hook.
// --- @param cb function // #param cb function The function that will be called when the hook is thrown.
/*
#example
bait.catch('hilbish.exit', function()
print 'Goodbye Hilbish!'
end)
#example
*/
func (b *Bait) bcatch(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { func (b *Bait) bcatch(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
name, catcher, err := util.HandleStrCallback(t, c) name, catcher, err := util.HandleStrCallback(t, c)
if err != nil { if err != nil {
@ -265,9 +270,9 @@ func (b *Bait) bcatch(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
} }
// catchOnce(name, cb) // catchOnce(name, cb)
// Same as catch, but only runs the `cb` once and then removes the hook // Catches an event, but only once. This will remove the hook immediately after it runs for the first time.
// --- @param name string // #param name string The name of the event
// --- @param cb function // #param cb function The function that will be called when the event is thrown.
func (b *Bait) bcatchOnce(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { func (b *Bait) bcatchOnce(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
name, catcher, err := util.HandleStrCallback(t, c) name, catcher, err := util.HandleStrCallback(t, c)
if err != nil { if err != nil {
@ -279,27 +284,10 @@ func (b *Bait) bcatchOnce(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
return c.Next(), nil return c.Next(), nil
} }
// release(name, catcher)
// Removes the `catcher` for the event with `name`.
// For this to work, `catcher` has to be the same function used to catch
// an event, like one saved to a variable.
// --- @param name string
// --- @param catcher function
func (b *Bait) brelease(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
name, catcher, err := util.HandleStrCallback(t, c)
if err != nil {
return nil, err
}
b.OffLua(name, catcher)
return c.Next(), nil
}
// hooks(name) -> table // hooks(name) -> table
// Returns a table with hooks (callback functions) on the event with `name`. // Returns a list of callbacks that are hooked on an event with the corresponding `name`.
// --- @param name string // #param name string The name of the function
// --- @returns table<function> // #returns table<function>
func (b *Bait) bhooks(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { func (b *Bait) bhooks(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err := c.Check1Arg(); err != nil { if err := c.Check1Arg(); err != nil {
return nil, err return nil, err
@ -327,3 +315,62 @@ func (b *Bait) bhooks(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
return c.PushingNext1(t.Runtime, rt.TableValue(luaHandlers)), nil return c.PushingNext1(t.Runtime, rt.TableValue(luaHandlers)), nil
} }
// release(name, catcher)
// Removes the `catcher` for the event with `name`.
// For this to work, `catcher` has to be the same function used to catch
// an event, like one saved to a variable.
// #param name string Name of the event the hook is on
// #param catcher function Hook function to remove
/*
#example
local hookCallback = function() print 'hi' end
bait.catch('event', hookCallback)
-- a little while later....
bait.release('event', hookCallback)
-- and now hookCallback will no longer be ran for the event.
#example
*/
func (b *Bait) brelease(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
name, catcher, err := util.HandleStrCallback(t, c)
if err != nil {
return nil, err
}
b.OffLua(name, catcher)
return c.Next(), nil
}
// throw(name, ...args)
// #param name string The name of the hook.
// #param args ...any The arguments to pass to the hook.
// Throws a hook with `name` with the provided `args`.
/*
#example
bait.throw('greeting', 'world')
-- This can then be listened to via
bait.catch('gretting', function(greetTo)
print('Hello ' .. greetTo)
end)
#example
*/
func (b *Bait) bthrow(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err := c.Check1Arg(); err != nil {
return nil, err
}
name, err := c.StringArg(0)
if err != nil {
return nil, err
}
ifaceSlice := make([]interface{}, len(c.Etc()))
for i, v := range c.Etc() {
ifaceSlice[i] = v
}
b.Emit(name, ifaceSlice...)
return c.Next(), nil
}

View File

@ -1,10 +1,9 @@
// library for custom commands // library for custom commands
/* /*
Commander is a library for writing custom commands in Lua. Commander is the library which handles Hilbish commands. This makes
In order to make it easier to write commands for Hilbish, the user able to add Lua-written commands to their shell without making
not require separate scripts and to be able to use in a config, a separate script in a bin folder. Instead, you may simply use the Commander
the Commander library exists. This is like a very simple wrapper library in your Hilbish config.
that works with Hilbish for writing commands. Example:
```lua ```lua
local commander = require 'commander' local commander = require 'commander'
@ -19,14 +18,14 @@ that will print `Hello world!` to output. One question you may
have is: What is the `sinks` parameter? have is: What is the `sinks` parameter?
The `sinks` parameter is a table with 3 keys: `in`, `out`, The `sinks` parameter is a table with 3 keys: `in`, `out`,
and `err`. The values of these is a @Sink. and `err`. All of them are a @Sink.
- `in` is the standard input. You can read from this sink - `in` is the standard input.
to get user input. (**This is currently unimplemented.**) You may use the read functions on this sink to get input from the user.
- `out` is standard output. This is usually where text meant for - `out` is standard output.
output should go. This is usually where command output should go.
- `err` is standard error. This sink is for writing errors, as the - `err` is standard error.
name would suggest. This sink is for writing errors, as the name would suggest.
*/ */
package commander package commander
@ -67,9 +66,22 @@ func (c *Commander) loaderFunc(rtm *rt.Runtime) (rt.Value, func()) {
} }
// register(name, cb) // register(name, cb)
// Register a command with `name` that runs `cb` when ran // Adds a new command with the given `name`. When Hilbish has to run a command with a name,
// --- @param name string // it will run the function providing the arguments and sinks.
// --- @param cb function // #param name string Name of the command
// #param cb function Callback to handle command invocation
/*
#example
-- When you run the command `hello` in the shell, it will print `Hello world`.
-- If you run it with, for example, `hello Hilbish`, it will print 'Hello Hilbish'
commander.register('hello', function(args, sinks)
local name = 'world'
if #args > 0 then name = args[1] end
sinks.out:writeln('Hello ' .. name)
end)
#example
*/
func (c *Commander) cregister(t *rt.Thread, ct *rt.GoCont) (rt.Cont, error) { func (c *Commander) cregister(t *rt.Thread, ct *rt.GoCont) (rt.Cont, error) {
cmdName, cmd, err := util.HandleStrCallback(t, ct) cmdName, cmd, err := util.HandleStrCallback(t, ct)
if err != nil { if err != nil {
@ -82,8 +94,8 @@ func (c *Commander) cregister(t *rt.Thread, ct *rt.GoCont) (rt.Cont, error) {
} }
// deregister(name) // deregister(name)
// Deregisters any command registered with `name` // Removes the named command. Note that this will only remove Commander-registered commands.
// --- @param name string // #param name string Name of the command to remove.
func (c *Commander) cderegister(t *rt.Thread, ct *rt.GoCont) (rt.Cont, error) { func (c *Commander) cderegister(t *rt.Thread, ct *rt.GoCont) (rt.Cont, error) {
if err := ct.Check1Arg(); err != nil { if err := ct.Check1Arg(); err != nil {
return nil, err return nil, err

View File

@ -1,7 +1,10 @@
// filesystem interaction and functionality library // filesystem interaction and functionality library
// The fs module provides easy and simple access to filesystem functions /*
// and other things, and acts an addition to the Lua standard library's The fs module provides filesystem functions to Hilbish. While Lua's standard
// I/O and filesystem functions. library has some I/O functions, they're missing a lot of the basics. The `fs`
library offers more functions and will work on any operating system Hilbish does.
#field pathSep The operating system's path separator.
*/
package fs package fs
import ( import (
@ -42,9 +45,46 @@ func loaderFunc(rtm *rt.Runtime) (rt.Value, func()) {
return rt.TableValue(mod), nil return rt.TableValue(mod), nil
} }
// abs(path) -> string
// Returns an absolute version of the `path`.
// This can be used to resolve short paths like `..` to `/home/user`.
// #param path string
// #returns string
func fabs(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
path, err := c.StringArg(0)
if err != nil {
return nil, err
}
path = util.ExpandHome(path)
abspath, err := filepath.Abs(path)
if err != nil {
return nil, err
}
return c.PushingNext1(t.Runtime, rt.StringValue(abspath)), nil
}
// basename(path) -> string
// Returns the "basename," or the last part of the provided `path`. If path is empty,
// `.` will be returned.
// #param path string Path to get the base name of.
// #returns string
func fbasename(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err := c.Check1Arg(); err != nil {
return nil, err
}
path, err := c.StringArg(0)
if err != nil {
return nil, err
}
return c.PushingNext(t.Runtime, rt.StringValue(filepath.Base(path))), nil
}
// cd(dir) // cd(dir)
// Changes directory to `dir` // Changes Hilbish's directory to `dir`.
// --- @param dir string // #param dir string Path to change directory to.
func fcd(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { func fcd(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err := c.Check1Arg(); err != nil { if err := c.Check1Arg(); err != nil {
return nil, err return nil, err
@ -63,10 +103,102 @@ func fcd(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
return c.Next(), err return c.Next(), err
} }
// dir(path) -> string
// Returns the directory part of `path`. If a file path like
// `~/Documents/doc.txt` then this function will return `~/Documents`.
// #param path string Path to get the directory for.
// #returns string
func fdir(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err := c.Check1Arg(); err != nil {
return nil, err
}
path, err := c.StringArg(0)
if err != nil {
return nil, err
}
return c.PushingNext(t.Runtime, rt.StringValue(filepath.Dir(path))), nil
}
// glob(pattern) -> matches (table)
// Match all files based on the provided `pattern`.
// For the syntax' refer to Go's filepath.Match function: https://pkg.go.dev/path/filepath#Match
// #param pattern string Pattern to compare files with.
// #returns table A list of file names/paths that match.
/*
#example
--[[
Within a folder that contains the following files:
a.txt
init.lua
code.lua
doc.pdf
]]--
local matches = fs.glob './*.lua'
print(matches)
-- -> {'init.lua', 'code.lua'}
#example
*/
func fglob(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err := c.Check1Arg(); err != nil {
return nil, err
}
pattern, err := c.StringArg(0)
if err != nil {
return nil, err
}
matches, err := filepath.Glob(pattern)
if err != nil {
return nil, err
}
luaMatches := rt.NewTable()
for i, match := range matches {
luaMatches.Set(rt.IntValue(int64(i + 1)), rt.StringValue(match))
}
return c.PushingNext(t.Runtime, rt.TableValue(luaMatches)), nil
}
// join(...path) -> string
// Takes any list of paths and joins them based on the operating system's path separator.
// #param path ...string Paths to join together
// #returns string The joined path.
/*
#example
-- This prints the directory for Hilbish's config!
print(fs.join(hilbish.userDir.config, 'hilbish'))
-- -> '/home/user/.config/hilbish' on Linux
#example
*/
func fjoin(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
strs := make([]string, len(c.Etc()))
for i, v := range c.Etc() {
if v.Type() != rt.StringType {
// +2; go indexes of 0 and first arg from above
return nil, fmt.Errorf("bad argument #%d to run (expected string, got %s)", i + 1, v.TypeName())
}
strs[i] = v.AsString()
}
res := filepath.Join(strs...)
return c.PushingNext(t.Runtime, rt.StringValue(res)), nil
}
// mkdir(name, recursive) // mkdir(name, recursive)
// Makes a directory called `name`. If `recursive` is true, it will create its parent directories. // Creates a new directory with the provided `name`.
// --- @param name string // With `recursive`, mkdir will create parent directories.
// --- @param recursive boolean // #param name string Name of the directory
// #param recursive boolean Whether to create parent directories for the provided name
/*
#example
-- This will create the directory foo, then create the directory bar in the
-- foo directory. If recursive is false in this case, it will fail.
fs.mkdir('./foo/bar', true)
*/
func fmkdir(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { 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
@ -93,15 +225,58 @@ func fmkdir(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
return c.Next(), err return c.Next(), err
} }
// readdir(path) -> table[string]
// Returns a list of all files and directories in the provided path.
// #param dir string
// #returns table
func freaddir(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err := c.Check1Arg(); err != nil {
return nil, err
}
dir, err := c.StringArg(0)
if err != nil {
return nil, err
}
dir = util.ExpandHome(dir)
names := rt.NewTable()
dirEntries, err := os.ReadDir(dir)
if err != nil {
return nil, err
}
for i, entry := range dirEntries {
names.Set(rt.IntValue(int64(i + 1)), rt.StringValue(entry.Name()))
}
return c.PushingNext1(t.Runtime, rt.TableValue(names)), nil
}
// stat(path) -> {} // stat(path) -> {}
// Returns a table of info about the `path`. // Returns the information about a given `path`.
// It contains the following keys: // The returned table contains the following values:
// name (string) - Name of the path // name (string) - Name of the path
// size (number) - Size of the path // size (number) - Size of the path in bytes
// mode (string) - Permission mode in an octal format string (with leading 0) // mode (string) - Unix permission mode in an octal format string (with leading 0)
// isDir (boolean) - If the path is a directory // isDir (boolean) - If the path is a directory
// --- @param path string // #param path string
// --- @returns table // #returns table
/*
#example
local inspect = require 'inspect'
local stat = fs.stat '~'
print(inspect(stat))
--[[
Would print the following:
{
isDir = true,
mode = "0755",
name = "username",
size = 12288
}
]]--
#example
*/
func fstat(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { func fstat(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err := c.Check1Arg(); err != nil { if err := c.Check1Arg(); err != nil {
return nil, err return nil, err
@ -125,128 +300,3 @@ func fstat(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
return c.PushingNext1(t.Runtime, rt.TableValue(statTbl)), nil return c.PushingNext1(t.Runtime, rt.TableValue(statTbl)), nil
} }
// readdir(dir) -> {}
// Returns a table of files in `dir`.
// --- @param dir string
// --- @return table
func freaddir(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err := c.Check1Arg(); err != nil {
return nil, err
}
dir, err := c.StringArg(0)
if err != nil {
return nil, err
}
dir = util.ExpandHome(dir)
names := rt.NewTable()
dirEntries, err := os.ReadDir(dir)
if err != nil {
return nil, err
}
for i, entry := range dirEntries {
names.Set(rt.IntValue(int64(i + 1)), rt.StringValue(entry.Name()))
}
return c.PushingNext1(t.Runtime, rt.TableValue(names)), nil
}
// abs(path) -> string
// Gives an absolute version of `path`.
// --- @param path string
// --- @returns string
func fabs(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
path, err := c.StringArg(0)
if err != nil {
return nil, err
}
path = util.ExpandHome(path)
abspath, err := filepath.Abs(path)
if err != nil {
return nil, err
}
return c.PushingNext1(t.Runtime, rt.StringValue(abspath)), nil
}
// basename(path) -> string
// Gives the basename of `path`. For the rules,
// see Go's filepath.Base
// --- @returns string
func fbasename(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err := c.Check1Arg(); err != nil {
return nil, err
}
path, err := c.StringArg(0)
if err != nil {
return nil, err
}
return c.PushingNext(t.Runtime, rt.StringValue(filepath.Base(path))), nil
}
// dir(path) -> string
// Returns the directory part of `path`. For the rules, see Go's
// filepath.Dir
// --- @param path string
// --- @returns string
func fdir(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err := c.Check1Arg(); err != nil {
return nil, err
}
path, err := c.StringArg(0)
if err != nil {
return nil, err
}
return c.PushingNext(t.Runtime, rt.StringValue(filepath.Dir(path))), nil
}
// glob(pattern) -> matches (table)
// Glob all files and directories that match the pattern.
// For the rules, see Go's filepath.Glob
// --- @param pattern string
// --- @returns table
func fglob(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err := c.Check1Arg(); err != nil {
return nil, err
}
pattern, err := c.StringArg(0)
if err != nil {
return nil, err
}
matches, err := filepath.Glob(pattern)
if err != nil {
return nil, err
}
luaMatches := rt.NewTable()
for i, match := range matches {
luaMatches.Set(rt.IntValue(int64(i + 1)), rt.StringValue(match))
}
return c.PushingNext(t.Runtime, rt.TableValue(luaMatches)), nil
}
// join(...) -> string
// Takes paths and joins them together with the OS's
// directory separator (forward or backward slash).
// --- @vararg string
// --- @returns string
func fjoin(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
strs := make([]string, len(c.Etc()))
for i, v := range c.Etc() {
if v.Type() != rt.StringType {
// +2; go indexes of 0 and first arg from above
return nil, fmt.Errorf("bad argument #%d to run (expected string, got %s)", i + 1, v.TypeName())
}
strs[i] = v.AsString()
}
res := filepath.Join(strs...)
return c.PushingNext(t.Runtime, rt.StringValue(res)), nil
}

View File

@ -34,7 +34,7 @@ func loaderFunc(rtm *rt.Runtime) (rt.Value, func()) {
// size() // size()
// Gets the dimensions of the terminal. Returns a table with `width` and `height` // Gets the dimensions of the terminal. Returns a table with `width` and `height`
// Note: this is not the size in relation to the dimensions of the display // NOTE: The size refers to the amount of columns and rows of text that can fit in the terminal.
func termsize(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { func termsize(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
w, h, err := term.GetSize(int(os.Stdin.Fd())) w, h, err := term.GetSize(int(os.Stdin.Fd()))
if err != nil { if err != nil {
@ -49,7 +49,7 @@ func termsize(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
} }
// saveState() // saveState()
// Saves the current state of the terminal // Saves the current state of the terminal.
func termsaveState(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { func termsaveState(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
state, err := term.GetState(int(os.Stdin.Fd())) state, err := term.GetState(int(os.Stdin.Fd()))
if err != nil { if err != nil {
@ -72,7 +72,7 @@ func termrestoreState(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
} }
// setRaw() // setRaw()
// Puts the terminal in raw mode // Puts the terminal into raw mode.
func termsetRaw(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { func termsetRaw(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
_, err := term.MakeRaw(int(os.Stdin.Fd())) _, err := term.MakeRaw(int(os.Stdin.Fd()))
if err != nil { if err != nil {

26
job.go
View File

@ -414,10 +414,16 @@ func (j *jobHandler) luaGetJob(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
// #interface jobs // #interface jobs
// add(cmdstr, args, execPath) // add(cmdstr, args, execPath)
// Adds a new job to the job table. Note that this does not immediately run it. // Creates a new job. This function does not run the job. This function is intended to be
// --- @param cmdstr string // used by runners, but can also be used to create jobs via Lua. Commanders cannot be ran as jobs.
// --- @param args table // #param cmdstr string String that a user would write for the job
// --- @param execPath string // #param args table Arguments for the commands. Has to include the name of the command.
// #param execPath string Binary to use to run the command. Does not
/*
#example
hilbish.jobs.add('go build', {'go', 'build'}, '/usr/bin/go')
#example
*/
func (j *jobHandler) luaAddJob(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { func (j *jobHandler) luaAddJob(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err := c.CheckNArgs(3); err != nil { if err := c.CheckNArgs(3); err != nil {
return nil, err return nil, err
@ -448,9 +454,9 @@ func (j *jobHandler) luaAddJob(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
} }
// #interface jobs // #interface jobs
// all() -> table<@Job> // all() -> table[@Job]
// Returns a table of all job objects. // Returns a table of all job objects.
// --- @returns table<Job> // #returns table[Job]
func (j *jobHandler) luaAllJobs(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { func (j *jobHandler) luaAllJobs(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
j.mu.RLock() j.mu.RLock()
defer j.mu.RUnlock() defer j.mu.RUnlock()
@ -465,8 +471,8 @@ func (j *jobHandler) luaAllJobs(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
// #interface jobs // #interface jobs
// disown(id) // disown(id)
// Disowns a job. This deletes it from the job table. // Disowns a job. This simply deletes it from the list of jobs without stopping it.
// --- @param id number // #param id number
func (j *jobHandler) luaDisownJob(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { func (j *jobHandler) luaDisownJob(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err := c.Check1Arg(); err != nil { if err := c.Check1Arg(); err != nil {
return nil, err return nil, err
@ -486,8 +492,8 @@ func (j *jobHandler) luaDisownJob(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
// #interface jobs // #interface jobs
// last() -> @Job // last() -> @Job
// Returns the last added job from the table. // Returns the last added job to the table.
// --- @returns Job // #returns Job
func (j *jobHandler) luaLastJob(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { func (j *jobHandler) luaLastJob(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
j.mu.RLock() j.mu.RLock()
defer j.mu.RUnlock() defer j.mu.RUnlock()

View File

@ -61,6 +61,7 @@ func moduleLoader(rtm *rt.Runtime) *rt.Table {
// load(path) // load(path)
// Loads a module at the designated `path`. // Loads a module at the designated `path`.
// It will throw if any error occurs. // It will throw if any error occurs.
// #param path string
func moduleLoad(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { func moduleLoad(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err := c.CheckNArgs(1); err != nil { if err := c.CheckNArgs(1); err != nil {
return nil, err return nil, err

View File

@ -89,7 +89,7 @@ Available sections: ]] .. table.concat(modules, ', ')
local size = terminal.size() local size = terminal.size()
self.region = { self.region = {
width = size.width, width = size.width,
height = size.height - 3 height = size.height - 2
} }
end end
gh:resize() gh:resize()
@ -102,7 +102,8 @@ Available sections: ]] .. table.concat(modules, ', ')
workingPage = self.specialPage workingPage = self.specialPage
end end
self.sink:write(ansikit.getCSI(self.region.height + 2 .. ';1', 'H')) self.sink:write(ansikit.getCSI(self.region.height + 1 .. ';1', 'H'))
self.sink:write(ansikit.getCSI(0, 'J'))
if not self.isSpecial then if not self.isSpecial then
if args[1] == 'api' then if args[1] == 'api' then
self.sink:writeln(lunacolors.reset(string.format('%s', workingPage.title))) self.sink:writeln(lunacolors.reset(string.format('%s', workingPage.title)))

7
os.go
View File

@ -8,10 +8,9 @@ import (
) )
// #interface os // #interface os
// OS Info // operating system info
// The `os` interface provides simple text information properties about // Provides simple text information properties about the current operating system.
// the current OS on the systen. This mainly includes the name and // This mainly includes the name and version.
// version.
// #field family Family name of the current OS // #field family Family name of the current OS
// #field name Pretty name of the current OS // #field name Pretty name of the current OS
// #field version Version of the current OS // #field version Version of the current OS

14
rl.go
View File

@ -267,7 +267,7 @@ func (lr *lineReader) Loader(rtm *rt.Runtime) *rt.Table {
// #interface history // #interface history
// add(cmd) // add(cmd)
// Adds a command to the history. // Adds a command to the history.
// --- @param cmd string // #param cmd string
func (lr *lineReader) luaAddHistory(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { func (lr *lineReader) luaAddHistory(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err := c.Check1Arg(); err != nil { if err := c.Check1Arg(); err != nil {
return nil, err return nil, err
@ -284,15 +284,15 @@ func (lr *lineReader) luaAddHistory(t *rt.Thread, c *rt.GoCont) (rt.Cont, error)
// #interface history // #interface history
// size() -> number // size() -> number
// Returns the amount of commands in the history. // Returns the amount of commands in the history.
// --- @returns number // #eturns number
func (lr *lineReader) luaSize(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { func (lr *lineReader) luaSize(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
return c.PushingNext1(t.Runtime, rt.IntValue(int64(lr.fileHist.Len()))), nil return c.PushingNext1(t.Runtime, rt.IntValue(int64(lr.fileHist.Len()))), nil
} }
// #interface history // #interface history
// get(idx) // get(index)
// Retrieves a command from the history based on the `idx`. // Retrieves a command from the history based on the `index`.
// --- @param idx number // #param index number
func (lr *lineReader) luaGetHistory(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { func (lr *lineReader) luaGetHistory(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err := c.Check1Arg(); err != nil { if err := c.Check1Arg(); err != nil {
return nil, err return nil, err
@ -309,8 +309,8 @@ func (lr *lineReader) luaGetHistory(t *rt.Thread, c *rt.GoCont) (rt.Cont, error)
// #interface history // #interface history
// all() -> table // all() -> table
// Retrieves all history. // Retrieves all history as a table.
// --- @returns table // #returns table
func (lr *lineReader) luaAllHistory(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { func (lr *lineReader) luaAllHistory(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
tbl := rt.NewTable() tbl := rt.NewTable()
size := lr.fileHist.Len() size := lr.fileHist.Len()

View File

@ -28,18 +28,18 @@ func runnerModeLoader(rtm *rt.Runtime) *rt.Table {
// #interface runner // #interface runner
// setMode(cb) // setMode(cb)
// This is the same as the `hilbish.runnerMode` function. It takes a callback, // This is the same as the `hilbish.runnerMode` function.
// which will be used to execute all interactive input. // It takes a callback, which will be used to execute all interactive input.
// In normal cases, neither callbacks should be overrided by the user, // In normal cases, neither callbacks should be overrided by the user,
// as the higher level functions listed below this will handle it. // as the higher level functions listed below this will handle it.
// --- @param cb function // #param cb function
func _runnerMode() {} func _runnerMode() {}
// #interface runner // #interface runner
// sh(cmd) // sh(cmd)
// Runs a command in Hilbish's shell script interpreter. // Runs a command in Hilbish's shell script interpreter.
// This is the equivalent of using `source`. // This is the equivalent of using `source`.
// --- @param cmd string // #param cmd string
func shRunner(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { func shRunner(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err := c.Check1Arg(); err != nil { if err := c.Check1Arg(); err != nil {
return nil, err return nil, err
@ -67,7 +67,7 @@ func shRunner(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
// lua(cmd) // lua(cmd)
// Evaluates `cmd` as Lua input. This is the same as using `dofile` // Evaluates `cmd` as Lua input. This is the same as using `dofile`
// or `load`, but is appropriated for the runner interface. // or `load`, but is appropriated for the runner interface.
// --- @param cmd string // #param cmd string
func luaRunner(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { func luaRunner(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err := c.Check1Arg(); err != nil { if err := c.Check1Arg(); err != nil {
return nil, err return nil, err

View File

@ -63,11 +63,10 @@ func (th *timersModule) get(id int) *timer {
// #interface timers // #interface timers
// create(type, time, callback) -> @Timer // create(type, time, callback) -> @Timer
// Creates a timer that runs based on the specified `time` in milliseconds. // Creates a timer that runs based on the specified `time`.
// The `type` can either be `hilbish.timers.INTERVAL` or `hilbish.timers.TIMEOUT` // #param type number What kind of timer to create, can either be `hilbish.timers.INTERVAL` or `hilbish.timers.TIMEOUT`
// --- @param type number // #param time number The amount of time the function should run in milliseconds.
// --- @param time number // #param callback function The function to run for the timer.
// --- @param callback function
func (th *timersModule) luaCreate(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { func (th *timersModule) luaCreate(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err := c.CheckNArgs(3); err != nil { if err := c.CheckNArgs(3); err != nil {
return nil, err return nil, err
@ -93,8 +92,8 @@ func (th *timersModule) luaCreate(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
// #interface timers // #interface timers
// get(id) -> @Timer // get(id) -> @Timer
// Retrieves a timer via its ID. // Retrieves a timer via its ID.
// --- @param id number // #param id number
// --- @returns Timer // #returns Timer
func (th *timersModule) luaGet(thr *rt.Thread, c *rt.GoCont) (rt.Cont, error) { func (th *timersModule) luaGet(thr *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
if err := c.Check1Arg(); err != nil { if err := c.Check1Arg(); err != nil {
return nil, err return nil, err
@ -122,15 +121,10 @@ a few seconds, you don't have to rely on timing tricks, as Hilbish has a
timer API to set intervals and timeouts. timer API to set intervals and timeouts.
These are the simple functions `hilbish.interval` and `hilbish.timeout` (doc These are the simple functions `hilbish.interval` and `hilbish.timeout` (doc
accessible with `doc hilbish`). But if you want slightly more control over accessible with `doc hilbish`, or `Module hilbish` on the Website).
them, there is the `hilbish.timers` interface. It allows you to get
a timer via ID and control them.
## Timer Object
All functions documented with the `Timer` type refer to a Timer object.
An example of usage: An example of usage:
``` ```lua
local t = hilbish.timers.create(hilbish.timers.TIMEOUT, 5000, function() local t = hilbish.timers.create(hilbish.timers.TIMEOUT, 5000, function()
print 'hello!' print 'hello!'
end) end)

View File

@ -1,5 +1,5 @@
baseURL = 'https://rosettea.github.io/Hilbish/'
languageCode = 'en-us' languageCode = 'en-us'
baseURL = 'https://rosettea.github.io/Hilbish/'
title = 'Hilbish' title = 'Hilbish'
theme = 'hsh' theme = 'hsh'
enableGitInfo = true enableGitInfo = true
@ -29,6 +29,14 @@ enableGitInfo = true
[markup.goldmark.renderer] [markup.goldmark.renderer]
unsafe = true unsafe = true
[markup.highlight]
lineNos = true
lineNumbersInTable = false
noClasses = false
codeFences = true
guessSyntax = true
tabWidth = 4
[author] [author]
[author.sammyette] [author.sammyette]
name = 'sammyette' name = 'sammyette'

View File

@ -0,0 +1 @@
../../docs

View File

@ -1 +0,0 @@
../../../docs/api/

View File

@ -0,0 +1,89 @@
.chroma {
display: inline-block;
padding: 0.5em;
}
/* Background */ .bg { background-color: #F7F7F7; }
/* PreWrapper */ .chroma { background-color: #F7F7F7; }
/* Other */ .chroma .x { }
/* Error */ .chroma .err { color: #a61717; background-color: #e3d2d2 }
/* CodeLine */ .chroma .cl { }
/* LineTableTD */ .chroma .lntd { vertical-align: top; padding: 0; margin: 0; border: 0; }
/* LineTable */ .chroma .lntable { border-spacing: 0; padding: 0; margin: 0; border: 0; }
/* LineHighlight */ .chroma .hl { background-color: #F7F7F7 }
/* LineNumbersTable */ .chroma .lnt { white-space: pre; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f }
/* LineNumbers */ .chroma .ln { white-space: pre; user-select: none; margin-right: 0.4em; padding: 0 0.4em 0 0.4em;color: #7f7f7f }
/* Line */ .chroma .line { display: flex; }
/* Keyword */ .chroma .k { color: #008800; font-weight: bold }
/* KeywordConstant */ .chroma .kc { color: #008800; font-weight: bold }
/* KeywordDeclaration */ .chroma .kd { color: #008800; font-weight: bold }
/* KeywordNamespace */ .chroma .kn { color: #008800; font-weight: bold }
/* KeywordPseudo */ .chroma .kp { color: #008800 }
/* KeywordReserved */ .chroma .kr { color: #008800; font-weight: bold }
/* KeywordType */ .chroma .kt { color: #888888; font-weight: bold }
/* Name */ .chroma .n { }
/* NameAttribute */ .chroma .na { color: #336699 }
/* NameBuiltin */ .chroma .nb { color: #003388 }
/* NameBuiltinPseudo */ .chroma .bp { }
/* NameClass */ .chroma .nc { color: #bb0066; font-weight: bold }
/* NameConstant */ .chroma .no { color: #003366; font-weight: bold }
/* NameDecorator */ .chroma .nd { color: #555555 }
/* NameEntity */ .chroma .ni { }
/* NameException */ .chroma .ne { color: #bb0066; font-weight: bold }
/* NameFunction */ .chroma .nf { color: #0066bb; font-weight: bold }
/* NameFunctionMagic */ .chroma .fm { }
/* NameLabel */ .chroma .nl { color: #336699; font-style: italic }
/* NameNamespace */ .chroma .nn { color: #bb0066; font-weight: bold }
/* NameOther */ .chroma .nx { }
/* NameProperty */ .chroma .py { color: #336699; font-weight: bold }
/* NameTag */ .chroma .nt { color: #bb0066; font-weight: bold }
/* NameVariable */ .chroma .nv { color: #336699 }
/* NameVariableClass */ .chroma .vc { color: #336699 }
/* NameVariableGlobal */ .chroma .vg { color: #dd7700 }
/* NameVariableInstance */ .chroma .vi { color: #3333bb }
/* NameVariableMagic */ .chroma .vm { }
/* Literal */ .chroma .l { }
/* LiteralDate */ .chroma .ld { }
/* LiteralString */ .chroma .s { color: #dd2200; background-color: #fff0f0 }
/* LiteralStringAffix */ .chroma .sa { color: #dd2200; background-color: #fff0f0 }
/* LiteralStringBacktick */ .chroma .sb { color: #dd2200; background-color: #fff0f0 }
/* LiteralStringChar */ .chroma .sc { color: #dd2200; background-color: #fff0f0 }
/* LiteralStringDelimiter */ .chroma .dl { color: #dd2200; background-color: #fff0f0 }
/* LiteralStringDoc */ .chroma .sd { color: #dd2200; background-color: #fff0f0 }
/* LiteralStringDouble */ .chroma .s2 { color: #dd2200; background-color: #fff0f0 }
/* LiteralStringEscape */ .chroma .se { color: #0044dd; background-color: #fff0f0 }
/* LiteralStringHeredoc */ .chroma .sh { color: #dd2200; background-color: #fff0f0 }
/* LiteralStringInterpol */ .chroma .si { color: #3333bb; background-color: #fff0f0 }
/* LiteralStringOther */ .chroma .sx { color: #22bb22; background-color: #f0fff0 }
/* LiteralStringRegex */ .chroma .sr { color: #008800; background-color: #fff0ff }
/* LiteralStringSingle */ .chroma .s1 { color: #dd2200; background-color: #fff0f0 }
/* LiteralStringSymbol */ .chroma .ss { color: #aa6600; background-color: #fff0f0 }
/* LiteralNumber */ .chroma .m { color: #0000dd; font-weight: bold }
/* LiteralNumberBin */ .chroma .mb { color: #0000dd; font-weight: bold }
/* LiteralNumberFloat */ .chroma .mf { color: #0000dd; font-weight: bold }
/* LiteralNumberHex */ .chroma .mh { color: #0000dd; font-weight: bold }
/* LiteralNumberInteger */ .chroma .mi { color: #0000dd; font-weight: bold }
/* LiteralNumberIntegerLong */ .chroma .il { color: #0000dd; font-weight: bold }
/* LiteralNumberOct */ .chroma .mo { color: #0000dd; font-weight: bold }
/* Operator */ .chroma .o { }
/* OperatorWord */ .chroma .ow { color: #008800 }
/* Punctuation */ .chroma .p { }
/* Comment */ .chroma .c { color: #888888 }
/* CommentHashbang */ .chroma .ch { color: #888888 }
/* CommentMultiline */ .chroma .cm { color: #888888 }
/* CommentSingle */ .chroma .c1 { color: #888888 }
/* CommentSpecial */ .chroma .cs { color: #cc0000; background-color: #fff0f0; font-weight: bold }
/* CommentPreproc */ .chroma .cp { color: #cc0000; font-weight: bold }
/* CommentPreprocFile */ .chroma .cpf { color: #cc0000; font-weight: bold }
/* Generic */ .chroma .g { }
/* GenericDeleted */ .chroma .gd { color: #000000; background-color: #ffdddd }
/* GenericEmph */ .chroma .ge { font-style: italic }
/* GenericError */ .chroma .gr { color: #aa0000 }
/* GenericHeading */ .chroma .gh { color: #333333 }
/* GenericInserted */ .chroma .gi { color: #000000; background-color: #ddffdd }
/* GenericOutput */ .chroma .go { color: #888888 }
/* GenericPrompt */ .chroma .gp { color: #555555 }
/* GenericStrong */ .chroma .gs { font-weight: bold }
/* GenericSubheading */ .chroma .gu { color: #666666 }
/* GenericTraceback */ .chroma .gt { color: #aa0000 }
/* GenericUnderline */ .chroma .gl { text-decoration: underline }
/* TextWhitespace */ .chroma .w { color: #bbbbbb }

View File

@ -23,7 +23,10 @@
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-0evHe/X+R7YkIZDRvuzKMRqM+OrBnVFBL6DOitfPri4tjfHxaWutUpFmBp4vmVor" crossorigin="anonymous"> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-0evHe/X+R7YkIZDRvuzKMRqM+OrBnVFBL6DOitfPri4tjfHxaWutUpFmBp4vmVor" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-pprn3073KE6tl6bjs2QrFaJGz5/SUsLqktiwsUTF55Jfv3qYSDhgCecCxMW52nD2" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-pprn3073KE6tl6bjs2QrFaJGz5/SUsLqktiwsUTF55Jfv3qYSDhgCecCxMW52nD2" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css" integrity="sha512-KfkfwYDsLkIlwQp6LFnl8zNdLGxu9YAA1QvwINks4PhcElQSvqcyVLLD9aMhXd13uQjoXtEKNosOWaZqXgel0g==" crossorigin="anonymous" referrerpolicy="no-referrer" /> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css" integrity="sha512-KfkfwYDsLkIlwQp6LFnl8zNdLGxu9YAA1QvwINks4PhcElQSvqcyVLLD9aMhXd13uQjoXtEKNosOWaZqXgel0g==" crossorigin="anonymous" referrerpolicy="no-referrer" />
{{ $syntax := resources.Get "css/syntax.css" | resources.Minify | resources.Fingerprint }}
<link rel="stylesheet" href="{{ $syntax.RelPermalink }}" integrity="{{ $syntax.Data.Integrity }}">
</link>
<style> <style>
.heading > .heading-link { .heading > .heading-link {
opacity: 0 opacity: 0
@ -34,5 +37,42 @@
opacity: 1; opacity: 1;
transition: all .1s ease-in; transition: all .1s ease-in;
} }
@keyframes highlight {
0% {
background: none
}
50% {
background: #fff2cf;
}
100% {
background: none;
}
}
div:target {
animation: highlight 1.2s;
animation-timing-function: cubic-bezier(1,-0.02,.45,.89);
}
table {
border-width: 1px;
border-style: solid;
border-color: #565c64;;
border-collapse: collapse;
margin-bottom: 12px;
}
table td {
padding: 5px;
}
table tr {
border-width: 1px;
}
thead {
display: none;
}
</style> </style>
</head> </head>