Skip to content

Commit

Permalink
chore: merge from master
Browse files Browse the repository at this point in the history
  • Loading branch information
TorchedSammy committed Oct 25, 2023
2 parents ae356f6 + a5b6fc8 commit e288826
Show file tree
Hide file tree
Showing 25 changed files with 294 additions and 32 deletions.
25 changes: 25 additions & 0 deletions .hilbishrc.lua
Original file line number Diff line number Diff line change
@@ -1,18 +1,39 @@
-- Default Hilbish config
local hilbish = require 'hilbish'
local lunacolors = require 'lunacolors'
local bait = require 'bait'
local ansikit = require 'ansikit'

local unreadCount = 0
local running = false
local function doPrompt(fail)
hilbish.prompt(lunacolors.format(
'{blue}%u {cyan}%d ' .. (fail and '{red}' or '{green}') .. ''
))
end

local function doNotifyPrompt()
if running or unreadCount == hilbish.messages.unreadCount() then return end

local notifPrompt = string.format('• %s unread notification%s', hilbish.messages.unreadCount(), hilbish.messages.unreadCount() > 1 and 's' or '')
unreadCount = hilbish.messages.unreadCount()
hilbish.prompt(lunacolors.blue(notifPrompt), 'right')

hilbish.timeout(function()
hilbish.prompt('', 'right')
end, 3000)
end

doPrompt()

bait.catch('command.preexec', function()
running = true
end)

bait.catch('command.exit', function(code)
running = false
doPrompt(code ~= 0)
doNotifyPrompt()
end)

