mirror of
https://github.com/Hilbis/Hilbish
synced 2025-07-03 01:32:03 +00:00
Compare commits
13 Commits
cdd31e1c4f
...
589ef8a6d3
Author | SHA1 | Date | |
---|---|---|---|
589ef8a6d3 | |||
005c373996 | |||
5ca534d4e5 | |||
702c75c0c2 | |||
9caecdc1a4 | |||
4e05026e4e | |||
24de9e5baf | |||
c121356e0f | |||
a2e23f1310 | |||
4ba285e74b | |||
6c51f1e374 | |||
789c2cc714 | |||
f3e1d1c4e7 |
34
api.go
34
api.go
@ -38,7 +38,6 @@ var exports = map[string]util.LuaExport{
|
||||
"complete": {hlcomplete, 2, false},
|
||||
"cwd": {hlcwd, 0, false},
|
||||
"exec": {hlexec, 1, false},
|
||||
"runnerMode": {hlrunnerMode, 1, false},
|
||||
"goro": {hlgoro, 1, true},
|
||||
"highlighter": {hlhighlighter, 1, false},
|
||||
"hinter": {hlhinter, 1, false},
|
||||
@ -301,7 +300,7 @@ hilbish.multiprompt '-->'
|
||||
*/
|
||||
func hlmultiprompt(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
if err := c.Check1Arg(); err != nil {
|
||||
return nil, err
|
||||
return c.PushingNext1(t.Runtime, rt.StringValue(multilinePrompt)), nil
|
||||
}
|
||||
prompt, err := c.StringArg(0)
|
||||
if err != nil {
|
||||
@ -639,37 +638,6 @@ func hlinputMode(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
return c.Next(), nil
|
||||
}
|
||||
|
||||
// runnerMode(mode)
|
||||
// **NOTE: This function is deprecated and will be removed in 3.0**
|
||||
// Use `hilbish.runner.setCurrent` instead.
|
||||
// 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.
|
||||
// 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
|
||||
// will call it to execute user input instead.
|
||||
// Read [about runner mode](../features/runner-mode) for more information.
|
||||
// #param mode string|function
|
||||
func hlrunnerMode(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
// TODO: Reimplement in Lua
|
||||
if err := c.Check1Arg(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mode := c.Arg(0)
|
||||
|
||||
switch mode.Type() {
|
||||
case rt.StringType:
|
||||
switch mode.AsString() {
|
||||
case "hybrid", "hybridRev", "lua", "sh": runnerMode = mode
|
||||
default: return nil, errors.New("execMode: expected either a function or hybrid, hybridRev, lua, sh. Received " + mode.AsString())
|
||||
}
|
||||
case rt.FunctionType: runnerMode = mode
|
||||
default: return nil, errors.New("execMode: expected either a function or hybrid, hybridRev, lua, sh. Received " + mode.TypeName())
|
||||
}
|
||||
|
||||
return c.Next(), nil
|
||||
}
|
||||
|
||||
// hinter(line, pos)
|
||||
// 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
|
||||
|
@ -84,6 +84,7 @@ var prefix = map[string]string{
|
||||
"commander": "c",
|
||||
"bait": "b",
|
||||
"terminal": "term",
|
||||
"snail": "snail",
|
||||
}
|
||||
|
||||
func getTagsAndDocs(docs string) (map[string][]tag, []string) {
|
||||
@ -203,11 +204,16 @@ func setupDocType(mod string, typ *doc.Type) *docPiece {
|
||||
}
|
||||
|
||||
typeTable[strings.ToLower(typeName)] = []string{parentMod, interfaces}
|
||||
println(typeName, parentMod, interfaces)
|
||||
|
||||
return dps
|
||||
}
|
||||
|
||||
func setupDoc(mod string, fun *doc.Func) *docPiece {
|
||||
if fun.Doc == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
docs := strings.TrimSpace(fun.Doc)
|
||||
tags, parts := getTagsAndDocs(docs)
|
||||
|
||||
@ -320,7 +326,7 @@ provided by Hilbish.
|
||||
|
||||
os.Mkdir("emmyLuaDocs", 0777)
|
||||
|
||||
dirs := []string{"./"}
|
||||
dirs := []string{"./", "./util"}
|
||||
filepath.Walk("golibs/", func (path string, info os.FileInfo, err error) error {
|
||||
if !info.IsDir() {
|
||||
return nil
|
||||
@ -347,7 +353,7 @@ provided by Hilbish.
|
||||
pieces := []docPiece{}
|
||||
typePieces := []docPiece{}
|
||||
mod := l
|
||||
if mod == "main" {
|
||||
if mod == "main" || mod == "util" {
|
||||
mod = "hilbish"
|
||||
}
|
||||
var hasInterfaces bool
|
||||
@ -431,14 +437,25 @@ provided by Hilbish.
|
||||
interfaceModules[modname].Types = append(interfaceModules[modname].Types, piece)
|
||||
}
|
||||
|
||||
docs[mod] = module{
|
||||
Types: filteredTypePieces,
|
||||
Docs: filteredPieces,
|
||||
ShortDescription: shortDesc,
|
||||
Description: strings.Join(desc, "\n"),
|
||||
HasInterfaces: hasInterfaces,
|
||||
Properties: docPieceTag("property", tags),
|
||||
Fields: docPieceTag("field", tags),
|
||||
println(mod)
|
||||
fmt.Println(filteredTypePieces)
|
||||
if newDoc, ok := docs[mod]; ok {
|
||||
println("fuck")
|
||||
oldMod := docs[mod]
|
||||
newDoc.Types = append(filteredTypePieces, oldMod.Types...)
|
||||
newDoc.Docs = append(filteredPieces, oldMod.Docs...)
|
||||
|
||||
docs[mod] = newDoc
|
||||
} else {
|
||||
docs[mod] = module{
|
||||
Types: filteredTypePieces,
|
||||
Docs: filteredPieces,
|
||||
ShortDescription: shortDesc,
|
||||
Description: strings.Join(desc, "\n"),
|
||||
HasInterfaces: hasInterfaces,
|
||||
Properties: docPieceTag("property", tags),
|
||||
Fields: docPieceTag("field", tags),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,6 @@ for _, fname in ipairs(files) do
|
||||
local mod = header:match(modpattern)
|
||||
if not mod then goto continue end
|
||||
|
||||
print(fname, mod)
|
||||
pieces[mod] = {}
|
||||
descriptions[mod] = {}
|
||||
|
||||
@ -42,10 +41,12 @@ for _, fname in ipairs(files) do
|
||||
|
||||
local dps = {
|
||||
description = {},
|
||||
example = {},
|
||||
params = {}
|
||||
}
|
||||
|
||||
local offset = 1
|
||||
local doingExample = false
|
||||
while true do
|
||||
local prev = lines[lineno - offset]
|
||||
|
||||
@ -59,17 +60,25 @@ for _, fname in ipairs(files) do
|
||||
|
||||
if emmy then
|
||||
if emmy == 'param' then
|
||||
print('bruh', emmythings[1], emmythings[2])
|
||||
table.insert(dps.params, 1, {
|
||||
name = emmythings[1],
|
||||
type = emmythings[2],
|
||||
-- the +1 accounts for space.
|
||||
description = table.concat(emmythings, ' '):sub(emmythings[1]:len() + 1 + emmythings[2]:len() + 1)
|
||||
})
|
||||
print(table.concat(emmythings, '/'))
|
||||
end
|
||||
else
|
||||
table.insert(dps.description, 1, docline)
|
||||
if docline:match '#example' then
|
||||
doingExample = not doingExample
|
||||
end
|
||||
|
||||
if not docline:match '#example' then
|
||||
if doingExample then
|
||||
table.insert(dps.example, 1, docline)
|
||||
else
|
||||
table.insert(dps.description, 1, docline)
|
||||
end
|
||||
end
|
||||
end
|
||||
offset = offset + 1
|
||||
else
|
||||
@ -77,7 +86,7 @@ for _, fname in ipairs(files) do
|
||||
end
|
||||
end
|
||||
|
||||
pieces[mod][funcName] = dps
|
||||
table.insert(pieces[mod], {funcName, dps})
|
||||
end
|
||||
docPiece = {}
|
||||
goto continue2
|
||||
@ -109,11 +118,15 @@ for iface, dps in pairs(pieces) do
|
||||
docParent = "API"
|
||||
path = string.format('docs/api/%s/%s.md', mod, iface)
|
||||
end
|
||||
if iface == 'hilbish' then
|
||||
docParent = "API"
|
||||
path = string.format('docs/api/hilbish/_index.md', mod, iface)
|
||||
end
|
||||
|
||||
fs.mkdir(fs.dir(path), true)
|
||||
|
||||
local exists = pcall(fs.stat, path)
|
||||
local newOrNotNature = exists and mod ~= 'nature'
|
||||
local newOrNotNature = (exists and mod ~= 'nature') or iface == 'hilbish'
|
||||
|
||||
local f <close> = io.open(path, newOrNotNature and 'r+' or 'w+')
|
||||
local tocPos
|
||||
@ -129,9 +142,6 @@ for iface, dps in pairs(pieces) do
|
||||
tocPos = f:seek()
|
||||
end
|
||||
end
|
||||
print(f)
|
||||
|
||||
print('mod and path:', mod, path)
|
||||
|
||||
local tocSearch = false
|
||||
for line in f:lines() do
|
||||
@ -144,7 +154,10 @@ for iface, dps in pairs(pieces) do
|
||||
end
|
||||
end
|
||||
|
||||
for func, docs in pairs(dps) do
|
||||
table.sort(dps, function(a, b) return a[1] < b[1] end)
|
||||
for _, piece in pairs(dps) do
|
||||
local func = piece[1]
|
||||
local docs = piece[2]
|
||||
local sig = string.format('%s.%s(', iface, func)
|
||||
local params = ''
|
||||
for idx, param in ipairs(docs.params) do
|
||||
@ -186,6 +199,10 @@ for iface, dps in pairs(pieces) do
|
||||
f:write(string.format('`%s` **`%s`** \n', param.name:gsub('%?$', ''), param.type))
|
||||
f:write(string.format('%s\n\n', param.description))
|
||||
end
|
||||
if #docs.example ~= 0 then
|
||||
f:write '#### Example\n'
|
||||
f:write(string.format('```lua\n%s\n```\n', table.concat(docs.example, '\n')))
|
||||
end
|
||||
--[[
|
||||
local params = table.filter(docs, function(t)
|
||||
return t:match '^%-%-%- @param'
|
||||
|
@ -28,10 +28,10 @@ interfaces and functions which directly relate to shell functionality.
|
||||
|<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, streams) -> 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.|
|
||||
|<a href="#timeout">timeout(cb, time) -> @Timer</a>|Executed the `cb` function after a period of `time`.|
|
||||
|<a href="#which">which(name) -> string</a>|Checks if `name` is a valid command.|
|
||||
|<a href="#runnerMode">runnerMode(mode)</a>|Sets the execution/runner mode for interactive Hilbish.|
|
||||
|<a href="#run">run(cmd, streams)</a>|Runs `cmd` in Hilbish's shell script interpreter.|
|
||||
|
||||
## Static module fields
|
||||
|||
|
||||
@ -408,72 +408,6 @@ Returns `input`, will be nil if Ctrl-D is pressed, or an error occurs.
|
||||
`string` **`prompt?`**
|
||||
Text to print before input, can be empty.
|
||||
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
<div id='run'>
|
||||
<h4 class='heading'>
|
||||
hilbish.run(cmd, streams) -> 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.
|
||||
The `streams` parameter specifies the output and input streams the command should use.
|
||||
For example, to write command output to a sink.
|
||||
As a table, the caller can directly specify the standard output, error, and input
|
||||
streams of the command with the table keys `out`, `err`, and `input` respectively.
|
||||
As a boolean, it specifies whether the command should use standard output or return its output streams.
|
||||
|
||||
#### Parameters
|
||||
`string` **`cmd`**
|
||||
|
||||
|
||||
`table|boolean` **`streams`**
|
||||
|
||||
|
||||
#### Example
|
||||
```lua
|
||||
|
||||
// This code is the same as `ls -l | wc -l`
|
||||
local fs = require 'fs'
|
||||
local pr, pw = fs.pipe()
|
||||
hilbish.run('ls -l', {
|
||||
stdout = pw,
|
||||
stderr = pw,
|
||||
})
|
||||
|
||||
pw:close()
|
||||
|
||||
hilbish.run('wc -l', {
|
||||
stdin = pr
|
||||
})
|
||||
|
||||
```
|
||||
</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 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),
|
||||
sh, and lua. It also accepts a function, to which if it is passed one
|
||||
will call it to execute user input instead.
|
||||
Read [about runner mode](../features/runner-mode) for more information.
|
||||
|
||||
#### Parameters
|
||||
`string|function` **`mode`**
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
@ -519,8 +453,7 @@ Will return the path of the binary, or a basename if it's a commander.
|
||||
<hr>
|
||||
|
||||
## Sink
|
||||
A sink is a structure that has input and/or output to/from
|
||||
a desination.
|
||||
A sink is a structure that has input and/or output to/from a desination.
|
||||
|
||||
### Methods
|
||||
#### autoFlush(auto)
|
||||
@ -542,3 +475,65 @@ Writes data to a sink.
|
||||
#### writeln(str)
|
||||
Writes data to a sink with a newline at the end.
|
||||
|
||||
<hr>
|
||||
<div id='run'>
|
||||
<h4 class='heading'>
|
||||
hilbish.run(cmd, streams)
|
||||
<a href="#run" class='heading-link'>
|
||||
<i class="fas fa-paperclip"></i>
|
||||
</a>
|
||||
</h4>
|
||||
|
||||
Runs `cmd` in Hilbish's shell script interpreter.
|
||||
The `streams` parameter specifies the output and input streams the command should use.
|
||||
For example, to write command output to a sink.
|
||||
As a table, the caller can directly specify the standard output, error, and input
|
||||
streams of the command with the table keys `out`, `err`, and `input` respectively.
|
||||
As a boolean, it specifies whether the command should use standard output or return its output streams.
|
||||
#### Parameters
|
||||
`cmd` **`string`**
|
||||
|
||||
|
||||
`streams` **`table|boolean`**
|
||||
|
||||
|
||||
#### Example
|
||||
```lua
|
||||
-- This code is the same as `ls -l | wc -l`
|
||||
local fs = require 'fs'
|
||||
local pr, pw = fs.pipe()
|
||||
hilbish.run('ls -l', {
|
||||
stdout = pw,
|
||||
stderr = pw,
|
||||
})
|
||||
pw:close()
|
||||
hilbish.run('wc -l', {
|
||||
stdin = pr
|
||||
})
|
||||
```
|
||||
</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.
|
||||
**NOTE: This function is deprecated and will be removed in 3.0**
|
||||
Use `hilbish.runner.setCurrent` instead.
|
||||
This determines whether 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),
|
||||
sh, and lua. It also accepts a function, to which if it is passed one
|
||||
will call it to execute user input instead.
|
||||
Read [about runner mode](../features/runner-mode) for more information.
|
||||
#### Parameters
|
||||
`mode` **`string|function`**
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
135
docs/api/hilbish/hilbish.messages.md
Normal file
135
docs/api/hilbish/hilbish.messages.md
Normal file
@ -0,0 +1,135 @@
|
||||
---
|
||||
title: Module hilbish.messages
|
||||
description: simplistic message passing
|
||||
layout: doc
|
||||
menu:
|
||||
docs:
|
||||
parent: "API"
|
||||
---
|
||||
|
||||
|
||||
## Introduction
|
||||
The messages interface defines a way for Hilbish-integrated commands,
|
||||
user config and other tasks to send notifications to alert the user.z
|
||||
The `hilbish.message` type is a table with the following keys:
|
||||
`title` (string): A title for the message notification.
|
||||
`text` (string): The contents of the message.
|
||||
`channel` (string): States the origin of the message, `hilbish.*` is reserved for Hilbish tasks.
|
||||
`summary` (string): A short summary of the `text`.
|
||||
`icon` (string): Unicode (preferably standard emoji) icon for the message notification
|
||||
`read` (boolean): Whether the full message has been read or not.
|
||||
|
||||
## Functions
|
||||
|||
|
||||
|----|----|
|
||||
|<a href="#unreadCount">unreadCount()</a>|Returns the amount of unread messages.|
|
||||
|<a href="#send">send(message)</a>|Sends a message.|
|
||||
|<a href="#readAll">readAll()</a>|Marks all messages as read.|
|
||||
|<a href="#read">read(idx)</a>|Marks a message at `idx` as read.|
|
||||
|<a href="#delete">delete(idx)</a>|Deletes the message at `idx`.|
|
||||
|<a href="#clear">clear()</a>|Deletes all messages.|
|
||||
|<a href="#all">all()</a>|Returns all messages.|
|
||||
<hr>
|
||||
<div id='all'>
|
||||
<h4 class='heading'>
|
||||
hilbish.messages.all()
|
||||
<a href="#all" class='heading-link'>
|
||||
<i class="fas fa-paperclip"></i>
|
||||
</a>
|
||||
</h4>
|
||||
|
||||
Returns all messages.
|
||||
#### Parameters
|
||||
This function has no parameters.
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
<div id='clear'>
|
||||
<h4 class='heading'>
|
||||
hilbish.messages.clear()
|
||||
<a href="#clear" class='heading-link'>
|
||||
<i class="fas fa-paperclip"></i>
|
||||
</a>
|
||||
</h4>
|
||||
|
||||
Deletes all messages.
|
||||
#### Parameters
|
||||
This function has no parameters.
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
<div id='delete'>
|
||||
<h4 class='heading'>
|
||||
hilbish.messages.delete(idx)
|
||||
<a href="#delete" class='heading-link'>
|
||||
<i class="fas fa-paperclip"></i>
|
||||
</a>
|
||||
</h4>
|
||||
|
||||
Deletes the message at `idx`.
|
||||
#### Parameters
|
||||
`idx` **`number`**
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
<div id='read'>
|
||||
<h4 class='heading'>
|
||||
hilbish.messages.read(idx)
|
||||
<a href="#read" class='heading-link'>
|
||||
<i class="fas fa-paperclip"></i>
|
||||
</a>
|
||||
</h4>
|
||||
|
||||
Marks a message at `idx` as read.
|
||||
#### Parameters
|
||||
`idx` **`number`**
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
<div id='readAll'>
|
||||
<h4 class='heading'>
|
||||
hilbish.messages.readAll()
|
||||
<a href="#readAll" class='heading-link'>
|
||||
<i class="fas fa-paperclip"></i>
|
||||
</a>
|
||||
</h4>
|
||||
|
||||
Marks all messages as read.
|
||||
#### Parameters
|
||||
This function has no parameters.
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
<div id='send'>
|
||||
<h4 class='heading'>
|
||||
hilbish.messages.send(message)
|
||||
<a href="#send" class='heading-link'>
|
||||
<i class="fas fa-paperclip"></i>
|
||||
</a>
|
||||
</h4>
|
||||
|
||||
Sends a message.
|
||||
#### Parameters
|
||||
`message` **`hilbish.message`**
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
<div id='unreadCount'>
|
||||
<h4 class='heading'>
|
||||
hilbish.messages.unreadCount()
|
||||
<a href="#unreadCount" class='heading-link'>
|
||||
<i class="fas fa-paperclip"></i>
|
||||
</a>
|
||||
</h4>
|
||||
|
||||
Returns the amount of unread messages.
|
||||
#### Parameters
|
||||
This function has no parameters.
|
||||
</div>
|
||||
|
@ -54,29 +54,16 @@ end)
|
||||
## Functions
|
||||
|||
|
||||
|----|----|
|
||||
|<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,
|
||||
as the higher level functions listed below this will handle it.
|
||||
|
||||
#### Parameters
|
||||
`function` **`cb`**
|
||||
|
||||
|
||||
</div>
|
||||
|<a href="#sh">sh()</a>|nil|
|
||||
|<a href="#setMode">setMode(mode)</a>|**NOTE: This function is deprecated and will be removed in 3.0**|
|
||||
|<a href="#setCurrent">setCurrent(name)</a>|Sets Hilbish's runner mode by name.|
|
||||
|<a href="#set">set(name, runner)</a>|*Sets* a runner by name. The difference between this function and|
|
||||
|<a href="#run">run(input, priv)</a>|Runs `input` with the currently set Hilbish runner.|
|
||||
|<a href="#getCurrent">getCurrent()</a>|Returns the current runner by name.|
|
||||
|<a href="#get">get(name)</a>|Get a runner by name.|
|
||||
|<a href="#exec">exec(cmd, runnerName)</a>|Executes `cmd` with a runner.|
|
||||
|<a href="#add">add(name, runner)</a>|Adds a runner to the table of available runners.|
|
||||
|
||||
<hr>
|
||||
<div id='runner.lua'>
|
||||
@ -97,20 +84,164 @@ or `load`, but is appropriated for the runner interface.
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
<div id='runner.sh'>
|
||||
<div id='add'>
|
||||
<h4 class='heading'>
|
||||
hilbish.runner.sh(cmd)
|
||||
<a href="#runner.sh" class='heading-link'>
|
||||
hilbish.runner.add(name, runner)
|
||||
<a href="#add" class='heading-link'>
|
||||
<i class="fas fa-paperclip"></i>
|
||||
</a>
|
||||
</h4>
|
||||
|
||||
Runs a command in Hilbish's shell script interpreter.
|
||||
This is the equivalent of using `source`.
|
||||
|
||||
Adds a runner to the table of available runners.
|
||||
If runner is a table, it must have the run function in it.
|
||||
#### Parameters
|
||||
`string` **`cmd`**
|
||||
`name` **`string`**
|
||||
Name of the runner
|
||||
|
||||
`runner` **`function|table`**
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
<div id='exec'>
|
||||
<h4 class='heading'>
|
||||
hilbish.runner.exec(cmd, runnerName)
|
||||
<a href="#exec" class='heading-link'>
|
||||
<i class="fas fa-paperclip"></i>
|
||||
</a>
|
||||
</h4>
|
||||
|
||||
Executes `cmd` with a runner.
|
||||
If `runnerName` is not specified, it uses the default Hilbish runner.
|
||||
#### Parameters
|
||||
`cmd` **`string`**
|
||||
|
||||
|
||||
`runnerName` **`string?`**
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
<div id='get'>
|
||||
<h4 class='heading'>
|
||||
hilbish.runner.get(name)
|
||||
<a href="#get" class='heading-link'>
|
||||
<i class="fas fa-paperclip"></i>
|
||||
</a>
|
||||
</h4>
|
||||
|
||||
Get a runner by name.
|
||||
#### Parameters
|
||||
`name` **`string`**
|
||||
Name of the runner to retrieve.
|
||||
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
<div id='getCurrent'>
|
||||
<h4 class='heading'>
|
||||
hilbish.runner.getCurrent()
|
||||
<a href="#getCurrent" class='heading-link'>
|
||||
<i class="fas fa-paperclip"></i>
|
||||
</a>
|
||||
</h4>
|
||||
|
||||
Returns the current runner by name.
|
||||
#### Parameters
|
||||
This function has no parameters.
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
<div id='run'>
|
||||
<h4 class='heading'>
|
||||
hilbish.runner.run(input, priv)
|
||||
<a href="#run" class='heading-link'>
|
||||
<i class="fas fa-paperclip"></i>
|
||||
</a>
|
||||
</h4>
|
||||
|
||||
Runs `input` with the currently set Hilbish runner.
|
||||
This method is how Hilbish executes commands.
|
||||
`priv` is an optional boolean used to state if the input should be saved to history.
|
||||
#### Parameters
|
||||
`input` **`string`**
|
||||
|
||||
|
||||
`priv` **`bool`**
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
<div id='set'>
|
||||
<h4 class='heading'>
|
||||
hilbish.runner.set(name, runner)
|
||||
<a href="#set" class='heading-link'>
|
||||
<i class="fas fa-paperclip"></i>
|
||||
</a>
|
||||
</h4>
|
||||
|
||||
*Sets* a runner by name. The difference between this function and
|
||||
add, is set will *not* check if the named runner exists.
|
||||
The runner table must have the run function in it.
|
||||
#### Parameters
|
||||
`name` **`string`**
|
||||
|
||||
|
||||
`runner` **`table`**
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
<div id='setCurrent'>
|
||||
<h4 class='heading'>
|
||||
hilbish.runner.setCurrent(name)
|
||||
<a href="#setCurrent" class='heading-link'>
|
||||
<i class="fas fa-paperclip"></i>
|
||||
</a>
|
||||
</h4>
|
||||
|
||||
Sets Hilbish's runner mode by name.
|
||||
#### Parameters
|
||||
`name` **`string`**
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
<div id='setMode'>
|
||||
<h4 class='heading'>
|
||||
hilbish.runner.setMode(mode)
|
||||
<a href="#setMode" class='heading-link'>
|
||||
<i class="fas fa-paperclip"></i>
|
||||
</a>
|
||||
</h4>
|
||||
|
||||
**NOTE: This function is deprecated and will be removed in 3.0**
|
||||
Use `hilbish.runner.setCurrent` instead.
|
||||
This is the same as the `hilbish.runnerMode` function.
|
||||
It takes a callback, which will be used to execute all interactive input.
|
||||
Or a string which names the runner mode to use.
|
||||
#### Parameters
|
||||
`mode` **`string|function`**
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
<div id='sh'>
|
||||
<h4 class='heading'>
|
||||
hilbish.runner.sh()
|
||||
<a href="#sh" class='heading-link'>
|
||||
<i class="fas fa-paperclip"></i>
|
||||
</a>
|
||||
</h4>
|
||||
|
||||
|
||||
#### Parameters
|
||||
This function has no parameters.
|
||||
</div>
|
||||
|
||||
|
45
docs/api/snail.md
Normal file
45
docs/api/snail.md
Normal file
@ -0,0 +1,45 @@
|
||||
---
|
||||
title: Module snail
|
||||
description: shell script interpreter library
|
||||
layout: doc
|
||||
menu:
|
||||
docs:
|
||||
parent: "API"
|
||||
---
|
||||
|
||||
## Introduction
|
||||
|
||||
The snail library houses Hilbish's Lua wrapper of its shell script interpreter.
|
||||
It's not very useful other than running shell scripts, which can be done with other
|
||||
Hilbish functions.
|
||||
|
||||
## Functions
|
||||
|||
|
||||
|----|----|
|
||||
|<a href="#new">new() -> @Snail</a>|Creates a new Snail instance.|
|
||||
|
||||
<hr>
|
||||
<div id='new'>
|
||||
<h4 class='heading'>
|
||||
snail.new() -> <a href="/Hilbish/docs/api/snail/#snail" style="text-decoration: none;" id="lol">Snail</a>
|
||||
<a href="#new" class='heading-link'>
|
||||
<i class="fas fa-paperclip"></i>
|
||||
</a>
|
||||
</h4>
|
||||
|
||||
Creates a new Snail instance.
|
||||
|
||||
#### Parameters
|
||||
This function has no parameters.
|
||||
</div>
|
||||
|
||||
## Types
|
||||
<hr>
|
||||
|
||||
## Snail
|
||||
A Snail is a shell script interpreter instance.
|
||||
|
||||
### Methods
|
||||
#### run(command, streams)
|
||||
Runs a shell command. Works the same as `hilbish.run`.
|
||||
|
@ -15,43 +15,11 @@ directories.
|
||||
## Functions
|
||||
|||
|
||||
|----|----|
|
||||
|<a href="#setOld">setOld(d)</a>|Sets the old directory string.|
|
||||
|<a href="#recent">recent(idx)</a>|Get entry from recent directories list based on index.|
|
||||
|<a href="#push">push(dir)</a>|Add `dir` to the recent directories list.|
|
||||
|<a href="#pop">pop(num)</a>|Remove the specified amount of dirs from the recent directories list.|
|
||||
|<a href="#peak">peak(num)</a>|Look at `num` amount of recent directories, starting from the latest.|
|
||||
|<a href="#push">push(dir)</a>|Add `dir` to the recent directories list.|
|
||||
|<a href="#setOld">setOld(d)</a>|Sets the old directory string.|
|
||||
<hr>
|
||||
<div id='setOld'>
|
||||
<h4 class='heading'>
|
||||
dirs.setOld(d)
|
||||
<a href="#setOld" class='heading-link'>
|
||||
<i class="fas fa-paperclip"></i>
|
||||
</a>
|
||||
</h4>
|
||||
|
||||
Sets the old directory string.
|
||||
#### Parameters
|
||||
`d` **`string`**
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
<div id='push'>
|
||||
<h4 class='heading'>
|
||||
dirs.push(dir)
|
||||
<a href="#push" class='heading-link'>
|
||||
<i class="fas fa-paperclip"></i>
|
||||
</a>
|
||||
</h4>
|
||||
|
||||
Add `dir` to the recent directories list.
|
||||
#### Parameters
|
||||
`dir` **`string`**
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
<div id='peak'>
|
||||
<h4 class='heading'>
|
||||
@ -83,6 +51,22 @@ Remove the specified amount of dirs from the recent directories list.
|
||||
`num` **`number`**
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
<div id='push'>
|
||||
<h4 class='heading'>
|
||||
dirs.push(dir)
|
||||
<a href="#push" class='heading-link'>
|
||||
<i class="fas fa-paperclip"></i>
|
||||
</a>
|
||||
</h4>
|
||||
|
||||
Add `dir` to the recent directories list.
|
||||
#### Parameters
|
||||
`dir` **`string`**
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
@ -101,3 +85,19 @@ Get entry from recent directories list based on index.
|
||||
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
<div id='setOld'>
|
||||
<h4 class='heading'>
|
||||
dirs.setOld(d)
|
||||
<a href="#setOld" class='heading-link'>
|
||||
<i class="fas fa-paperclip"></i>
|
||||
</a>
|
||||
</h4>
|
||||
|
||||
Sets the old directory string.
|
||||
#### Parameters
|
||||
`d` **`string`**
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
@ -17,29 +17,9 @@ is by the Greenhouse pager.
|
||||
## Functions
|
||||
|||
|
||||
|----|----|
|
||||
|<a href="#renderInfoBlock">renderInfoBlock(type, text)</a>|Renders an info block. An info block is a block of text with|
|
||||
|<a href="#renderCodeBlock">renderCodeBlock(text)</a>|Assembles and renders a code block. This returns|
|
||||
|<a href="#highlight">highlight(text)</a>|Performs basic Lua code highlighting.|
|
||||
|<a href="#renderInfoBlock">renderInfoBlock(type, text)</a>|Renders an info block. An info block is a block of text with|
|
||||
<hr>
|
||||
<div id='renderInfoBlock'>
|
||||
<h4 class='heading'>
|
||||
doc.renderInfoBlock(type, text)
|
||||
<a href="#renderInfoBlock" class='heading-link'>
|
||||
<i class="fas fa-paperclip"></i>
|
||||
</a>
|
||||
</h4>
|
||||
|
||||
Renders an info block. An info block is a block of text with
|
||||
an icon and styled text block.
|
||||
#### Parameters
|
||||
`type` **`string`**
|
||||
Type of info block. The only one specially styled is the `warning`.
|
||||
|
||||
`text` **`string`**
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
<div id='highlight'>
|
||||
<h4 class='heading'>
|
||||
@ -74,3 +54,23 @@ and styles it to resemble a code block.
|
||||
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
<div id='renderInfoBlock'>
|
||||
<h4 class='heading'>
|
||||
doc.renderInfoBlock(type, text)
|
||||
<a href="#renderInfoBlock" class='heading-link'>
|
||||
<i class="fas fa-paperclip"></i>
|
||||
</a>
|
||||
</h4>
|
||||
|
||||
Renders an info block. An info block is a block of text with
|
||||
an icon and styled text block.
|
||||
#### Parameters
|
||||
`type` **`string`**
|
||||
Type of info block. The only one specially styled is the `warning`.
|
||||
|
||||
`text` **`string`**
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
@ -7,12 +7,6 @@ local hilbish = {}
|
||||
--- @param cmd string
|
||||
function hilbish.aliases.add(alias, cmd) end
|
||||
|
||||
--- 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,
|
||||
--- as the higher level functions listed below this will handle it.
|
||||
function hilbish.runner.setMode(cb) end
|
||||
|
||||
--- Returns the current input line.
|
||||
function hilbish.editor.getLine() end
|
||||
|
||||
@ -131,24 +125,6 @@ function hilbish.prompt(str, typ) end
|
||||
--- Returns `input`, will be nil if Ctrl-D is pressed, or an error occurs.
|
||||
function hilbish.read(prompt) end
|
||||
|
||||
--- Runs `cmd` in Hilbish's shell script interpreter.
|
||||
--- The `streams` parameter specifies the output and input streams the command should use.
|
||||
--- For example, to write command output to a sink.
|
||||
--- As a table, the caller can directly specify the standard output, error, and input
|
||||
--- streams of the command with the table keys `out`, `err`, and `input` respectively.
|
||||
--- As a boolean, it specifies whether the command should use standard output or return its output streams.
|
||||
---
|
||||
function hilbish.run(cmd, streams) end
|
||||
|
||||
--- 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.
|
||||
--- 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
|
||||
--- will call it to execute user input instead.
|
||||
--- Read [about runner mode](../features/runner-mode) for more information.
|
||||
function hilbish.runnerMode(mode) end
|
||||
|
||||
--- Executed the `cb` function after a period of `time`.
|
||||
--- This creates a Timer that starts ticking immediately.
|
||||
function hilbish.timeout(cb, time) end
|
||||
@ -168,28 +144,6 @@ function hilbish.jobs:foreground() end
|
||||
--- or `load`, but is appropriated for the runner interface.
|
||||
function hilbish.runner.lua(cmd) end
|
||||
|
||||
--- Sets/toggles the option of automatically flushing output.
|
||||
--- A call with no argument will toggle the value.
|
||||
--- @param auto boolean|nil
|
||||
function hilbish:autoFlush(auto) end
|
||||
|
||||
--- Flush writes all buffered input to the sink.
|
||||
function hilbish:flush() end
|
||||
|
||||
--- Reads a liine of input from the sink.
|
||||
--- @returns string
|
||||
function hilbish:read() end
|
||||
|
||||
--- Reads all input from the sink.
|
||||
--- @returns string
|
||||
function hilbish:readAll() end
|
||||
|
||||
--- Writes data to a sink.
|
||||
function hilbish:write(str) end
|
||||
|
||||
--- Writes data to a sink with a newline at the end.
|
||||
function hilbish:writeln(str) end
|
||||
|
||||
--- Starts running the job.
|
||||
function hilbish.jobs:start() end
|
||||
|
||||
@ -200,10 +154,6 @@ function hilbish.jobs:stop() end
|
||||
--- It will throw if any error occurs.
|
||||
function hilbish.module.load(path) end
|
||||
|
||||
--- Runs a command in Hilbish's shell script interpreter.
|
||||
--- This is the equivalent of using `source`.
|
||||
function hilbish.runner.sh(cmd) end
|
||||
|
||||
--- Starts a timer.
|
||||
function hilbish.timers:start() end
|
||||
|
||||
@ -262,4 +212,26 @@ function hilbish.timers.create(type, time, callback) end
|
||||
--- Retrieves a timer via its ID.
|
||||
function hilbish.timers.get(id) end
|
||||
|
||||
--- Sets/toggles the option of automatically flushing output.
|
||||
--- A call with no argument will toggle the value.
|
||||
--- @param auto boolean|nil
|
||||
function hilbish:autoFlush(auto) end
|
||||
|
||||
--- Flush writes all buffered input to the sink.
|
||||
function hilbish:flush() end
|
||||
|
||||
--- Reads a liine of input from the sink.
|
||||
--- @returns string
|
||||
function hilbish:read() end
|
||||
|
||||
--- Reads all input from the sink.
|
||||
--- @returns string
|
||||
function hilbish:readAll() end
|
||||
|
||||
--- Writes data to a sink.
|
||||
function hilbish:write(str) end
|
||||
|
||||
--- Writes data to a sink with a newline at the end.
|
||||
function hilbish:writeln(str) end
|
||||
|
||||
return hilbish
|
||||
|
11
emmyLuaDocs/snail.lua
Normal file
11
emmyLuaDocs/snail.lua
Normal file
@ -0,0 +1,11 @@
|
||||
--- @meta
|
||||
|
||||
local snail = {}
|
||||
|
||||
--- Creates a new Snail instance.
|
||||
function snail.new() end
|
||||
|
||||
--- Runs a shell command. Works the same as `hilbish.run`.
|
||||
function snail:run(command, streams) end
|
||||
|
||||
return snail
|
83
emmyLuaDocs/util.lua
Normal file
83
emmyLuaDocs/util.lua
Normal file
@ -0,0 +1,83 @@
|
||||
--- @meta
|
||||
|
||||
local util = {}
|
||||
|
||||
---
|
||||
function util.AbbrevHome changes the user's home directory in the path string to ~ (tilde) end
|
||||
|
||||
---
|
||||
function util. end
|
||||
|
||||
---
|
||||
function util.DoFile runs the contents of the file in the Lua runtime. end
|
||||
|
||||
---
|
||||
function util.DoString runs the code string in the Lua runtime. end
|
||||
|
||||
--- directory.
|
||||
function util.ExpandHome expands ~ (tilde) in the path, changing it to the user home end
|
||||
|
||||
---
|
||||
function util. end
|
||||
|
||||
---
|
||||
function util.ForEach loops through a Lua table. end
|
||||
|
||||
---
|
||||
function util. end
|
||||
|
||||
--- a string and a closure.
|
||||
function util.HandleStrCallback handles function parameters for Go functions which take end
|
||||
|
||||
---
|
||||
function util. end
|
||||
|
||||
---
|
||||
function util. end
|
||||
|
||||
---
|
||||
function util.SetExports puts the Lua function exports in the table. end
|
||||
|
||||
--- It is accessible via the __docProp metatable. It is a table of the names of the fields.
|
||||
function util.SetField sets a field in a table, adding docs for it. end
|
||||
|
||||
--- is one which has a metatable proxy to ensure no overrides happen to it.
|
||||
--- It sets the field in the table and sets the __docProp metatable on the
|
||||
--- user facing table.
|
||||
function util.SetFieldProtected sets a field in a protected table. A protected table end
|
||||
|
||||
--- Sets/toggles the option of automatically flushing output.
|
||||
--- A call with no argument will toggle the value.
|
||||
--- @param auto boolean|nil
|
||||
function util:autoFlush(auto) end
|
||||
|
||||
--- Flush writes all buffered input to the sink.
|
||||
function util:flush() end
|
||||
|
||||
---
|
||||
function util. end
|
||||
|
||||
--- Reads a liine of input from the sink.
|
||||
--- @returns string
|
||||
function util:read() end
|
||||
|
||||
--- Reads all input from the sink.
|
||||
--- @returns string
|
||||
function util:readAll() end
|
||||
|
||||
--- Writes data to a sink.
|
||||
function util:write(str) end
|
||||
|
||||
--- Writes data to a sink with a newline at the end.
|
||||
function util:writeln(str) end
|
||||
|
||||
---
|
||||
function util. end
|
||||
|
||||
---
|
||||
function util. end
|
||||
|
||||
---
|
||||
function util. end
|
||||
|
||||
return util
|
133
exec.go
133
exec.go
@ -3,13 +3,9 @@ package main
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"hilbish/util"
|
||||
//herror "hilbish/errors"
|
||||
|
||||
rt "github.com/arnodel/golua/runtime"
|
||||
//"github.com/yuin/gopher-lua/parse"
|
||||
)
|
||||
@ -20,100 +16,11 @@ var runnerMode rt.Value = rt.NilValue
|
||||
|
||||
func runInput(input string, priv bool) {
|
||||
running = true
|
||||
cmdString := aliases.Resolve(input)
|
||||
hooks.Emit("command.preexec", input, cmdString)
|
||||
|
||||
currentRunner := runnerMode
|
||||
|
||||
rerun:
|
||||
var exitCode uint8
|
||||
var cont bool
|
||||
var newline bool
|
||||
// save incase it changes while prompting (For some reason)
|
||||
input, exitCode, cont, newline, runnerErr, err := runLuaRunner(currentRunner, input)
|
||||
runnerRun := hshMod.Get(rt.StringValue("runner")).AsTable().Get(rt.StringValue("run"))
|
||||
_, err := rt.Call1(l.MainThread(), runnerRun, rt.StringValue(input), rt.BoolValue(priv))
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
cmdFinish(124, input, priv)
|
||||
return
|
||||
}
|
||||
// we only use `err` to check for lua eval error
|
||||
// our actual error should only be a runner provided error at this point
|
||||
// command not found type, etc
|
||||
err = runnerErr
|
||||
|
||||
if cont {
|
||||
input, err = continuePrompt(input, newline)
|
||||
if err == nil {
|
||||
goto rerun
|
||||
} else if err == io.EOF {
|
||||
lr.SetPrompt(fmtPrompt(prompt))
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil && err != io.EOF {
|
||||
if exErr, ok := util.IsExecError(err); ok {
|
||||
hooks.Emit("command." + exErr.Typ, exErr.Cmd)
|
||||
} else {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
}
|
||||
}
|
||||
cmdFinish(exitCode, input, priv)
|
||||
}
|
||||
|
||||
func reprompt(input string, newline bool) (string, error) {
|
||||
for {
|
||||
/*
|
||||
if strings.HasSuffix(input, "\\") {
|
||||
input = strings.TrimSuffix(input, "\\") + "\n"
|
||||
}
|
||||
*/
|
||||
in, err := continuePrompt(input, newline)
|
||||
if err != nil {
|
||||
lr.SetPrompt(fmtPrompt(prompt))
|
||||
return input, err
|
||||
}
|
||||
|
||||
return in, nil
|
||||
}
|
||||
}
|
||||
|
||||
func runLuaRunner(runr rt.Value, userInput string) (input string, exitCode uint8, continued bool, newline bool, runnerErr, err error) {
|
||||
term := rt.NewTerminationWith(l.MainThread().CurrentCont(), 3, false)
|
||||
err = rt.Call(l.MainThread(), runr, []rt.Value{rt.StringValue(userInput)}, term)
|
||||
if err != nil {
|
||||
return "", 124, false, false, nil, err
|
||||
}
|
||||
|
||||
var runner *rt.Table
|
||||
var ok bool
|
||||
runnerRet := term.Get(0)
|
||||
if runner, ok = runnerRet.TryTable(); !ok {
|
||||
fmt.Fprintln(os.Stderr, "runner did not return a table")
|
||||
exitCode = 125
|
||||
input = userInput
|
||||
return
|
||||
}
|
||||
|
||||
if code, ok := runner.Get(rt.StringValue("exitCode")).TryInt(); ok {
|
||||
exitCode = uint8(code)
|
||||
}
|
||||
|
||||
if inp, ok := runner.Get(rt.StringValue("input")).TryString(); ok {
|
||||
input = inp
|
||||
}
|
||||
|
||||
if errStr, ok := runner.Get(rt.StringValue("err")).TryString(); ok {
|
||||
runnerErr = fmt.Errorf("%s", errStr)
|
||||
}
|
||||
|
||||
if c, ok := runner.Get(rt.StringValue("continue")).TryBool(); ok {
|
||||
continued = c
|
||||
}
|
||||
|
||||
if nl, ok := runner.Get(rt.StringValue("newline")).TryBool(); ok {
|
||||
newline = nl
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func handleLua(input string) (string, uint8, error) {
|
||||
@ -143,34 +50,6 @@ func handleLua(input string) (string, uint8, error) {
|
||||
return cmdString, 125, err
|
||||
}
|
||||
|
||||
/*
|
||||
func execSh(cmdString string) (input string, exitcode uint8, cont bool, newline bool, e error) {
|
||||
_, _, err := execCommand(cmdString, nil)
|
||||
if err != nil {
|
||||
// If input is incomplete, start multiline prompting
|
||||
if syntax.IsIncomplete(err) {
|
||||
if !interactive {
|
||||
return cmdString, 126, false, false, err
|
||||
}
|
||||
|
||||
newline := false
|
||||
if strings.Contains(err.Error(), "unclosed here-document") {
|
||||
newline = true
|
||||
}
|
||||
return cmdString, 126, true, newline, err
|
||||
} else {
|
||||
if code, ok := interp.IsExitStatus(err); ok {
|
||||
return cmdString, code, false, false, nil
|
||||
} else {
|
||||
return cmdString, 126, false, false, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cmdString, 0, false, false, nil
|
||||
}
|
||||
*/
|
||||
|
||||
func splitInput(input string) ([]string, string) {
|
||||
// end my suffering
|
||||
// TODO: refactor this garbage
|
||||
@ -204,11 +83,3 @@ func splitInput(input string) ([]string, string) {
|
||||
|
||||
return cmdArgs, cmdstr.String()
|
||||
}
|
||||
|
||||
func cmdFinish(code uint8, cmdstr string, private bool) {
|
||||
util.SetField(l, hshMod, "exitCode", rt.IntValue(int64(code)))
|
||||
// using AsValue (to convert to lua type) on an interface which is an int
|
||||
// results in it being unknown in lua .... ????
|
||||
// so we allow the hook handler to take lua runtime Values
|
||||
hooks.Emit("command.exit", rt.IntValue(int64(code)), cmdstr, private)
|
||||
}
|
||||
|
@ -1,3 +1,9 @@
|
||||
// shell script interpreter library
|
||||
/*
|
||||
The snail library houses Hilbish's Lua wrapper of its shell script interpreter.
|
||||
It's not very useful other than running shell scripts, which can be done with other
|
||||
Hilbish functions.
|
||||
*/
|
||||
package snail
|
||||
|
||||
import (
|
||||
@ -25,7 +31,7 @@ func loaderFunc(rtm *rt.Runtime) (rt.Value, func()) {
|
||||
snailMeta := rt.NewTable()
|
||||
snailMethods := rt.NewTable()
|
||||
snailFuncs := map[string]util.LuaExport{
|
||||
"run": {srun, 3, false},
|
||||
"run": {snailrun, 3, false},
|
||||
}
|
||||
util.SetExports(rtm, snailMethods, snailFuncs)
|
||||
|
||||
@ -39,7 +45,7 @@ func loaderFunc(rtm *rt.Runtime) (rt.Value, func()) {
|
||||
rtm.SetRegistry(snailMetaKey, rt.TableValue(snailMeta))
|
||||
|
||||
exports := map[string]util.LuaExport{
|
||||
"new": util.LuaExport{snew, 0, false},
|
||||
"new": util.LuaExport{snailnew, 0, false},
|
||||
}
|
||||
|
||||
mod := rt.NewTable()
|
||||
@ -48,12 +54,17 @@ func loaderFunc(rtm *rt.Runtime) (rt.Value, func()) {
|
||||
return rt.TableValue(mod), nil
|
||||
}
|
||||
|
||||
func snew(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
// new() -> @Snail
|
||||
// Creates a new Snail instance.
|
||||
func snailnew(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
s := New(t.Runtime)
|
||||
return c.PushingNext1(t.Runtime, rt.UserDataValue(snailUserData(s))), nil
|
||||
}
|
||||
|
||||
func srun(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
// #member
|
||||
// run(command, streams)
|
||||
// Runs a shell command. Works the same as `hilbish.run`.
|
||||
func snailrun(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
if err := c.CheckNArgs(2); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -157,7 +168,7 @@ func handleStream(v rt.Value, strms *util.Streams, errStream, inStream bool) err
|
||||
return nil
|
||||
}
|
||||
|
||||
func snailArg(c *rt.GoCont, arg int) (*snail, error) {
|
||||
func snailArg(c *rt.GoCont, arg int) (*Snail, error) {
|
||||
s, ok := valueToSnail(c.Arg(arg))
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("#%d must be a snail", arg + 1)
|
||||
@ -166,17 +177,17 @@ func snailArg(c *rt.GoCont, arg int) (*snail, error) {
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func valueToSnail(val rt.Value) (*snail, bool) {
|
||||
func valueToSnail(val rt.Value) (*Snail, bool) {
|
||||
u, ok := val.TryUserData()
|
||||
if !ok {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
s, ok := u.Value().(*snail)
|
||||
s, ok := u.Value().(*Snail)
|
||||
return s, ok
|
||||
}
|
||||
|
||||
func snailUserData(s *snail) *rt.UserData {
|
||||
func snailUserData(s *Snail) *rt.UserData {
|
||||
snailMeta := s.runtime.Registry(snailMetaKey)
|
||||
return rt.NewUserData(s, snailMeta.AsTable())
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
// shell script interpreter library
|
||||
package snail
|
||||
|
||||
import (
|
||||
@ -23,21 +22,23 @@ import (
|
||||
"mvdan.cc/sh/v3/expand"
|
||||
)
|
||||
|
||||
type snail struct{
|
||||
// #type
|
||||
// A Snail is a shell script interpreter instance.
|
||||
type Snail struct{
|
||||
runner *interp.Runner
|
||||
runtime *rt.Runtime
|
||||
}
|
||||
|
||||
func New(rtm *rt.Runtime) *snail {
|
||||
func New(rtm *rt.Runtime) *Snail {
|
||||
runner, _ := interp.New()
|
||||
|
||||
return &snail{
|
||||
return &Snail{
|
||||
runner: runner,
|
||||
runtime: rtm,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *snail) Run(cmd string, strms *util.Streams) (bool, io.Writer, io.Writer, error){
|
||||
func (s *Snail) Run(cmd string, strms *util.Streams) (bool, io.Writer, io.Writer, error){
|
||||
file, err := syntax.NewParser().Parse(strings.NewReader(cmd), "")
|
||||
if err != nil {
|
||||
return false, nil, nil, err
|
||||
|
@ -1,8 +1,31 @@
|
||||
-- @module hilbish
|
||||
local hilbish = require 'hilbish'
|
||||
local snail = require 'snail'
|
||||
|
||||
hilbish.snail = snail.new()
|
||||
|
||||
--- Runs `cmd` in Hilbish's shell script interpreter.
|
||||
--- The `streams` parameter specifies the output and input streams the command should use.
|
||||
--- For example, to write command output to a sink.
|
||||
--- As a table, the caller can directly specify the standard output, error, and input
|
||||
--- streams of the command with the table keys `out`, `err`, and `input` respectively.
|
||||
--- As a boolean, it specifies whether the command should use standard output or return its output streams.
|
||||
--- #example
|
||||
--- -- This code is the same as `ls -l | wc -l`
|
||||
--- local fs = require 'fs'
|
||||
--- local pr, pw = fs.pipe()
|
||||
--- hilbish.run('ls -l', {
|
||||
--- stdout = pw,
|
||||
--- stderr = pw,
|
||||
--- })
|
||||
--- pw:close()
|
||||
--- hilbish.run('wc -l', {
|
||||
--- stdin = pr
|
||||
--- })
|
||||
--- #example
|
||||
-- @param cmd string
|
||||
-- @param streams table|boolean
|
||||
-- @returns number, string, string
|
||||
function hilbish.run(cmd, streams)
|
||||
local sinks = {}
|
||||
|
||||
@ -28,3 +51,26 @@ function hilbish.run(cmd, streams)
|
||||
|
||||
return table.unpack(returns)
|
||||
end
|
||||
|
||||
--- Sets the execution/runner mode for interactive Hilbish.
|
||||
--- **NOTE: This function is deprecated and will be removed in 3.0**
|
||||
--- Use `hilbish.runner.setCurrent` instead.
|
||||
--- This determines whether 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),
|
||||
--- sh, and lua. It also accepts a function, to which if it is passed one
|
||||
--- will call it to execute user input instead.
|
||||
--- Read [about runner mode](../features/runner-mode) for more information.
|
||||
-- @param mode string|function
|
||||
function hilbish.runnerMode(mode)
|
||||
if type(mode) == 'string' then
|
||||
hilbish.runner.setCurrent(mode)
|
||||
elseif type(mode) == 'function' then
|
||||
hilbish.runner.set('_', {
|
||||
run = mode
|
||||
})
|
||||
hilbish.runner.setCurrent '_'
|
||||
else
|
||||
error('expected runner mode type to be either string or function, got', type(mode))
|
||||
end
|
||||
end
|
||||
|
@ -72,10 +72,8 @@ end
|
||||
--- Sets Hilbish's runner mode by name.
|
||||
--- @param name string
|
||||
function hilbish.runner.setCurrent(name)
|
||||
local r = hilbish.runner.get(name)
|
||||
hilbish.runner.get(name) -- throws if it doesnt exist.
|
||||
currentRunner = name
|
||||
|
||||
hilbish.runner.setMode(r.run)
|
||||
end
|
||||
|
||||
--- Returns the current runner by name.
|
||||
@ -84,6 +82,77 @@ function hilbish.runner.getCurrent()
|
||||
return currentRunner
|
||||
end
|
||||
|
||||
--- **NOTE: This function is deprecated and will be removed in 3.0**
|
||||
--- Use `hilbish.runner.setCurrent` instead.
|
||||
--- This is the same as the `hilbish.runnerMode` function.
|
||||
--- It takes a callback, which will be used to execute all interactive input.
|
||||
--- Or a string which names the runner mode to use.
|
||||
-- @param mode string|function
|
||||
function hilbish.runner.setMode(mode)
|
||||
hilbish.runnerMode(mode)
|
||||
end
|
||||
|
||||
local function finishExec(exitCode, input, priv)
|
||||
hilbish.exitCode = exitCode
|
||||
bait.throw('command.exit', exitCode, input, priv)
|
||||
end
|
||||
|
||||
local function continuePrompt(prev, newline)
|
||||
local multilinePrompt = hilbish.multiprompt()
|
||||
-- the return of hilbish.read is nil when error or ctrl-d
|
||||
local cont = hilbish.read(multilinePrompt)
|
||||
if not cont then
|
||||
return
|
||||
end
|
||||
|
||||
if newline then
|
||||
cont = '\n' .. cont
|
||||
end
|
||||
|
||||
if cont:match '\\$' then
|
||||
cont = cont:gsub('\\$', '') .. '\n'
|
||||
end
|
||||
|
||||
return prev .. cont
|
||||
end
|
||||
|
||||
--- Runs `input` with the currently set Hilbish runner.
|
||||
--- This method is how Hilbish executes commands.
|
||||
--- `priv` is an optional boolean used to state if the input should be saved to history.
|
||||
-- @param input string
|
||||
-- @param priv bool
|
||||
function hilbish.runner.run(input, priv)
|
||||
local command = hilbish.aliases.resolve(input)
|
||||
bait.throw('command.preexec', input, command)
|
||||
|
||||
::rerun::
|
||||
local runner = hilbish.runner.get(currentRunner)
|
||||
local ok, out = pcall(runner.run, input)
|
||||
if not ok then
|
||||
io.stderr:write(out .. '\n')
|
||||
finishExec(124, out.input, priv)
|
||||
return
|
||||
end
|
||||
|
||||
if out.continue then
|
||||
local contInput = continuePrompt(input, out.newline)
|
||||
if contInput then
|
||||
input = contInput
|
||||
goto rerun
|
||||
end
|
||||
end
|
||||
|
||||
if out.err then
|
||||
local fields = string.split(out.err, ': ')
|
||||
if fields[2] == 'not-found' or fields[2] == 'not-executable' then
|
||||
bait.throw('command.' .. fields[2], fields[1])
|
||||
else
|
||||
io.stderr:write(out.err .. '\n')
|
||||
end
|
||||
end
|
||||
finishExec(out.exitCode, out.input, priv)
|
||||
end
|
||||
|
||||
function hilbish.runner.sh(input)
|
||||
return hilbish.snail:run(input)
|
||||
end
|
||||
|
@ -53,9 +53,7 @@ end)
|
||||
*/
|
||||
func runnerModeLoader(rtm *rt.Runtime) *rt.Table {
|
||||
exports := map[string]util.LuaExport{
|
||||
//"sh": {shRunner, 1, false},
|
||||
"lua": {luaRunner, 1, false},
|
||||
"setMode": {hlrunnerMode, 1, false},
|
||||
}
|
||||
|
||||
mod := rt.NewTable()
|
||||
@ -64,48 +62,6 @@ func runnerModeLoader(rtm *rt.Runtime) *rt.Table {
|
||||
return mod
|
||||
}
|
||||
|
||||
// #interface runner
|
||||
// setMode(cb)
|
||||
// **NOTE: This function is deprecated and will be removed in 3.0**
|
||||
// Use `hilbish.runner.setCurrent` instead.
|
||||
// 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,
|
||||
// as the higher level functions (setCurrent) this will handle it.
|
||||
// #param cb function
|
||||
func _runnerMode() {}
|
||||
|
||||
// #interface runner
|
||||
// sh(cmd)
|
||||
// Runs a command in Hilbish's shell script interpreter.
|
||||
// This is the equivalent of using `source`.
|
||||
// #param cmd string
|
||||
/*
|
||||
func shRunner(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||
if err := c.Check1Arg(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cmd, err := c.StringArg(0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_, exitCode, cont, newline, err := execSh(aliases.Resolve(cmd))
|
||||
var luaErr rt.Value = rt.NilValue
|
||||
if err != nil {
|
||||
luaErr = rt.StringValue(err.Error())
|
||||
}
|
||||
runnerRet := rt.NewTable()
|
||||
runnerRet.Set(rt.StringValue("input"), rt.StringValue(cmd))
|
||||
runnerRet.Set(rt.StringValue("exitCode"), rt.IntValue(int64(exitCode)))
|
||||
runnerRet.Set(rt.StringValue("continue"), rt.BoolValue(cont))
|
||||
runnerRet.Set(rt.StringValue("newline"), rt.BoolValue(newline))
|
||||
runnerRet.Set(rt.StringValue("err"), luaErr)
|
||||
|
||||
return c.PushingNext(t.Runtime, rt.TableValue(runnerRet)), nil
|
||||
}
|
||||
*/
|
||||
|
||||
// #interface runner
|
||||
// lua(cmd)
|
||||
// Evaluates `cmd` as Lua input. This is the same as using `dofile`
|
||||
|
@ -14,8 +14,7 @@ import (
|
||||
var sinkMetaKey = rt.StringValue("hshsink")
|
||||
|
||||
// #type
|
||||
// A sink is a structure that has input and/or output to/from
|
||||
// a desination.
|
||||
// A sink is a structure that has input and/or output to/from a desination.
|
||||
type Sink struct{
|
||||
Rw *bufio.ReadWriter
|
||||
file *os.File
|
||||
|
Loading…
x
Reference in New Issue
Block a user