From 6cd294373cd823a3394e0748bd2fd3b1c03fde76 Mon Sep 17 00:00:00 2001 From: sammyette Date: Thu, 3 Apr 2025 08:45:02 -0400 Subject: [PATCH] feat: add abbreviations (#340) --- docs/api/hilbish/hilbish.abbr.md | 67 ++++++++++++++++++++++++++++++ docs/api/hilbish/hilbish.editor.md | 21 ++++++++++ editor.go | 22 +++++++++- emmyLuaDocs/hilbish.lua | 3 ++ nature/abbr.lua | 61 +++++++++++++++++++++++++++ nature/init.lua | 1 + readline/vimdelete.go | 4 ++ 7 files changed, 178 insertions(+), 1 deletion(-) create mode 100644 docs/api/hilbish/hilbish.abbr.md create mode 100644 nature/abbr.lua diff --git a/docs/api/hilbish/hilbish.abbr.md b/docs/api/hilbish/hilbish.abbr.md new file mode 100644 index 0000000..8e88c19 --- /dev/null +++ b/docs/api/hilbish/hilbish.abbr.md @@ -0,0 +1,67 @@ +--- +title: Module hilbish.abbr +description: command line abbreviations +layout: doc +menu: + docs: + parent: "API" +--- + + +## Introduction +The abbr module manages Hilbish abbreviations. These are words that can be replaced +with longer command line strings when entered. +As an example, `git push` can be abbreviated to `gp`. When the user types +`gp` into the command line, after hitting space or enter, it will expand to `git push`. +Abbreviations can be used as an alternative to aliases. They are saved entirely in the history +Instead of the aliased form of the same command. + +## Functions +||| +|----|----| +|remove(abbr)|Removes the named `abbr`.| +|add(abbr, expanded|function, opts)|Adds an abbreviation. The `abbr` is the abbreviation itself,| +
+
+

+hilbish.abbr.add(abbr, expanded|function, opts) + + + +

+ +Adds an abbreviation. The `abbr` is the abbreviation itself, +while `expanded` is what the abbreviation should expand to. +It can be either a function or a string. If it is a function, it will expand to what +the function returns. +`opts` is a table that accepts 1 key: `anywhere`. +`opts.anywhere` defines whether the abbr expands anywhere in the command line or not, +whereas the default behavior is only at the beginning of the line +#### Parameters +`abbr` **`string`** + + +`expanded|function` **`string`** + + +`opts` **`table`** + + +
+ +
+
+

+hilbish.abbr.remove(abbr) + + + +

+ +Removes the named `abbr`. +#### Parameters +`abbr` **`string`** + + +
+ diff --git a/docs/api/hilbish/hilbish.editor.md b/docs/api/hilbish/hilbish.editor.md index c70b605..6dac64b 100644 --- a/docs/api/hilbish/hilbish.editor.md +++ b/docs/api/hilbish/hilbish.editor.md @@ -14,12 +14,30 @@ directly interact with the line editor in use. ## Functions ||| |----|----| +|deleteByAmount(amount)|Deletes characters in the line by the given amount.| |getLine() -> string|Returns the current input line.| |getVimRegister(register) -> string|Returns the text that is at the register.| |insert(text)|Inserts text into the Hilbish command line.| |getChar() -> string|Reads a keystroke from the user. This is in a format of something like Ctrl-L.| |setVimRegister(register, text)|Sets the vim register at `register` to hold the passed text.| +
+
+

+hilbish.editor.deleteByAmount(amount) + + + +

+ +Deletes characters in the line by the given amount. + +#### Parameters +`number` **`amount`** + + +
+

@@ -96,6 +114,9 @@ hilbish.editor.setVimRegister(register, text) Sets the vim register at `register` to hold the passed text. #### Parameters +`string` **`register`** + + `string` **`text`** diff --git a/editor.go b/editor.go index 9c49440..2c04f25 100644 --- a/editor.go +++ b/editor.go @@ -17,6 +17,7 @@ func editorLoader(rtm *rt.Runtime) *rt.Table { "getVimRegister": {editorGetRegister, 2, false}, "getLine": {editorGetLine, 0, false}, "readChar": {editorReadChar, 0, false}, + "deleteByAmount": {editorDeleteByAmount, 1, false}, } mod := rt.NewTable() @@ -47,7 +48,7 @@ func editorInsert(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { // #interface editor // setVimRegister(register, text) // Sets the vim register at `register` to hold the passed text. -// #aram register string +// #param register string // #param text string func editorSetRegister(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { if err := c.Check1Arg(); err != nil { @@ -106,3 +107,22 @@ func editorReadChar(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { return c.PushingNext1(t.Runtime, rt.StringValue(string(buf))), nil } + +// #interface editor +// deleteByAmount(amount) +// Deletes characters in the line by the given amount. +// #param amount number +func editorDeleteByAmount(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) { + if err := c.Check1Arg(); err != nil { + return nil, err + } + + amount, err := c.IntArg(0) + if err != nil { + return nil, err + } + + lr.rl.DeleteByAmount(int(amount)) + + return c.Next(), nil +} diff --git a/emmyLuaDocs/hilbish.lua b/emmyLuaDocs/hilbish.lua index 4b4bd8f..a2935bb 100644 --- a/emmyLuaDocs/hilbish.lua +++ b/emmyLuaDocs/hilbish.lua @@ -7,6 +7,9 @@ local hilbish = {} --- @param cmd string function hilbish.aliases.add(alias, cmd) end +--- Deletes characters in the line by the given amount. +function hilbish.editor.deleteByAmount(amount) end + --- Returns the current input line. function hilbish.editor.getLine() end diff --git a/nature/abbr.lua b/nature/abbr.lua new file mode 100644 index 0000000..cbe89ff --- /dev/null +++ b/nature/abbr.lua @@ -0,0 +1,61 @@ +-- @module hilbish.abbr +-- command line abbreviations +-- The abbr module manages Hilbish abbreviations. These are words that can be replaced +-- with longer command line strings when entered. +-- As an example, `git push` can be abbreviated to `gp`. When the user types +-- `gp` into the command line, after hitting space or enter, it will expand to `git push`. +-- Abbreviations can be used as an alternative to aliases. They are saved entirely in the history +-- Instead of the aliased form of the same command. +local bait = require 'bait' +local hilbish = require 'hilbish' +hilbish.abbr = { + all = {} +} + +--- Adds an abbreviation. The `abbr` is the abbreviation itself, +--- while `expanded` is what the abbreviation should expand to. +--- It can be either a function or a string. If it is a function, it will expand to what +--- the function returns. +--- `opts` is a table that accepts 1 key: `anywhere`. +--- `opts.anywhere` defines whether the abbr expands anywhere in the command line or not, +--- whereas the default behavior is only at the beginning of the line +-- @param abbr string +-- @param expanded|function string +-- @param opts table +function hilbish.abbr.add(abbr, expanded, opts) + print(abbr, expanded, opts) + opts = opts or {} + opts.abbr = abbr + opts.expand = expanded + hilbish.abbr.all[abbr] = opts +end + +--- Removes the named `abbr`. +-- @param abbr string +function hilbish.abbr.remove(abbr) + hilbish.abbr.all[abbr] = nil +end + +bait.catch('hilbish.rawInput', function(c) + -- 0x0d == enter + if c == ' ' or c == string.char(0x0d) then + -- check if the last "word" was a valid abbreviation + local line = hilbish.editor.getLine() + local lineSplits = string.split(line, ' ') + local thisAbbr = hilbish.abbr.all[lineSplits[#lineSplits]] + + if thisAbbr and (#lineSplits == 1 or thisAbbr.anywhere == true) then + hilbish.editor.deleteByAmount(-lineSplits[#lineSplits]:len()) + if type(thisAbbr.expand) == 'string' then + hilbish.editor.insert(thisAbbr.expand) + elseif type(thisAbbr.expand) == 'function' then + local expandRet = thisAbbr.expand() + if type(expandRet) ~= 'string' then + print(string.format('abbr %s has an expand function that did not return a string. instead it returned: %s', thisAbbr.abbr, expandRet)) + return + end + hilbish.editor.insert(expandRet) + end + end + end +end) diff --git a/nature/init.lua b/nature/init.lua index 4c47bfe..cd4fd7a 100644 --- a/nature/init.lua +++ b/nature/init.lua @@ -26,6 +26,7 @@ require 'nature.opts' require 'nature.vim' require 'nature.runner' require 'nature.hummingbird' +require 'nature.abbr' local shlvl = tonumber(os.getenv 'SHLVL') if shlvl ~= nil then diff --git a/readline/vimdelete.go b/readline/vimdelete.go index 7a07259..f5c1806 100644 --- a/readline/vimdelete.go +++ b/readline/vimdelete.go @@ -142,6 +142,10 @@ func (rl *Instance) viDeleteByAdjust(adjust int) { rl.updateHelpers() } +func (rl *Instance) DeleteByAmount(adjust int) { + rl.viDeleteByAdjust(adjust) +} + func (rl *Instance) vimDeleteToken(r rune) bool { tokens, _, _ := tokeniseSplitSpaces(rl.line, 0) pos := int(r) - 48 // convert ASCII to integer