diff --git a/.hilbishrc.lua b/.hilbishrc.lua index 249f97e..0361bed 100644 --- a/.hilbishrc.lua +++ b/.hilbishrc.lua @@ -47,3 +47,16 @@ end) bait.catch('hilbish.notification', function(notif) doNotifyPrompt() end) + +hilbish.complete('command.comp', function(query, ctx, fields) + local cg = { + items = { + 'list item 1', + ['--command-flag-here'] = {'this does a thing', '--the-flag-alias'}, + ['--styled-command-flag-here'] = {'this does a thing', '--the-flag-alias', display = lunacolors.blue '--styled-command-flag-here'} + }, + type = 'list' + } + + return {cg}, prefix +end) diff --git a/readline/comp-group.go b/readline/comp-group.go index b2ee4b8..74b528a 100644 --- a/readline/comp-group.go +++ b/readline/comp-group.go @@ -14,6 +14,7 @@ type CompletionGroup struct { Suggestions []string Aliases map[string]string // A candidate has an alternative name (ex: --long, -l option flags) Descriptions map[string]string // Items descriptions + ItemDisplays map[string]string // What to display the item as (can be used for styling items) DisplayType TabDisplayType // Map, list or normal MaxLength int // Each group can be limited in the number of comps offered diff --git a/readline/comp-list.go b/readline/comp-list.go index cdcda8f..403cf5d 100644 --- a/readline/comp-list.go +++ b/readline/comp-list.go @@ -217,6 +217,11 @@ func (g *CompletionGroup) writeList(rl *Instance) (comp string) { alt = strings.Repeat(" ", maxLengthAlt+1) // + 2 to keep account of spaces } + styledSugg, ok := g.ItemDisplays[item] + if ok { + sugg = fmt.Sprintf("\r%s%-"+cellWidth+"s", highlight(y, 0), fmtEscape(styledSugg)) + } + // Description description := g.Descriptions[g.Suggestions[i]] if len(description) > maxDescWidth { diff --git a/rl.go b/rl.go index 231d04b..95b1bd0 100644 --- a/rl.go +++ b/rl.go @@ -138,10 +138,13 @@ func newLineReader(prompt string, noHist bool) *lineReader { items := []string{} itemDescriptions := make(map[string]string) + itemDisplays := make(map[string]string) util.ForEach(luaCompItems.AsTable(), func(lkey rt.Value, lval rt.Value) { if keytyp := lkey.Type(); keytyp == rt.StringType { // ['--flag'] = {'description', '--flag-alias'} + // OR + // ['--flag'] = {description = '', alias = '', display = ''} itemName, ok := lkey.TryString() vlTbl, okk := lval.TryTable() if !ok && !okk { @@ -152,10 +155,20 @@ func newLineReader(prompt string, noHist bool) *lineReader { items = append(items, itemName) itemDescription, ok := vlTbl.Get(rt.IntValue(1)).TryString() if !ok { - // TODO: error - return + // if we can't get it by number index, try by string key + itemDescription, ok = vlTbl.Get(rt.StringValue("description")).TryString() + if !ok { + // TODO: error? + return + } } itemDescriptions[itemName] = itemDescription + + // display + // this is optional, so only act when we get it and it's a string + if itemDisplay, ok := vlTbl.Get(rt.StringValue("display")).TryString(); ok { + itemDisplays[itemName] = itemDisplay + } } else if keytyp == rt.IntType { vlStr, ok := lval.TryString() if !ok { @@ -180,6 +193,7 @@ func newLineReader(prompt string, noHist bool) *lineReader { compGroups = append(compGroups, &readline.CompletionGroup{ DisplayType: dispType, Descriptions: itemDescriptions, + ItemDisplays: itemDisplays, Suggestions: items, TrimSlash: false, NoSpace: true,