chore: merge from master

history-searcher
TorchedSammy 2022-07-17 11:56:14 -04:00
commit 001bd15ced
Signed by: sammyette
GPG Key ID: 904FC49417B44DCD
16 changed files with 135 additions and 86 deletions

View File

@ -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
@ -65,7 +66,10 @@ will be ran on startup
- Message of the day on startup (`hilbish.motd`), mainly intended as quick
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.
@ -88,6 +92,10 @@ of a dot. (ie. `job.stop()` -> `job:stop()`)
- All `fs` module functions which take paths now implicitly expand ~ to home.
- **Breaking Change:** `hilbish.greeting` has been moved to an opt (`hilbish.opts.greeting`) and is
always printed by default. To disable it, set the opt to false.
- History is now fetched from Lua, which means users can override `hilbish.history`
methods to make it act how they want.
- `guide` has been removed. See the [website](https://rosettea.github.io/Hilbish/)
for general tips and documentation
### Fixed
- If in Vim replace mode, input at the end of the line inserts instead of
@ -122,6 +130,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

View File

@ -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`

View File

@ -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

View File

@ -540,13 +540,9 @@ func splitInput(input string) ([]string, string) {
}
func cmdFinish(code uint8, cmdstr string, private bool) {
// if input has space at the beginning, dont put in history
if interactive && !private {
handleHistory(cmdstr)
}
util.SetField(l, hshMod, "exitCode", rt.IntValue(int64(code)), "Exit code of last exected command")
// 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.Em.Emit("command.exit", rt.IntValue(int64(code)), cmdstr)
hooks.Em.Emit("command.exit", rt.IntValue(int64(code)), cmdstr, private)
}

View File

@ -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
}

View File

@ -4,21 +4,69 @@ import (
"errors"
"io/fs"
"os"
"path/filepath"
"strings"
rt "github.com/arnodel/golua/runtime"
)
type luaHistory struct {}
func (h *luaHistory) Write(line string) (int, error) {
histWrite := hshMod.Get(rt.StringValue("history")).AsTable().Get(rt.StringValue("add"))
ln, err := rt.Call1(l.MainThread(), histWrite, rt.StringValue(line))
var num int64
if ln.Type() == rt.IntType {
num = ln.AsInt()
}
return int(num), err
}
func (h *luaHistory) GetLine(idx int) (string, error) {
histGet := hshMod.Get(rt.StringValue("history")).AsTable().Get(rt.StringValue("get"))
lcmd, err := rt.Call1(l.MainThread(), histGet, rt.IntValue(int64(idx)))
var cmd string
if lcmd.Type() == rt.StringType {
cmd = lcmd.AsString()
}
return cmd, err
}
func (h *luaHistory) Len() int {
histSize := hshMod.Get(rt.StringValue("history")).AsTable().Get(rt.StringValue("size"))
ln, _ := rt.Call1(l.MainThread(), histSize)
var num int64
if ln.Type() == rt.IntType {
num = ln.AsInt()
}
return int(num)
}
func (h *luaHistory) Dump() interface{} {
// hilbish.history interface already has all function, this isnt used in readline
return nil
}
type fileHistory struct {
items []string
f *os.File
}
func newFileHistory() *fileHistory {
err := os.MkdirAll(defaultHistDir, 0755)
func newFileHistory(path string) *fileHistory {
dir := filepath.Dir(path)
err := os.MkdirAll(dir, 0755)
if err != nil {
panic(err)
}
data, err := os.ReadFile(defaultHistPath)
data, err := os.ReadFile(path)
if err != nil {
if !errors.Is(err, fs.ErrNotExist) {
panic(err)
@ -33,7 +81,7 @@ func newFileHistory() *fileHistory {
}
itms = append(itms, l)
}
f, err := os.OpenFile(defaultHistPath, os.O_APPEND | os.O_WRONLY | os.O_CREATE, 0755)
f, err := os.OpenFile(path, os.O_APPEND | os.O_WRONLY | os.O_CREATE, 0755)
if err != nil {
panic(err)
}

View File

@ -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)
}

4
lua.go
View File

@ -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)

View File

@ -269,11 +269,6 @@ func fmtPrompt(prompt string) string {
return nprompt
}
func handleHistory(cmd string) {
lr.AddHistory(cmd)
// TODO: load history again (history shared between sessions like this ye)
}
func removeDupes(slice []string) []string {
all := make(map[string]bool)
newSlice := []string{}

View File

@ -1,54 +0,0 @@
local ansikit = require 'ansikit'
local commander = require 'commander'
local helpTexts = {
[[
Hello there! Welcome to Hilbish, the comfy and nice little shell for
Lua users and fans. Hilbish is configured with Lua, and its
scripts are also in Lua. It also runs both Lua and shell script when
interactive (aka normal usage).
]],
[[
What does that mean for you, the user? It means that if you prefer to
use Lua for scripting instead of shell script but still have ordinary
shell usage for interactive use.
]],
[[
If this is your first time using Hilbish and Lua, check out the
Programming in Lua book here: https://www.lua.org/pil
After (or if you already know Lua) check out the doc command.
It is an in shell tool for documentation about Hilbish provided
functions and modules.
]],
[[
If you've updated from a pre-1.0 version (0.7.1 as an example)
you'll want to move your config from ~/.hilbishrc.lua to
]] ..
hilbish.userDir.config .. '/hilbish/init.lua' ..
[[
and also change all global functions (prompt, alias) to be
in the hilbish module (hilbish.prompt, hilbish.alias as examples).
And if this is your first time (most likely), you can copy a config
from ]] .. hilbish.dataDir,
[[
Since 1.0 is a big release, you'll want to check the changelog
at https://github.com/Rosettea/Hilbish/releases/tag/v1.0.0
to find more breaking changes.
]]
}
commander.register('guide', function()
ansikit.clear()
ansikit.cursorTo(0, 0)
for _, text in ipairs(helpTexts) do
print(text)
local out = hilbish.read('Hit enter to continue ')
ansikit.clear()
ansikit.cursorTo(0, 0)
if not out then
return
end
end
print 'Hope you enjoy using Hilbish!'
end)

View File

@ -3,7 +3,6 @@ require 'nature.commands.cd'
require 'nature.commands.cdr'
require 'nature.commands.doc'
require 'nature.commands.exit'
require 'nature.commands.guide'
require 'nature.commands.disown'
require 'nature.commands.fg'
require 'nature.commands.bg'

View File

@ -0,0 +1,5 @@
local bait = require 'bait'
bait.catch('command.exit', function(_, cmd, priv)
if not priv and hilbish.opts.history then hilbish.history.add(cmd) end
end)

View File

@ -21,6 +21,7 @@ end
local defaultOpts = {
autocd = false,
history = true,
greeting = string.format([[Welcome to {magenta}Hilbish{reset}, {cyan}%s{reset}.
The nice lil shell for {blue}Lua{reset} fanatics!
]], hilbish.user),

View File

@ -94,7 +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]...)

26
rl.go
View File

@ -13,18 +13,22 @@ import (
type lineReader struct {
rl *readline.Instance
fileHist *fileHistory
}
var fileHist *fileHistory
var hinter *rt.Closure
var highlighter *rt.Closure
func newLineReader(prompt string, noHist bool) *lineReader {
rl := readline.NewInstance()
lr := &lineReader{
rl: rl,
}
// we don't mind hilbish.read rl instances having completion,
// but it cant have shared history
if !noHist {
fileHist = newFileHistory()
rl.SetHistoryCtrlR("History", fileHist)
lr.fileHist = newFileHistory(defaultHistPath)
rl.SetHistoryCtrlR("History", &luaHistory{})
rl.HistoryAutoWrite = false
}
oldSearcher := rl.HistorySearcher
@ -190,9 +194,7 @@ func newLineReader(prompt string, noHist bool) *lineReader {
return pfx, compGroups
}
return &lineReader{
rl,
}
return lr
}
func (lr *lineReader) Read() (string, error) {
@ -231,7 +233,7 @@ func (lr *lineReader) SetRightPrompt(p string) {
}
func (lr *lineReader) AddHistory(cmd string) {
fileHist.Write(cmd)
lr.fileHist.Write(cmd)
}
func (lr *lineReader) ClearInput() {
@ -272,7 +274,7 @@ func (lr *lineReader) luaAddHistory(t *rt.Thread, c *rt.GoCont) (rt.Cont, error)
}
func (lr *lineReader) luaSize(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
return c.PushingNext1(t.Runtime, rt.IntValue(int64(fileHist.Len()))), nil
return c.PushingNext1(t.Runtime, rt.IntValue(int64(lr.fileHist.Len()))), nil
}
func (lr *lineReader) luaGetHistory(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
@ -284,17 +286,17 @@ func (lr *lineReader) luaGetHistory(t *rt.Thread, c *rt.GoCont) (rt.Cont, error)
return nil, err
}
cmd, _ := fileHist.GetLine(int(idx))
cmd, _ := lr.fileHist.GetLine(int(idx))
return c.PushingNext1(t.Runtime, rt.StringValue(cmd)), nil
}
func (lr *lineReader) luaAllHistory(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
tbl := rt.NewTable()
size := fileHist.Len()
size := lr.fileHist.Len()
for i := 1; i < size; i++ {
cmd, _ := fileHist.GetLine(i)
cmd, _ := lr.fileHist.GetLine(i)
tbl.Set(rt.IntValue(int64(i)), rt.StringValue(cmd))
}
@ -302,6 +304,6 @@ func (lr *lineReader) luaAllHistory(t *rt.Thread, c *rt.GoCont) (rt.Cont, error)
}
func (lr *lineReader) luaClearHistory(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
fileHist.clear()
lr.fileHist.clear()
return c.Next(), nil
}

View File

@ -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 = ""