diff --git a/api.go b/api.go index 93e29d0..f5bcb9f 100644 --- a/api.go +++ b/api.go @@ -556,12 +556,39 @@ func hlinterval(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { // complete(scope, cb) // Registers a completion handler for the specified scope. -// A `scope` is currently only expected to be `command.`, +// A `scope` is expected to be `command.`, // replacing with the name of the command (for example `command.git`). // The documentation for completions, under Features/Completions or `doc completions` // provides more details. // #param scope string // #param cb function +/* +#example +-- This is a very simple example. Read the full doc for completions for details. +hilbish.complete('command.sudo', function(query, ctx, fields) + if #fields == 0 then + -- complete for commands + local comps, pfx = hilbish.completion.bins(query, ctx, fields) + local compGroup = { + items = comps, -- our list of items to complete + type = 'grid' -- what our completions will look like. + } + + return {compGroup}, pfx + end + + -- otherwise just be boring and return files + + local comps, pfx = hilbish.completion.files(query, ctx, fields) + local compGroup = { + items = comps, + type = 'grid' + } + + return {compGroup}, pfx +end) +#example +*/ func hlcomplete(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { scope, cb, err := util.HandleStrCallback(t, c) if err != nil { diff --git a/docs/api/bait.md b/docs/api/bait.md index 950d680..60b1056 100644 --- a/docs/api/bait.md +++ b/docs/api/bait.md @@ -37,7 +37,7 @@ this function will set the user prompt. |----|----| |catch(name, cb)|Catches an event. This function can be used to act on events.| |catchOnce(name, cb)|Catches an event, but only once. This will remove the hook immediately after it runs for the first time.| -|hooks(name) -> table|Returns a list of callbacks that are hooked on an event with the corresponding `name`.| +|hooks(name) -> table|Returns a table of functions that are hooked on an event with the corresponding `name`.| |release(name, catcher)|Removes the `catcher` for the event with `name`.| |throw(name, ...args)|Throws a hook with `name` with the provided `args`.| @@ -96,11 +96,11 @@ bait.hooks(name) -> table -Returns a list of callbacks that are hooked on an event with the corresponding `name`. +Returns a table of functions that are hooked on an event with the corresponding `name`. #### Parameters `string` **`name`** -The name of the function +The name of the hook diff --git a/docs/api/hilbish/_index.md b/docs/api/hilbish/_index.md index ad3d6b7..66f01ee 100644 --- a/docs/api/hilbish/_index.md +++ b/docs/api/hilbish/_index.md @@ -113,7 +113,7 @@ hilbish.complete(scope, cb) Registers a completion handler for the specified scope. -A `scope` is currently only expected to be `command.`, +A `scope` is expected to be `command.`, replacing with the name of the command (for example `command.git`). The documentation for completions, under Features/Completions or `doc completions` provides more details. @@ -125,6 +125,32 @@ provides more details. `function` **`cb`** +#### Example +```lua +-- This is a very simple example. Read the full doc for completions for details. +hilbish.complete('command.sudo', function(query, ctx, fields) + if #fields == 0 then + -- complete for commands + local comps, pfx = hilbish.completion.bins(query, ctx, fields) + local compGroup = { + items = comps, -- our list of items to complete + type = 'grid' -- what our completions will look like. + } + + return {compGroup}, pfx + end + + -- otherwise just be boring and return files + + local comps, pfx = hilbish.completion.files(query, ctx, fields) + local compGroup = { + items = comps, + type = 'grid' + } + + return {compGroup}, pfx +end) +```
diff --git a/docs/api/hilbish/hilbish.runner.md b/docs/api/hilbish/hilbish.runner.md index 9a5cf71..b5cfde4 100644 --- a/docs/api/hilbish/hilbish.runner.md +++ b/docs/api/hilbish/hilbish.runner.md @@ -8,12 +8,47 @@ menu: --- ## Introduction -The runner interface contains functions that allow the user to change + The runner interface contains functions that allow the user to change how Hilbish interprets interactive input. Users can add and change the default runner for interactive input to any language or script of their choosing. A good example is using it to write command in Fennel. +Runners are functions that evaluate user input. The default runners in +Hilbish can run shell script and Lua code. + +A runner is passed the input and has to return a table with these values. +All are not required, only the useful ones the runner needs to return. +(So if there isn't an error, just omit `err`.) + +- `exitCode` (number): A numerical code to indicate the exit result. +- `input` (string): The user input. This will be used to add +to the history. +- `err` (string): A string to indicate an interal error for the runner. +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 to prompt the user for more input. + +Here is a simple example of a fennel runner. It falls back to +shell script if fennel eval has an error. +```lua +local fennel = require 'fennel' + +hilbish.runnerMode(function(input) + local ok = pcall(fennel.eval, input) + if ok then + return { + input = input + } + end + + return hilbish.runner.sh(input) +end) +``` + ## Functions ||| |----|----| diff --git a/docs/completions.md b/docs/completions.md index 0ea60c2..59ead1b 100644 --- a/docs/completions.md +++ b/docs/completions.md @@ -7,59 +7,72 @@ menu: parent: "Features" --- -Hilbish has a pretty good completion system. It has a nice looking -menu, with 2 types of menus: grid (like file completions) or -list. +Completions for commands can be created with the [`hilbish.complete`](../api/hilbish#complete) +function. See the link for how to use it. +To create completions for a command is simple. +The callback will be passed 3 parameters: +- `query` (string): The text that the user is currently trying to complete. +This should be used to match entries. +- `ctx` (string): Contains the entire line. Use this if +more text is needed to be parsed for context. +- `fields` (string): The `ctx` split up by spaces. + +In most cases, the completer just uses `fields` to check the amount +and `query` on what to match entries on. + +In order to return your results, it has to go within a "completion group." +Then you return a table of completion groups and a prefix. The prefix will +usually just be the `query`. + +Hilbish allows one to mix completion menus of different types, so +a grid menu and a list menu can be used and complete and display at the same time. +A completion group is a table with these keys: +- `type` (string): type of completion menu, either `grid` or `list`. +- `items` (table): a list of items. + +The requirements of the `items` table is different based on the +`type`. If it is a `grid`, it can simply be a table of strings. + +Otherwise if it is a `list` then each entry can +either be a string or a table. +Example: +```lua +local cg = { + items = { + 'list item 1', + ['--command-flag-here'] = {'this does a thing', '--the-flag-alias'} + }, + type = 'list' +} +local cg2 = { + items = {'just', 'a bunch', 'of items', 'here', 'hehe'}, + type = 'grid' +} + +return {cg, cg2}, prefix +``` + +Which looks like this: +{{< video src="https://safe.saya.moe/t4CiLK6dgPbD.mp4" >}} + +# Completion Handler Like most parts of Hilbish, it's made to be extensible and customizable. The default handler for completions in general can be overwritten to provide more advanced completions if needed. +This usually doesn't need to be done though, unless you know +what you're doing. -# Completion Handler -By default, it provides 3 things: for the first argument, +The default completion handler provides 3 things: binaries (with a plain name requested to complete, those in -$PATH), files, or command completions. With the default -completion handler, it will try to run a handler for the -command or fallback to file completions. +$PATH), files, or command completions. It will try to run a handler +for the command or fallback to file completions. -To overwrite it, just assign a function to -`hilbish.completion.handler` like so: +To overwrite it, just assign a function to `hilbish.completion.handler` like so: +```lua +-- line is the entire line as a string +-- pos is the position of the cursor. function hilbish.completion.handler(line, pos) -- do things end - -It is passed 2 arguments, the entire line, and the current -cursor position. The functions in the completion interface -take 3 arguments: query, ctx, and fields. - -- The `query`, which what the user is currently trying to complete -- `ctx`, being just the entire line -- `fields` being a table of arguments. It's just `ctx` split up, -delimited by spaces. - -It's expected to return 2 things: a table of completion groups, and -a prefix. A completion group is defined as a table with 2 keys: -`items` and `type`. - -- The `items` field is just a table of items to use for completions. -- The `type` is for the completion menu type, being either `grid` or -`list`. - -The prefix is what all the completions start with. It should be empty -if the user doesn't have a query. If the beginning of the completion -item does not match the prefix, it will be replaced and fixed -properly in the line. It is case sensitive. - -If you want to overwrite the functionality of the general completion -handler, or make your command completion have files as well -(and filter them), then there is the `files` function, which is -mentioned below. - -# Completion Interface -## Functions -- `files(query, ctx, fields)` -> table, prefix: get file completions, -based on the user's query. -- `bins(query, ctx, fields)` -> table, prefix: get binary/executable -completions, based on user query. -- `call(scope, query, ctx, fields)` -> table, prefix: call a completion -handler with `scope`, usually being in the form of `command.` +``` diff --git a/docs/features/runner-mode.md b/docs/features/runner-mode.md index 58b55dd..0f7a8dd 100644 --- a/docs/features/runner-mode.md +++ b/docs/features/runner-mode.md @@ -19,3 +19,48 @@ 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`, +which determines how Hilbish will run user input. By default, this is +set to `hybrid` which is the previously mentioned behaviour of running Lua +first then going to shell script. If you want the reverse order, you can +set it to `hybridRev` and for isolated modes there is `sh` and `lua` +respectively. + +You can also set it to a function, which will be called everytime Hilbish +needs to run interactive input. For more detail, see the [API documentation](../../api/hilbish/hilbish.runner) + +The `hilbish.runner` interface is an alternative to using `hilbish.runnerMode` +and also provides the shell script and Lua runner functions that Hilbish itself uses. + +A runner function is expected to return a table with the following values: +- `exitCode` (number): Exit code of the command +- `input` (string): The text input of the user. This is used by Hilbish to append extra input, in case +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. + - `: not-found` will throw a `command.not-found` hook + based on what `` is. + - `: not-executable` will throw a `command.not-executable` hook. +- `continue` (boolean): Whether Hilbish should prompt the user for no input + +## Functions +These are the "low level" functions for the `hilbish.runner` interface. + ++ setMode(mode) > The same as `hilbish.runnerMode` ++ sh(input) -> table > Runs `input` in Hilbish's sh interpreter ++ lua(input) -> table > Evals `input` as Lua code + +These functions should be preferred over the previous ones. ++ setCurrent(mode) > The same as `setMode`, but works with runners managed +via the functions below. ++ add(name, runner) > Adds a runner to a table of available runners. The `runner` +argument is either a function or a table with a run callback. ++ set(name, runner) > The same as `add` but requires passing a table and +overwrites if the `name`d runner already exists. ++ get(name) > runner > Gets a runner by name. It is a table with at least a +run function, to run input. ++ exec(cmd, runnerName) > Runs `cmd` with a runner. If `runnerName` isn't passed, +the current runner mode is used. diff --git a/docs/jobs.md b/docs/jobs.md index 59f2113..8651051 100644 --- a/docs/jobs.md +++ b/docs/jobs.md @@ -1,11 +1,4 @@ ---- -title: Jobs -description: Controls for background commands in Hilbish. -layout: doc -menu: - docs: - parent: "Features" ---- +(This has mainly been replaced by [hilbish.jobs](../api/hilbish.jobs)). Hilbish has pretty standard job control. It's missing one or two things, but works well. One thing which is different from other shells diff --git a/docs/runner-mode.md b/docs/runner-mode.md deleted file mode 100644 index 4844c27..0000000 --- a/docs/runner-mode.md +++ /dev/null @@ -1,70 +0,0 @@ -Hilbish allows you to change how interactive text can be interpreted. -This is mainly due to the fact that the default method Hilbish uses -is that it runs Lua first and then falls back to shell script. - -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`, -which determines how Hilbish will run user input. By default, this is -set to `hybrid` which is the previously mentioned behaviour of running Lua -first then going to shell script. If you want the reverse order, you can -set it to `hybridRev` and for isolated modes there is `sh` and `lua` -respectively. - -You can also set it to a function, which will be called everytime Hilbish -needs to run interactive input. For example, you can set this to a simple -function to compile and evaluate Fennel, and now you can run Fennel. -You can even mix it with sh to make a hybrid mode with Lua replaced by -Fennel. - -An example: -hilbish.runnerMode(function(input) - local ok = pcall(fennel.eval, input) - if ok then - return input, 0, nil - end - - return hilbish.runner.sh(input) -end) - -The `hilbish.runner` interface is an alternative to using `hilbish.runnerMode` -and also provides the shell script and Lua runner functions that Hilbish itself uses. - -A runner function is expected to return a table with the following values: -- `exitCode` (number): Exit code of the command -- `input` (string): The text input of the user. This is used by Hilbish to append extra input, in case -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. - - `: not-found` will throw a `command.not-found` hook - based on what `` is. - - `: not-executable` will throw a `command.not-executable` hook. -- `continue` (boolean): Whether Hilbish should prompt the user for no input - -## Functions -These are the "low level" functions for the `hilbish.runner` interface. - -+ setMode(mode) > The same as `hilbish.runnerMode` -+ sh(input) -> table > Runs `input` in Hilbish's sh interpreter -+ lua(input) -> table > Evals `input` as Lua code - -These functions should be preferred over the previous ones. -+ setCurrent(mode) > The same as `setMode`, but works with runners managed -via the functions below. -+ add(name, runner) > Adds a runner to a table of available runners. The `runner` -argument is either a function or a table with a run callback. -+ set(name, runner) > The same as `add` but requires passing a table and -overwrites if the `name`d runner already exists. -+ get(name) > runner > Gets a runner by name. It is a table with at least a -run function, to run input. -+ exec(cmd, runnerName) > Runs `cmd` with a runner. If `runnerName` isn't passed, -the current runner mode is used. diff --git a/emmyLuaDocs/bait.lua b/emmyLuaDocs/bait.lua index 09f3d98..c38eea1 100644 --- a/emmyLuaDocs/bait.lua +++ b/emmyLuaDocs/bait.lua @@ -10,7 +10,7 @@ function bait.catch(name, cb) end --- Catches an event, but only once. This will remove the hook immediately after it runs for the first time. function bait.catchOnce(name, cb) end ---- Returns a list of callbacks that are hooked on an event with the corresponding `name`. +--- Returns a table of functions that are hooked on an event with the corresponding `name`. function bait.hooks(name) end --- Removes the `catcher` for the event with `name`. diff --git a/emmyLuaDocs/hilbish.lua b/emmyLuaDocs/hilbish.lua index 8521065..20deb48 100644 --- a/emmyLuaDocs/hilbish.lua +++ b/emmyLuaDocs/hilbish.lua @@ -61,10 +61,12 @@ function hilbish.alias(cmd, orig) end function hilbish.appendPath(dir) end --- Registers a completion handler for the specified scope. ---- A `scope` is currently only expected to be `command.`, +--- A `scope` is expected to be `command.`, --- replacing with the name of the command (for example `command.git`). --- The documentation for completions, under Features/Completions or `doc completions` --- provides more details. +--- +--- function hilbish.complete(scope, cb) end --- Returns the current directory of the shell diff --git a/golibs/bait/bait.go b/golibs/bait/bait.go index 8f24d17..1f85c76 100644 --- a/golibs/bait/bait.go +++ b/golibs/bait/bait.go @@ -285,8 +285,8 @@ func (b *Bait) bcatchOnce(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { } // hooks(name) -> table -// Returns a list of callbacks that are hooked on an event with the corresponding `name`. -// #param name string The name of the function +// Returns a table of functions that are hooked on an event with the corresponding `name`. +// #param name string The name of the hook // #returns table func (b *Bait) bhooks(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { if err := c.Check1Arg(); err != nil { diff --git a/runnermode.go b/runnermode.go index 56a0178..55adfdc 100644 --- a/runnermode.go +++ b/runnermode.go @@ -8,11 +8,47 @@ import ( // #interface runner // interactive command runner customization -// The runner interface contains functions that allow the user to change -// how Hilbish interprets interactive input. -// Users can add and change the default runner for interactive input to any -// language or script of their choosing. A good example is using it to -// write command in Fennel. +/* The runner interface contains functions that allow the user to change +how Hilbish interprets interactive input. +Users can add and change the default runner for interactive input to any +language or script of their choosing. A good example is using it to +write command in Fennel. + +Runners are functions that evaluate user input. The default runners in +Hilbish can run shell script and Lua code. + +A runner is passed the input and has to return a table with these values. +All are not required, only the useful ones the runner needs to return. +(So if there isn't an error, just omit `err`.) + +- `exitCode` (number): A numerical code to indicate the exit result. +- `input` (string): The user input. This will be used to add +to the history. +- `err` (string): A string to indicate an interal error for the runner. +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 to prompt the user for more input. + +Here is a simple example of a fennel runner. It falls back to +shell script if fennel eval has an error. +```lua +local fennel = require 'fennel' + +hilbish.runnerMode(function(input) + local ok = pcall(fennel.eval, input) + if ok then + return { + input = input + } + end + + return hilbish.runner.sh(input) +end) +``` +*/ func runnerModeLoader(rtm *rt.Runtime) *rt.Table { exports := map[string]util.LuaExport{ "sh": {shRunner, 1, false}, diff --git a/website/static/completion.mp4 b/website/static/completion.mp4 new file mode 100644 index 0000000..057f9ab Binary files /dev/null and b/website/static/completion.mp4 differ diff --git a/website/themes/hsh/layouts/shortcodes/video.html b/website/themes/hsh/layouts/shortcodes/video.html new file mode 100644 index 0000000..d0f1314 --- /dev/null +++ b/website/themes/hsh/layouts/shortcodes/video.html @@ -0,0 +1,5 @@ + +