Compare commits

..

8 Commits

11 changed files with 249 additions and 133 deletions

View File

@ -64,11 +64,13 @@ type docPiece struct {
Fields []docPiece Fields []docPiece
Properties []docPiece Properties []docPiece
Params []param 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)
@ -89,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 {
@ -98,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:]
@ -188,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}
@ -273,6 +285,7 @@ start:
Fields: fields, Fields: fields,
Properties: properties, Properties: properties,
Params: params, 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
@ -565,6 +578,10 @@ func main() {
f.WriteString(strings.Join(p.Doc, " ")) f.WriteString(strings.Join(p.Doc, " "))
f.WriteString("\n\n") 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("</div>")
f.WriteString("\n\n") f.WriteString("\n\n")
} }

View File

@ -35,11 +35,11 @@ this function will set the user prompt.
## Functions ## Functions
||| |||
|----|----| |----|----|
|<a href="#catch">catch(name, cb)</a>|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>|Same as catch, but only runs the `cb` once and then removes the hook| |<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 table with hooks (callback functions) on the event with `name`.| |<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="#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`| |<a href="#throw">throw(name, ...args)</a>|Throws a hook with `name` with the provided `args`.|
<hr><div id='catch'> <hr><div id='catch'>
<h4 class='heading'> <h4 class='heading'>
@ -49,14 +49,22 @@ bait.catch(name, cb)
</a> </a>
</h4> </h4>
Catches a hook with `name`. Runs the `cb` when it is thrown Catches an event. This function can be used to act on events.
#### Parameters #### Parameters
`string` **`name`** `string` **`name`**
ummm The name of the hook.
`function` **`cb`** `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> </div>
<hr><div id='catchOnce'> <hr><div id='catchOnce'>
@ -67,9 +75,14 @@ bait.catchOnce(name, cb)
</a> </a>
</h4> </h4>
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.
#### Parameters #### Parameters
This function has no parameters. `string` **`name`**
The name of the event
`function` **`cb`**
The function that will be called when the event is thrown.
</div> </div>
<hr><div id='hooks'> <hr><div id='hooks'>
@ -80,9 +93,11 @@ bait.hooks(name) -> table
</a> </a>
</h4> </h4>
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`.
#### Parameters #### Parameters
This function has no parameters. `string` **`name`**
The name of the function
</div> </div>
<hr><div id='release'> <hr><div id='release'>
@ -96,8 +111,25 @@ bait.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.
#### Parameters #### Parameters
This function has no 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> </div>
<hr><div id='throw'> <hr><div id='throw'>
@ -108,7 +140,9 @@ bait.throw(name, ...args)
</a> </a>
</h4> </h4>
Throws a hook with `name` with the provided `args` Throws a hook with `name` with the provided `args`.
#### Parameters #### Parameters
`string` **`name`** `string` **`name`**
The name of the hook. The name of the hook.
@ -116,5 +150,14 @@ The name of the hook.
`any` **`args`** (This type is variadic. You can pass an infinite amount of parameters with this type.) `any` **`args`** (This type is variadic. You can pass an infinite amount of parameters with this type.)
The arguments to pass to the hook. 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> </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,20 +27,20 @@ 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. 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
||| |||
|----|----| |----|----|
|<a href="#deregister">deregister(name)</a>|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>|Register a command with `name` that runs `cb` when ran| |<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,|
<hr><div id='deregister'> <hr><div id='deregister'>
<h4 class='heading'> <h4 class='heading'>
@ -51,9 +50,11 @@ commander.deregister(name)
</a> </a>
</h4> </h4>
Deregisters any command registered with `name` Removes the named command. Note that this will only remove Commander-registered commands.
#### Parameters #### Parameters
This function has no parameters. `string` **`name`**
Name of the command to remove.
</div> </div>
<hr><div id='register'> <hr><div id='register'>
@ -64,8 +65,27 @@ commander.register(name, cb)
</a> </a>
</h4> </h4>
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,
it will run the function providing the arguments and sinks.
#### Parameters #### Parameters
This function has no 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> </div>

View File

@ -7,16 +7,5 @@ menu:
docs docs
--- ---
Here is a list of bait hooks that are thrown by Hilbish. If a hook is related Hooks are Hilbish's versions of events, which are used via the [Bait](../api/bait) module.
to a command, it will have the `command` scope, as example. For more detail on how to act on these hooks, you may check the Bait page.
Here is the format for a doc for a hook:
+ {hook name} -> args > description
`{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

@ -2,29 +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.
---
---
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

@ -247,33 +247,17 @@ func handleHook(t *rt.Thread, c *rt.GoCont, name string, catcher *rt.Closure, ar
} }
} }
// 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`
// --- @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 ummm // #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 {
@ -286,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 {
@ -300,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
@ -348,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. 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

@ -30,7 +30,10 @@ enableGitInfo = true
unsafe = true unsafe = true
[markup.highlight] [markup.highlight]
style = 'pastie' lineNos = true
lineNumbersInTable = false
noClasses = false
codeFences = true
[author] [author]
[author.sammyette] [author.sammyette]

View File

@ -1,11 +1,15 @@
/* Background */ .bg { background-color: #edfdff; } .chroma {
/* PreWrapper */ .chroma { background-color: #edfdff; } display: inline-block;
padding: 0.5em;
}
/* Background */ .bg { background-color: #F7F7F7; }
/* PreWrapper */ .chroma { background-color: #F7F7F7; }
/* Other */ .chroma .x { } /* Other */ .chroma .x { }
/* Error */ .chroma .err { color: #a61717; background-color: #e3d2d2 } /* Error */ .chroma .err { color: #a61717; background-color: #e3d2d2 }
/* CodeLine */ .chroma .cl { } /* CodeLine */ .chroma .cl { }
/* LineTableTD */ .chroma .lntd { vertical-align: top; padding: 0; margin: 0; border: 0; } /* LineTableTD */ .chroma .lntd { vertical-align: top; padding: 0; margin: 0; border: 0; }
/* LineTable */ .chroma .lntable { border-spacing: 0; padding: 0; margin: 0; border: 0; } /* LineTable */ .chroma .lntable { border-spacing: 0; padding: 0; margin: 0; border: 0; }
/* LineHighlight */ .chroma .hl { background-color: #edfdff } /* 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 } /* 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 } /* 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; } /* Line */ .chroma .line { display: flex; }

View File

@ -70,5 +70,9 @@
table tr { table tr {
border-width: 1px; border-width: 1px;
} }
thead {
display: none;
}
</style> </style>
</head> </head>