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/83] 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/83] 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/83] 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/83] 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/83] 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/83] 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/83] 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/83] 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/83] 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/83] 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/83] 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/83] 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/83] 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/83] 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/83] 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/83] 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/83] 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/83] 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/83] 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/83] 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' From 3e0a2d630b6983a8c163e7746a89e3ed65e8eb51 Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Tue, 19 Jul 2022 17:55:03 -0400 Subject: [PATCH 21/83] feat(hilbish.editor): add getLine function to get contents of line --- editor.go | 7 +++++++ readline/line.go | 2 +- readline/timer.go | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/editor.go b/editor.go index 323f50b..868f458 100644 --- a/editor.go +++ b/editor.go @@ -11,6 +11,7 @@ func editorLoader(rtm *rt.Runtime) *rt.Table { "insert": {editorInsert, 1, false}, "setVimRegister": {editorSetRegister, 1, false}, "getVimRegister": {editorGetRegister, 2, false}, + "getLine": {editorGetLine, 0, false}, } mod := rt.NewTable() @@ -68,3 +69,9 @@ func editorGetRegister(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { return c.PushingNext1(t.Runtime, rt.StringValue(string(buf))), nil } + +func editorGetLine(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { + buf := lr.rl.GetLine() + + return c.PushingNext1(t.Runtime, rt.StringValue(string(buf))), nil +} diff --git a/readline/line.go b/readline/line.go index 974a34d..2024bb0 100644 --- a/readline/line.go +++ b/readline/line.go @@ -18,7 +18,7 @@ func (rl *Instance) updateLine(line []rune) { // getLine - In many places we need the current line input. We either return the real line, // or the one that includes the current completion candidate, if there is any. -func (rl *Instance) getLine() []rune { +func (rl *Instance) GetLine() []rune { if len(rl.currentComp) > 0 { return rl.lineComp } diff --git a/readline/timer.go b/readline/timer.go index dc53ca9..76eab23 100644 --- a/readline/timer.go +++ b/readline/timer.go @@ -24,7 +24,7 @@ func delayedSyntaxTimer(rl *Instance, i int64) { // } // We pass either the current line or the one with the current completion. - newLine := rl.DelayedSyntaxWorker(rl.getLine()) + newLine := rl.DelayedSyntaxWorker(rl.GetLine()) var sLine string count := atomic.LoadInt64(&rl.delayedSyntaxCount) if count != i { From 7de835fab440680575bde1ac87d260d59dd28e44 Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Tue, 26 Jul 2022 10:41:12 -0400 Subject: [PATCH 22/83] chore: update lunacolors (adds blackBg format arg) --- libs/lunacolors | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/lunacolors b/libs/lunacolors index d60cd77..8467b87 160000 --- a/libs/lunacolors +++ b/libs/lunacolors @@ -1 +1 @@ -Subproject commit d60cd77c73875b5bb55e5a2fdc30bae01a7ac499 +Subproject commit 8467b87dd8d49c68b4100b2d129d5f071544b8cf From 387d7d2243c1378ccd59fb77e7dd767870feb662 Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Tue, 26 Jul 2022 19:24:02 -0400 Subject: [PATCH 23/83] fix: percentages in completion entries causing a problem in the completion menus --- CHANGELOG.md | 2 ++ readline/comp-grid.go | 4 ++-- readline/comp-group.go | 6 ++++++ readline/comp-list.go | 4 ++-- readline/comp-map.go | 4 ++-- 5 files changed, 14 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 522c8d5..48d54f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -138,6 +138,8 @@ menu is open. - `hilbish.dataDir` now has tilde (`~`) expanded. - Arrow keys now work on Windows terminals. - Escape codes now work. +- Escape percentage symbols in completion entries, so you will no longer see +an error of missing format variable ## [1.2.0] - 2022-03-17 ### Added diff --git a/readline/comp-grid.go b/readline/comp-grid.go index 2679835..48a2039 100644 --- a/readline/comp-grid.go +++ b/readline/comp-grid.go @@ -99,7 +99,7 @@ func (g *CompletionGroup) writeGrid(rl *Instance) (comp string) { // If group title, print it and adjust offset. if g.Name != "" { - comp += fmt.Sprintf("%s%s%s %s\n", BOLD, YELLOW, g.Name, RESET) + comp += fmt.Sprintf("%s%s%s %s\n", BOLD, YELLOW, fmtEscape(g.Name), RESET) rl.tcUsedY++ } @@ -124,7 +124,7 @@ func (g *CompletionGroup) writeGrid(rl *Instance) (comp string) { comp += seqInvert } - comp += fmt.Sprintf("%-"+cellWidth+"s %s", g.Suggestions[i], seqReset) + comp += fmt.Sprintf("%-"+cellWidth+"s %s", fmtEscape(g.Suggestions[i]), seqReset) } // Always add a newline to the group if the end if not punctuated with one diff --git a/readline/comp-group.go b/readline/comp-group.go index 6a6e7bc..0c53ed1 100644 --- a/readline/comp-group.go +++ b/readline/comp-group.go @@ -1,5 +1,7 @@ package readline +import "strings" + // CompletionGroup - A group/category of items offered to completion, with its own // name, descriptions and completion display format/type. // The output, if there are multiple groups available for a given completion input, @@ -285,3 +287,7 @@ func (g *CompletionGroup) goLastCell() { g.tcPosX = 0 } } + +func fmtEscape(s string) string { + return strings.Replace(s, "%", "%%", -1) +} diff --git a/readline/comp-list.go b/readline/comp-list.go index 42add2f..cdcda8f 100644 --- a/readline/comp-list.go +++ b/readline/comp-list.go @@ -206,12 +206,12 @@ func (g *CompletionGroup) writeList(rl *Instance) (comp string) { if len(item) > maxLength { item = item[:maxLength-3] + "..." } - sugg := fmt.Sprintf("\r%s%-"+cellWidth+"s", highlight(y, 0), item) + sugg := fmt.Sprintf("\r%s%-"+cellWidth+"s", highlight(y, 0), fmtEscape(item)) // Alt suggestion alt, ok := g.Aliases[item] if ok { - alt = fmt.Sprintf(" %s%"+cellWidthAlt+"s", highlight(y, 1), alt) + alt = fmt.Sprintf(" %s%"+cellWidthAlt+"s", highlight(y, 1), fmtEscape(alt)) } else { // Else, make an empty cell alt = strings.Repeat(" ", maxLengthAlt+1) // + 2 to keep account of spaces diff --git a/readline/comp-map.go b/readline/comp-map.go index 42b56cf..ec985ff 100644 --- a/readline/comp-map.go +++ b/readline/comp-map.go @@ -76,7 +76,7 @@ func (g *CompletionGroup) writeMap(rl *Instance) (comp string) { if g.Name != "" { // Print group title (changes with line returns depending on type) - comp += fmt.Sprintf("%s%s%s %s\n", BOLD, YELLOW, g.Name, RESET) + comp += fmt.Sprintf("%s%s%s %s\n", BOLD, YELLOW, fmtEscape(g.Name), RESET) rl.tcUsedY++ } @@ -126,7 +126,7 @@ func (g *CompletionGroup) writeMap(rl *Instance) (comp string) { } comp += fmt.Sprintf("\r%-"+cellWidth+"s %s %-"+itemWidth+"s %s\n", - description, highlight(y), item, seqReset) + description, highlight(y), fmtEscape(item), seqReset) } // Add the equivalent of this group's size to final screen clearing From 6ce4fb3973c3e484d84c901c92dd87c1a99880cb Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Tue, 16 Aug 2022 12:30:39 -0400 Subject: [PATCH 24/83] fix: add dot to sample config path on windows --- vars_windows.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vars_windows.go b/vars_windows.go index 403941f..d1bd7b6 100644 --- a/vars_windows.go +++ b/vars_windows.go @@ -12,6 +12,6 @@ var ( .. hilbish.userDir.config .. '\\Hilbish\\libs\\?.lua;'` dataDir = util.ExpandHome("~\\Appdata\\Roaming\\Hilbish") // ~ and \ gonna cry? preloadPath = dataDir + "\\nature\\init.lua" - sampleConfPath = dataDir + "\\hilbishrc.lua" // Path to default/sample config + sampleConfPath = dataDir + "\\.hilbishrc.lua" // Path to default/sample config defaultConfDir = "" ) From 2337f9ab60d0b2773420ac46db467a03694d85e7 Mon Sep 17 00:00:00 2001 From: sammy <38820196+TorchedSammy@users.noreply.github.com> Date: Wed, 17 Aug 2022 18:01:32 -0400 Subject: [PATCH 25/83] refactor: use custom event emitter (#193) * refactor: use custom event emitter * fix: sigint hook emit on windows * fix: restore correct hilbish conf file * fix: call recoverer for go listeners * refactor(golibs/bait): use 1 map for listeners * feat: add once listeners, ability to remove listeners and remove listener on error * perf: reslice listener slice instead of trying to do ordered move with append * feat(bait): add release function to remove event listener * perf: remove listener directly from once emit instead of using off function * refactor: use bait event emitter on commander * docs(golibs/bait): add doc strings for functions * docs: set changelog * docs(golibs/bait): add docs for lua release function --- CHANGELOG.md | 5 + api.go | 2 +- exec.go | 6 +- golibs/bait/bait.go | 202 ++++++++++++++++++++++++++++++---- golibs/commander/commander.go | 8 +- job.go | 6 +- lua.go | 22 +++- main.go | 10 +- rl.go | 4 +- signal_unix.go | 8 +- signal_windows.go | 2 +- 11 files changed, 226 insertions(+), 49 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 48d54f2..49904ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -70,6 +70,11 @@ set `hilbish.opts.motd` to false. disables commands being added to history. - `hilbish.rawInput` hook for input from the readline library - Completion of files in quotes +- A new and "safer" event emitter has been added. This causes a performance deficit, but avoids a lot of +random errors introduced with the new Lua runtime (see [#197]) +- `bait.release(name, catcher)` removes `handler` for the named `event` + +[#197]: https://github.com/Rosettea/Hilbish/issues/197 ### Changed - **Breaking Change:** Upgraded to Lua 5.4. diff --git a/api.go b/api.go index dacae02..d060597 100644 --- a/api.go +++ b/api.go @@ -189,7 +189,7 @@ func getenv(key, fallback string) string { func setVimMode(mode string) { util.SetField(l, hshMod, "vimMode", rt.StringValue(mode), "Current Vim mode of Hilbish (nil if not in Vim mode)") - hooks.Em.Emit("hilbish.vimMode", mode) + hooks.Emit("hilbish.vimMode", mode) } func unsetVimMode() { diff --git a/exec.go b/exec.go index e1862ed..d605a4e 100644 --- a/exec.go +++ b/exec.go @@ -85,7 +85,7 @@ func isExecError(err error) (execError, bool) { func runInput(input string, priv bool) { running = true cmdString := aliases.Resolve(input) - hooks.Em.Emit("command.preexec", input, cmdString) + hooks.Emit("command.preexec", input, cmdString) rerun: var exitCode uint8 @@ -140,7 +140,7 @@ func runInput(input string, priv bool) { if err != nil { if exErr, ok := isExecError(err); ok { - hooks.Em.Emit("command." + exErr.typ, exErr.cmd) + hooks.Emit("command." + exErr.typ, exErr.cmd) err = exErr.sprint() } fmt.Fprintln(os.Stderr, err) @@ -544,5 +544,5 @@ func cmdFinish(code uint8, cmdstr string, private bool) { // 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, private) + hooks.Emit("command.exit", rt.IntValue(int64(code)), cmdstr, private) } diff --git a/golibs/bait/bait.go b/golibs/bait/bait.go index 3112903..89e0c4a 100644 --- a/golibs/bait/bait.go +++ b/golibs/bait/bait.go @@ -1,27 +1,41 @@ package bait import ( - "fmt" "hilbish/util" rt "github.com/arnodel/golua/runtime" "github.com/arnodel/golua/lib/packagelib" - "github.com/chuckpreslar/emission" ) -type Bait struct{ - Em *emission.Emitter - Loader packagelib.Loader +type listenerType int +const ( + goListener listenerType = iota + luaListener +) + +// Recoverer is a function which is called when a panic occurs in an event. +type Recoverer func(event string, handler *Listener, err interface{}) + +// Listener is a struct that holds the handler for an event. +type Listener struct{ + typ listenerType + once bool + caller func(...interface{}) + luaCaller *rt.Closure } -func New() Bait { - emitter := emission.NewEmitter() - emitter.RecoverWith(func(hookname, hookfunc interface{}, err error) { - emitter.Off(hookname, hookfunc) - fmt.Println(err) - }) - b := Bait{ - Em: emitter, +type Bait struct{ + Loader packagelib.Loader + recoverer Recoverer + handlers map[string][]*Listener + rtm *rt.Runtime +} + +// New creates a new Bait instance. +func New(rtm *rt.Runtime) *Bait { + b := &Bait{ + handlers: make(map[string][]*Listener), + rtm: rtm, } b.Loader = packagelib.Loader{ Load: b.loaderFunc, @@ -31,11 +45,148 @@ func New() Bait { return b } +// Emit throws an event. +func (b *Bait) Emit(event string, args ...interface{}) { + handles := b.handlers[event] + if handles == nil { + return + } + + for idx, handle := range handles { + defer func() { + if err := recover(); err != nil { + b.callRecoverer(event, handle, err) + } + }() + + if handle.typ == luaListener { + funcVal := rt.FunctionValue(handle.luaCaller) + var luaArgs []rt.Value + for _, arg := range args { + var luarg rt.Value + switch arg.(type) { + case rt.Value: luarg = arg.(rt.Value) + default: luarg = rt.AsValue(arg) + } + luaArgs = append(luaArgs, luarg) + } + _, err := rt.Call1(b.rtm.MainThread(), funcVal, luaArgs...) + if err != nil { + // panicking here won't actually cause hilbish to panic and instead will + // print the error and remove the hook. reference the recoverer function in lua.go + panic(err) + } + } else { + handle.caller(args...) + } + + if handle.once { + b.removeListener(event, idx) + } + } +} + +// On adds a Go function handler for an event. +func (b *Bait) On(event string, handler func(...interface{})) *Listener { + listener := &Listener{ + typ: goListener, + caller: handler, + } + + b.addListener(event, listener) + return listener +} + +// OnLua adds a Lua function handler for an event. +func (b *Bait) OnLua(event string, handler *rt.Closure) *Listener { + listener :=&Listener{ + typ: luaListener, + luaCaller: handler, + } + b.addListener(event, listener) + + return listener +} + +// Off removes a Go function handler for an event. +func (b *Bait) Off(event string, listener *Listener) { + handles := b.handlers[event] + + for i, handle := range handles { + if handle == listener { + b.removeListener(event, i) + } + } +} + +// OffLua removes a Lua function handler for an event. +func (b *Bait) OffLua(event string, handler *rt.Closure) { + handles := b.handlers[event] + + for i, handle := range handles { + if handle.luaCaller == handler { + b.removeListener(event, i) + } + } +} + +// Once adds a Go function listener for an event that only runs once. +func (b *Bait) Once(event string, handler func(...interface{})) *Listener { + listener := &Listener{ + typ: goListener, + once: true, + caller: handler, + } + b.addListener(event, listener) + + return listener +} + +// OnceLua adds a Lua function listener for an event that only runs once. +func (b *Bait) OnceLua(event string, handler *rt.Closure) *Listener { + listener := &Listener{ + typ: luaListener, + once: true, + luaCaller: handler, + } + b.addListener(event, listener) + + return listener +} + +// SetRecoverer sets the function to be executed when a panic occurs in an event. +func (b *Bait) SetRecoverer(recoverer Recoverer) { + b.recoverer = recoverer +} + +func (b *Bait) addListener(event string, listener *Listener) { + if b.handlers[event] == nil { + b.handlers[event] = []*Listener{} + } + + b.handlers[event] = append(b.handlers[event], listener) +} + + +func (b *Bait) removeListener(event string, idx int) { + b.handlers[event][idx] = b.handlers[event][len(b.handlers[event]) - 1] + + b.handlers[event] = b.handlers[event][:len(b.handlers[event]) - 1] +} + +func (b *Bait) callRecoverer(event string, handler *Listener, err interface{}) { + if b.recoverer == nil { + panic(err) + } + b.recoverer(event, handler, err) +} + func (b *Bait) loaderFunc(rtm *rt.Runtime) (rt.Value, func()) { exports := map[string]util.LuaExport{ "catch": util.LuaExport{b.bcatch, 2, false}, "catchOnce": util.LuaExport{b.bcatchOnce, 2, false}, "throw": util.LuaExport{b.bthrow, 1, true}, + "release": util.LuaExport{b.brelease, 2, false}, } mod := rt.NewTable() util.SetExports(rtm, mod, exports) @@ -89,7 +240,7 @@ func (b *Bait) bthrow(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { for i, v := range c.Etc() { ifaceSlice[i] = v } - b.Em.Emit(name, ifaceSlice...) + b.Emit(name, ifaceSlice...) return c.Next(), nil } @@ -104,9 +255,7 @@ func (b *Bait) bcatch(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { return nil, err } - b.Em.On(name, func(args ...interface{}) { - handleHook(t, c, name, catcher, args...) - }) + b.OnLua(name, catcher) return c.Next(), nil } @@ -121,9 +270,22 @@ func (b *Bait) bcatchOnce(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { return nil, err } - b.Em.Once(name, func(args ...interface{}) { - handleHook(t, c, name, catcher, args...) - }) + b.OnceLua(name, catcher) + + return c.Next(), nil +} + +// release(name, catcher) +// Removes the `catcher` for the event with `name` +// For this to work, `catcher` has to be the same function used to catch +// an event, like one saved to a variable. +func (b *Bait) brelease(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { + name, catcher, err := util.HandleStrCallback(t, c) + if err != nil { + return nil, err + } + + b.OffLua(name, catcher) return c.Next(), nil } diff --git a/golibs/commander/commander.go b/golibs/commander/commander.go index d279e0c..24f1c03 100644 --- a/golibs/commander/commander.go +++ b/golibs/commander/commander.go @@ -2,20 +2,20 @@ package commander import ( "hilbish/util" + "hilbish/golibs/bait" rt "github.com/arnodel/golua/runtime" "github.com/arnodel/golua/lib/packagelib" - "github.com/chuckpreslar/emission" ) type Commander struct{ - Events *emission.Emitter + Events *bait.Bait Loader packagelib.Loader } -func New() Commander { +func New(rtm *rt.Runtime) Commander { c := Commander{ - Events: emission.NewEmitter(), + Events: bait.New(rtm), } c.Loader = packagelib.Loader{ Load: c.loaderFunc, diff --git a/job.go b/job.go index 7dd07d3..709cc1f 100644 --- a/job.go +++ b/job.go @@ -67,7 +67,7 @@ func (j *job) start() error { j.pid = proc.Pid j.running = true - hooks.Em.Emit("job.start", rt.UserDataValue(j.ud)) + hooks.Emit("job.start", rt.UserDataValue(j.ud)) return err } @@ -82,7 +82,7 @@ func (j *job) stop() { func (j *job) finish() { j.running = false - hooks.Em.Emit("job.done", rt.UserDataValue(j.ud)) + hooks.Emit("job.done", rt.UserDataValue(j.ud)) } func (j *job) wait() { @@ -236,7 +236,7 @@ func (j *jobHandler) add(cmd string, args []string, path string) *job { jb.ud = jobUserData(jb) j.jobs[j.latestID] = jb - hooks.Em.Emit("job.add", rt.UserDataValue(jb.ud)) + hooks.Emit("job.add", rt.UserDataValue(jb.ud)) return jb } diff --git a/lua.go b/lua.go index 92ece05..419970c 100644 --- a/lua.go +++ b/lua.go @@ -32,28 +32,38 @@ func luaInit() { lib.LoadLibs(l, fs.Loader) lib.LoadLibs(l, terminal.Loader) - cmds := commander.New() + cmds := commander.New(l) // When a command from Lua is added, register it for use - cmds.Events.On("commandRegister", func(cmdName string, cmd *rt.Closure) { + cmds.Events.On("commandRegister", func(args ...interface{}) { + cmdName := args[0].(string) + cmd := args[1].(*rt.Closure) + commands[cmdName] = cmd }) - cmds.Events.On("commandDeregister", func(cmdName string) { + cmds.Events.On("commandDeregister", func(args ...interface{}) { + cmdName := args[0].(string) + delete(commands, cmdName) }) lib.LoadLibs(l, cmds.Loader) - hooks = bait.New() + hooks = bait.New(l) + hooks.SetRecoverer(func(event string, handler *bait.Listener, err interface{}) { + fmt.Println("Error in", event, "event:", err) + hooks.Off(event, handler) + }) + lib.LoadLibs(l, hooks.Loader) // Add Ctrl-C handler - hooks.Em.On("signal.sigint", func() { + hooks.On("signal.sigint", func(...interface{}) { if !interactive { os.Exit(0) } }) lr.rl.RawInputCallback = func(r []rune) { - hooks.Em.Emit("hilbish.rawInput", string(r)) + hooks.Emit("hilbish.rawInput", string(r)) } // Add more paths that Lua can require from diff --git a/main.go b/main.go index e53055d..ee0f584 100644 --- a/main.go +++ b/main.go @@ -30,7 +30,7 @@ var ( userDataDir string curuser *user.User - hooks bait.Bait + hooks *bait.Bait defaultConfPath string defaultHistPath string ) @@ -138,7 +138,7 @@ func main() { } else { runConfig(*configflag) } - hooks.Em.Emit("hilbish.init") + hooks.Emit("hilbish.init") if fileInfo, _ := os.Stdin.Stat(); (fileInfo.Mode() & os.ModeCharDevice) == 0 { scanner := bufio.NewScanner(bufio.NewReader(os.Stdin)) @@ -177,7 +177,7 @@ input: if err == io.EOF { // Exit if user presses ^D (ctrl + d) - hooks.Em.Emit("hilbish.exit") + hooks.Emit("hilbish.exit") break } if err != nil { @@ -196,7 +196,7 @@ input: input = strings.TrimSpace(input) if len(input) == 0 { running = true - hooks.Em.Emit("command.exit", 0) + hooks.Emit("command.exit", 0) continue } @@ -227,7 +227,7 @@ input: } func continuePrompt(prev string) (string, error) { - hooks.Em.Emit("multiline", nil) + hooks.Emit("multiline", nil) lr.SetPrompt(multilinePrompt) cont, err := lr.Read() if err != nil { diff --git a/rl.go b/rl.go index 6350aa2..59423ff 100644 --- a/rl.go +++ b/rl.go @@ -48,7 +48,7 @@ func newLineReader(prompt string, noHist bool) *lineReader { case readline.VimActionPaste: actionStr = "paste" case readline.VimActionYank: actionStr = "yank" } - hooks.Em.Emit("hilbish.vimAction", actionStr, args) + hooks.Emit("hilbish.vimAction", actionStr, args) } rl.HintText = func(line []rune, pos int) []rune { if hinter == nil { @@ -179,7 +179,7 @@ func newLineReader(prompt string, noHist bool) *lineReader { } func (lr *lineReader) Read() (string, error) { - hooks.Em.Emit("command.precmd", nil) + hooks.Emit("command.precmd", nil) s, err := lr.rl.Readline() // this is so dumb if err == readline.EOF { diff --git a/signal_unix.go b/signal_unix.go index bd5984c..2e6c885 100644 --- a/signal_unix.go +++ b/signal_unix.go @@ -15,11 +15,11 @@ func handleSignals() { for s := range c { switch s { - case os.Interrupt: hooks.Em.Emit("signal.sigint") + case os.Interrupt: hooks.Emit("signal.sigint") case syscall.SIGTERM: exit(0) - case syscall.SIGWINCH: hooks.Em.Emit("signal.resize") - case syscall.SIGUSR1: hooks.Em.Emit("signal.sigusr1") - case syscall.SIGUSR2: hooks.Em.Emit("signal.sigusr2") + case syscall.SIGWINCH: hooks.Emit("signal.resize") + case syscall.SIGUSR1: hooks.Emit("signal.sigusr1") + case syscall.SIGUSR2: hooks.Emit("signal.sigusr2") } } } diff --git a/signal_windows.go b/signal_windows.go index 9f67537..42a9fff 100644 --- a/signal_windows.go +++ b/signal_windows.go @@ -14,7 +14,7 @@ func handleSignals() { for s := range c { switch s { case os.Interrupt: - hooks.Em.Emit("signal.sigint") + hooks.Emit("signal.sigint") if !running && interactive { lr.ClearInput() } From 3dcd99563a2c8de16745893cce115c8eb28bbc0f Mon Sep 17 00:00:00 2001 From: TorchedSammy Date: Wed, 17 Aug 2022 22:01:55 +0000 Subject: [PATCH 26/83] docs: [ci] generate new docs --- docs/bait.txt | 4 ++++ emmyLuaDocs/bait.lua | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/docs/bait.txt b/docs/bait.txt index 9f1e54b..fdc712f 100644 --- a/docs/bait.txt +++ b/docs/bait.txt @@ -2,5 +2,9 @@ catch(name, cb) > Catches a hook with `name`. Runs the `cb` when it is thrown catchOnce(name, cb) > Same as catch, but only runs the `cb` once and then removes the hook +release(name, catcher) > Removes the `catcher` for the event with `name` +For this to work, `catcher` has to be the same function used to catch +an event, like one saved to a variable. + throw(name, ...args) > Throws a hook with `name` with the provided `args` diff --git a/emmyLuaDocs/bait.lua b/emmyLuaDocs/bait.lua index 01ca774..a5ecebd 100644 --- a/emmyLuaDocs/bait.lua +++ b/emmyLuaDocs/bait.lua @@ -12,6 +12,11 @@ function bait.catch(name, cb) end --- @param cb function function bait.catchOnce(name, cb) end +--- Removes the `catcher` for the event with `name` +--- For this to work, `catcher` has to be the same function used to catch +--- an event, like one saved to a variable. +function bait.release() end + --- Throws a hook with `name` with the provided `args` --- @param name string --- @vararg any From 20870b9004b9cad0441db069c8c11897b7f65686 Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Wed, 17 Aug 2022 18:05:20 -0400 Subject: [PATCH 27/83] fix: only print motd when interactive --- nature/opts/motd.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nature/opts/motd.lua b/nature/opts/motd.lua index b22f5a2..5f30a6c 100644 --- a/nature/opts/motd.lua +++ b/nature/opts/motd.lua @@ -7,7 +7,7 @@ anymore, that will definitely be why! A MOTD, very message, much day. ]] bait.catch('hilbish.init', function() - if hilbish.opts.motd then + if hilbish.interactive and hilbish.opts.motd then print(lunacolors.format(hilbish.motd)) end end) From a1410ae7ad259a6f7e1f42f48060c82bb4fb017f Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Tue, 30 Aug 2022 21:52:07 -0400 Subject: [PATCH 28/83] fix: set prompt to normal after ctrl d exit this prevents the prompt being stuck at the multiline prompt instead of normal prompt after exiting via the ctrl d bind --- exec.go | 1 + 1 file changed, 1 insertion(+) diff --git a/exec.go b/exec.go index d605a4e..dcf8845 100644 --- a/exec.go +++ b/exec.go @@ -152,6 +152,7 @@ func reprompt(input string) (string, error) { for { in, err := continuePrompt(strings.TrimSuffix(input, "\\")) if err != nil { + lr.SetPrompt(fmtPrompt(prompt)) return input, err } From a1ce2ecba683589851aa2f3c6684824c67f52e87 Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Tue, 30 Aug 2022 22:37:21 -0400 Subject: [PATCH 29/83] fix(readline): correct function to count len of prompt to accomodate east asian characters --- readline/prompt.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/readline/prompt.go b/readline/prompt.go index 79f7c71..0f6ca5a 100644 --- a/readline/prompt.go +++ b/readline/prompt.go @@ -4,7 +4,6 @@ import ( "fmt" ansi "github.com/acarl005/stripansi" - "github.com/rivo/uniseg" ) // SetPrompt will define the readline prompt string. @@ -209,7 +208,7 @@ func (rl *Instance) colorizeVimPrompt(p []rune) (cp []rune) { // getting its real-printed length. func getRealLength(s string) (l int) { stripped := ansi.Strip(s) - return uniseg.GraphemeClusterCount(stripped) + return getWidth([]rune(stripped)) } func (rl *Instance) echoRightPrompt() { From c96605e79c85ee62b56ddf20be87d0b8dc7d96a8 Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Tue, 30 Aug 2022 23:07:24 -0400 Subject: [PATCH 30/83] feat: allow hilbish.runner.sh to be overridden --- exec.go | 12 +++++++++++- runnermode.go | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/exec.go b/exec.go index dcf8845..26c0b73 100644 --- a/exec.go +++ b/exec.go @@ -221,7 +221,17 @@ func handleLua(cmdString string) (string, uint8, error) { return cmdString, 125, err } -func handleSh(cmdString string) (string, uint8, bool, error) { +func handleSh(cmdString string) (input string, exitCode uint8, cont bool, runErr error) { + shRunner := hshMod.Get(rt.StringValue("runner")).AsTable().Get(rt.StringValue("sh")) + var err error + input, exitCode, cont, runErr, err = runLuaRunner(shRunner, cmdString) + if err != nil { + runErr = err + } + return +} + +func execSh(cmdString string) (string, uint8, bool, error) { _, _, err := execCommand(cmdString, true) if err != nil { // If input is incomplete, start multiline prompting diff --git a/runnermode.go b/runnermode.go index eca33ba..b8995cd 100644 --- a/runnermode.go +++ b/runnermode.go @@ -28,7 +28,7 @@ func shRunner(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { return nil, err } - input, exitCode, cont, err := handleSh(cmd) + input, exitCode, cont, err := execSh(cmd) var luaErr rt.Value = rt.NilValue if err != nil { luaErr = rt.StringValue(err.Error()) From 2e192be2e1c11a95d5de968f860b05bbe4a4f3d8 Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Tue, 30 Aug 2022 23:08:22 -0400 Subject: [PATCH 31/83] refactor: setup autocd opt in a better way with the previous commit allowing users to override hilbish.runner.sh and it being ran by hilbish, the code for the autocd opt can just override that function and do the autocd functionality instead of reimplementing a hybrid runner. this means that if any other custom runner wants autocd functionality they can have it with the sh runner --- nature/opts/autocd.lua | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/nature/opts/autocd.lua b/nature/opts/autocd.lua index ac32f32..ce68230 100644 --- a/nature/opts/autocd.lua +++ b/nature/opts/autocd.lua @@ -1,13 +1,8 @@ local fs = require 'fs' -function cdHandle(inp) - local res = hilbish.runner.lua(inp) - - if not res.err then - return res - end - - res = hilbish.runner.sh(inp) +local oldShRunner = hilbish.runner.sh +function hilbish.runner.sh(input) + local res = oldShRunner(input) if res.exit ~= 0 and hilbish.opts.autocd then local ok, stat = pcall(fs.stat, res.input) @@ -21,5 +16,3 @@ function cdHandle(inp) return res end - -hilbish.runner.setMode(cdHandle) From c13889592f194ea98abc692043e04cf14fa843c8 Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Tue, 30 Aug 2022 23:10:47 -0400 Subject: [PATCH 32/83] fix: pass alias expanded string to sh runner (fixes #201) i have no idea why it didnt before, it *shouldnt* introduce any problems and fixes this one. --- exec.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/exec.go b/exec.go index 26c0b73..6e24719 100644 --- a/exec.go +++ b/exec.go @@ -101,7 +101,7 @@ func runInput(input string, priv bool) { cmdFinish(0, input, priv) return } - input, exitCode, cont, err = handleSh(input) + input, exitCode, cont, err = handleSh(cmdString) case "hybridRev": _, _, _, err = handleSh(input) if err == nil { @@ -112,7 +112,7 @@ func runInput(input string, priv bool) { case "lua": input, exitCode, err = handleLua(cmdString) case "sh": - input, exitCode, cont, err = handleSh(input) + input, exitCode, cont, err = handleSh(cmdString) } } else { // can only be a string or function so From 1eed4cc7ee70deb3eda5026db43007d00fe61929 Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Tue, 30 Aug 2022 23:38:46 -0400 Subject: [PATCH 33/83] fix: add back empty string in command line split this fixes file completion in normal usage without using quotes. it basically cut out the space at the end which prevented normal usage without adding an additional space or using quotes for file completion --- complete.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/complete.go b/complete.go index 3a2899d..76d65f7 100644 --- a/complete.go +++ b/complete.go @@ -27,6 +27,9 @@ func splitQuote(str string) []string { sb.WriteRune(r) } } + if strings.HasSuffix(str, " ") { + split = append(split, "") + } if sb.Len() > 0 { split = append(split, sb.String()) From 59cec0ffa50bfcc8744c1cf42140b289d85df339 Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Fri, 2 Sep 2022 22:19:30 -0400 Subject: [PATCH 34/83] fix: call hinter for hint text handler --- rl.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rl.go b/rl.go index 59423ff..f6cb6cd 100644 --- a/rl.go +++ b/rl.go @@ -55,7 +55,7 @@ func newLineReader(prompt string, noHist bool) *lineReader { return []rune{} } - retVal, err := rt.Call1(l.MainThread(), rt.FunctionValue(highlighter), + retVal, err := rt.Call1(l.MainThread(), rt.FunctionValue(hinter), rt.StringValue(string(line)), rt.IntValue(int64(pos))) if err != nil { fmt.Println(err) From 959030f70d615dda47c9a75b0c6494ed4fad1890 Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Fri, 2 Sep 2022 23:01:39 -0400 Subject: [PATCH 35/83] refactor: automatically load all nature commands --- nature/commands/init.lua | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/nature/commands/init.lua b/nature/commands/init.lua index 13b33be..93113cd 100644 --- a/nature/commands/init.lua +++ b/nature/commands/init.lua @@ -1,8 +1,19 @@ --- Add command builtins -require 'nature.commands.cd' -require 'nature.commands.cdr' -require 'nature.commands.doc' -require 'nature.commands.exit' -require 'nature.commands.disown' -require 'nature.commands.fg' -require 'nature.commands.bg' +local fs = require 'fs' + +-- explanation: this specific function gives to us info about +-- the currently running source. this includes a path to the +-- source file (info.source) +-- we will use that to automatically load all commands by reading +-- all the files in this dir and just requiring it. +local info = debug.getinfo(1) +local commandDir = fs.dir(info.source) +if commandDir == '.' then return end + +local commands = fs.readdir(commandDir) +for _, command in ipairs(commands) do + local name = command:gsub('%.lua', '') -- chop off extension + if name ~= 'init' then + -- skip this file (for obvious reasons) + require('nature.commands.' .. name) + end +end From ee34ccdbc32d37093fb4d9cdf4646ace9cee7f86 Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Sat, 17 Sep 2022 10:48:34 -0400 Subject: [PATCH 36/83] fix: check if key in _G is string before trying to getenv --- nature/init.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/nature/init.lua b/nature/init.lua index df31d8d..2b8b8c4 100644 --- a/nature/init.lua +++ b/nature/init.lua @@ -28,7 +28,9 @@ do return got_virt end - virt_G[key] = os.getenv(key) + if type(key) == 'string' then + virt_G[key] = os.getenv(key) + end return virt_G[key] end, From 7108523a4c7d4debdac7ae834c83520a9a66bda2 Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Sat, 17 Sep 2022 14:08:15 -0400 Subject: [PATCH 37/83] fix: remove logging of autostart modules --- nature/init.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/nature/init.lua b/nature/init.lua index 2b8b8c4..5359dc0 100644 --- a/nature/init.lua +++ b/nature/init.lua @@ -56,7 +56,6 @@ do if ok then for _, module in ipairs(modules) do local entry = package.searchpath(module, startSearchPath) - print(entry) if entry then dofile(entry) end From 8f41005da77ab4b496b1ffe6864d10df11f6e8bc Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Sat, 17 Sep 2022 20:24:31 -0400 Subject: [PATCH 38/83] chore: update changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 49904ad..f24d618 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -145,6 +145,9 @@ menu is open. - Escape codes now work. - Escape percentage symbols in completion entries, so you will no longer see an error of missing format variable +- Fix an error with sh syntax in aliases +- Prompt now works with east asian characters (CJK) +- Set back the prompt to normal after exiting the continue prompt with ctrl-d ## [1.2.0] - 2022-03-17 ### Added From 8647dc57a11be912942fa69f9cc3c8cd0c9bb6a7 Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Sat, 17 Sep 2022 20:28:52 -0400 Subject: [PATCH 39/83] fix: set cmdString after prompting for continue input makes sure that the old + new input is actually used for builtin runners --- exec.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exec.go b/exec.go index 6e24719..5aee94a 100644 --- a/exec.go +++ b/exec.go @@ -130,7 +130,7 @@ func runInput(input string, priv bool) { } if cont { - input, err = reprompt(input) + cmdString, err = reprompt(input) if err == nil { goto rerun } else if err == io.EOF { From e5c8e5eaffae28099c8b83db4fef501a899d23a4 Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Sat, 17 Sep 2022 21:00:28 -0400 Subject: [PATCH 40/83] fix!: pass non expanded input to builtin runners fixes an issue with expanded aliases being added to history with a recent commit (6th time now with this issue?) and makes behavior with other runners consistent this can technically be a breaking change to people overriding the sh runner function --- exec.go | 15 ++++++++------- runnermode.go | 4 ++-- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/exec.go b/exec.go index 5aee94a..caf7d1b 100644 --- a/exec.go +++ b/exec.go @@ -96,23 +96,23 @@ func runInput(input string, priv bool) { if currentRunner.Type() == rt.StringType { switch currentRunner.AsString() { case "hybrid": - _, _, err = handleLua(cmdString) + _, _, err = handleLua(input) if err == nil { cmdFinish(0, input, priv) return } - input, exitCode, cont, err = handleSh(cmdString) + input, exitCode, cont, err = handleSh(input) case "hybridRev": _, _, _, err = handleSh(input) if err == nil { cmdFinish(0, input, priv) return } - input, exitCode, err = handleLua(cmdString) + input, exitCode, err = handleLua(input) case "lua": - input, exitCode, err = handleLua(cmdString) + input, exitCode, err = handleLua(input) case "sh": - input, exitCode, cont, err = handleSh(cmdString) + input, exitCode, cont, err = handleSh(input) } } else { // can only be a string or function so @@ -130,7 +130,7 @@ func runInput(input string, priv bool) { } if cont { - cmdString, err = reprompt(input) + input, err = reprompt(input) if err == nil { goto rerun } else if err == io.EOF { @@ -195,7 +195,8 @@ func runLuaRunner(runr rt.Value, userInput string) (input string, exitCode uint8 return } -func handleLua(cmdString string) (string, uint8, error) { +func handleLua(input string) (string, uint8, error) { + cmdString := aliases.Resolve(input) // First try to load input, essentially compiling to bytecode chunk, err := l.CompileAndLoadLuaChunk("", []byte(cmdString), rt.TableValue(l.GlobalEnv())) if err != nil && noexecute { diff --git a/runnermode.go b/runnermode.go index b8995cd..c26ed03 100644 --- a/runnermode.go +++ b/runnermode.go @@ -28,13 +28,13 @@ func shRunner(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { return nil, err } - input, exitCode, cont, err := execSh(cmd) + _, exitCode, cont, err := execSh(aliases.Resolve(cmd)) var luaErr rt.Value = rt.NilValue if err != nil { luaErr = rt.StringValue(err.Error()) } runnerRet := rt.NewTable() - runnerRet.Set(rt.StringValue("input"), rt.StringValue(input)) + runnerRet.Set(rt.StringValue("input"), rt.StringValue(cmd)) runnerRet.Set(rt.StringValue("exitCode"), rt.IntValue(int64(exitCode))) runnerRet.Set(rt.StringValue("continue"), rt.BoolValue(cont)) runnerRet.Set(rt.StringValue("err"), luaErr) From 91596fa81c77e11415180f19405af801f9612b9d Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Mon, 10 Oct 2022 17:33:36 -0400 Subject: [PATCH 41/83] docs: document drop in windows support --- CHANGELOG.md | 2 ++ README.md | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f24d618..1fdae95 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased **NOTE:** Hilbish now uses [Task] insead of Make for builds. +Windows support is also now at a lower tier; The only thing guaranteed is +Hilbish *compiling* on Windows. [Task]: https://taskfile.dev/#/ diff --git a/README.md b/README.md index 86879d1..00c8e76 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,10 @@ and aims to be infinitely configurable. If something isn't, open an issue! # Installation +**NOTE:** Hilbish is not guaranteed to work properly on Windows, starting +from the 2.0 version. It will still be able to compile, but functionality +may be lacking. + ## Prebuilt binaries Go [here](https://nightly.link/Rosettea/Hilbish/workflows/build/master) for builds on the master branch. From 22f6ea8a3eaec2d81b8e9a6d2ecd4e4fc9db1b0c Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Mon, 10 Oct 2022 17:34:08 -0400 Subject: [PATCH 42/83] docs: remove getting started from readme toc --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 00c8e76..5ca8232 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,6 @@ and aims to be infinitely configurable. If something isn't, open an issue! - [AUR](#AUR) - [Nixpkgs](#Nixpkgs) - [Manual Build](#Manual-Build) -- [Getting Started](#Getting-Started) - [Contributing](#Contributing) # Screenshots From 7db2a2c826efdcefc44d0a542c59b4815efbe084 Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Mon, 10 Oct 2022 18:11:09 -0400 Subject: [PATCH 43/83] fix: check if there is cmd input before attempting to add to history (closes #206) --- nature/opts/history.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/nature/opts/history.lua b/nature/opts/history.lua index f7ab1d7..016b22d 100644 --- a/nature/opts/history.lua +++ b/nature/opts/history.lua @@ -1,5 +1,6 @@ local bait = require 'bait' bait.catch('command.exit', function(_, cmd, priv) + if not cmd then return end if not priv and hilbish.opts.history then hilbish.history.add(cmd) end end) From 308e2578722d61d236508a35b60a744f18ab4b39 Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Mon, 10 Oct 2022 18:17:58 -0400 Subject: [PATCH 44/83] fix(readline): take into account newlines when calculating amount of lines taken up by input this does not really fix the issue of multiline input being broken completely, but prevents the prompt being reprinted on input --- readline/update.go | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/readline/update.go b/readline/update.go index 0c2de38..8f85c6d 100644 --- a/readline/update.go +++ b/readline/update.go @@ -1,6 +1,10 @@ package readline -import "golang.org/x/text/width" +import ( + "strings" + + "golang.org/x/text/width" +) // updateHelpers is a key part of the whole refresh process: // it should coordinate reprinting the input line, any Infos and completions @@ -52,19 +56,19 @@ func (rl *Instance) updateReferences() { rl.posY = 0 rl.fullY = 0 - var fullLine, cPosLine int + var curLine []rune if len(rl.currentComp) > 0 { - fullLine = getWidth(rl.lineComp) - cPosLine = getWidth(rl.lineComp[:rl.pos]) + curLine = rl.lineComp } else { - fullLine = getWidth(rl.line) - cPosLine = getWidth(rl.line[:rl.pos]) + curLine = rl.line } + fullLine := getWidth(curLine) + cPosLine := getWidth(curLine[:rl.pos]) // We need the X offset of the whole line toEndLine := rl.promptLen + fullLine fullOffset := toEndLine / GetTermWidth() - rl.fullY = fullOffset + rl.fullY = fullOffset + strings.Count(string(curLine), "\n") fullRest := toEndLine % GetTermWidth() rl.fullX = fullRest From b4ca5bfda378d2029e72942b1cc74dff7f00656d Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Mon, 10 Oct 2022 18:19:24 -0400 Subject: [PATCH 45/83] fix(readline): put cursor at end of text when exiting editor --- readline/vim.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/readline/vim.go b/readline/vim.go index 886927b..d496705 100644 --- a/readline/vim.go +++ b/readline/vim.go @@ -245,7 +245,7 @@ func (rl *Instance) vi(r rune) { } // Keep the previous cursor position - prev := rl.pos + //prev := rl.pos new, err := rl.StartEditorWithBuffer(multiline, "") if err != nil || len(new) == 0 || string(new) == string(multiline) { @@ -257,11 +257,11 @@ func (rl *Instance) vi(r rune) { // Clean the shell and put the new buffer, with adjusted pos if needed. rl.clearLine() rl.line = new - if prev > len(rl.line) { - rl.pos = len(rl.line) - 1 + rl.pos = len(rl.line) + /*if prev > len(rl.line) { } else { rl.pos = prev - } + }*/ case 'w': // If we were not yanking From 3bec2c91a8d58f328243759f9ed9dda7b8c409ec Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Mon, 10 Oct 2022 18:26:54 -0400 Subject: [PATCH 46/83] fix: create an empty line reader instance for hilbish.read (closes #190) --- api.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/api.go b/api.go index d060597..ed59396 100644 --- a/api.go +++ b/api.go @@ -263,7 +263,9 @@ func hlread(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { if err != nil { return nil, err } - lualr := newLineReader("", true) + lualr := &lineReader{ + rl: readline.NewInstance(), + } lualr.SetPrompt(luaprompt) input, err := lualr.Read() From 3ee2b033300c322908f06c7b0e64a47335cd436d Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Mon, 10 Oct 2022 18:40:29 -0400 Subject: [PATCH 47/83] feat: make prompt optional in hilbish.read --- api.go | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/api.go b/api.go index ed59396..3e5f892 100644 --- a/api.go +++ b/api.go @@ -250,23 +250,27 @@ func hlcwd(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { } -// read(prompt) -> input? +// read(prompt?) -> input? // Read input from the user, using Hilbish's line editor/input reader. // This is a separate instance from the one Hilbish actually uses. // Returns `input`, will be nil if ctrl + d is pressed, or an error occurs (which shouldn't happen) // --- @param prompt string func hlread(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { - if err := c.Check1Arg(); err != nil { - return nil, err + luaprompt := c.Arg(0) + if typ := luaprompt.Type(); typ != rt.StringType && typ != rt.NilType { + return nil, errors.New("expected #1 to be a string") } - luaprompt, err := c.StringArg(0) - if err != nil { - return nil, err + prompt, ok := luaprompt.TryString() + if !ok { + // if we are here and `luaprompt` is not a string, it's nil + // substitute with an empty string + prompt = "" } + lualr := &lineReader{ rl: readline.NewInstance(), } - lualr.SetPrompt(luaprompt) + lualr.SetPrompt(prompt) input, err := lualr.Read() if err != nil { From 300248de5417593ed58534ff9db48b9d0852e7e3 Mon Sep 17 00:00:00 2001 From: TorchedSammy Date: Mon, 10 Oct 2022 22:41:10 +0000 Subject: [PATCH 48/83] docs: [ci] generate new docs --- docs/hilbish.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/hilbish.txt b/docs/hilbish.txt index d9763a0..20a9bd7 100644 --- a/docs/hilbish.txt +++ b/docs/hilbish.txt @@ -41,7 +41,7 @@ These will be formatted and replaced with the appropriate values. `%u` - Name of current user `%h` - Hostname of device -read(prompt) -> input? > Read input from the user, using Hilbish's line editor/input reader. +read(prompt?) -> input? > Read input from the user, using Hilbish's line editor/input reader. This is a separate instance from the one Hilbish actually uses. Returns `input`, will be nil if ctrl + d is pressed, or an error occurs (which shouldn't happen) From 0db7f96fd75ab8e791d832d955d1a4f54f007b62 Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Mon, 10 Oct 2022 18:55:03 -0400 Subject: [PATCH 49/83] build: disable cgo in builds --- Taskfile.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Taskfile.yaml b/Taskfile.yaml index 067f2ba..54b5ea0 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -13,13 +13,13 @@ vars: tasks: default: cmds: - - go build {{.GOFLAGS}} + - CGO_ENABLED=0 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}} + - CGO_ENABLED=0 go build {{.GOFLAGS}} install: cmds: From 068a5b514916c92a1afc32f9460de8c877180934 Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Tue, 11 Oct 2022 17:41:13 -0400 Subject: [PATCH 50/83] feat(bait): add error hook and hooks function (closes #205) an `error` hook is now thrown when an event in lua throws an error (errors from go side should not happen) it includes the event name, handler, and error message a hooks function has also been added. it returns a table of handlers for a specific event. --- docs/hooks/index.txt | 5 +++++ golibs/bait/bait.go | 41 +++++++++++++++++++++++++++++++++++++++-- lua.go | 2 +- nature/init.lua | 5 +++++ 4 files changed, 50 insertions(+), 3 deletions(-) diff --git a/docs/hooks/index.txt b/docs/hooks/index.txt index f771543..6616b05 100644 --- a/docs/hooks/index.txt +++ b/docs/hooks/index.txt @@ -6,3 +6,8 @@ Here is the format for a doc for a hook: `` just means the arguments of the hook. If a hook doc has the format of `arg...`, it means the hook can take/recieve any number of `arg`. + ++ error -> eventName, handler, err > Emitted when there is an error in +an event handler. The `eventName` is the name of the event the handler +is for, the `handler` is the callback function, and `err` is the error +message. diff --git a/golibs/bait/bait.go b/golibs/bait/bait.go index 89e0c4a..f071f92 100644 --- a/golibs/bait/bait.go +++ b/golibs/bait/bait.go @@ -1,6 +1,8 @@ package bait import ( + "errors" + "hilbish/util" rt "github.com/arnodel/golua/runtime" @@ -72,8 +74,12 @@ func (b *Bait) Emit(event string, args ...interface{}) { } _, err := rt.Call1(b.rtm.MainThread(), funcVal, luaArgs...) if err != nil { - // panicking here won't actually cause hilbish to panic and instead will - // print the error and remove the hook. reference the recoverer function in lua.go + if event != "error" { + b.Emit("error", event, handle.luaCaller, err.Error()) + return + } + // if there is an error in an error event handler, panic instead + // (calls the go recoverer function) panic(err) } } else { @@ -187,6 +193,7 @@ func (b *Bait) loaderFunc(rtm *rt.Runtime) (rt.Value, func()) { "catchOnce": util.LuaExport{b.bcatchOnce, 2, false}, "throw": util.LuaExport{b.bthrow, 1, true}, "release": util.LuaExport{b.brelease, 2, false}, + "hooks": util.LuaExport{b.bhooks, 1, false}, } mod := rt.NewTable() util.SetExports(rtm, mod, exports) @@ -289,3 +296,33 @@ func (b *Bait) brelease(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { return c.Next(), nil } + +// hooks(name) -> {cb, cb...} +// Returns a table with hooks on the event with `name`. +func (b *Bait) bhooks(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { + if err := c.Check1Arg(); err != nil { + return nil, err + } + evName, err := c.StringArg(0) + if err != nil { + return nil, err + } + noHooks := errors.New("no hooks for event " + evName) + + handlers := b.handlers[evName] + if handlers == nil { + return nil, noHooks + } + + luaHandlers := rt.NewTable() + for _, handler := range handlers { + if handler.typ != luaListener { continue } + luaHandlers.Set(rt.IntValue(luaHandlers.Len() + 1), rt.FunctionValue(handler.luaCaller)) + } + + if luaHandlers.Len() == 0 { + return nil, noHooks + } + + return c.PushingNext1(t.Runtime, rt.TableValue(luaHandlers)), nil +} diff --git a/lua.go b/lua.go index 419970c..79eb1f7 100644 --- a/lua.go +++ b/lua.go @@ -49,7 +49,7 @@ func luaInit() { hooks = bait.New(l) hooks.SetRecoverer(func(event string, handler *bait.Listener, err interface{}) { - fmt.Println("Error in", event, "event:", err) + fmt.Println("Error in `error` hook handler:", err) hooks.Off(event, handler) }) diff --git a/nature/init.lua b/nature/init.lua index 5359dc0..aa85a2e 100644 --- a/nature/init.lua +++ b/nature/init.lua @@ -1,5 +1,6 @@ -- Prelude initializes everything else for our shell local _ = require 'succulent' -- Function additions +local bait = require 'bait' local fs = require 'fs' package.path = package.path .. ';' .. hilbish.dataDir .. '/?/init.lua' @@ -64,3 +65,7 @@ do package.path = package.path .. ';' .. startSearchPath end + +bait.catch('error', function(event, handler, err) + bait.release(event, handler) +end) From cc6e5d01ddf65349401914832b66f4bb3ff00ee1 Mon Sep 17 00:00:00 2001 From: TorchedSammy Date: Tue, 11 Oct 2022 21:43:22 +0000 Subject: [PATCH 51/83] docs: [ci] generate new docs --- docs/bait.txt | 2 ++ emmyLuaDocs/bait.lua | 3 +++ 2 files changed, 5 insertions(+) diff --git a/docs/bait.txt b/docs/bait.txt index fdc712f..2b6f7ae 100644 --- a/docs/bait.txt +++ b/docs/bait.txt @@ -2,6 +2,8 @@ catch(name, cb) > Catches a hook with `name`. Runs the `cb` when it is thrown catchOnce(name, cb) > Same as catch, but only runs the `cb` once and then removes the hook +hooks(name) -> {cb, cb...} > Returns a table with hooks on the event with `name`. + release(name, catcher) > Removes the `catcher` for the event with `name` For this to work, `catcher` has to be the same function used to catch an event, like one saved to a variable. diff --git a/emmyLuaDocs/bait.lua b/emmyLuaDocs/bait.lua index a5ecebd..c2c4b60 100644 --- a/emmyLuaDocs/bait.lua +++ b/emmyLuaDocs/bait.lua @@ -12,6 +12,9 @@ function bait.catch(name, cb) end --- @param cb function function bait.catchOnce(name, cb) end +--- Returns a table with hooks on the event with `name`. +function bait.hooks() end + --- Removes the `catcher` for the event with `name` --- For this to work, `catcher` has to be the same function used to catch --- an event, like one saved to a variable. From 0d32a10ca3b0c047d7fa2a3e76e01143af9c7779 Mon Sep 17 00:00:00 2001 From: sammy <38820196+TorchedSammy@users.noreply.github.com> Date: Fri, 14 Oct 2022 19:15:40 -0400 Subject: [PATCH 52/83] feat: add builtins clear, exec and cat (#208) * feat: add clear and exec command * docs: add builtins to changelog * feat: add cat command --- CHANGELOG.md | 1 + nature/commands/cat.lua | 25 +++++++++++++++++++++++++ nature/commands/clear.lua | 7 +++++++ nature/commands/exec.lua | 5 +++++ 4 files changed, 38 insertions(+) create mode 100644 nature/commands/cat.lua create mode 100644 nature/commands/clear.lua create mode 100644 nature/commands/exec.lua diff --git a/CHANGELOG.md b/CHANGELOG.md index 1fdae95..738991a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -75,6 +75,7 @@ disables commands being added to history. - A new and "safer" event emitter has been added. This causes a performance deficit, but avoids a lot of random errors introduced with the new Lua runtime (see [#197]) - `bait.release(name, catcher)` removes `handler` for the named `event` +- `exec`, `clear` and `cat` builtin commands [#197]: https://github.com/Rosettea/Hilbish/issues/197 diff --git a/nature/commands/cat.lua b/nature/commands/cat.lua new file mode 100644 index 0000000..132db5f --- /dev/null +++ b/nature/commands/cat.lua @@ -0,0 +1,25 @@ +local commander = require 'commander' +local fs = require 'fs' + +commander.register('cat', function(args) + local exit = 0 + + if #args == 0 then + print [[ +usage: cat [file]...]] + end + + for _, fName in ipairs(args) do + local f = io.open(fName) + if f == nil then + exit = 1 + print(string.format('cat: %s: no such file or directory', fName)) + goto continue + end + + io.write(f:read '*a') + ::continue:: + end + io.flush() + return exit +end) diff --git a/nature/commands/clear.lua b/nature/commands/clear.lua new file mode 100644 index 0000000..68aa197 --- /dev/null +++ b/nature/commands/clear.lua @@ -0,0 +1,7 @@ +local ansikit = require 'ansikit' +local commander = require 'commander' + +commander.register('clear', function() + ansikit.clear(true) + ansikit.cursorTo(0, 0) +end) diff --git a/nature/commands/exec.lua b/nature/commands/exec.lua new file mode 100644 index 0000000..d279e31 --- /dev/null +++ b/nature/commands/exec.lua @@ -0,0 +1,5 @@ +local commander = require 'commander' + +commander.register('exec', function(args) + hilbish.exec(args[1]) +end) From fe47c6c7a189bdec5139511a0c533c8f4131b77a Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Fri, 14 Oct 2022 19:16:24 -0400 Subject: [PATCH 53/83] chore: change version to rc1 --- vars.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vars.go b/vars.go index 810c1ee..70406cf 100644 --- a/vars.go +++ b/vars.go @@ -11,7 +11,7 @@ var ( // Version info var ( - ver = "v2.0.0" + ver = "v2.0.0-rc1" releaseName = "Hibiscus" gitCommit string gitBranch string From 6ffcc498ac59fa8f1f33f3079a89eda5b8accd47 Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Fri, 14 Oct 2022 19:25:18 -0400 Subject: [PATCH 54/83] docs: update changelog for rc --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 738991a..13f8b0d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -152,6 +152,11 @@ an error of missing format variable - Prompt now works with east asian characters (CJK) - Set back the prompt to normal after exiting the continue prompt with ctrl-d +## [2.0.0-rc1] - 2022-09-14 +This is a pre-release version of Hilbish for testing. To see the changelog, +refer to the `Unreleased` section of the [full changelog](CHANGELOG.md) +(version 2.0.0 for future reference). + ## [1.2.0] - 2022-03-17 ### Added - Job Management additions @@ -575,6 +580,8 @@ This input for example will prompt for more input to complete: First "stable" release of Hilbish. +[2.0.0-rc1]: https://github.com/Rosettea/Hilbish/compare/v1.2.0...v2.0.0-rc1 +[1.2.0]: https://github.com/Rosettea/Hilbish/compare/v1.1.4...v1.2.0 [1.1.0]: https://github.com/Rosettea/Hilbish/compare/v1.0.4...v1.1.0 [1.0.4]: https://github.com/Rosettea/Hilbish/compare/v1.0.3...v1.0.4 [1.0.3]: https://github.com/Rosettea/Hilbish/compare/v1.0.2...v1.0.3 From 1febe66f846f500f4bd07fe14691e3b359f49c80 Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Thu, 17 Nov 2022 19:18:57 -0400 Subject: [PATCH 55/83] fix(readline): use uniseg to calculate width of virtual tab entry (closes #209) --- readline/tab-virtual.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/readline/tab-virtual.go b/readline/tab-virtual.go index fa7318e..d1e1d76 100644 --- a/readline/tab-virtual.go +++ b/readline/tab-virtual.go @@ -2,6 +2,7 @@ package readline import ( "strings" + "github.com/rivo/uniseg" ) // insertCandidateVirtual - When a completion candidate is selected, we insert it virtually in the input line: @@ -249,10 +250,10 @@ func (rl *Instance) viJumpEVirtual(tokeniser func([]rune, int) ([]string, int, i return case pos >= len(word)-1: word = rTrimWhiteSpace(split[index+1]) - adjust = len(split[index]) - pos - adjust += len(word) - 1 + adjust = uniseg.GraphemeClusterCount(split[index]) - pos + adjust += uniseg.GraphemeClusterCount(word) - 1 default: - adjust = len(word) - pos - 1 + adjust = uniseg.GraphemeClusterCount(word) - pos - 1 } return } From 8b547f2af039c45968b505a7dc947766b305ac9e Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Fri, 25 Nov 2022 16:56:35 -0400 Subject: [PATCH 56/83] feat: make tab completion work with spaces and escaped characters --- CHANGELOG.md | 3 +++ complete.go | 62 +++++++++++++++++++++++++++++++++------------------- 2 files changed, 42 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 13f8b0d..32db1e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -151,6 +151,9 @@ an error of missing format variable - Fix an error with sh syntax in aliases - Prompt now works with east asian characters (CJK) - Set back the prompt to normal after exiting the continue prompt with ctrl-d +- Users can now tab complete files with spaces while quoted or with escaped spaces. +This means a query of `Files\ to\ ` with file names of `Files to tab complete` and `Files to complete` +will result in the files being completed. ## [2.0.0-rc1] - 2022-09-14 This is a pre-release version of Hilbish for testing. To see the changelog, diff --git a/complete.go b/complete.go index 76d65f7..7c5153f 100644 --- a/complete.go +++ b/complete.go @@ -11,15 +11,49 @@ import ( rt "github.com/arnodel/golua/runtime" ) -func splitQuote(str string) []string { +var charEscapeMap = []string{ + "\"", "\\\"", + "'", "\\'", + "`", "\\`", + " ", "\\ ", + "(", "\\(", + ")", "\\)", + "[", "\\[", + "]", "\\]", + "$", "\\$", + "&", "\\&", + "*", "\\*", + ">", "\\>", + "<", "\\<", + "|", "\\|", +} +var charEscapeMapInvert = invert(charEscapeMap) +var escapeReplaer = strings.NewReplacer(charEscapeMap...) +var escapeInvertReplaer = strings.NewReplacer(charEscapeMapInvert...) + +func invert(m []string) []string { + newM := make([]string, len(charEscapeMap)) + for i := range m { + if (i + 1) % 2 == 0 { + newM[i] = m[i - 1] + newM[i - 1] = m[i] + } + } + + return newM +} + +func splitForFile(str string) []string { split := []string{} sb := &strings.Builder{} quoted := false - for _, r := range str { + for i, r := range str { if r == '"' { quoted = !quoted sb.WriteRune(r) + } else if r == ' ' && str[i - 1] == '\\' { + sb.WriteRune(r) } else if !quoted && r == ' ' { split = append(split, sb.String()) sb.Reset() @@ -39,7 +73,7 @@ func splitQuote(str string) []string { } func fileComplete(query, ctx string, fields []string) ([]string, string) { - q := splitQuote(ctx) + q := splitForFile(ctx) return matchPath(q[len(q) - 1]) } @@ -66,7 +100,6 @@ func binaryComplete(query, ctx string, fields []string) ([]string, string) { // filter out executables, but in path for _, dir := range filepath.SplitList(os.Getenv("PATH")) { - // print dir to stderr for debugging // search for an executable which matches our query string if matches, err := filepath.Glob(filepath.Join(dir, query + "*")); err == nil { // get basename from matches @@ -102,6 +135,7 @@ func matchPath(query string) ([]string, string) { var entries []string var baseName string + query = escapeInvertReplaer.Replace(query) path, _ := filepath.Abs(util.ExpandHome(filepath.Dir(query))) if string(query) == "" { // filepath base below would give us "." @@ -129,25 +163,7 @@ func matchPath(query string) ([]string, string) { } func escapeFilename(fname string) string { - args := []string{ - "\"", "\\\"", - "'", "\\'", - "`", "\\`", - " ", "\\ ", - "(", "\\(", - ")", "\\)", - "[", "\\[", - "]", "\\]", - "$", "\\$", - "&", "\\&", - "*", "\\*", - ">", "\\>", - "<", "\\<", - "|", "\\|", - } - - r := strings.NewReplacer(args...) - return r.Replace(fname) + return escapeReplaer.Replace(fname) } func completionLoader(rtm *rt.Runtime) *rt.Table { From 3eaeb6a5da169925fe748c096ac3069c3cb97b00 Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Fri, 25 Nov 2022 18:39:18 -0400 Subject: [PATCH 57/83] fix(readline): grip completion menu fixes - dont print item left justified if the max number of cells is 1 (this fixes issues in cjk as an example) - trim items that are longer than the terminal width --- readline/comp-grid.go | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/readline/comp-grid.go b/readline/comp-grid.go index 48a2039..c198bdb 100644 --- a/readline/comp-grid.go +++ b/readline/comp-grid.go @@ -4,7 +4,8 @@ import ( "fmt" "strconv" "strings" -) + "github.com/rivo/uniseg" +) // initGrid - Grid display details. Called each time we want to be sure to have // a working completion group either immediately, or later on. Generally defered. @@ -13,8 +14,8 @@ func (g *CompletionGroup) initGrid(rl *Instance) { // Compute size of each completion item box tcMaxLength := 1 for i := range g.Suggestions { - if len(g.Suggestions[i]) > tcMaxLength { - tcMaxLength = len([]rune(g.Suggestions[i])) + if uniseg.GraphemeClusterCount(g.Suggestions[i]) > tcMaxLength { + tcMaxLength = uniseg.GraphemeClusterCount(g.Suggestions[i]) } } @@ -103,7 +104,7 @@ func (g *CompletionGroup) writeGrid(rl *Instance) (comp string) { rl.tcUsedY++ } - cellWidth := strconv.Itoa((GetTermWidth() / g.tcMaxX) - 2) + cellWidth := strconv.Itoa((GetTermWidth() / g.tcMaxX) - 4) x := 0 y := 1 @@ -124,7 +125,15 @@ func (g *CompletionGroup) writeGrid(rl *Instance) (comp string) { comp += seqInvert } - comp += fmt.Sprintf("%-"+cellWidth+"s %s", fmtEscape(g.Suggestions[i]), seqReset) + sugg := g.Suggestions[i] + if len(sugg) > GetTermWidth() { + sugg = sugg[:GetTermWidth() - 4] + "..." + } + formatStr := "%-"+cellWidth+"s%s " + if g.tcMaxX == 1 { + formatStr = "%s%s" + } + comp += fmt.Sprintf(formatStr, fmtEscape(sugg), seqReset) } // Always add a newline to the group if the end if not punctuated with one From d6338fc021f56ee5a58f1d5ca5d93b958eba2dbd Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Fri, 25 Nov 2022 19:08:38 -0400 Subject: [PATCH 58/83] fix(readline): make completion search menu display --- readline/readline.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/readline/readline.go b/readline/readline.go index 731e297..9723f95 100644 --- a/readline/readline.go +++ b/readline/readline.go @@ -238,7 +238,9 @@ func (rl *Instance) Readline() (string, error) { // Normal completion search does only refresh the search pattern and the comps if rl.modeTabFind || rl.modeAutoFind { + rl.resetVirtualComp(false) rl.backspaceTabFind() + rl.renderHelpers() rl.viUndoSkipAppend = true } else { // Always cancel any virtual completion @@ -517,7 +519,9 @@ func (rl *Instance) Readline() (string, error) { if rl.modeAutoFind || rl.modeTabFind { rl.resetVirtualComp(false) rl.updateTabFind(r[:i]) + rl.renderHelpers() rl.viUndoSkipAppend = true + continue } else { rl.resetVirtualComp(false) rl.editorInput(r[:i]) From ef3e7d92bc1303c866a2f27e84e12943a040dcf9 Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Fri, 25 Nov 2022 19:13:32 -0400 Subject: [PATCH 59/83] chore: update changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 32db1e1..11d44e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -154,6 +154,9 @@ an error of missing format variable - Users can now tab complete files with spaces while quoted or with escaped spaces. This means a query of `Files\ to\ ` with file names of `Files to tab complete` and `Files to complete` will result in the files being completed. +- Fixed grid menu display if cell width ends up being the width of the terminal +- Cut off item names in grid menu if its longer than cell width +- Fix completion search menu disappearing ## [2.0.0-rc1] - 2022-09-14 This is a pre-release version of Hilbish for testing. To see the changelog, From ff4609e4320f51d202dc575733ffc5232b814ec1 Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Fri, 25 Nov 2022 19:21:36 -0400 Subject: [PATCH 60/83] feat: add hilbish.cancel hook (closes #213) --- CHANGELOG.md | 1 + docs/hooks/hilbish.txt | 2 ++ main.go | 7 +++++-- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 11d44e8..7c02489 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -76,6 +76,7 @@ disables commands being added to history. random errors introduced with the new Lua runtime (see [#197]) - `bait.release(name, catcher)` removes `handler` for the named `event` - `exec`, `clear` and `cat` builtin commands +- `hilbish.cancel` hook [#197]: https://github.com/Rosettea/Hilbish/issues/197 diff --git a/docs/hooks/hilbish.txt b/docs/hooks/hilbish.txt index d6d5542..3d6d2ea 100644 --- a/docs/hooks/hilbish.txt +++ b/docs/hooks/hilbish.txt @@ -5,3 +5,5 @@ + `hilbish.vimAction` -> actionName, args > Sent when the user does a "vim action," being something like yanking or pasting text. See `doc vim-mode actions` for more info. + ++ `hilbish.cancel` > Sent when the user cancels their input with Ctrl-C. diff --git a/main.go b/main.go index ee0f584..1b5e6b8 100644 --- a/main.go +++ b/main.go @@ -181,11 +181,14 @@ input: break } if err != nil { - if err != readline.CtrlC { + if err == readline.CtrlC { + fmt.Println("^C") + hooks.Emit("hilbish.cancel") + } else { // If we get a completely random error, print fmt.Fprintln(os.Stderr, err) } - fmt.Println("^C") + // TODO: Halt if any other error occurs continue } var priv bool From ebec5856904e5f5b6c8b88045c27afab23d5bad8 Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Fri, 25 Nov 2022 19:35:26 -0400 Subject: [PATCH 61/83] fix: binary completion with spaces (closes #210) --- complete.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/complete.go b/complete.go index 7c5153f..99da07f 100644 --- a/complete.go +++ b/complete.go @@ -79,6 +79,9 @@ func fileComplete(query, ctx string, fields []string) ([]string, string) { } func binaryComplete(query, ctx string, fields []string) ([]string, string) { + q := splitForFile(ctx) + query = q[len(q) - 1] + var completions []string prefixes := []string{"./", "../", "/", "~/"} @@ -88,7 +91,7 @@ func binaryComplete(query, ctx string, fields []string) ([]string, string) { if len(fileCompletions) != 0 { for _, f := range fileCompletions { fullPath, _ := filepath.Abs(util.ExpandHome(query + strings.TrimPrefix(f, filePref))) - if err := findExecutable(fullPath, false, true); err != nil { + if err := findExecutable(escapeInvertReplaer.Replace(fullPath), false, true); err != nil { continue } completions = append(completions, f) From bd4e0df7b32e43115ae307d7ff7b9ab0c8da3b11 Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Fri, 25 Nov 2022 20:14:29 -0400 Subject: [PATCH 62/83] feat: select 1st item on history find menu (closes #148) cancels on escape unless the user moves to another item --- readline/readline.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/readline/readline.go b/readline/readline.go index 9723f95..7397faf 100644 --- a/readline/readline.go +++ b/readline/readline.go @@ -333,6 +333,8 @@ func (rl *Instance) Readline() (string, error) { rl.modeTabFind = true rl.updateTabFind([]rune{}) + rl.updateVirtualComp() + rl.renderHelpers() rl.viUndoSkipAppend = true // Tab Completion & Completion Search --------------------------------------------------------------- @@ -486,7 +488,10 @@ func (rl *Instance) Readline() (string, error) { if string(r[:i]) != seqShiftTab && string(r[:i]) != seqForwards && string(r[:i]) != seqBackwards && string(r[:i]) != seqUp && string(r[:i]) != seqDown { - rl.resetVirtualComp(false) + // basically only applies except on 1st ctrl r open + // so if we have not explicitly selected something + // (tabCompletionSelect is false) drop virtual completion + rl.resetVirtualComp(!rl.tabCompletionSelect) } } @@ -608,6 +613,7 @@ func (rl *Instance) escapeSeq(r []rune) { case string(charEscape): switch { case rl.modeAutoFind: + rl.resetVirtualComp(true) rl.resetTabFind() rl.clearHelpers() rl.resetTabCompletion() @@ -615,6 +621,7 @@ func (rl *Instance) escapeSeq(r []rune) { rl.renderHelpers() case rl.modeTabFind: + rl.resetVirtualComp(true) rl.resetTabFind() rl.resetTabCompletion() From 06102ebdaeb8664005632c4ed935a8b89b6ef5a0 Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Wed, 30 Nov 2022 13:20:00 -0400 Subject: [PATCH 63/83] perf: preallocate history slice --- history.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/history.go b/history.go index a8eb089..51ccf27 100644 --- a/history.go +++ b/history.go @@ -73,13 +73,13 @@ func newFileHistory(path string) *fileHistory { } } - itms := []string{""} lines := strings.Split(string(data), "\n") + itms := make([]string, len(lines) - 1) for i, l := range lines { if i == len(lines) - 1 { continue } - itms = append(itms, l) + itms[i] = l } f, err := os.OpenFile(path, os.O_APPEND | os.O_WRONLY | os.O_CREATE, 0755) if err != nil { From b395b70ecdf6bfad7d0bfd6b09047a608f25aa7f Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Wed, 30 Nov 2022 14:26:43 -0400 Subject: [PATCH 64/83] fix: escape completion prefix if completions are escaped fixes an issue with duplicated characters when completing escaped paths --- complete.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/complete.go b/complete.go index 99da07f..c2a107c 100644 --- a/complete.go +++ b/complete.go @@ -161,6 +161,9 @@ func matchPath(query string) ([]string, string) { entries = append(entries, entry) } } + if !strings.HasPrefix(oldQuery, "\"") { + baseName = escapeFilename(baseName) + } return entries, baseName } From 3f9b23038192c84ff2f73491c70593ddf6b1aced Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Wed, 30 Nov 2022 14:29:46 -0400 Subject: [PATCH 65/83] chore: update changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c02489..1c621d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -77,7 +77,9 @@ random errors introduced with the new Lua runtime (see [#197]) - `bait.release(name, catcher)` removes `handler` for the named `event` - `exec`, `clear` and `cat` builtin commands - `hilbish.cancel` hook +- 1st item on history is now inserted when history search menu is opened ([#148]) +[#148]: https://github.com/Rosettea/Hilbish/issues/148 [#197]: https://github.com/Rosettea/Hilbish/issues/197 ### Changed @@ -158,6 +160,7 @@ will result in the files being completed. - Fixed grid menu display if cell width ends up being the width of the terminal - Cut off item names in grid menu if its longer than cell width - Fix completion search menu disappearing +- Completion paths having duplicated characters if it's escaped ## [2.0.0-rc1] - 2022-09-14 This is a pre-release version of Hilbish for testing. To see the changelog, From b6aecb12f603ae89c660e52eb5cf733b2a3065d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20de=20S=C3=A1?= Date: Thu, 1 Dec 2022 10:29:27 -0300 Subject: [PATCH 66/83] chore: add .editorconfig file (#217) --- .editorconfig | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..a06ed29 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,6 @@ +root = true + +[*] +charset = utf-8 +indent_size = 4 +indent_style = tab From 5e2b3367de00f2a50ecd4fd441334583fc9dea9d Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Thu, 1 Dec 2022 20:04:24 -0400 Subject: [PATCH 67/83] docs(bait): add annotation strings for release and hooks functions --- golibs/bait/bait.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/golibs/bait/bait.go b/golibs/bait/bait.go index f071f92..70e122c 100644 --- a/golibs/bait/bait.go +++ b/golibs/bait/bait.go @@ -286,6 +286,8 @@ func (b *Bait) bcatchOnce(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { // Removes the `catcher` for the event with `name` // For this to work, `catcher` has to be the same function used to catch // an event, like one saved to a variable. +// --- @param name string +// --- @param catcher function func (b *Bait) brelease(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { name, catcher, err := util.HandleStrCallback(t, c) if err != nil { @@ -299,6 +301,8 @@ func (b *Bait) brelease(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { // hooks(name) -> {cb, cb...} // Returns a table with hooks on the event with `name`. +// --- @param name string +// --- @returns table func (b *Bait) bhooks(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { if err := c.Check1Arg(); err != nil { return nil, err From 09d04a7850f25db730dbfe833eaf402538045ff2 Mon Sep 17 00:00:00 2001 From: TorchedSammy Date: Fri, 2 Dec 2022 00:05:24 +0000 Subject: [PATCH 68/83] docs: [ci] generate new docs --- emmyLuaDocs/bait.lua | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/emmyLuaDocs/bait.lua b/emmyLuaDocs/bait.lua index c2c4b60..a957e00 100644 --- a/emmyLuaDocs/bait.lua +++ b/emmyLuaDocs/bait.lua @@ -13,12 +13,16 @@ function bait.catch(name, cb) end function bait.catchOnce(name, cb) end --- Returns a table with hooks on the event with `name`. -function bait.hooks() end +--- @param name string +--- @returns table +function bait.hooks(name) end --- Removes the `catcher` for the event with `name` --- For this to work, `catcher` has to be the same function used to catch --- an event, like one saved to a variable. -function bait.release() end +--- @param name string +--- @param catcher function +function bait.release(name, catcher) end --- Throws a hook with `name` with the provided `args` --- @param name string From 4e850bb3224e901b427c3f7ffc5d1608bc0c2775 Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Fri, 2 Dec 2022 09:39:22 -0400 Subject: [PATCH 69/83] ci: set build version to 1.18, use task for release builds --- .github/workflows/build.yml | 2 +- .github/workflows/release.yml | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 371d284..4aab838 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -25,7 +25,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v2 with: - go-version: '1.17.7' + go-version: '1.18.8' - name: Download Task run: 'sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d' - name: Build diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a3a2840..3165a2f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -33,10 +33,13 @@ jobs: - uses: actions/checkout@v3 with: submodules: true + - name: Download Task + run: 'sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d' - uses: wangyoucao577/go-release-action@v1.25 with: github_token: ${{ secrets.GITHUB_TOKEN }} goos: ${{ matrix.goos }} goarch: ${{ matrix.goarch }} + build_command: task binary_name: hilbish extra_files: LICENSE README.md CHANGELOG.md .hilbishrc.lua nature libs docs emmyLuaDocs From 395f3c0742511fcd5cf5b4c8c65e1b33616c3816 Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Fri, 2 Dec 2022 09:42:06 -0400 Subject: [PATCH 70/83] ci: remove extra indent in release action --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3165a2f..9f9163d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -34,7 +34,7 @@ jobs: with: submodules: true - name: Download Task - run: 'sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d' + run: 'sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d' - uses: wangyoucao577/go-release-action@v1.25 with: github_token: ${{ secrets.GITHUB_TOKEN }} From 604dedb36d172a18dd3b805412c9879766eac5d8 Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Mon, 5 Dec 2022 14:16:43 -0400 Subject: [PATCH 71/83] chore: update lunacolors --- libs/lunacolors | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/lunacolors b/libs/lunacolors index 8467b87..34a57c9 160000 --- a/libs/lunacolors +++ b/libs/lunacolors @@ -1 +1 @@ -Subproject commit 8467b87dd8d49c68b4100b2d129d5f071544b8cf +Subproject commit 34a57c964590f89aa065188a588c7b38aff99c28 From 26ff6c9a46ae757963f7fdd9b075a99cc043c75e Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Mon, 5 Dec 2022 23:15:35 -0400 Subject: [PATCH 72/83] fix(nature/completions): get command name properly for custom completions --- CHANGELOG.md | 1 + nature/completions.lua | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c621d1..1a2c86e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -161,6 +161,7 @@ will result in the files being completed. - Cut off item names in grid menu if its longer than cell width - Fix completion search menu disappearing - Completion paths having duplicated characters if it's escaped +- Get custom completion command properly to call from Lua ## [2.0.0-rc1] - 2022-09-14 This is a pre-release version of Hilbish for testing. To see the changelog, diff --git a/nature/completions.lua b/nature/completions.lua index d20cc59..f8127a1 100644 --- a/nature/completions.lua +++ b/nature/completions.lua @@ -24,7 +24,7 @@ function hilbish.completion.handler(line, pos) return {compGroup}, pfx else local ok, compGroups, pfx = pcall(hilbish.completion.call, - 'command.' .. #fields[1], query, ctx, fields) + 'command.' .. fields[1], query, ctx, fields) if ok then return compGroups, pfx end From 9131c7250128fb8c74316cf8e3f95e30132cf711 Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Mon, 5 Dec 2022 23:38:52 -0400 Subject: [PATCH 73/83] build: apply hilbish datadir to allow changing install path --- Taskfile.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Taskfile.yaml b/Taskfile.yaml index 54b5ea0..f6b1d0f 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -8,14 +8,14 @@ vars: BINDIR: '{{default .bindir__ .BINDIR}}' libdir__: '{{.PREFIX}}/share/hilbish' LIBDIR: '{{default .libdir__ .LIBDIR}}' - GOFLAGS: '-ldflags "-s -w"' + GOFLAGS: '-ldflags "-s -w -X main.dataDir={{.LIBDIR}}"' tasks: default: cmds: - CGO_ENABLED=0 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)"' + GOFLAGS: '-ldflags "-s -w -X main.dataDir={{.LIBDIR}} -X main.gitCommit=$(git rev-parse --short HEAD) -X main.gitBranch=$(git rev-parse --abbrev-ref HEAD)"' build: cmds: From 9c8d7692bc73c59dfaa9d74e90bf7b3448f5e434 Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Tue, 6 Dec 2022 10:29:47 -0400 Subject: [PATCH 74/83] chore: revert "build: apply hilbish datadir to allow changing install path" This reverts commit 9131c7250128fb8c74316cf8e3f95e30132cf711. temporary revert, will have to apply datadir eventually --- Taskfile.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Taskfile.yaml b/Taskfile.yaml index f6b1d0f..54b5ea0 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -8,14 +8,14 @@ vars: BINDIR: '{{default .bindir__ .BINDIR}}' libdir__: '{{.PREFIX}}/share/hilbish' LIBDIR: '{{default .libdir__ .LIBDIR}}' - GOFLAGS: '-ldflags "-s -w -X main.dataDir={{.LIBDIR}}"' + GOFLAGS: '-ldflags "-s -w"' tasks: default: cmds: - CGO_ENABLED=0 go build {{.GOFLAGS}} vars: - GOFLAGS: '-ldflags "-s -w -X main.dataDir={{.LIBDIR}} -X main.gitCommit=$(git rev-parse --short HEAD) -X main.gitBranch=$(git rev-parse --abbrev-ref HEAD)"' + GOFLAGS: '-ldflags "-s -w -X main.gitCommit=$(git rev-parse --short HEAD) -X main.gitBranch=$(git rev-parse --abbrev-ref HEAD)"' build: cmds: From 1024f9344613576772e79f71455081cd31950b8f Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Tue, 6 Dec 2022 12:54:56 -0400 Subject: [PATCH 75/83] chore: update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a2c86e..6d8c4f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -103,6 +103,7 @@ 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. +- **Breaking Change:** `command.no-perm` hook has been replaced with `command.not-executable` - 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/) From 4ee160fb664907b0ad405d1f461831a508ad4053 Mon Sep 17 00:00:00 2001 From: sammyette Date: Fri, 9 Dec 2022 21:45:52 -0400 Subject: [PATCH 76/83] fix: provide correct command when navigating history (#214) fixes an issue of going up and down in history results in the incorrect order of commands being inserted (nothing happens to the order in the history itself, just when navigating via arrow keys) * fix: provide correct command when navigating history previously, the order while navigating history with the arrow keys would be incorrect meaning the command you expect if you go u then go back down would not be there * chore: update changelog --- CHANGELOG.md | 1 + readline/history.go | 18 +++++++----------- readline/instance.go | 1 + readline/readline.go | 2 +- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6d8c4f1..f240f11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -163,6 +163,7 @@ will result in the files being completed. - Fix completion search menu disappearing - Completion paths having duplicated characters if it's escaped - Get custom completion command properly to call from Lua +- Put proper command on the line when using up and down arrow keys to go through command history ## [2.0.0-rc1] - 2022-09-14 This is a pre-release version of Hilbish for testing. To see the changelog, diff --git a/readline/history.go b/readline/history.go index 41200c6..f772813 100644 --- a/readline/history.go +++ b/readline/history.go @@ -123,23 +123,20 @@ func (rl *Instance) walkHistory(i int) { // When we are exiting the current line buffer to move around // the history, we make buffer the current line - if rl.histPos == 0 && (rl.histPos+i) == 1 { + if rl.histOffset == 0 && rl.histOffset + i == 1 { rl.lineBuf = string(rl.line) } - switch rl.histPos + i { - case 0, history.Len() + 1: - rl.histPos = 0 + rl.histOffset += i + if rl.histOffset == 0 { rl.line = []rune(rl.lineBuf) rl.pos = len(rl.lineBuf) - return - case -1: - rl.histPos = 0 - rl.lineBuf = string(rl.line) - default: + } else if rl.histOffset <= -1 { + rl.histOffset = 0 + } else { dedup = true old = string(rl.line) - new, err = history.GetLine(history.Len() - rl.histPos - 1) + new, err = history.GetLine(history.Len() - rl.histOffset) if err != nil { rl.resetHelpers() print("\r\n" + err.Error() + "\r\n") @@ -148,7 +145,6 @@ func (rl *Instance) walkHistory(i int) { } rl.clearLine() - rl.histPos += i rl.line = []rune(new) rl.pos = len(rl.line) if rl.pos > 0 { diff --git a/readline/instance.go b/readline/instance.go index fcd8379..039f040 100644 --- a/readline/instance.go +++ b/readline/instance.go @@ -134,6 +134,7 @@ type Instance struct { // history operating params lineBuf string histPos int + histOffset int histNavIdx int // Used for quick history navigation. // diff --git a/readline/readline.go b/readline/readline.go index 7397faf..dc8407c 100644 --- a/readline/readline.go +++ b/readline/readline.go @@ -49,7 +49,7 @@ func (rl *Instance) Readline() (string, error) { // History Init // We need this set to the last command, so that we can access it quickly - rl.histPos = 0 + rl.histOffset = 0 rl.viUndoHistory = []undoItem{{line: "", pos: 0}} // Multisplit From f7e725b5b9cf50088726b411c6777f6e7b31a59f Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Fri, 9 Dec 2022 21:49:58 -0400 Subject: [PATCH 77/83] docs: make note on task --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5ca8232..8302d48 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,8 @@ 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/#/) +- [Task](https://taskfile.dev/#/) + - **Do go to the link here for the installation of Task. Too much people install taskwarrior, which is the wrong program** ### Build First, clone Hilbish. The recursive is required, as some Lua libraries From 8d40179a73fe5942707cd43f9c0463dee53eedd8 Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Sat, 10 Dec 2022 17:27:42 -0400 Subject: [PATCH 78/83] fix(readline): dont do anything if length of input rune slice is 0 this fixes an issue when readline splits multiline input. sometimes, the multiple lines just end up being "stray?" inputs of enter plus a newline. this can happen if a user attempts to prefire the enter key while a command is running, for example --- readline/readline.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/readline/readline.go b/readline/readline.go index dc8407c..f1d6c96 100644 --- a/readline/readline.go +++ b/readline/readline.go @@ -546,6 +546,10 @@ func (rl *Instance) Readline() (string, error) { // entry readline is currently configured for and then update the line entries // accordingly. func (rl *Instance) editorInput(r []rune) { + if len(r) == 0 { + return + } + switch rl.modeViMode { case VimKeys: rl.vi(r[0]) From 813354b662808411ad9add0a831f30ee8d2ce4eb Mon Sep 17 00:00:00 2001 From: sammyette Date: Mon, 12 Dec 2022 21:01:44 -0400 Subject: [PATCH 79/83] build!: set datadir of hilbish and change default prefix to /usr/local (#221) BREAKING (ish) CHANGE: Hilbish will by default install to `/usr/local`. To revert this, set `PREFIX="/usr/"` --- Taskfile.yaml | 6 +++--- vars_linux.go | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Taskfile.yaml b/Taskfile.yaml index 54b5ea0..603633f 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -3,19 +3,19 @@ version: '3' vars: - PREFIX: '{{default "/usr" .PREFIX}}' + PREFIX: '{{default "/usr/local" .PREFIX}}' bindir__: '{{.PREFIX}}/bin' BINDIR: '{{default .bindir__ .BINDIR}}' libdir__: '{{.PREFIX}}/share/hilbish' LIBDIR: '{{default .libdir__ .LIBDIR}}' - GOFLAGS: '-ldflags "-s -w"' + GOFLAGS: '-ldflags "-s -w -X main.dataDir={{.LIBDIR}}"' tasks: default: cmds: - CGO_ENABLED=0 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)"' + GOFLAGS: '-ldflags "-s -w -X main.dataDir={{.LIBDIR}} -X main.gitCommit=$(git rev-parse --short HEAD) -X main.gitBranch=$(git rev-parse --abbrev-ref HEAD)"' build: cmds: diff --git a/vars_linux.go b/vars_linux.go index 815ba6a..e1160ba 100644 --- a/vars_linux.go +++ b/vars_linux.go @@ -14,7 +14,7 @@ var ( .. hilbish.userDir.config .. '/hilbish/?/init.lua;' .. hilbish.userDir.config .. '/hilbish/?/?.lua;' .. hilbish.userDir.config .. '/hilbish/?.lua'` - dataDir = "/usr/share/hilbish" + dataDir = "/usr/local/share/hilbish" preloadPath = dataDir + "/nature/init.lua" sampleConfPath = dataDir + "/.hilbishrc.lua" // Path to default/sample config defaultConfDir = "" From 5ca728ba0689e69a234e5d4d28099140fca7e2c2 Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Mon, 12 Dec 2022 21:03:36 -0400 Subject: [PATCH 80/83] docs: change task link and notice --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 8302d48..b4f85f7 100644 --- a/README.md +++ b/README.md @@ -69,8 +69,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/#/) - - **Do go to the link here for the installation of Task. Too much people install taskwarrior, which is the wrong program** +- [Task](https://taskfile.dev/installation/) (**Go on the hyperlink here to see Task's install method for your OS.**) ### Build First, clone Hilbish. The recursive is required, as some Lua libraries From 6ca36847f163373f79ca756ddb5e2bb87d53e25b Mon Sep 17 00:00:00 2001 From: TorchedSammy <38820196+TorchedSammy@users.noreply.github.com> Date: Mon, 12 Dec 2022 21:03:58 -0400 Subject: [PATCH 81/83] docs: add bolded notes/changes for building and installing hilbish 2.0 --- CHANGELOG.md | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f240f11..e856546 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,16 @@ # 🎀 Changelog ## Unreleased -**NOTE:** Hilbish now uses [Task] insead of Make for builds. -Windows support is also now at a lower tier; The only thing guaranteed is -Hilbish *compiling* on Windows. +**NOTES FOR USERS/PACKAGERS UPDATING:** +- Hilbish now uses [Task] insead of Make for builds. +- The doc format has been changed from plain text to markdown. +**YOU MUST reinstall Hilbish to remove the duplicate, old docs.** +- Hilbish will by default install to **`/usr/local`** instead of just `/usr/` +when building via Task. This is mainly to avoid conflict of distro packages +and local installs, and is the correct place when building from git either way. +To keep Hilbish in `/usr`, you must have `PREFIX="/usr/"` when running `task build` or `task install` +- Windows is no longer supported. It will build and run, but **will** have problems. +If you want to help fix the situation, start a discussion or open an issue and contribute. [Task]: https://taskfile.dev/#/ From 0a49e1a4ef4004a680e92a137d65cadca0d309f0 Mon Sep 17 00:00:00 2001 From: sammyette Date: Tue, 13 Dec 2022 12:57:27 -0400 Subject: [PATCH 82/83] feat: print command errors via hook this allows users to remove the handlers and print a custom message to their liking --- exec.go | 4 ++-- nature/init.lua | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/exec.go b/exec.go index caf7d1b..d668192 100644 --- a/exec.go +++ b/exec.go @@ -141,9 +141,9 @@ func runInput(input string, priv bool) { if err != nil { if exErr, ok := isExecError(err); ok { hooks.Emit("command." + exErr.typ, exErr.cmd) - err = exErr.sprint() + } else { + fmt.Fprintln(os.Stderr, err) } - fmt.Fprintln(os.Stderr, err) } cmdFinish(exitCode, input, priv) } diff --git a/nature/init.lua b/nature/init.lua index aa85a2e..ecd1054 100644 --- a/nature/init.lua +++ b/nature/init.lua @@ -69,3 +69,11 @@ end bait.catch('error', function(event, handler, err) bait.release(event, handler) end) + +bait.catch('command.not-found', function(cmd) + print(string.format('hilbish: %s not found', cmd)) +end) + +bait.catch('command.not-executable', function(cmd) + print(string.format('hilbish: %s: not executable', cmd)) +end) From 7b3dc951c9ce5e99b911ec4ad136aef45ce54ca6 Mon Sep 17 00:00:00 2001 From: sammyette Date: Tue, 13 Dec 2022 15:14:48 -0400 Subject: [PATCH 83/83] docs: add website (#176) --- .github/workflows/website.yml | 31 ++++ website/.hugo_build.lock | 0 website/archetypes/default.md | 6 + website/config.toml | 25 ++++ website/content/_index.md | 134 ++++++++++++++++++ website/content/docs/_index.md | 19 +++ website/content/docs/faq.md | 25 ++++ website/content/docs/features/_index.md | 11 ++ website/content/docs/features/runner-mode.md | 17 +++ website/content/docs/getting-started.md | 59 ++++++++ website/content/install.md | 38 +++++ website/static/hilbish-flower.png | Bin 0 -> 15941 bytes website/themes/hsh/LICENSE | 21 +++ website/themes/hsh/archetypes/default.md | 2 + website/themes/hsh/layouts/404.html | 7 + .../_default/_markup/render-heading.html | 6 + .../layouts/_default/_markup/render-link.html | 4 + .../themes/hsh/layouts/_default/baseof.html | 21 +++ website/themes/hsh/layouts/_default/doc.html | 53 +++++++ website/themes/hsh/layouts/_default/list.html | 0 website/themes/hsh/layouts/_default/page.html | 7 + .../themes/hsh/layouts/_default/single.html | 8 ++ website/themes/hsh/layouts/index.html | 6 + .../themes/hsh/layouts/partials/footer.html | 32 +++++ website/themes/hsh/layouts/partials/head.html | 26 ++++ .../themes/hsh/layouts/partials/header.html | 25 ++++ .../hsh/layouts/shortcodes/warning.html | 6 + website/themes/hsh/theme.toml | 21 +++ 28 files changed, 610 insertions(+) create mode 100644 .github/workflows/website.yml create mode 100644 website/.hugo_build.lock create mode 100644 website/archetypes/default.md create mode 100644 website/config.toml create mode 100644 website/content/_index.md create mode 100644 website/content/docs/_index.md create mode 100644 website/content/docs/faq.md create mode 100644 website/content/docs/features/_index.md create mode 100644 website/content/docs/features/runner-mode.md create mode 100644 website/content/docs/getting-started.md create mode 100644 website/content/install.md create mode 100644 website/static/hilbish-flower.png create mode 100644 website/themes/hsh/LICENSE create mode 100644 website/themes/hsh/archetypes/default.md create mode 100644 website/themes/hsh/layouts/404.html create mode 100644 website/themes/hsh/layouts/_default/_markup/render-heading.html create mode 100644 website/themes/hsh/layouts/_default/_markup/render-link.html create mode 100644 website/themes/hsh/layouts/_default/baseof.html create mode 100644 website/themes/hsh/layouts/_default/doc.html create mode 100644 website/themes/hsh/layouts/_default/list.html create mode 100644 website/themes/hsh/layouts/_default/page.html create mode 100644 website/themes/hsh/layouts/_default/single.html create mode 100644 website/themes/hsh/layouts/index.html create mode 100644 website/themes/hsh/layouts/partials/footer.html create mode 100644 website/themes/hsh/layouts/partials/head.html create mode 100644 website/themes/hsh/layouts/partials/header.html create mode 100644 website/themes/hsh/layouts/shortcodes/warning.html create mode 100644 website/themes/hsh/theme.toml diff --git a/.github/workflows/website.yml b/.github/workflows/website.yml new file mode 100644 index 0000000..fc06a70 --- /dev/null +++ b/.github/workflows/website.yml @@ -0,0 +1,31 @@ +name: Build website + +on: + push: + branches: + - master + - website + +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + submodules: true + fetch-depth: 0 + + - name: Setup Hugo + uses: peaceiris/actions-hugo@v2 + with: + hugo-version: 'latest' + extended: true + + - name: Build + run: 'cd website && hugo --minify' + + - name: Deploy + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./website/public diff --git a/website/.hugo_build.lock b/website/.hugo_build.lock new file mode 100644 index 0000000..e69de29 diff --git a/website/archetypes/default.md b/website/archetypes/default.md new file mode 100644 index 0000000..00e77bd --- /dev/null +++ b/website/archetypes/default.md @@ -0,0 +1,6 @@ +--- +title: "{{ replace .Name "-" " " | title }}" +date: {{ .Date }} +draft: true +--- + diff --git a/website/config.toml b/website/config.toml new file mode 100644 index 0000000..ff6b801 --- /dev/null +++ b/website/config.toml @@ -0,0 +1,25 @@ +baseURL = 'https://rosettea.github.io/Hilbish/' +languageCode = 'en-us' +title = 'Hilbish' +theme = 'hsh' +enableGitInfo = true + +[menu] +[[menu.nav]] + identifier = 'home' + name = 'Home' + pageref = '/' + weight = 1 +[[menu.nav]] + identifier = 'install' + name = 'Install' + pageref = '/install' + weight = 2 +[[menu.nav]] + identifier = 'docs' + name = 'Docs' + pageref = '/docs' + weight = 3 + +[markup.goldmark.renderer] +unsafe = true diff --git a/website/content/_index.md b/website/content/_index.md new file mode 100644 index 0000000..2b1087b --- /dev/null +++ b/website/content/_index.md @@ -0,0 +1,134 @@ +--- +description: 'Something Unique. Hilbish is the new interactive shell for Lua fans. Extensible, scriptable, configurable: All in Lua.' +--- + +[//]: <> + + +
+

Something Unique.

+

+ Hilbish is the new interactive shell for Lua fans.
+ Extensible, scriptable, configurable: All in Lua. +

+ Install + Github +
+ +
+ +
+
+
+
+
+ + + +
+
+
Simple and Easy Scripting
+
+

+ Hilbish is configured and scripted in the Lua programming language. + This removes all the old, ugly things about Shell script and introduces + everything good about Lua, including other languages (Moonscript & Fennel). +

+
+
+
+
+
+
+
+
+
+ + + +
+
+
History and Completion Menus
+
+

+ Hilbish provides the user with proper menus for completions, + history searching. Want to see your previous commands? Hit Ctrl-R. +

+
+
+
+
+
+
+
+
+
+ + + +
+
+
Tons of Features, and More to Come
+
+

+ Hilbish offers a bunch of features to make your interactive + shell experience rich. Things like syntax highlighting and hinting + available via the Lua API. +

+

* Command hints shown in photo are not default.

+
+
+
+
+
+ + +
+ +
+ +

Why not just Lua?

+

+ Hilbish is your interactive shell as well as a just a Lua interpreter + and enhanced REPL.
+

+
    +
  • Batteries included Lua runtime that's also your user shell!
  • +
  • Hilbish is easily cross platform. It has OS agnostic interfaces for easy cross platform Lua code.
  • +
+ +
+ +

Try It Today!

+

+ Hilbish is known to run on the 3 major platforms (Windows, MacOS, Linux) + but likely builds on other Unixes! +
+ Windows doesn't work as well as it should, so if you're a Windows user, + say something! +

+

diff --git a/website/content/docs/_index.md b/website/content/docs/_index.md new file mode 100644 index 0000000..4f30ab3 --- /dev/null +++ b/website/content/docs/_index.md @@ -0,0 +1,19 @@ +--- +title: Introduction +layout: doc +weight: -1 +menu: docs +--- + +Here lies the documentation for Hilbish, the hyper extensible Lua shell. +Hilbish provides you with a few quality of life features and useful +functions to ensure you can make the shell fully yours. + +These features include: +- Completion and history search menus +- Hinting and syntax highlighting (scripted by user) + +# Installation +Steps on installing Hilbish will be at the Install page in the navigation bar +at the top. This also included getting development builds from the GitHub +repository. diff --git a/website/content/docs/faq.md b/website/content/docs/faq.md new file mode 100644 index 0000000..d5cd1a2 --- /dev/null +++ b/website/content/docs/faq.md @@ -0,0 +1,25 @@ +--- +title: Frequently Asked Questions +layout: doc +weight: -20 +menu: docs +--- + +# Is Hilbish POSIX compliant? +No, it is not. POSIX compliance is a non-goal. Perhaps in the future, +someone would be able to write a native plugin to support shell scripting +(which would be against it's main goal, but ....) + +# Windows Support? +It compiles for Windows (CI ensures it does), but otherwise it is not +directly supported. If you'd like to improve this situation, +checkout [the discussion](https://github.com/Rosettea/Hilbish/discussions/165). + +# Where is the API documentation? +The builtin `doc` command supplies all documentation of Hilbish provided +APIs. This will be on the website in the near future. + +# Why? +Hilbish emerged from the desire of a Lua configured shell. +It was the initial reason that it was created, but now it's more: +to be hyper extensible, simpler and more user friendly. diff --git a/website/content/docs/features/_index.md b/website/content/docs/features/_index.md new file mode 100644 index 0000000..0e14346 --- /dev/null +++ b/website/content/docs/features/_index.md @@ -0,0 +1,11 @@ +--- +title: Features +layout: doc +weight: -40 +menu: docs +--- + +Hilbish has a wide range of features to enhance the user's experience and +is always adding new ones. If there is something missing here or something +you would like to see, please [start a discussion](https://github.com/Rosettea/Hilbish/discussions) +or comment on any existing ones which match your request. diff --git a/website/content/docs/features/runner-mode.md b/website/content/docs/features/runner-mode.md new file mode 100644 index 0000000..87ecc8b --- /dev/null +++ b/website/content/docs/features/runner-mode.md @@ -0,0 +1,17 @@ +--- +title: Runner Mode +description: Customize the interactive script/command runner. +layout: doc +menu: + docs: + parent: "Features" +--- + +Hilbish allows you to change how interactive text can be interpreted. +This is mainly due to the fact that the default method Hilbish uses +is that it runs Lua first and then falls back to shell script. + +In some cases, someone might want to switch to just shell script to avoid +it while interactive but still have a Lua config, or go full Lua to use +Hilbish as a REPL. This also allows users to add alternative languages, +instead of either like Fennel. diff --git a/website/content/docs/getting-started.md b/website/content/docs/getting-started.md new file mode 100644 index 0000000..f0fe56d --- /dev/null +++ b/website/content/docs/getting-started.md @@ -0,0 +1,59 @@ +--- +title: Getting Started +layout: doc +weight: -10 +menu: docs +--- + +To start Hilbish, open a terminal. If Hilbish has been installed and is not the +default shell, you can simply run `hilbish` to start it. This will launch +a normal interactive session. +To exit, you can either run the `exit` command or hit Ctrl+D. + +# Setting as Default +## Login shell +There are a few ways to make Hilbish your default shell. A simple way is +to make it your user/login shell. + +{{< warning `It is not recommended to set Hilbish as your login shell. That is expected to be a +POSIX compliant shell, which Hilbish is not. At most, there will just be a +few variables missing in your environment` >}} + +To do that, simply run `chsh -s /usr/bin/hilbish`. +Some distros (namely Fedora) might have `lchsh` instead, which is used like `lchsh `. +When prompted, you can put the path for Hilbish. + +## Default with terminal +The simpler way is to set the default shell for your terminal. The way of +doing this depends on how your terminal settings are configured. + +## Run after login shell +Some shells (like zsh) have an rc file, like `.zlogin`, which is ran when the shell session +is a login shell. In that file, you can run Hilbish. Example: + +``` +exec hilbish -S -l +``` + +This will replace the shell with Hilbish, set $SHELL to Hilbish and launch it as a login shell. + +# Configuration +Once installation and setup has been done, you can then configure Hilbish. +It is configured and scripted via Lua, so the config file is a Lua file. +You can use any pure Lua library to do whatever you want. + +Hilbish's sample configuration is usually located in `hilbish.dataDir .. '/.hilbishrc.lua'`. +You can print that path via Lua to see what it is: `print(hilbish.dataDir .. '/.hilbishrc.lua')`. +As an example, it will usually will result in `/usr/share/hilbish/.hilbishrc.lua` on Linux. + +To edit your user configuration, you can copy that file to `hilbish.userDir.config .. '/hilbish/init.lua'`, +which follows XDG on Linux and MacOS, and is located in %APPDATA% on Windows. + +As the directory is usually `~/.config` on Linux, you can run this command to copy it: +`cp /usr/share/hilbish/.hilbishrc.lua ~/.config/hilbish/init.lua` + +Now you can get to editing it. Since it's just a Lua file, having basic +knowledge of Lua would help. All of Lua's standard libraries and functions +from Lua 5.4 are available. Hilbish has some custom and modules that are +available. To see them, you can run the `doc` command. This also works as +general documentation for other things. diff --git a/website/content/install.md b/website/content/install.md new file mode 100644 index 0000000..731b8c0 --- /dev/null +++ b/website/content/install.md @@ -0,0 +1,38 @@ +--- +title: Install +description: Steps on how to install Hilbish on all the OSes and distros supported. +layout: page +--- + +## Official Binaries +The best way to get Hilbish is to get a build directly from GitHub. +At any time, there are 2 versions of Hilbish recommended for download: +the latest stable release, and development builds from the master branch. + +You can download both at any time, but note that the development builds may +have breaking changes. + +For the latest **stable release**, check here: https://github.com/Rosettea/Hilbish/releases/latest +For a **development build**: https://nightly.link/Rosettea/Hilbish/workflows/build/master + +## Package Repositories +### Arch Linux (AUR) +Hilbish is on the AUR. Setup an AUR helper, and install. +Example with yay: + +``` +yay -S hilbish +``` + +Or, from master branch: +``` +yay -S hilbish-git +``` + +### Alpine Linux +Hilbish is currentlty in the testing/edge repository for Alpine. +Follow the steps [here](https://wiki.alpinelinux.org/wiki/Enable_Community_Repository) +(Using testing repositories) and install: +``` +apk add hilbish +``` diff --git a/website/static/hilbish-flower.png b/website/static/hilbish-flower.png new file mode 100644 index 0000000000000000000000000000000000000000..b4fb0f72d2cb09e1a301e0ca24cd857e7435be6c GIT binary patch literal 15941 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 +
+

Go Home

+
+ +{{ end }} diff --git a/website/themes/hsh/layouts/_default/_markup/render-heading.html b/website/themes/hsh/layouts/_default/_markup/render-heading.html new file mode 100644 index 0000000..6ea5346 --- /dev/null +++ b/website/themes/hsh/layouts/_default/_markup/render-heading.html @@ -0,0 +1,6 @@ + + {{ .Text | safeHTML }} + +{{ if eq .Text ""}} +
+{{ end }} diff --git a/website/themes/hsh/layouts/_default/_markup/render-link.html b/website/themes/hsh/layouts/_default/_markup/render-link.html new file mode 100644 index 0000000..9c2a95e --- /dev/null +++ b/website/themes/hsh/layouts/_default/_markup/render-link.html @@ -0,0 +1,4 @@ + + {{ .Text | safeHTML }} + + diff --git a/website/themes/hsh/layouts/_default/baseof.html b/website/themes/hsh/layouts/_default/baseof.html new file mode 100644 index 0000000..dad9ef8 --- /dev/null +++ b/website/themes/hsh/layouts/_default/baseof.html @@ -0,0 +1,21 @@ + + + {{- partial "head.html" . -}} + + + + + + + + + + + + + + {{- partial "header.html" . -}} + {{- block "main" . }}{{- end }} + {{- partial "footer.html" . -}} + + diff --git a/website/themes/hsh/layouts/_default/doc.html b/website/themes/hsh/layouts/_default/doc.html new file mode 100644 index 0000000..bebbf5e --- /dev/null +++ b/website/themes/hsh/layouts/_default/doc.html @@ -0,0 +1,53 @@ +{{ define "main" }} +
+
+
+ +
+
+
+
+

{{ .Title }}

+

+ {{ $date := .Date.UTC.Format "Jan 2, 2006" }} + {{ $lastmod := .Lastmod.UTC.Format "Jan 2, 2006" }} + {{ if and (ne $lastmod $date) (gt .Lastmod .Date) }} + Last updated {{ $lastmod }}
+ {{ end }} + + {{ if .Description }} + {{ .Description }}
+ {{ end}} +

+ {{.Content}} +
+ + +
+
+{{ end }} + diff --git a/website/themes/hsh/layouts/_default/list.html b/website/themes/hsh/layouts/_default/list.html new file mode 100644 index 0000000..e69de29 diff --git a/website/themes/hsh/layouts/_default/page.html b/website/themes/hsh/layouts/_default/page.html new file mode 100644 index 0000000..69aaf99 --- /dev/null +++ b/website/themes/hsh/layouts/_default/page.html @@ -0,0 +1,7 @@ +{{ define "main" }} +
+
+ {{.Content}} +
+
+{{ end }} diff --git a/website/themes/hsh/layouts/_default/single.html b/website/themes/hsh/layouts/_default/single.html new file mode 100644 index 0000000..0ac0e37 --- /dev/null +++ b/website/themes/hsh/layouts/_default/single.html @@ -0,0 +1,8 @@ +{{ define "main" }} +
+
+

{{ .Title }}

+ {{.Content}} +
+
+{{ end }} diff --git a/website/themes/hsh/layouts/index.html b/website/themes/hsh/layouts/index.html new file mode 100644 index 0000000..a9f64d2 --- /dev/null +++ b/website/themes/hsh/layouts/index.html @@ -0,0 +1,6 @@ +{{ define "main" }} +
+ {{.Content}} +
+{{ end }} + diff --git a/website/themes/hsh/layouts/partials/footer.html b/website/themes/hsh/layouts/partials/footer.html new file mode 100644 index 0000000..15aa193 --- /dev/null +++ b/website/themes/hsh/layouts/partials/footer.html @@ -0,0 +1,32 @@ + diff --git a/website/themes/hsh/layouts/partials/head.html b/website/themes/hsh/layouts/partials/head.html new file mode 100644 index 0000000..3556074 --- /dev/null +++ b/website/themes/hsh/layouts/partials/head.html @@ -0,0 +1,26 @@ + + {{ $title := print .Title " — " .Site.Title }} + {{ if .IsHome }}{{ $title = .Site.Title }}{{ end }} + {{ $title }} + + + + + + + + + + + + + + + + + + + + + + diff --git a/website/themes/hsh/layouts/partials/header.html b/website/themes/hsh/layouts/partials/header.html new file mode 100644 index 0000000..281b602 --- /dev/null +++ b/website/themes/hsh/layouts/partials/header.html @@ -0,0 +1,25 @@ +
+ +
diff --git a/website/themes/hsh/layouts/shortcodes/warning.html b/website/themes/hsh/layouts/shortcodes/warning.html new file mode 100644 index 0000000..b217b57 --- /dev/null +++ b/website/themes/hsh/layouts/shortcodes/warning.html @@ -0,0 +1,6 @@ + diff --git a/website/themes/hsh/theme.toml b/website/themes/hsh/theme.toml new file mode 100644 index 0000000..a567739 --- /dev/null +++ b/website/themes/hsh/theme.toml @@ -0,0 +1,21 @@ +# theme.toml template for a Hugo theme +# See https://github.com/gohugoio/hugoThemes#themetoml for an example + +name = "Hsh" +license = "MIT" +licenselink = "https://github.com/yourname/yourtheme/blob/master/LICENSE" +description = "" +homepage = "http://example.com/" +tags = [] +features = [] +min_version = "0.41.0" + +[author] + name = "" + homepage = "" + +# If porting an existing theme +[original] + name = "" + homepage = "" + repo = ""