bait.catch('hilbish.vimMode', function(mode)
Expand All @@ -22,3 +43,7 @@ bait.catch('hilbish.vimMode', function(mode)
ansikit.cursorStyle(ansikit.lineCursor)
end
end)

bait.catch('hilbish.notification', function(notif)
doNotifyPrompt()
end)
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,25 @@
- `read()` method for retrieving input (so now the `in` sink of commanders is useful)
- `flush()` and `autoFlush()` related to flushing outputs
- `pipe` property to check if a sink with input is a pipe (like stdin)
- Add fuzzy search to history search (enable via `hilbish.opts.fuzzy = true`)
- Show indexes on cdr list
- Fix doc command not displaying correct subdocs when using shorthand api doc access (`doc api hilbish.jobs` as an example)
- `hilbish.messages` interface (details in [#219])
- `hilbish.notification` signal when a message/notification is sent
- `notifyJobFinish` opt to send a notification when background jobs are
completed.
- Allow numbered arg substitutions in aliases.
- Example: `hilbish.alias('hello', 'echo %1 says hello')` allows the user to run `hello hilbish`
which will output `hilbish says hello`.
- Greenhouse
- Greenhouse is a pager library and program. Basic usage is `greenhouse <file>`
- Using this also brings enhancements to the `doc` command like easy
navigation of neighboring doc files.

### Fixed
- Return the prefix when calling `hilbish.completions.call`

[#219]: https://github.com/Rosettea/Hilbish/issues/219
### Fixed
- Replaced `sed` in-place editing with `grep` and `mv` for compatibility with BSD utils

Expand Down
27 changes: 26 additions & 1 deletion aliases.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package main

import (
"regexp"
"strconv"
"strings"
"sync"

Expand Down Expand Up @@ -46,9 +48,32 @@ func (a *aliasModule) Resolve(cmdstr string) string {
a.mu.RLock()
defer a.mu.RUnlock()

args := strings.Split(cmdstr, " ")
arg, _ := regexp.Compile(`[\\]?%\d+`)

args, _ := splitInput(cmdstr)
if len(args) == 0 {
// this shouldnt reach but...????
return cmdstr
}

for a.aliases[args[0]] != "" {
alias := a.aliases[args[0]]
alias = arg.ReplaceAllStringFunc(alias, func(a string) string {
idx, _ := strconv.Atoi(a[1:])
if strings.HasPrefix(a, "\\") || idx == 0 {
return strings.TrimPrefix(a, "\\")
}

if idx + 1 > len(args) {
return a
}
val := args[idx]
args = cut(args, idx)
cmdstr = strings.Join(args, " ")

return val
})

cmdstr = alias + strings.TrimPrefix(cmdstr, args[0])
cmdArgs, _ := splitInput(cmdstr)
args = cmdArgs
Expand Down
2 changes: 2 additions & 0 deletions api.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// The Hilbish module includes the core API, containing
// interfaces and functions which directly relate to shell functionality.
// #field ver The version of Hilbish
// #field goVersion The version of Go that Hilbish was compiled with
// #field user Username of the user
// #field host Hostname of the machine
// #field dataDir Directory for Hilbish data files, including the docs and default modules
Expand Down Expand Up @@ -110,6 +111,7 @@ func hilbishLoad(rtm *rt.Runtime) (rt.Value, func()) {
}

util.SetFieldProtected(fakeMod, mod, "ver", rt.StringValue(getVersion()))
util.SetFieldProtected(fakeMod, mod, "goVersion", rt.StringValue(runtime.Version()))
util.SetFieldProtected(fakeMod, mod, "user", rt.StringValue(username))
util.SetFieldProtected(fakeMod, mod, "host", rt.StringValue(host))
util.SetFieldProtected(fakeMod, mod, "home", rt.StringValue(curuser.HomeDir))
Expand Down
9 changes: 5 additions & 4 deletions complete.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,15 +253,16 @@ func callLuaCompleter(t *rt.Thread, c *rt.GoCont) (rt.Cont, error) {
}

// we must keep the holy 80 cols
completerReturn, err := rt.Call1(l.MainThread(),
rt.FunctionValue(completecb), rt.StringValue(query),
rt.StringValue(ctx), rt.TableValue(fields))
cont := c.Next()
err = rt.Call(l.MainThread(), rt.FunctionValue(completecb),
[]rt.Value{rt.StringValue(query), rt.StringValue(ctx), rt.TableValue(fields)},
cont)

if err != nil {
return nil, err
}

return c.PushingNext1(t.Runtime, completerReturn), nil
return cont, nil
}

// #interface completions
Expand Down
1 change: 1 addition & 0 deletions docs/api/hilbish/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ interfaces and functions which directly relate to shell functionality.

## Interface fields
- `ver`: The version of Hilbish
- `goVersion`: The version of Go that Hilbish was compiled with
- `user`: Username of the user
- `host`: Hostname of the machine
- `dataDir`: Directory for Hilbish data files, including the docs and default modules
Expand Down
5 changes: 5 additions & 0 deletions docs/hooks/command.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
+ `command.preexec` -> input, cmdStr > Thrown before a command
is executed. The `input` is the user written command, while `cmdStr`
is what will be executed (`input` will have aliases while `cmdStr`
will have alias resolved input).

+ `command.exit` -> code, cmdStr > Thrown when a command exits.
`code` is the exit code of the command, and `cmdStr` is the command that was run.

Expand Down
3 changes: 3 additions & 0 deletions docs/hooks/hilbish.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@
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.

+ `hilbish.notification` -> message > Sent when a message is
sent.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ require (
github.com/chuckpreslar/emission v0.0.0-20170206194824-a7ddd980baf9
github.com/maxlandon/readline v0.1.0-beta.0.20211027085530-2b76cabb8036
github.com/pborman/getopt v1.1.0
github.com/sahilm/fuzzy v0.1.0
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a
golang.org/x/term v0.0.0-20220411215600-e5f449aeb171
mvdan.cc/sh/v3 v3.5.1
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJ
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.8.1-0.20210923151022-86f73c517451 h1:d1PiN4RxzIFXCJTvRkvSkKqwtRAl5ZV4lATKtQI0B7I=
github.com/rogpeppe/go-internal v1.8.1-0.20210923151022-86f73c517451/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o=
github.com/sahilm/fuzzy v0.1.0 h1:FzWGaw2Opqyu+794ZQ9SYifWv2EIXpwP4q8dY1kDAwI=
github.com/sahilm/fuzzy v0.1.0/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220513210516-0976fa681c29 h1:w8s32wxx3sY+OjLlv9qltkLU5yvJzxjjgiHWLjdIcw4=
Expand Down
2 changes: 1 addition & 1 deletion lua.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func luaInit() {
}

// Add more paths that Lua can require from
err := util.DoString(l, "package.path = package.path .. " + requirePaths)
_, err := util.DoString(l, "package.path = package.path .. " + requirePaths)
if err != nil {
fmt.Fprintln(os.Stderr, "Could not add Hilbish require paths! Libraries will be missing. This shouldn't happen.")
}
Expand Down
8 changes: 6 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ func main() {
}

if *verflag {
fmt.Printf("Hilbish %s\n", getVersion())
fmt.Printf("Hilbish %s\nCompiled with %s\n", getVersion(), runtime.Version())
os.Exit(0)
}

Expand Down Expand Up @@ -289,7 +289,7 @@ func removeDupes(slice []string) []string {

func contains(s []string, e string) bool {
for _, a := range s {
if a == e {
if strings.ToLower(a) == strings.ToLower(e) {
return true
}
}
Expand Down Expand Up @@ -324,3 +324,7 @@ func getVersion() string {

return v.String()
}

func cut(slice []string, idx int) []string {
return append(slice[:idx], slice[idx + 1:]...)
}
84 changes: 84 additions & 0 deletions nature/hummingbird.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
local bait = require 'bait'
local commander = require 'commander'
local lunacolors = require 'lunacolors'

local M = {}
local counter = 0
local unread = 0
M._messages = {}
M.icons = {
INFO = '',
SUCCESS = '',
WARN = '',
ERROR = ''
}

hilbish.messages = {}

--- Represents a Hilbish message.
--- @class hilbish.message
--- @field icon string Unicode (preferably standard emoji) icon for the message notification.
--- @field title string Title of the message (like an email subject).
--- @field text string Contents of the message.
--- @field channel string Short identifier of the message. `hilbish` and `hilbish.*` is preserved for internal Hilbish messages.
--- @field summary string A short summary of the message.
--- @field read boolean Whether the full message has been read or not.

function expect(tbl, field)
if not tbl[field] or tbl[field] == '' then
error(string.format('expected field %s in message'))
end
end

--- Sends a message.
--- @param message hilbish.message
function hilbish.messages.send(message)
expect(message, 'text')
expect(message, 'title')
counter = counter + 1
unread = unread + 1
message.index = counter
message.read = false

M._messages[message.index] = message
bait.throw('hilbish.notification', message)
end

function hilbish.messages.read(idx)
local msg = M._messages[idx]
if msg then
M._messages[idx].read = true
unread = unread - 1
end
end

function hilbish.messages.readAll(idx)
for _, msg in ipairs(hilbish.messages.all()) do
hilbish.messages.read(msg.index)
end
end

function hilbish.messages.unreadCount()
return unread
end

function hilbish.messages.delete(idx)
local msg = M._messages[idx]
if not msg then
error(string.format('invalid message index %d', idx or -1))
end

M._messages[idx] = nil
end

function hilbish.messages.clear()
for _, msg in ipairs(hilbish.messages.all()) do
hilbish.messages.delete(msg.index)
end
end

function hilbish.messages.all()
return M._messages
end

return M
1 change: 1 addition & 0 deletions nature/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ require 'nature.completions'
require 'nature.opts'
require 'nature.vim'
require 'nature.runner'
require 'nature.hummingbird'

local shlvl = tonumber(os.getenv 'SHLVL')
if shlvl ~= nil then
Expand Down
6 changes: 4 additions & 2 deletions nature/opts/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ setmetatable(hilbish.opts, {

local function setupOpt(name, default)
opts[name] = default
require('nature.opts.' .. name)
pcall(require, 'nature.opts.' .. name)
end

local defaultOpts = {
Expand All @@ -25,7 +25,9 @@ local defaultOpts = {
greeting = string.format([[Welcome to {magenta}Hilbish{reset}, {cyan}%s{reset}.
The nice lil shell for {blue}Lua{reset} fanatics!
]], hilbish.user),
motd = true
motd = true,
fuzzy = false,
notifyJobFinish = true
}

for optsName, default in pairs(defaultOpts) do
Expand Down
23 changes: 23 additions & 0 deletions nature/opts/notifyJobFinish.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
local bait = require 'bait'
local lunacolors = require 'lunacolors'

bait.catch('job.done', function(job)
if not hilbish.opts.notifyJobFinish then return end
local notifText = string.format(lunacolors.format [[
Background job with ID#%d has exited (PID %d).
Command string: {bold}{yellow}%s{reset}]], job.id, job.pid, job.cmd)

if job.stdout ~= '' then
notifText = notifText .. '\n\nStandard output:\n' .. job.stdout
end
if job.stderr ~= '' then
notifText = notifText .. '\n\nStandard error:\n' .. job.stderr
end

hilbish.messages.send {
channel = 'jobNotify',
title = string.format('Job ID#%d Exited', job.id),
summary = string.format(lunacolors.format 'Background job with command {bold}{yellow}%s{reset} has finished running!', job.cmd),
text = notifText
}
end)
7 changes: 3 additions & 4 deletions readline/comp-group.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,18 +71,17 @@ func (g *CompletionGroup) init(rl *Instance) {
// The rx parameter is passed, as the shell already checked that the search pattern is valid.
func (g *CompletionGroup) updateTabFind(rl *Instance) {

suggs := make([]string, 0)

suggs := rl.Searcher(rl.search, g.Suggestions)
// We perform filter right here, so we create a new completion group, and populate it with our results.
for i := range g.Suggestions {
/*for i := range g.Suggestions {
if rl.regexSearch == nil { continue }
if rl.regexSearch.MatchString(g.Suggestions[i]) {
suggs = append(suggs, g.Suggestions[i])
} else if g.DisplayType == TabDisplayList && rl.regexSearch.MatchString(g.Descriptions[g.Suggestions[i]]) {
// this is a list so lets also check the descriptions
suggs = append(suggs, g.Suggestions[i])
}
}
}*/

// We overwrite the group's items, (will be refreshed as soon as something is typed in the search)
g.Suggestions = suggs
Expand Down
Loading

0 comments on commit e288826

Please sign in to comment.