fix: add suggestion icons & refactor bad generic code in suggestions.go

Signed-off-by: cpendery <cpendery@vt.edu>
This commit is contained in:
cpendery
2023-09-12 23:20:32 -04:00
parent 59f810fb2b
commit 1a6e79c489
5 changed files with 54 additions and 62 deletions
+3 -1
View File
@@ -18,6 +18,7 @@ var (
type Suggestion struct {
Name string
NamePrefix string
Description string
}
@@ -287,7 +288,8 @@ func LoadSuggestions(cmd string) ([]Suggestion, string, int) {
suggestions := []Suggestion{}
for _, suggestion := range termSuggestions.Suggestions {
suggestions = append(suggestions, Suggestion{Name: suggestion.Name, Description: suggestion.Description})
icon := model.TermIcons[suggestion.Type]
suggestions = append(suggestions, Suggestion{Name: suggestion.Name, NamePrefix: icon, Description: suggestion.Description})
}
lastSuggestionCmd, lastSuggestion, lastCmdRunes, lastArgDescription = cmd, suggestions, lastRunes, termSuggestions.ArgumentDescription
return suggestions, termSuggestions.ArgumentDescription, lastRunes
+3
View File
@@ -34,12 +34,15 @@ func walk(includeFiles bool) []model.TermSuggestion {
continue
}
description := file
suggestionType := model.TermSuggestionTypeFile
if dirItem.IsDir() {
description = directory
suggestionType = model.TermSuggestionTypeFolder
}
suggestions = append(suggestions, model.TermSuggestion{
Name: dirItem.Name(),
Description: description,
Type: suggestionType,
})
}
return suggestions
+18 -22
View File
@@ -9,14 +9,6 @@ type Subcommand struct {
FilterStrategy FilterStrategy
}
func (s Subcommand) GetName() []string {
return s.Name
}
func (s Subcommand) GetDescription() string {
return s.Description
}
type Option struct {
Name []string //single or array string, required
Args []Arg //single or array Arg, optional
@@ -25,14 +17,6 @@ type Option struct {
ExclusiveOn []string
}
func (o Option) GetName() []string {
return o.Name
}
func (o Option) GetDescription() string {
return o.Description
}
type Arg struct {
Name string //single, optional
Description string //single, optional
@@ -58,15 +42,19 @@ type TermSuggestions struct {
type TermSuggestion struct {
Name string
Description string
Type TermSuggestionType
}
func (t TermSuggestion) GetName() []string {
return []string{t.Name}
}
type TermSuggestionType string
func (t TermSuggestion) GetDescription() string {
return t.Description
}
const (
TermSuggestionTypeFolder TermSuggestionType = "folder"
TermSuggestionTypeFile TermSuggestionType = "file"
TermSuggestionTypeArg TermSuggestionType = "arg"
TermSuggestionTypeSubcommand TermSuggestionType = "subcommand"
TermSuggestionTypeOption TermSuggestionType = "option"
TermSuggestionTypeDefault TermSuggestionType = ""
)
type ProcessedToken struct {
Token string
@@ -99,4 +87,12 @@ const (
var (
Templates = []Template{TemplateFilepaths, TemplateFolders, TemplateHistory, TemplateHelp}
TermIcons = map[TermSuggestionType]string{
TermSuggestionTypeFolder: "📁",
TermSuggestionTypeFile: "📄",
TermSuggestionTypeSubcommand: "📦",
TermSuggestionTypeOption: "⚙️ ",
TermSuggestionTypeArg: "💪",
TermSuggestionTypeDefault: "💪",
}
)
+24 -34
View File
@@ -10,33 +10,21 @@ import (
"github.com/lithammer/fuzzysearch/fuzzy"
)
type matchable interface {
GetName() []string
GetDescription() string
type match struct {
name string
rank int
item model.TermSuggestion
}
func fuzzyMatch[M matchable](input string, targets []M, suggestions *[]model.TermSuggestion) {
type match struct {
name string
rank int
item M
}
func fuzzyMatch(input string, targets []model.TermSuggestion, suggestions *[]model.TermSuggestion) {
matchers := []match{}
for _, item := range targets {
bestName := ""
bestNameRank := -1
for _, n := range item.GetName() {
rank := fuzzy.RankMatch(input, n)
if rank > bestNameRank {
bestName = n
bestNameRank = rank
}
}
if bestNameRank != -1 {
rank := fuzzy.RankMatch(input, item.Name)
if rank != -1 {
matchers = append(matchers, match{
name: bestName,
name: item.Name,
item: item,
rank: bestNameRank,
rank: rank,
})
}
}
@@ -46,34 +34,33 @@ func fuzzyMatch[M matchable](input string, targets []M, suggestions *[]model.Ter
for _, m := range matchers {
*suggestions = append(*suggestions, model.TermSuggestion{
Name: m.name,
Description: m.item.GetDescription(),
Description: m.item.Description,
Type: m.item.Type,
})
}
}
func getFuzzyFilteredRecommendations(input string, suggestions *[]model.TermSuggestion) {
results := []model.TermSuggestion{}
fuzzyMatch[model.TermSuggestion](input, *suggestions, &results)
fuzzyMatch(input, *suggestions, &results)
*suggestions = results
}
func prefixMatch[M matchable](input string, subcommands []M, suggestions *[]model.TermSuggestion) {
for _, sub := range subcommands {
for _, n := range sub.GetName() {
if strings.HasPrefix(n, input) {
*suggestions = append(*suggestions, model.TermSuggestion{
Name: n,
Description: sub.GetDescription(),
})
break
}
func prefixMatch(input string, targets []model.TermSuggestion, suggestions *[]model.TermSuggestion) {
for _, targ := range targets {
if strings.HasPrefix(targ.Name, input) {
*suggestions = append(*suggestions, model.TermSuggestion{
Name: targ.Name,
Description: targ.Description,
Type: targ.Type,
})
}
}
}
func getPrefixFilteredRecommendations(input string, suggestions *[]model.TermSuggestion) {
results := []model.TermSuggestion{}
prefixMatch[model.TermSuggestion](input, *suggestions, &results)
prefixMatch(input, *suggestions, &results)
*suggestions = results
}
@@ -100,6 +87,7 @@ func getSuggestionDrivenRecommendations(suggestionSet []model.Suggestion, sugges
*suggestions = append(*suggestions, model.TermSuggestion{
Name: getLongName(suggestion.Name),
Description: suggestion.Description,
Type: model.TermSuggestionTypeDefault,
})
}
}
@@ -109,6 +97,7 @@ func getSubcommandDrivenRecommendations(spec model.Subcommand, suggestions *[]mo
*suggestions = append(*suggestions, model.TermSuggestion{
Name: getLongName(sub.Name),
Description: sub.Description,
Type: model.TermSuggestionTypeSubcommand,
})
}
}
@@ -118,6 +107,7 @@ func getOptionDrivenRecommendations(options []model.Option, suggestions *[]model
*suggestions = append(*suggestions, model.TermSuggestion{
Name: getShortName(op.Name),
Description: op.Description,
Type: model.TermSuggestionTypeOption,
})
}
}
+6 -5
View File
@@ -106,12 +106,13 @@ func (m Model) Update(msg tea.Msg, command string, userInputCursorLocation int)
return m
}
func (m Model) renderSuggestion(suggestion string, position, cursor, width int) string {
content := wordTrunc(suggestion, width)
func (m Model) renderSuggestion(suggestion autocomplete.Suggestion, position, cursor, width int) string {
content := suggestion.NamePrefix + " " + suggestion.Name
truncatedContent := wordTrunc(content, width)
if position == m.cursor%MaxSuggestions {
return lipgloss.NewStyle().Background(lipgloss.Color("#7D56F4")).Width(width).Render(content)
return lipgloss.NewStyle().Background(lipgloss.Color("#7D56F4")).Width(width).Render(truncatedContent)
}
return lipgloss.NewStyle().Render(content)
return lipgloss.NewStyle().Render(truncatedContent)
}
func wordWrap(content string, width int) string {
@@ -147,7 +148,7 @@ func (m Model) renderSuggestions(width int) string {
r := make([]string, len(m.suggestions))
for idx, suggestion := range m.suggestions {
r[idx] = m.renderSuggestion(suggestion.Name, idx, m.cursor, width)
r[idx] = m.renderSuggestion(suggestion, idx, m.cursor, width)
}
if m.argDescription != "" {