Compare commits

...

3 Commits

11 changed files with 95 additions and 79 deletions

View File

@ -11,6 +11,8 @@
### Changed ### Changed
- Remove usage of `hilbish.goro` in Greenhouse. - Remove usage of `hilbish.goro` in Greenhouse.
- Values in `hilbish` table are no longer protected. This means
they can be overridden. (#287)
## [2.2.1] - 2023-12-26 ## [2.2.1] - 2023-12-26
### Fixed ### Fixed

61
api.go
View File

@ -59,47 +59,8 @@ var hilbishLoader = packagelib.Loader{
} }
func hilbishLoad(rtm *rt.Runtime) (rt.Value, func()) { func hilbishLoad(rtm *rt.Runtime) (rt.Value, func()) {
fakeMod := rt.NewTable()
modmt := rt.NewTable()
mod := rt.NewTable() mod := rt.NewTable()
modIndex := func(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
arg := c.Arg(1)
val := mod.Get(arg)
return c.PushingNext1(t.Runtime, val), nil
}
modNewIndex := func(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
k, err := c.StringArg(1)
if err != nil {
return nil, err
}
v := c.Arg(2)
if k == "highlighter" {
var err error
// fine to assign, since itll be either nil or a closure
highlighter, err = c.ClosureArg(2)
if err != nil {
return nil, errors.New("hilbish.highlighter has to be a function")
}
} else if k == "hinter" {
var err error
hinter, err = c.ClosureArg(2)
if err != nil {
return nil, errors.New("hilbish.hinter has to be a function")
}
} else if modVal := mod.Get(rt.StringValue(k)); modVal != rt.NilValue {
return nil, errors.New("not allowed to override in hilbish table")
}
mod.Set(rt.StringValue(k), v)
return c.Next(), nil
}
modmt.Set(rt.StringValue("__newindex"), rt.FunctionValue(rt.NewGoFunction(modNewIndex, "__newindex", 3, false)))
modmt.Set(rt.StringValue("__index"), rt.FunctionValue(rt.NewGoFunction(modIndex, "__index", 2, false)))
fakeMod.SetMetatable(modmt)
util.SetExports(rtm, mod, exports) util.SetExports(rtm, mod, exports)
hshMod = mod hshMod = mod
@ -110,16 +71,16 @@ func hilbishLoad(rtm *rt.Runtime) (rt.Value, func()) {
username = strings.Split(username, "\\")[1] // for some reason Username includes the hostname on windows username = strings.Split(username, "\\")[1] // for some reason Username includes the hostname on windows
} }
util.SetFieldProtected(fakeMod, mod, "ver", rt.StringValue(getVersion())) util.SetField(rtm, mod, "ver", rt.StringValue(getVersion()))
util.SetFieldProtected(fakeMod, mod, "goVersion", rt.StringValue(runtime.Version())) util.SetField(rtm, mod, "goVersion", rt.StringValue(runtime.Version()))
util.SetFieldProtected(fakeMod, mod, "user", rt.StringValue(username)) util.SetField(rtm, mod, "user", rt.StringValue(username))
util.SetFieldProtected(fakeMod, mod, "host", rt.StringValue(host)) util.SetField(rtm, mod, "host", rt.StringValue(host))
util.SetFieldProtected(fakeMod, mod, "home", rt.StringValue(curuser.HomeDir)) util.SetField(rtm, mod, "home", rt.StringValue(curuser.HomeDir))
util.SetFieldProtected(fakeMod, mod, "dataDir", rt.StringValue(dataDir)) util.SetField(rtm, mod, "dataDir", rt.StringValue(dataDir))
util.SetFieldProtected(fakeMod, mod, "interactive", rt.BoolValue(interactive)) util.SetField(rtm, mod, "interactive", rt.BoolValue(interactive))
util.SetFieldProtected(fakeMod, mod, "login", rt.BoolValue(login)) util.SetField(rtm, mod, "login", rt.BoolValue(login))
util.SetFieldProtected(fakeMod, mod, "vimMode", rt.NilValue) util.SetField(rtm, mod, "vimMode", rt.NilValue)
util.SetFieldProtected(fakeMod, mod, "exitCode", rt.IntValue(0)) util.SetField(rtm, mod, "exitCode", rt.IntValue(0))
// hilbish.userDir table // hilbish.userDir table
hshuser := userDirLoader(rtm) hshuser := userDirLoader(rtm)
@ -171,7 +132,7 @@ func hilbishLoad(rtm *rt.Runtime) (rt.Value, func()) {
pluginModule := moduleLoader(rtm) pluginModule := moduleLoader(rtm)
mod.Set(rt.StringValue("module"), rt.TableValue(pluginModule)) mod.Set(rt.StringValue("module"), rt.TableValue(pluginModule))
return rt.TableValue(fakeMod), nil return rt.TableValue(mod), nil
} }
func getenv(key, fallback string) string { func getenv(key, fallback string) string {

2
go.mod
View File

@ -1,6 +1,6 @@
module hilbish module hilbish
go 1.17 go 1.18
require ( require (
github.com/arnodel/golua v0.0.0-20220221163911-dfcf252b6f86 github.com/arnodel/golua v0.0.0-20220221163911-dfcf252b6f86

View File

@ -1,21 +1,7 @@
local opts = {}
hilbish.opts = {} hilbish.opts = {}
setmetatable(hilbish.opts, {
__newindex = function(_, k, v)
if opts[k] == nil then
error(string.format('opt %s does not exist', k))
end
opts[k] = v
end,
__index = function(_, k)
return opts[k]
end
})
local function setupOpt(name, default) local function setupOpt(name, default)
opts[name] = default hilbish.opts[name] = default
pcall(require, 'nature.opts.' .. name) pcall(require, 'nature.opts.' .. name)
end end

View File

@ -1,6 +1,7 @@
package readline package readline
import ( import (
// "fmt"
"os" "os"
"regexp" "regexp"
"strconv" "strconv"
@ -68,6 +69,40 @@ func (rl *Instance) getCursorPos() (x int, y int) {
// This means that they are not used to keep any reference point when // This means that they are not used to keep any reference point when
// when we internally move around clearning and printing things // when we internally move around clearning and printing things
/*
func moveCursorUpBuffered(i int) {
if i < 1 {
return
}
fmt.Fprintf(rl.bufferedOut, "\x1b[%dA", i)
}
func moveCursorDownBuffered(i int) {
if i < 1 {
return
}
fmt.Fprintf(rl.bufferedOut, "\x1b[%dB", i)
}
func moveCursorForwardsBuffered(i int) {
if i < 1 {
return
}
fmt.Fprintf(rl.bufferedOut, "\x1b[%dC", i)
}
func moveCursorUpBuffered(i int) {
if i < 1 {
return
}
fmt.Fprintf(rl.bufferedOut, "\x1b[%dD", i)
}
*/
func moveCursorUp(i int) { func moveCursorUp(i int) {
if i < 1 { if i < 1 {
return return
@ -100,6 +135,14 @@ func moveCursorBackwards(i int) {
printf("\x1b[%dD", i) printf("\x1b[%dD", i)
} }
func hideCursor() {
print(seqHideCursor)
}
func unhideCursor() {
print(seqUnhideCursor)
}
func (rl *Instance) backspace(forward bool) { func (rl *Instance) backspace(forward bool) {
if len(rl.line) == 0 || rl.pos == 0 { if len(rl.line) == 0 || rl.pos == 0 {
return return

View File

@ -1,6 +1,6 @@
module github.com/maxlandon/readline module github.com/maxlandon/readline
go 1.16 go 1.18
require ( require (
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d

View File

@ -1,6 +1,7 @@
package readline package readline
import ( import (
"bufio"
"os" "os"
"regexp" "regexp"
"sync" "sync"
@ -203,6 +204,8 @@ type Instance struct {
ViActionCallback func(ViAction, []string) ViActionCallback func(ViAction, []string)
RawInputCallback func([]rune) // called on all input RawInputCallback func([]rune) // called on all input
bufferedOut *bufio.Writer
} }
// 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.
@ -251,6 +254,8 @@ func NewInstance() *Instance {
return suggs return suggs
} }
rl.bufferedOut = bufio.NewWriter(os.Stdout)
// Registers // Registers
rl.initRegisters() rl.initRegisters()

View File

@ -33,19 +33,21 @@ func (rl *Instance) GetLine() []rune {
func (rl *Instance) echo() { func (rl *Instance) echo() {
// Then we print the prompt, and the line, // Then we print the prompt, and the line,
hideCursor()
switch { switch {
case rl.PasswordMask != 0: case rl.PasswordMask != 0:
case rl.PasswordMask > 0: case rl.PasswordMask > 0:
print(strings.Repeat(string(rl.PasswordMask), len(rl.line)) + " ") rl.bufprint(strings.Repeat(string(rl.PasswordMask), len(rl.line)) + " ")
default: default:
// Go back to prompt position, and clear everything below // Go back to prompt position, and clear everything below
moveCursorBackwards(GetTermWidth()) moveCursorBackwards(GetTermWidth())
moveCursorUp(rl.posY) moveCursorUp(rl.posY)
print(seqClearScreenBelow) rl.bufprint(seqClearScreenBelow)
// Print the prompt // Print the prompt
print(string(rl.realPrompt)) rl.bufprint(string(rl.realPrompt))
// Assemble the line, taking virtual completions into account // Assemble the line, taking virtual completions into account
var line []rune var line []rune
@ -57,11 +59,13 @@ func (rl *Instance) echo() {
// Print the input line with optional syntax highlighting // Print the input line with optional syntax highlighting
if rl.SyntaxHighlighter != nil { if rl.SyntaxHighlighter != nil {
print(rl.SyntaxHighlighter(line)) rl.bufprint(rl.SyntaxHighlighter(line))
} else { } else {
print(string(line)) rl.bufprint(string(line))
} }
} }
rl.bufflush()
// Update references with new coordinates only now, because // Update references with new coordinates only now, because
// the new line may be longer/shorter than the previous one. // the new line may be longer/shorter than the previous one.
@ -72,6 +76,7 @@ func (rl *Instance) echo() {
moveCursorUp(rl.fullY) moveCursorUp(rl.fullY)
moveCursorDown(rl.posY) moveCursorDown(rl.posY)
moveCursorForwards(rl.posX) moveCursorForwards(rl.posX)
unhideCursor()
} }
func (rl *Instance) insert(r []rune) { func (rl *Instance) insert(r []rune) {
@ -159,7 +164,7 @@ func (rl *Instance) clearLine() {
moveCursorForwards(rl.promptLen) moveCursorForwards(rl.promptLen)
// Clear everything after & below the cursor // Clear everything after & below the cursor
print(seqClearScreenBelow) //print(seqClearScreenBelow)
// Real input line // Real input line
rl.line = []rune{} rl.line = []rune{}

View File

@ -48,7 +48,7 @@ func (rl *Instance) RefreshPromptLog(log string) (err error) {
rl.stillOnRefresh = true rl.stillOnRefresh = true
moveCursorUp(rl.infoY + rl.tcUsedY) moveCursorUp(rl.infoY + rl.tcUsedY)
moveCursorBackwards(GetTermWidth()) moveCursorBackwards(GetTermWidth())
print("\r\n" + seqClearScreenBelow) //print("\r\n" + seqClearScreenBelow)
// Print the log // Print the log
fmt.Printf(log) fmt.Printf(log)
@ -97,7 +97,7 @@ func (rl *Instance) RefreshPromptInPlace(prompt string) (err error) {
print(seqClearLine) print(seqClearLine)
moveCursorUp(rl.infoY + rl.tcUsedY) moveCursorUp(rl.infoY + rl.tcUsedY)
moveCursorBackwards(GetTermWidth()) moveCursorBackwards(GetTermWidth())
print("\r\n" + seqClearScreenBelow) //print("\r\n" + seqClearScreenBelow)
// Add a new line if needed // Add a new line if needed
if rl.Multiline { if rl.Multiline {
@ -137,7 +137,7 @@ func (rl *Instance) RefreshPromptCustom(prompt string, offset int, clearLine boo
moveCursorUp(offset) moveCursorUp(offset)
// Then clear everything below our new position // Then clear everything below our new position
print(seqClearScreenBelow) //print(seqClearScreenBelow)
// Update the prompt if a special has been passed. // Update the prompt if a special has been passed.
if prompt != "" { if prompt != "" {

View File

@ -276,13 +276,14 @@ func (rl *Instance) writeTabCompletion() {
// than what their MaxLength allows them to, cycling sometimes occur, // than what their MaxLength allows them to, cycling sometimes occur,
// but does not fully clears itself: some descriptions are messed up with. // but does not fully clears itself: some descriptions are messed up with.
// We always clear the screen as a result, between writings. // We always clear the screen as a result, between writings.
print(seqClearScreenBelow) //rl.bufprint(seqClearScreenBelow)
// Crop the completions so that it fits within our MaxTabCompleterRows // Crop the completions so that it fits within our MaxTabCompleterRows
completions, rl.tcUsedY = rl.cropCompletions(completions) completions, rl.tcUsedY = rl.cropCompletions(completions)
// Then we print all of them. // Then we print all of them.
fmt.Printf(completions) rl.bufprintF(completions)
rl.bufflush()
} }
// cropCompletions - When the user cycles through a completion list longer // cropCompletions - When the user cycles through a completion list longer

View File

@ -1,6 +1,7 @@
package readline package readline
import ( import (
"fmt"
"strings" "strings"
"golang.org/x/text/width" "golang.org/x/text/width"
@ -120,7 +121,7 @@ func (rl *Instance) clearHelpers() {
moveCursorForwards(rl.fullX) moveCursorForwards(rl.fullX)
// Clear everything below // Clear everything below
print(seqClearScreenBelow) //print(seqClearScreenBelow)
// Go back to current cursor position // Go back to current cursor position
moveCursorBackwards(GetTermWidth()) moveCursorBackwards(GetTermWidth())
@ -195,3 +196,15 @@ func (rl *Instance) renderHelpers() {
moveCursorUp(rl.fullY - rl.posY) moveCursorUp(rl.fullY - rl.posY)
moveCursorForwards(rl.posX) moveCursorForwards(rl.posX)
} }
func (rl *Instance) bufprintF(format string, a ...any) {
fmt.Fprintf(rl.bufferedOut, format, a...)
}
func (rl *Instance) bufprint(text string) {
fmt.Fprint(rl.bufferedOut, text)
}
func (rl *Instance) bufflush() {
rl.bufferedOut.Flush()
}