diff --git a/CHANGELOG.md b/CHANGELOG.md index 98b8250..c0737a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -56,6 +56,7 @@ having and using multiple runners. - `fs.basename(path)` gets the basename of path - `fs.dir(path)` gets the directory part of path - `fs.glob(pattern)` globs files and directories based on patterns + - `fs.join(dirs...)` joins directories by OS dir separator - .. and 2 properties - `fs.pathSep` is the separator for filesystem paths and directories - `fs.pathListSep` is the separator for $PATH env entries @@ -67,6 +68,8 @@ small news pieces for releases. It is printed by default. To disable it, set `hilbish.opts.motd` to false. - `history` opt has been added and is true by default. Setting it to false disables commands being added to history. +- `hilbish.rawInput` hook for input from the readline library +- Completion of files in quotes ### Changed - **Breaking Change:** Upgraded to Lua 5.4. @@ -125,6 +128,14 @@ for explanation. Lua `job.stop` function. - Jobs are always started in sh exec handler now instead of only successful start. - SIGTERM is handled properly now, which means stopping jobs and timers. +- Fix panic on trailing newline on pasted multiline text. +- Completions will no longer be refreshed if the prompt refreshes while the +menu is open. +- Print error on search fail instead of panicking +- Windows related fixes: + - `hilbish.dataDir` now has tilde (`~`) expanded. + - Arrow keys now work on Windows terminals. + - Escape codes now work. ## [1.2.0] - 2022-03-17 ### Added diff --git a/docs/fs.txt b/docs/fs.txt index c3d173e..8372afd 100644 --- a/docs/fs.txt +++ b/docs/fs.txt @@ -11,6 +11,9 @@ filepath.Dir glob(pattern) > Glob all files and directories that match the pattern. For the rules, see Go's filepath.Glob +join(paths...) > Takes paths and joins them together with the OS's +directory separator (forward or backward slash). + mkdir(name, recursive) > Makes a directory called `name`. If `recursive` is true, it will create its parent directories. readdir(dir) > Returns a table of files in `dir` diff --git a/emmyLuaDocs/fs.lua b/emmyLuaDocs/fs.lua index 5fbfb2b..14e7be4 100644 --- a/emmyLuaDocs/fs.lua +++ b/emmyLuaDocs/fs.lua @@ -22,6 +22,10 @@ function fs.dir() end --- For the rules, see Go's filepath.Glob function fs.glob() end +--- Takes paths and joins them together with the OS's +--- directory separator (forward or backward slash). +function fs.join() end + --- Makes a directory called `name`. If `recursive` is true, it will create its parent directories. --- @param name string --- @param recursive boolean diff --git a/golibs/fs/fs.go b/golibs/fs/fs.go index 88a04c5..5b12e73 100644 --- a/golibs/fs/fs.go +++ b/golibs/fs/fs.go @@ -1,6 +1,7 @@ package fs import ( + "fmt" "path/filepath" "strconv" "os" @@ -27,6 +28,7 @@ func loaderFunc(rtm *rt.Runtime) (rt.Value, func()) { "basename": util.LuaExport{fbasename, 1, false}, "dir": util.LuaExport{fdir, 1, false}, "glob": util.LuaExport{fglob, 1, false}, + "join": util.LuaExport{fjoin, 0, true}, } mod := rt.NewTable() util.SetExports(rtm, mod, exports) @@ -216,3 +218,21 @@ func fglob(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { return c.PushingNext(t.Runtime, rt.TableValue(luaMatches)), nil } + +// join(paths...) +// Takes paths and joins them together with the OS's +// directory separator (forward or backward slash). +func fjoin(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { + strs := make([]string, len(c.Etc())) + for i, v := range c.Etc() { + if v.Type() != rt.StringType { + // +2; go indexes of 0 and first arg from above + return nil, fmt.Errorf("bad argument #%d to run (expected string, got %s)", i + 1, v.TypeName()) + } + strs[i] = v.AsString() + } + + res := filepath.Join(strs...) + + return c.PushingNext(t.Runtime, rt.StringValue(res)), nil +} diff --git a/init_windows.go b/init_windows.go index ee17a6b..825069d 100644 --- a/init_windows.go +++ b/init_windows.go @@ -5,7 +5,13 @@ package main import "golang.org/x/sys/windows" func init() { - var mode uint32 - windows.GetConsoleMode(windows.Stdout, &mode) - windows.SetConsoleMode(windows.Stdout, mode | windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING) + // vt output (escape codes) + var outMode uint32 + windows.GetConsoleMode(windows.Stdout, &outMode) + windows.SetConsoleMode(windows.Stdout, outMode | windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING) + + // vt input + var inMode uint32 + windows.GetConsoleMode(windows.Stdin, &inMode) + windows.SetConsoleMode(windows.Stdin, inMode | windows.ENABLE_VIRTUAL_TERMINAL_INPUT) } diff --git a/lua.go b/lua.go index 8f3c0fb..92ece05 100644 --- a/lua.go +++ b/lua.go @@ -12,12 +12,16 @@ import ( rt "github.com/arnodel/golua/runtime" "github.com/arnodel/golua/lib" + "github.com/arnodel/golua/lib/debuglib" ) var minimalconf = `hilbish.prompt '& '` func luaInit() { l = rt.New(os.Stdout) + l.PushContext(rt.RuntimeContextDef{ + MessageHandler: debuglib.Traceback, + }) lib.LoadAll(l) lib.LoadLibs(l, hilbishLoader) @@ -48,6 +52,10 @@ func luaInit() { } }) + lr.rl.RawInputCallback = func(r []rune) { + hooks.Em.Emit("hilbish.rawInput", string(r)) + } + // Add more paths that Lua can require from err := util.DoString(l, "package.path = package.path .. " + requirePaths) if err != nil { diff --git a/readline/instance.go b/readline/instance.go index f04811e..fcd8379 100644 --- a/readline/instance.go +++ b/readline/instance.go @@ -198,6 +198,8 @@ type Instance struct { ViModeCallback func(ViMode) ViActionCallback func(ViAction, []string) + + RawInputCallback func([]rune) // called on all input } // NewInstance is used to create a readline instance and initialise it with sane defaults. diff --git a/readline/readline.go b/readline/readline.go index c00fda9..731e297 100644 --- a/readline/readline.go +++ b/readline/readline.go @@ -94,6 +94,9 @@ func (rl *Instance) Readline() (string, error) { rl.skipStdinRead = false r := []rune(string(b)) + if rl.RawInputCallback != nil { + rl.RawInputCallback(r[:i]) + } if isMultiline(r[:i]) || len(rl.multiline) > 0 { rl.multiline = append(rl.multiline, b[:i]...) diff --git a/vars_windows.go b/vars_windows.go index a257baf..403941f 100644 --- a/vars_windows.go +++ b/vars_windows.go @@ -2,13 +2,15 @@ package main +import "hilbish/util" + // String vars that are free to be changed at compile time var ( requirePaths = commonRequirePaths + `.. ';' .. hilbish.userDir.config .. '\\Hilbish\\libs\\?\\init.lua;' .. hilbish.userDir.config .. '\\Hilbish\\libs\\?\\?.lua;' .. hilbish.userDir.config .. '\\Hilbish\\libs\\?.lua;'` - dataDir = "~\\Appdata\\Roaming\\Hilbish" // ~ and \ gonna cry? + dataDir = util.ExpandHome("~\\Appdata\\Roaming\\Hilbish") // ~ and \ gonna cry? preloadPath = dataDir + "\\nature\\init.lua" sampleConfPath = dataDir + "\\hilbishrc.lua" // Path to default/sample config defaultConfDir = ""