mirror of
https://github.com/Hilbis/Hilbish
synced 2025-07-01 16:52:03 +00:00
feat: transition to writing readline lua functions in readline package, and some misc stuff
This commit is contained in:
parent
2117a3747b
commit
45ceb9097f
15
api.go
15
api.go
@ -25,8 +25,9 @@ import (
|
|||||||
|
|
||||||
"hilbish/util"
|
"hilbish/util"
|
||||||
|
|
||||||
rt "github.com/arnodel/golua/runtime"
|
|
||||||
"github.com/arnodel/golua/lib/packagelib"
|
"github.com/arnodel/golua/lib/packagelib"
|
||||||
|
rt "github.com/arnodel/golua/runtime"
|
||||||
|
|
||||||
//"github.com/arnodel/golua/lib/iolib"
|
//"github.com/arnodel/golua/lib/iolib"
|
||||||
"github.com/maxlandon/readline"
|
"github.com/maxlandon/readline"
|
||||||
//"mvdan.cc/sh/v3/interp"
|
//"mvdan.cc/sh/v3/interp"
|
||||||
@ -118,9 +119,6 @@ func hilbishLoad(rtm *rt.Runtime) (rt.Value, func()) {
|
|||||||
timersModule := timers.loader(rtm)
|
timersModule := timers.loader(rtm)
|
||||||
mod.Set(rt.StringValue("timers"), rt.TableValue(timersModule))
|
mod.Set(rt.StringValue("timers"), rt.TableValue(timersModule))
|
||||||
|
|
||||||
editorModule := editorLoader(rtm)
|
|
||||||
mod.Set(rt.StringValue("editor"), rt.TableValue(editorModule))
|
|
||||||
|
|
||||||
versionModule := rt.NewTable()
|
versionModule := rt.NewTable()
|
||||||
util.SetField(rtm, versionModule, "branch", rt.StringValue(gitBranch))
|
util.SetField(rtm, versionModule, "branch", rt.StringValue(gitBranch))
|
||||||
util.SetField(rtm, versionModule, "full", rt.StringValue(getVersion()))
|
util.SetField(rtm, versionModule, "full", rt.StringValue(getVersion()))
|
||||||
@ -194,7 +192,6 @@ func hlcwd(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
|||||||
return c.PushingNext1(t.Runtime, rt.StringValue(cwd)), nil
|
return c.PushingNext1(t.Runtime, rt.StringValue(cwd)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// read(prompt) -> input (string)
|
// read(prompt) -> input (string)
|
||||||
// Read input from the user, using Hilbish's line editor/input reader.
|
// Read input from the user, using Hilbish's line editor/input reader.
|
||||||
// This is a separate instance from the one Hilbish actually uses.
|
// This is a separate instance from the one Hilbish actually uses.
|
||||||
@ -268,8 +265,10 @@ func hlprompt(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
|||||||
case "left":
|
case "left":
|
||||||
prompt = p
|
prompt = p
|
||||||
lr.SetPrompt(fmtPrompt(prompt))
|
lr.SetPrompt(fmtPrompt(prompt))
|
||||||
case "right": lr.SetRightPrompt(fmtPrompt(p))
|
case "right":
|
||||||
default: return nil, errors.New("expected prompt type to be right or left, got " + typ)
|
lr.SetRightPrompt(fmtPrompt(p))
|
||||||
|
default:
|
||||||
|
return nil, errors.New("expected prompt type to be right or left, got " + typ)
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.Next(), nil
|
return c.Next(), nil
|
||||||
@ -667,7 +666,9 @@ func hlhinter(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
|||||||
// #example
|
// #example
|
||||||
// --This code will highlight all double quoted strings in green.
|
// --This code will highlight all double quoted strings in green.
|
||||||
// function hilbish.highlighter(line)
|
// function hilbish.highlighter(line)
|
||||||
|
//
|
||||||
// return line:gsub('"%w+"', function(c) return lunacolors.green(c) end)
|
// return line:gsub('"%w+"', function(c) return lunacolors.green(c) end)
|
||||||
|
//
|
||||||
// end
|
// end
|
||||||
// #example
|
// #example
|
||||||
// #param line string
|
// #param line string
|
||||||
|
2
go.mod
2
go.mod
@ -30,7 +30,7 @@ require (
|
|||||||
|
|
||||||
replace mvdan.cc/sh/v3 => github.com/Rosettea/sh/v3 v3.4.0-0.dev.0.20240815163633-562273e09b73
|
replace mvdan.cc/sh/v3 => github.com/Rosettea/sh/v3 v3.4.0-0.dev.0.20240815163633-562273e09b73
|
||||||
|
|
||||||
replace github.com/maxlandon/readline => ./readline
|
replace github.com/maxlandon/readline => ./golibs/readline
|
||||||
|
|
||||||
replace layeh.com/gopher-luar => github.com/layeh/gopher-luar v1.0.10
|
replace layeh.com/gopher-luar => github.com/layeh/gopher-luar v1.0.10
|
||||||
|
|
||||||
|
@ -5,6 +5,8 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"regexp"
|
"regexp"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/arnodel/golua/lib/packagelib"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Instance is used to encapsulate the parameter group and run time of any given
|
// Instance is used to encapsulate the parameter group and run time of any given
|
||||||
@ -206,6 +208,8 @@ type Instance struct {
|
|||||||
RawInputCallback func([]rune) // called on all input
|
RawInputCallback func([]rune) // called on all input
|
||||||
|
|
||||||
bufferedOut *bufio.Writer
|
bufferedOut *bufio.Writer
|
||||||
|
|
||||||
|
Loader packagelib.Loader
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewInstance is used to create a readline instance and initialise it with sane defaults.
|
// NewInstance is used to create a readline instance and initialise it with sane defaults.
|
||||||
@ -245,7 +249,9 @@ func NewInstance() *Instance {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, hay := range haystack {
|
for _, hay := range haystack {
|
||||||
if rl.regexSearch == nil { continue }
|
if rl.regexSearch == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
if rl.regexSearch.MatchString(hay) {
|
if rl.regexSearch.MatchString(hay) {
|
||||||
suggs = append(suggs, hay)
|
suggs = append(suggs, hay)
|
||||||
}
|
}
|
||||||
@ -256,6 +262,11 @@ func NewInstance() *Instance {
|
|||||||
|
|
||||||
rl.bufferedOut = bufio.NewWriter(os.Stdout)
|
rl.bufferedOut = bufio.NewWriter(os.Stdout)
|
||||||
|
|
||||||
|
rl.Loader = packagelib.Loader{
|
||||||
|
Name: "readline",
|
||||||
|
Load: rl.luaLoader,
|
||||||
|
}
|
||||||
|
|
||||||
// Registers
|
// Registers
|
||||||
rl.initRegisters()
|
rl.initRegisters()
|
||||||
|
|
||||||
|
124
golibs/readline/lua.go
Normal file
124
golibs/readline/lua.go
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
// line reader library
|
||||||
|
// The readline module is responsible for reading input from the user.
|
||||||
|
// The readline module is what Hilbish uses to read input from the user,
|
||||||
|
// including all the interactive features of Hilbish like history search,
|
||||||
|
// syntax highlighting, everything. The global Hilbish readline instance
|
||||||
|
// is usable at `hilbish.editor`.
|
||||||
|
package readline
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
|
||||||
|
"hilbish/util"
|
||||||
|
|
||||||
|
rt "github.com/arnodel/golua/runtime"
|
||||||
|
)
|
||||||
|
|
||||||
|
var rlMetaKey = rt.StringValue("__readline")
|
||||||
|
|
||||||
|
func (rl *Instance) luaLoader(rtm *rt.Runtime) (rt.Value, func()) {
|
||||||
|
rlMethods := rt.NewTable()
|
||||||
|
rlMethodss := map[string]util.LuaExport{
|
||||||
|
"read": {luaRead, 1, false},
|
||||||
|
"insert": {luaInsert, 2, false},
|
||||||
|
}
|
||||||
|
util.SetExports(rtm, rlMethods, rlMethodss)
|
||||||
|
|
||||||
|
jobMeta := rt.NewTable()
|
||||||
|
rlIndex := func(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||||
|
_, err := rlArg(c, 0)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
arg := c.Arg(1)
|
||||||
|
val := rlMethods.Get(arg)
|
||||||
|
|
||||||
|
return c.PushingNext1(t.Runtime, val), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
jobMeta.Set(rt.StringValue("__index"), rt.FunctionValue(rt.NewGoFunction(rlIndex, "__index", 2, false)))
|
||||||
|
rtm.SetRegistry(rlMetaKey, rt.TableValue(jobMeta))
|
||||||
|
|
||||||
|
rlFuncs := map[string]util.LuaExport{
|
||||||
|
"new": {luaNew, 0, false},
|
||||||
|
}
|
||||||
|
|
||||||
|
luaRl := rt.NewTable()
|
||||||
|
util.SetExports(rtm, luaRl, rlFuncs)
|
||||||
|
|
||||||
|
return rt.TableValue(luaRl), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func luaNew(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||||
|
rl := NewInstance()
|
||||||
|
ud := rlUserData(t.Runtime, rl)
|
||||||
|
|
||||||
|
return c.PushingNext1(t.Runtime, rt.UserDataValue(ud)), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func luaInsert(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||||
|
if err := c.CheckNArgs(2); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
rl, err := rlArg(c, 0)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
text, err := c.StringArg(1)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
rl.insert([]rune(text))
|
||||||
|
|
||||||
|
return c.Next(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func luaRead(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
|
||||||
|
if err := c.Check1Arg(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
rl, err := rlArg(c, 0)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
inp, err := rl.Readline()
|
||||||
|
if err == EOF {
|
||||||
|
fmt.Println("")
|
||||||
|
return nil, io.EOF
|
||||||
|
} else if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.PushingNext1(t.Runtime, rt.StringValue(inp)), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func rlArg(c *rt.GoCont, arg int) (*Instance, error) {
|
||||||
|
j, ok := valueToRl(c.Arg(arg))
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("#%d must be a readline", arg+1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return j, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func valueToRl(val rt.Value) (*Instance, bool) {
|
||||||
|
u, ok := val.TryUserData()
|
||||||
|
if !ok {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
|
||||||
|
j, ok := u.Value().(*Instance)
|
||||||
|
return j, ok
|
||||||
|
}
|
||||||
|
|
||||||
|
func rlUserData(rtm *rt.Runtime, rl *Instance) *rt.UserData {
|
||||||
|
rlMeta := rtm.Registry(rlMetaKey)
|
||||||
|
return rt.NewUserData(rl, rlMeta.AsTable())
|
||||||
|
}
|
6
lua.go
6
lua.go
@ -5,16 +5,16 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"hilbish/util"
|
|
||||||
"hilbish/golibs/bait"
|
"hilbish/golibs/bait"
|
||||||
"hilbish/golibs/commander"
|
"hilbish/golibs/commander"
|
||||||
"hilbish/golibs/fs"
|
"hilbish/golibs/fs"
|
||||||
"hilbish/golibs/snail"
|
"hilbish/golibs/snail"
|
||||||
"hilbish/golibs/terminal"
|
"hilbish/golibs/terminal"
|
||||||
|
"hilbish/util"
|
||||||
|
|
||||||
rt "github.com/arnodel/golua/runtime"
|
|
||||||
"github.com/arnodel/golua/lib"
|
"github.com/arnodel/golua/lib"
|
||||||
"github.com/arnodel/golua/lib/debuglib"
|
"github.com/arnodel/golua/lib/debuglib"
|
||||||
|
rt "github.com/arnodel/golua/runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
var minimalconf = `hilbish.prompt '& '`
|
var minimalconf = `hilbish.prompt '& '`
|
||||||
@ -55,7 +55,7 @@ func luaInit() {
|
|||||||
|
|
||||||
cmds = commander.New(l)
|
cmds = commander.New(l)
|
||||||
lib.LoadLibs(l, cmds.Loader)
|
lib.LoadLibs(l, cmds.Loader)
|
||||||
|
lib.LoadLibs(l, lr.rl.Loader)
|
||||||
|
|
||||||
// Add more paths that Lua can require from
|
// Add more paths that Lua can require from
|
||||||
_, err := util.DoString(l, "package.path = package.path .. "+requirePaths)
|
_, err := util.DoString(l, "package.path = package.path .. "+requirePaths)
|
||||||
|
3
nature/editor.lua
Normal file
3
nature/editor.lua
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
local readline = require 'readline'
|
||||||
|
|
||||||
|
hilbish.editor = readline.new()
|
@ -28,6 +28,7 @@ require 'nature.vim'
|
|||||||
require 'nature.runner'
|
require 'nature.runner'
|
||||||
require 'nature.hummingbird'
|
require 'nature.hummingbird'
|
||||||
require 'nature.abbr'
|
require 'nature.abbr'
|
||||||
|
require 'nature.editor'
|
||||||
|
|
||||||
local shlvl = tonumber(os.getenv 'SHLVL')
|
local shlvl = tonumber(os.getenv 'SHLVL')
|
||||||
if shlvl ~= nil then
|
if shlvl ~= nil then
|
||||||
@ -94,3 +95,16 @@ end)
|
|||||||
bait.catch('command.not-executable', function(cmd)
|
bait.catch('command.not-executable', function(cmd)
|
||||||
print(string.format('hilbish: %s: not executable', cmd))
|
print(string.format('hilbish: %s: not executable', cmd))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
print 'we are at the end'
|
||||||
|
while true do
|
||||||
|
print 'reading input'
|
||||||
|
local ok, res = pcall(function() return hilbish.editor:read() end)
|
||||||
|
if not ok then
|
||||||
|
print(res)
|
||||||
|
print(res == 'EOF')
|
||||||
|
os.exit(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
print(ok, res)
|
||||||
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user