package readlineimport ()// Completion represents a completion candidate.typeCompletion = completion.Candidate// Completions holds all completions candidates and their associated data,// including usage strings, messages, and suffix matchers for autoremoval.// Some of those additional settings will apply to all contained candidates,// except when these candidates have their own corresponding settings.typeCompletionsstruct { values completion.RawValues messages completion.Messages noSpace completion.SuffixMatcher usage string listLong map[string]bool noSort map[string]bool listSep map[string]string pad map[string]bool escapes map[string]bool// Initially this will be set to the part of the current word // from the beginning of the word up to the position of the cursor. // It may be altered to give a prefix for all matches. PREFIX string// Initially this will be set to the part of the current word, // starting from the cursor position up to the end of the word. // It may be altered so that inserted completions don't overwrite // entirely any suffix when completing in the middle of a word. SUFFIX string}// CompleteValues completes arbitrary keywords (values).func ( ...string) Completions { := make([]Completion, 0, len())for , := range { = append(, Completion{Value: ,Display: ,Description: "", }) }returnCompletions{values: }}// CompleteStyledValues is like CompleteValues but also accepts a style.func ( ...string) Completions {if := len(); %2 != 0 {returnCompleteMessage("invalid amount of arguments [CompleteStyledValues]: %v", ) } := make([]Completion, 0, len()/2)for := 0; < len(); += 2 { = append(, Completion{Value: [],Display: [],Description: "",Style: [+1], }) }returnCompletions{values: }}// CompleteValuesDescribed completes arbitrary key (values) with an additional description (value, description pairs).func ( ...string) Completions {if := len(); %2 != 0 {returnCompleteMessage("invalid amount of arguments [CompleteValuesDescribed]: %v", ) } := make([]Completion, 0, len()/2)for := 0; < len(); += 2 { = append(, Completion{Value: [],Display: [],Description: [+1], }) }returnCompletions{values: }}// CompleteStyledValuesDescribed is like CompleteValues but also accepts a style.func ( ...string) Completions {if := len(); %3 != 0 {returnCompleteMessage("invalid amount of arguments [CompleteStyledValuesDescribed]: %v", ) } := make([]Completion, 0, len()/3)for := 0; < len(); += 3 { = append(, Completion{Value: [],Display: [],Description: [+1],Style: [+2], }) }returnCompletions{values: }}// CompleteMessage ads a help message to display along with// or in places where no completions can be generated.func ( string, ...any) Completions { := Completions{}iflen() > 0 { = fmt.Sprintf(, ...) } .messages.Add()return}// CompleteRaw directly accepts a list of prepared Completion values.func ( []Completion) Completions {returnCompletions{values: completion.RawValues()}}// Message displays a help messages in places where no completions can be generated.func ( string, ...any) Completions { := Completions{}iflen() > 0 { = fmt.Sprintf(, ...) } .messages.Add()return}// Suppress suppresses specific error messages using regular expressions.func ( Completions) ( ...string) Completions {if := .messages.Suppress(...); != nil {returnCompleteMessage(.Error()) }return}// NoSpace disables space suffix for given characters (or all if none are given).// These suffixes will be used for all completions that have not specified their// own suffix-matching patterns.// This is used for slash-autoremoval in path completions, comma-separated completions, etc.func ( Completions) ( ...rune) Completions {iflen() == 0 { .noSpace.Add('*') } .noSpace.Add(...)return}// Prefix adds a prefix to values (only the ones inserted, not the display values)//// a := CompleteValues("melon", "drop", "fall").Invoke(c)// b := a.Prefix("water") // ["watermelon", "waterdrop", "waterfall"] but display still ["melon", "drop", "fall"]func ( Completions) ( string) Completions {for , := range .values { .values[].Value = + .Value }return}// Suffix adds a suffx to values (only the ones inserted, not the display values)//// a := CompleteValues("apple", "melon", "orange").Invoke(c)// b := a.Suffix("juice") // ["applejuice", "melonjuice", "orangejuice"] but display still ["apple", "melon", "orange"]func ( Completions) ( string) Completions {for , := range .values { .values[].Value = .Value + }return}// Usage sets the usage.func ( Completions) ( string, ...any) Completions {return .UsageF(func() string {returnfmt.Sprintf(, ...) })}// UsageF sets the usage using a function.func ( Completions) ( func() string) Completions {if := (); != "" { .usage = }return}// Style sets the style, accepting cterm color codes, eg. 255, 30, etc.//// CompleteValues("yes").Style("35")// CompleteValues("no").Style("255")func ( Completions) ( string) Completions {return .StyleF(func( string) string {return })}// StyleR sets the style using a reference//// CompleteValues("value").StyleR(&style.Value)// CompleteValues("description").StyleR(&style.Value)func ( Completions) ( *string) Completions {if != nil {return .Style(*) }return}// StyleF sets the style using a function//// CompleteValues("dir/", "test.txt").StyleF(myStyleFunc)// CompleteValues("true", "false").StyleF(styleForKeyword)func ( Completions) ( func( string) string) Completions {for , := range .values { .values[].Style = (.Value) }return}// Tag sets the tag.//// CompleteValues("192.168.1.1", "127.0.0.1").Tag("interfaces").func ( Completions) ( string) Completions {return .TagF(func( string) string {return })}// TagF sets the tag using a function.//// CompleteValues("192.168.1.1", "127.0.0.1").TagF(func(value string) string {// return "interfaces"// })func ( Completions) ( func( string) string) Completions {for , := range .values { .values[].Tag = (.Value) }return}// DisplayList forces the completions to be list below each other as a list.// A series of tags can be passed to restrict this to these tags. If empty,// will be applied to all completions.func ( Completions) ( ...string) Completions {if .listLong == nil { .listLong = make(map[string]bool) }iflen() == 0 { .listLong["*"] = true }for , := range { .listLong[] = true }return}// ListSeparator accepts a custom separator to use between the candidates and their descriptions.// If more than one separator is given, the list is considered to be a map of tag:separators, in// which case it will fail if the list has an odd number of values.//// If one only one value is given, will apply to all completions (and their tags if any).// If no value is given, no modifications will be made.func ( Completions) ( ...string) Completions {if .listSep == nil { .listSep = make(map[string]string) }if := len(); len() > 1 && %2 != 0 {returnCompleteMessage("invalid amount of arguments (ListSeparator): %v", ) }iflen() == 1 {iflen(.listSep) == 0 { .listSep["*"] = [0] } else {for := range .listSep { .listSep[] = [0] } } } else {for := 0; < len(); += 2 { .listSep[[]] = [+1] } }return}// NoSort forces the completions not to sort the completions in alphabetical order.// A series of tags can be passed to restrict this to these tags. If empty, will be// applied to all completions.func ( Completions) ( ...string) Completions {if .noSort == nil { .noSort = make(map[string]bool) }iflen() == 0 { .noSort["*"] = true }for , := range { .noSort[] = true }return}// Filter filters given values (this should be done before any call// to Prefix/Suffix as those alter the values being filtered)//// a := CompleteValues("A", "B", "C").Invoke(c)// b := a.Filter([]string{"B"}) // ["A", "C"]func ( Completions) ( []string) Completions { .values = .values.Filter(...)return}// JustifyDescriptions accepts a list of tags for which descriptions (if any), will be left justified.// If no arguments are given, description justification (padding) will apply to all tags.func ( Completions) ( ...string) Completions {if .pad == nil { .pad = make(map[string]bool) }iflen() == 0 { .pad["*"] = true }for , := range { .pad[] = true }return}// PreserveEscapes forces the completion engine to keep all escaped characters in// the inserted completion (c.Value of the Completion type). By default, those are// stripped out and only kept in the completion.Display. If no arguments are given,// escape sequence preservation will apply to all tags.//// This has very few use cases: one of them might be when you want to read a string// from the readline shell that might include color sequences to be preserved.// In such cases, this function gives a double advantage: the resulting completion// is still "color-displayed" in the input line, and returned to the readline with// them. A classic example is where you want to read a prompt string configuration.//// Note that this option might have various undefined behaviors when it comes to// completion prefix matching, insertion, removal and related things.func ( Completions) ( ...string) Completions {if .escapes == nil { .escapes = make(map[string]bool) }iflen() == 0 { .escapes["*"] = true }for , := range { .escapes[] = true }return}// Merge merges Completions (existing values are overwritten)//// a := CompleteValues("A", "B").Invoke(c)// b := CompleteValues("B", "C").Invoke(c)// c := a.Merge(b) // ["A", "B", "C"]func ( Completions) ( ...Completions) Completions { := make(map[string]Completion)for , := rangeappend([]Completions{}, ...) {for , := range .values { [.Value] = } }for , := range { .merge() } := make([]Completion, 0, len())for , := range { = append(, ) } .values = return}// EachValue runs a function on each value, overwriting with the returned one.func ( *Completions) ( func( Completion) Completion) {for , := range .values { .values[] = () }}func ( *Completions) ( Completions) {if .usage != "" { .usage = .usage } .noSpace.Merge(.noSpace) .messages.Merge(.messages)for := range .listLong {if , := .listLong[]; ! { .listLong[] = true } }for := range .noSort {if , := .noSort[]; ! { .noSort[] = true } }for := range .listSep {if , := .listSep[]; ! { .listSep[] = .listSep[] } }for := range .pad {if , := .pad[]; ! { .pad[] = .pad[] } }}func ( *Completions) () completion.Values { := completion.AddRaw(.values) .Messages = .messages .NoSpace = .noSpace .Usage = .usage .ListLong = .listLong .NoSort = .noSort .ListSep = .listSep .Pad = .pad .Escapes = .escapes .PREFIX = .PREFIX .SUFFIX = .SUFFIXreturn}
The pages are generated with Goldsv0.8.2. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.