From d27ce26be0cdd2465a7550ca06491b694ede5cb0 Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Sat, 9 Jul 2022 10:45:11 -0400 Subject: [PATCH 01/20] feat: complete files plainly if tab query begins with quotes (workaround #183) --- complete.go | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/complete.go b/complete.go index 01a8137..3a2899d 100644 --- a/complete.go +++ b/complete.go @@ -11,8 +11,34 @@ import ( rt "github.com/arnodel/golua/runtime" ) +func splitQuote(str string) []string { + split := []string{} + sb := &strings.Builder{} + quoted := false + + for _, r := range str { + if r == '"' { + quoted = !quoted + sb.WriteRune(r) + } else if !quoted && r == ' ' { + split = append(split, sb.String()) + sb.Reset() + } else { + sb.WriteRune(r) + } + } + + if sb.Len() > 0 { + split = append(split, sb.String()) + } + + return split +} + func fileComplete(query, ctx string, fields []string) ([]string, string) { - return matchPath(query) + q := splitQuote(ctx) + + return matchPath(q[len(q) - 1]) } func binaryComplete(query, ctx string, fields []string) ([]string, string) { @@ -68,6 +94,8 @@ func binaryComplete(query, ctx string, fields []string) ([]string, string) { } func matchPath(query string) ([]string, string) { + oldQuery := query + query = strings.TrimPrefix(query, "\"") var entries []string var baseName string @@ -87,7 +115,9 @@ func matchPath(query string) ([]string, string) { if file.IsDir() { entry = entry + string(os.PathSeparator) } - entry = escapeFilename(entry) + if !strings.HasPrefix(oldQuery, "\"") { + entry = escapeFilename(entry) + } entries = append(entries, entry) } } From e0694c886214d65d83774d39049988ae98da7af6 Mon Sep 17 00:00:00 2001 From: sammy <38820196+TorchedSammy@users.noreply.github.com> Date: Sat, 9 Jul 2022 08:44:53 -0700 Subject: [PATCH 02/20] build!: replace make with task (#171) * build!: replace make with task allows easy windows building (besides literally go build) down the line because getting make on windows is dumb and even if you do it probably wouldnt work as intended on there (i also find task more intuitive for simple things) * ci: use task in build workflow instead of make * style: remove whitespace errors in task file * docs: add task in changelog * docs: fix link to task * docs: change message for task notice --- .github/workflows/build.yml | 4 +++- CHANGELOG.md | 4 ++++ Makefile | 30 ------------------------------ Taskfile.yaml | 36 ++++++++++++++++++++++++++++++++++++ 4 files changed, 43 insertions(+), 31 deletions(-) delete mode 100644 Makefile create mode 100644 Taskfile.yaml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 08c69ef..371d284 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -26,8 +26,10 @@ jobs: uses: actions/setup-go@v2 with: go-version: '1.17.7' + - name: Download Task + run: 'sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d' - name: Build - run: GOOS=${{ matrix.goos }} GOARCH=${{ matrix.goarch }} make + run: GOOS=${{ matrix.goos }} GOARCH=${{ matrix.goarch }} ./bin/task - uses: actions/upload-artifact@v2 if: matrix.goos == 'windows' with: diff --git a/CHANGELOG.md b/CHANGELOG.md index dd733c6..1a2a091 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ # 🎀 Changelog ## Unreleased +**NOTE:** Hilbish now uses [Task] insead of Make for builds. + +[Task]: https://taskfile.dev/#/ + ### Added - Inline hints, akin to fish and the others. To make a handler for hint text, you can set the `hilbish.hinter` function. diff --git a/Makefile b/Makefile deleted file mode 100644 index 40945d3..0000000 --- a/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -PREFIX ?= /usr -BINDIR ?= $(PREFIX)/bin -LIBDIR ?= $(PREFIX)/share/hilbish - -MY_GOFLAGS = -ldflags "-s -w" - -all: dev - -dev: MY_GOFLAGS = -ldflags "-s -w -X main.gitCommit=$(shell git rev-parse --short HEAD) -X main.gitBranch=$(shell git rev-parse --abbrev-ref HEAD)" -dev: build - -build: - go build $(MY_GOFLAGS) - -install: - install -v -d "$(DESTDIR)$(BINDIR)/" && install -m 0755 -v hilbish "$(DESTDIR)$(BINDIR)/hilbish" - mkdir -p "$(DESTDIR)$(LIBDIR)" - cp -r libs docs emmyLuaDocs nature .hilbishrc.lua "$(DESTDIR)$(LIBDIR)" - grep -qxF "$(DESTDIR)$(BINDIR)/hilbish" /etc/shells || echo "$(DESTDIR)$(BINDIR)/hilbish" >> /etc/shells - -uninstall: - rm -vrf \ - "$(DESTDIR)$(BINDIR)/hilbish" \ - "$(DESTDIR)$(LIBDIR)" - sed -i '/hilbish/d' /etc/shells - -clean: - go clean - -.PHONY: all dev build install uninstall clean diff --git a/Taskfile.yaml b/Taskfile.yaml new file mode 100644 index 0000000..067f2ba --- /dev/null +++ b/Taskfile.yaml @@ -0,0 +1,36 @@ +# https://taskfile.dev + +version: '3' + +vars: + PREFIX: '{{default "/usr" .PREFIX}}' + bindir__: '{{.PREFIX}}/bin' + BINDIR: '{{default .bindir__ .BINDIR}}' + libdir__: '{{.PREFIX}}/share/hilbish' + LIBDIR: '{{default .libdir__ .LIBDIR}}' + GOFLAGS: '-ldflags "-s -w"' + +tasks: + default: + cmds: + - go build {{.GOFLAGS}} + vars: + GOFLAGS: '-ldflags "-s -w -X main.gitCommit=$(git rev-parse --short HEAD) -X main.gitBranch=$(git rev-parse --abbrev-ref HEAD)"' + + build: + cmds: + - go build {{.GOFLAGS}} + + install: + cmds: + - install -v -d "{{.DESTDIR}}{{.BINDIR}}/" && install -m 0755 -v hilbish "{{.DESTDIR}}{{.BINDIR}}/hilbish" + - mkdir -p "{{.DESTDIR}}{{.LIBDIR}}" + - cp -r libs docs emmyLuaDocs nature .hilbishrc.lua {{.DESTDIR}}{{.LIBDIR}} + - grep -qxF "{{.DESTDIR}}{{.BINDIR}}/hilbish" /etc/shells || echo "{{.DESTDIR}}{{.BINDIR}}/hilbish" >> /etc/shells + + uninstall: + cmds: + - rm -vrf + "{{.DESTDIR}}{{.BINDIR}}/hilbish" + "{{.DESTDIR}}{{.LIBDIR}}" + - sed -i '/hilbish/d' /etc/shells From 90ed12d55132586ea83d4683459053606d116597 Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Sat, 9 Jul 2022 17:04:50 -0400 Subject: [PATCH 03/20] feat: add hilbish.init hook (closes #186) --- CHANGELOG.md | 1 + main.go | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a2a091..5e056df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -61,6 +61,7 @@ having and using multiple runners. - `fs.pathListSep` is the separator for $PATH env entries - Lua modules located in `hilbish.userDir.data .. '/hilbish/start'` (like `~/.local/share/hilbish/start/foo/init.lua`) will be ran on startup +- `hilbish.init` hook, thrown after Hilbish has initialized Lua side ### Changed - **Breaking Change:** Upgraded to Lua 5.4. diff --git a/main.go b/main.go index 9421bfc..ce1a7f3 100644 --- a/main.go +++ b/main.go @@ -138,6 +138,7 @@ func main() { } else { runConfig(*configflag) } + hooks.Em.Emit("hilbish.init") if fileInfo, _ := os.Stdin.Stat(); (fileInfo.Mode() & os.ModeCharDevice) == 0 { scanner := bufio.NewScanner(bufio.NewReader(os.Stdin)) From a106f4aea0e80d96b81317bc806d547a7f23acc7 Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Sat, 9 Jul 2022 17:15:13 -0400 Subject: [PATCH 04/20] refactor!: move hilbish.greeting to an opt (closes #184) --- .hilbishrc.lua | 2 -- CHANGELOG.md | 5 +++-- api.go | 6 ------ nature/opts/greeting.lua | 8 ++++++++ nature/opts/init.lua | 5 ++++- 5 files changed, 15 insertions(+), 11 deletions(-) create mode 100644 nature/opts/greeting.lua diff --git a/.hilbishrc.lua b/.hilbishrc.lua index 4a06b26..5d6382b 100644 --- a/.hilbishrc.lua +++ b/.hilbishrc.lua @@ -9,8 +9,6 @@ local function doPrompt(fail) )) end -print(lunacolors.format(hilbish.greeting)) - doPrompt() bait.catch('command.exit', function(code) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e056df..efda87e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -77,12 +77,13 @@ It can (at the moment) have 4 variables: User input has been added to the return to account for runners wanting to prompt for continued input, and to add it properly to history. `continue` got added so that it would be easier for runners to get continued input -without having to actually handle it at all. - +without having to actually handle it at all. - **Breaking Change:** Job objects and timers are now Lua userdata instead of a table, so their functions require you to call them with a colon instead 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. ### Fixed - If in Vim replace mode, input at the end of the line inserts instead of diff --git a/api.go b/api.go index 3aca037..dacae02 100644 --- a/api.go +++ b/api.go @@ -44,7 +44,6 @@ var exports = map[string]util.LuaExport{ "which": {hlwhich, 1, false}, } -var greeting string var hshMod *rt.Table var hilbishLoader = packagelib.Loader{ Load: hilbishLoad, @@ -103,10 +102,6 @@ func hilbishLoad(rtm *rt.Runtime) (rt.Value, func()) { username = strings.Split(username, "\\")[1] // for some reason Username includes the hostname on windows } - greeting = `Welcome to {magenta}Hilbish{reset}, {cyan}` + username + `{reset}. -The nice lil shell for {blue}Lua{reset} fanatics! -Check out the {blue}{bold}guide{reset} command to get started. -` util.SetFieldProtected(fakeMod, mod, "ver", rt.StringValue(getVersion()), "Hilbish version") util.SetFieldProtected(fakeMod, mod, "user", rt.StringValue(username), "Username of user") util.SetFieldProtected(fakeMod, mod, "host", rt.StringValue(host), "Host name of the machine") @@ -114,7 +109,6 @@ Check out the {blue}{bold}guide{reset} command to get started. util.SetFieldProtected(fakeMod, mod, "dataDir", rt.StringValue(dataDir), "Directory for Hilbish's data files") util.SetFieldProtected(fakeMod, mod, "interactive", rt.BoolValue(interactive), "If this is an interactive shell") util.SetFieldProtected(fakeMod, mod, "login", rt.BoolValue(login), "Whether this is a login shell") - util.SetFieldProtected(fakeMod, mod, "greeting", rt.StringValue(greeting), "Hilbish's welcome message for interactive shells. It has Lunacolors formatting.") util.SetFieldProtected(fakeMod, mod, "vimMode", rt.NilValue, "Current Vim mode of Hilbish (nil if not in Vim mode)") util.SetFieldProtected(fakeMod, mod, "exitCode", rt.IntValue(0), "Exit code of last exected command") util.Document(fakeMod, "Hilbish's core API, containing submodules and functions which relate to the shell itself.") diff --git a/nature/opts/greeting.lua b/nature/opts/greeting.lua new file mode 100644 index 0000000..ed408d7 --- /dev/null +++ b/nature/opts/greeting.lua @@ -0,0 +1,8 @@ +local bait = require 'bait' +local lunacolors = require 'lunacolors' + +bait.catch('hilbish.init', function() + if hilbish.interactive and type(hilbish.opts.greeting) == 'string' then + print(lunacolors.format(hilbish.opts.greeting)) + end +end) diff --git a/nature/opts/init.lua b/nature/opts/init.lua index 59d3cbd..d9de420 100644 --- a/nature/opts/init.lua +++ b/nature/opts/init.lua @@ -20,7 +20,10 @@ local function setupOpt(name, default) end local defaultOpts = { - autocd = false + autocd = false, + greeting = string.format([[Welcome to {magenta}Hilbish{reset}, {cyan}%s{reset}. +The nice lil shell for {blue}Lua{reset} fanatics! +]], hilbish.user) } for optsName, default in pairs(defaultOpts) do From 6eea5bce47646f27eaed44aa147f53429c0a1fd7 Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Sat, 9 Jul 2022 17:54:21 -0400 Subject: [PATCH 05/20] feat: add motd (closes #185) --- CHANGELOG.md | 3 +++ nature/opts/init.lua | 3 ++- nature/opts/motd.lua | 13 +++++++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 nature/opts/motd.lua diff --git a/CHANGELOG.md b/CHANGELOG.md index efda87e..b3ab22b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -62,6 +62,9 @@ having and using multiple runners. - Lua modules located in `hilbish.userDir.data .. '/hilbish/start'` (like `~/.local/share/hilbish/start/foo/init.lua`) will be ran on startup - `hilbish.init` hook, thrown after Hilbish has initialized Lua side +- 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. ### Changed - **Breaking Change:** Upgraded to Lua 5.4. diff --git a/nature/opts/init.lua b/nature/opts/init.lua index d9de420..0b32f3f 100644 --- a/nature/opts/init.lua +++ b/nature/opts/init.lua @@ -23,7 +23,8 @@ local defaultOpts = { autocd = false, greeting = string.format([[Welcome to {magenta}Hilbish{reset}, {cyan}%s{reset}. The nice lil shell for {blue}Lua{reset} fanatics! -]], hilbish.user) +]], hilbish.user), + motd = true } for optsName, default in pairs(defaultOpts) do diff --git a/nature/opts/motd.lua b/nature/opts/motd.lua new file mode 100644 index 0000000..b22f5a2 --- /dev/null +++ b/nature/opts/motd.lua @@ -0,0 +1,13 @@ +local bait = require 'bait' +local lunacolors = require 'lunacolors' + +hilbish.motd = [[ +Hilbish 2.0 is a {red}major{reset} update! If your config doesn't work +anymore, that will definitely be why! A MOTD, very message, much day. +]] + +bait.catch('hilbish.init', function() + if hilbish.opts.motd then + print(lunacolors.format(hilbish.motd)) + end +end) From 60dd5f598a43c471e4b9cbb22886a6a0806ce99e Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Sat, 9 Jul 2022 18:38:57 -0400 Subject: [PATCH 06/20] docs: replace make with task on readme --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index bb2ca29..bdb4dc9 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,7 @@ If you're new to nix you should probably read up on how to do that [here](https: ## Manual Build ### Prerequisites - [Go 1.17+](https://go.dev) +- [Task](https://taskfile.dev/#/) ### Build First, clone Hilbish. The recursive is required, as some Lua libraries @@ -78,16 +79,16 @@ go get -d ./... To build, run: ``` -make dev +task ``` Or, if you want a stable branch, run these commands: ``` git checkout $(git describe --tags `git rev-list --tags --max-count=1`) -make build +task build ``` -After you did all that, run `sudo make install` to install Hilbish globally. +After you did all that, run `sudo task install` to install Hilbish globally. # Getting Started At startup, you should see a message which says to run a `guide` command. From 83a2ce38ea57da06ef731062804c67d5ef2c7a8a Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Sat, 9 Jul 2022 18:39:21 -0400 Subject: [PATCH 07/20] docs: remove getting started section on readme --- README.md | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/README.md b/README.md index bdb4dc9..86879d1 100644 --- a/README.md +++ b/README.md @@ -90,20 +90,6 @@ task build After you did all that, run `sudo task install` to install Hilbish globally. -# Getting Started -At startup, you should see a message which says to run a `guide` command. -This guide is a *very* simple and basic step through text of what Hilbish is -and where to find documentation. - -Documentation is primarily viewed via the in shell `doc` command. -Autogenerated function docs and general docs about other things are included -there, so be sure to read it. - -Using Hilbish is the same as using any other Linux shell, with an addition -that you can also run Lua. Hilbish can also act as an enhanced Lua REPL -via `hilbish.runnerMode 'lua'`. To switch back to normal, use -`hilbish.runnerMode 'hybrid'`. - # Contributing Any kind of contributions are welcome! Hilbish is very easy to contribute to. Read [CONTRIBUTING.md](CONTRIBUTING.md) as a guideline to doing so. From 08e29515133ee4c43e169a15378e4fb96c507163 Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Sun, 10 Jul 2022 20:34:00 -0400 Subject: [PATCH 08/20] feat: add raw input hook (closes #180) --- CHANGELOG.md | 1 + lua.go | 4 ++++ readline/instance.go | 2 ++ readline/readline.go | 1 + 4 files changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b3ab22b..42812d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -65,6 +65,7 @@ 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. +- `hilbish.rawInput` hook for input from the readline library ### Changed - **Breaking Change:** Upgraded to Lua 5.4. diff --git a/lua.go b/lua.go index 8f3c0fb..d7eb823 100644 --- a/lua.go +++ b/lua.go @@ -48,6 +48,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..50d04b9 100644 --- a/readline/readline.go +++ b/readline/readline.go @@ -94,6 +94,7 @@ func (rl *Instance) Readline() (string, error) { rl.skipStdinRead = false r := []rune(string(b)) + rl.RawInputCallback(r[:i]) if isMultiline(r[:i]) || len(rl.multiline) > 0 { rl.multiline = append(rl.multiline, b[:i]...) From b65acca9037a5d687a2bfa769c9f8929fbb50543 Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Sun, 10 Jul 2022 22:07:01 -0400 Subject: [PATCH 09/20] fix: initialize line reader before lua init --- main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.go b/main.go index ce1a7f3..9e3068a 100644 --- a/main.go +++ b/main.go @@ -116,8 +116,8 @@ func main() { } go handleSignals() - luaInit() lr = newLineReader("", false) + luaInit() // If user's config doesn't exixt, if _, err := os.Stat(defaultConfPath); os.IsNotExist(err) && *configflag == defaultConfPath { // Read default from current directory From 2b480e50e69eb959485dd624efd60302ee383111 Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Wed, 13 Jul 2022 10:08:23 -0400 Subject: [PATCH 10/20] feat: print tracebacks for errors --- lua.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lua.go b/lua.go index d7eb823..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) From e185a3268540c50681941115edc187aa3156760e Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Wed, 13 Jul 2022 14:10:29 -0400 Subject: [PATCH 11/20] fix: expand tilde in dataDir on windows --- vars_windows.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/vars_windows.go b/vars_windows.go index a257baf..78f459d 100644 --- a/vars_windows.go +++ b/vars_windows.go @@ -2,13 +2,17 @@ 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 = "" From be8bdef9c895a6a04da476a39e665380cad86278 Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Wed, 13 Jul 2022 14:18:23 -0400 Subject: [PATCH 12/20] style: use single line import instead of list syntax --- vars_windows.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/vars_windows.go b/vars_windows.go index 78f459d..403941f 100644 --- a/vars_windows.go +++ b/vars_windows.go @@ -2,9 +2,7 @@ package main -import ( - "hilbish/util" -) +import "hilbish/util" // String vars that are free to be changed at compile time var ( From dd9aa4b6ea58b9cd6dde5e4a178edb9184f68e76 Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Wed, 13 Jul 2022 15:04:18 -0400 Subject: [PATCH 13/20] fix: enable vt input for windows --- init_windows.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/init_windows.go b/init_windows.go index ee17a6b..0d74ba9 100644 --- a/init_windows.go +++ b/init_windows.go @@ -7,5 +7,5 @@ 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) + windows.SetConsoleMode(windows.Stdout, mode | windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING | windows.ENABLE_VIRTUAL_TERMINAL_INPUT) } From 990256006166c8be5e27d9c0ce4068cfa0d8a8bf Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Wed, 13 Jul 2022 15:11:06 -0400 Subject: [PATCH 14/20] fix: set vt in on stdin --- init_windows.go | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/init_windows.go b/init_windows.go index 0d74ba9..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 | windows.ENABLE_VIRTUAL_TERMINAL_INPUT) + // 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) } From dd9bdca5e05bea8ba5623b400b1dd82963fbc7f3 Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Wed, 13 Jul 2022 15:35:33 -0400 Subject: [PATCH 15/20] fix(readline): only call raw input callback if not nil --- readline/readline.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/readline/readline.go b/readline/readline.go index 50d04b9..731e297 100644 --- a/readline/readline.go +++ b/readline/readline.go @@ -94,7 +94,9 @@ func (rl *Instance) Readline() (string, error) { rl.skipStdinRead = false r := []rune(string(b)) - rl.RawInputCallback(r[:i]) + if rl.RawInputCallback != nil { + rl.RawInputCallback(r[:i]) + } if isMultiline(r[:i]) || len(rl.multiline) > 0 { rl.multiline = append(rl.multiline, b[:i]...) From 083c2664386ddcb5eb699e3738e53b9063b678fb Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Wed, 13 Jul 2022 15:38:07 -0400 Subject: [PATCH 16/20] feat(golibs/fs): add join function to join path elements --- golibs/fs/fs.go | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) 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 +} From c8c30e9861d23e730e71a68f928df54b65807614 Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Wed, 13 Jul 2022 15:46:18 -0400 Subject: [PATCH 17/20] docs: update changelog --- CHANGELOG.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 42812d4..997d3de 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 @@ -66,6 +67,7 @@ will be ran on startup small news pieces for releases. It is printed by default. To disable it, set `hilbish.opts.motd` to false. - `hilbish.rawInput` hook for input from the readline library +- Completion of files in quotes ### Changed - **Breaking Change:** Upgraded to Lua 5.4. @@ -122,6 +124,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 From f7806f54798812854fad0ae60f28083c9cead402 Mon Sep 17 00:00:00 2001 From: TorchedSammy Date: Wed, 13 Jul 2022 19:46:40 +0000 Subject: [PATCH 18/20] docs: [ci] generate new docs --- docs/fs.txt | 3 +++ emmyLuaDocs/fs.lua | 4 ++++ 2 files changed, 7 insertions(+) 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 From 349380ae6bc511f82efbb1ae413ec775c8a715f8 Mon Sep 17 00:00:00 2001 From: sammy <38820196+TorchedSammy@users.noreply.github.com> Date: Wed, 13 Jul 2022 13:02:09 -0700 Subject: [PATCH 19/20] feat: lua backed history (#187) * refactor: put file history handler in line reader instance instead of global * feat: add lua history handler in go * feat: use lua to retrieve readline history * refactor: handle history in lua this also introduces a new opt: history if it is false, command history won't get added * fix: remove nature.history require * docs: add changes in changelog * fix: add comma after history opt --- CHANGELOG.md | 4 +++ exec.go | 6 +---- history.go | 56 ++++++++++++++++++++++++++++++++++++++--- main.go | 5 ---- nature/opts/history.lua | 5 ++++ nature/opts/init.lua | 1 + rl.go | 26 ++++++++++--------- 7 files changed, 77 insertions(+), 26 deletions(-) create mode 100644 nature/opts/history.lua diff --git a/CHANGELOG.md b/CHANGELOG.md index 997d3de..c0737a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -66,6 +66,8 @@ 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 @@ -90,6 +92,8 @@ 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. ### Fixed - If in Vim replace mode, input at the end of the line inserts instead of diff --git a/exec.go b/exec.go index cc5016a..e1862ed 100644 --- a/exec.go +++ b/exec.go @@ -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) } diff --git a/history.go b/history.go index b666515..a8eb089 100644 --- a/history.go +++ b/history.go @@ -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) } diff --git a/main.go b/main.go index 9e3068a..e53055d 100644 --- a/main.go +++ b/main.go @@ -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{} diff --git a/nature/opts/history.lua b/nature/opts/history.lua new file mode 100644 index 0000000..f7ab1d7 --- /dev/null +++ b/nature/opts/history.lua @@ -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) diff --git a/nature/opts/init.lua b/nature/opts/init.lua index 0b32f3f..ae95ee1 100644 --- a/nature/opts/init.lua +++ b/nature/opts/init.lua @@ -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), diff --git a/rl.go b/rl.go index 88adc65..6350aa2 100644 --- a/rl.go +++ b/rl.go @@ -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 } rl.ShowVimMode = false @@ -171,9 +175,7 @@ func newLineReader(prompt string, noHist bool) *lineReader { return pfx, compGroups } - return &lineReader{ - rl, - } + return lr } func (lr *lineReader) Read() (string, error) { @@ -212,7 +214,7 @@ func (lr *lineReader) SetRightPrompt(p string) { } func (lr *lineReader) AddHistory(cmd string) { - fileHist.Write(cmd) + lr.fileHist.Write(cmd) } func (lr *lineReader) ClearInput() { @@ -253,7 +255,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) { @@ -265,17 +267,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)) } @@ -283,6 +285,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 } From 09a8b41063d0ddb4d53770be072d7b6b40c4abf5 Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Wed, 13 Jul 2022 16:04:57 -0400 Subject: [PATCH 20/20] chore!: remove guide command (closes #188) --- CHANGELOG.md | 2 ++ nature/commands/guide.lua | 54 --------------------------------------- nature/commands/init.lua | 1 - 3 files changed, 2 insertions(+), 55 deletions(-) delete mode 100644 nature/commands/guide.lua diff --git a/CHANGELOG.md b/CHANGELOG.md index c0737a1..522c8d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -94,6 +94,8 @@ of a dot. (ie. `job.stop()` -> `job:stop()`) 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 diff --git a/nature/commands/guide.lua b/nature/commands/guide.lua deleted file mode 100644 index 1c1e346..0000000 --- a/nature/commands/guide.lua +++ /dev/null @@ -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) diff --git a/nature/commands/init.lua b/nature/commands/init.lua index 8ecbf86..13b33be 100644 --- a/nature/commands/init.lua +++ b/nature/commands/init.lua @@ -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'