mirror of
https://github.com/wavetermdev/inshellisense.git
synced 2026-08-05 13:43:30 -07:00
fix: completions on long args when short exist
Signed-off-by: cpendery <cpendery@vt.edu>
This commit is contained in:
+18
-28
@@ -110,6 +110,10 @@ func getPersistentOptions(existingOptions []model.Option, newOptions []model.Opt
|
||||
func getSubcommandDrivenRecommendation(spec model.Subcommand, persistentOptions []model.Option, partialCmd *commandToken, argsDepleted bool, argsFromSubcommand bool, acceptedTokens []model.ProcessedToken) model.TermSuggestions {
|
||||
suggestions := []model.TermSuggestion{}
|
||||
allOptions := append(spec.Options, persistentOptions...)
|
||||
var partialToken *string = nil
|
||||
if partialCmd != nil {
|
||||
partialToken = &partialCmd.token
|
||||
}
|
||||
|
||||
if argsDepleted && argsFromSubcommand {
|
||||
return model.TermSuggestions{
|
||||
@@ -118,24 +122,15 @@ func getSubcommandDrivenRecommendation(spec model.Subcommand, persistentOptions
|
||||
}
|
||||
if len(spec.Args) != 0 {
|
||||
activeArg := spec.Args[0]
|
||||
getGeneratorDrivenRecommendations(activeArg.Generator, &suggestions)
|
||||
getSuggestionDrivenRecommendations(activeArg.Suggestions, &suggestions)
|
||||
getTemplateDrivenRecommendations(activeArg.Templates, &suggestions)
|
||||
getGeneratorDrivenRecommendations(activeArg.Generator, &suggestions, partialToken, spec.FilterStrategy)
|
||||
getSuggestionDrivenRecommendations(activeArg.Suggestions, &suggestions, partialToken, spec.FilterStrategy)
|
||||
getTemplateDrivenRecommendations(activeArg.Templates, &suggestions, partialToken, spec.FilterStrategy)
|
||||
}
|
||||
if !argsFromSubcommand {
|
||||
getSubcommandDrivenRecommendations(spec, &suggestions)
|
||||
getOptionDrivenRecommendations(allOptions, &suggestions, acceptedTokens)
|
||||
getSubcommandDrivenRecommendations(spec, &suggestions, partialToken, spec.FilterStrategy)
|
||||
getOptionDrivenRecommendations(allOptions, &suggestions, acceptedTokens, partialToken, spec.FilterStrategy)
|
||||
}
|
||||
|
||||
removeDuplicateRecommendation(&suggestions, acceptedTokens)
|
||||
if partialCmd != nil {
|
||||
switch spec.FilterStrategy {
|
||||
case model.FilterStrategyFuzzy:
|
||||
getFuzzyFilteredRecommendations(partialCmd.token, &suggestions)
|
||||
case model.FilterStrategyPrefix, model.FilterStrategyEmpty:
|
||||
getPrefixFilteredRecommendations(partialCmd.token, &suggestions)
|
||||
}
|
||||
}
|
||||
|
||||
return model.TermSuggestions{
|
||||
Suggestions: suggestions,
|
||||
@@ -146,25 +141,20 @@ func getArgDrivenRecommendation(args []model.Arg, spec model.Subcommand, persist
|
||||
suggestions := []model.TermSuggestion{}
|
||||
activeArg := args[0]
|
||||
allOptions := append(spec.Options, persistentOptions...)
|
||||
var partialToken *string = nil
|
||||
if partialCmd != nil {
|
||||
partialToken = &partialCmd.token
|
||||
}
|
||||
|
||||
getGeneratorDrivenRecommendations(activeArg.Generator, &suggestions)
|
||||
getSuggestionDrivenRecommendations(activeArg.Suggestions, &suggestions)
|
||||
getTemplateDrivenRecommendations(activeArg.Templates, &suggestions)
|
||||
getGeneratorDrivenRecommendations(activeArg.Generator, &suggestions, partialToken, activeArg.FilterStrategy)
|
||||
getSuggestionDrivenRecommendations(activeArg.Suggestions, &suggestions, partialToken, activeArg.FilterStrategy)
|
||||
getTemplateDrivenRecommendations(activeArg.Templates, &suggestions, partialToken, activeArg.FilterStrategy)
|
||||
|
||||
if activeArg.IsOptional {
|
||||
getSubcommandDrivenRecommendations(spec, &suggestions)
|
||||
getOptionDrivenRecommendations(allOptions, &suggestions, acceptedTokens)
|
||||
getSubcommandDrivenRecommendations(spec, &suggestions, partialToken, activeArg.FilterStrategy)
|
||||
getOptionDrivenRecommendations(allOptions, &suggestions, acceptedTokens, partialToken, activeArg.FilterStrategy)
|
||||
}
|
||||
|
||||
removeDuplicateRecommendation(&suggestions, acceptedTokens)
|
||||
if partialCmd != nil {
|
||||
switch spec.FilterStrategy {
|
||||
case model.FilterStrategyFuzzy:
|
||||
getFuzzyFilteredRecommendations(partialCmd.token, &suggestions)
|
||||
case model.FilterStrategyPrefix, model.FilterStrategyEmpty:
|
||||
getPrefixFilteredRecommendations(partialCmd.token, &suggestions)
|
||||
}
|
||||
}
|
||||
|
||||
argDescriptionSuggestion := ""
|
||||
if len(suggestions) == 0 {
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
package model
|
||||
|
||||
func (t TermSuggestion) GetName() []string {
|
||||
return []string{t.Name}
|
||||
}
|
||||
|
||||
func (t TermSuggestion) GetDescription() string {
|
||||
return t.Description
|
||||
}
|
||||
|
||||
func (t TermSuggestion) GetType() TermSuggestionType {
|
||||
return t.Type
|
||||
}
|
||||
|
||||
func (o Option) GetName() []string {
|
||||
return o.Name
|
||||
}
|
||||
|
||||
func (o Option) GetDescription() string {
|
||||
return o.Description
|
||||
}
|
||||
|
||||
func (o Option) GetType() TermSuggestionType {
|
||||
return TermSuggestionTypeOption
|
||||
}
|
||||
|
||||
func (s Suggestion) GetName() []string {
|
||||
return s.Name
|
||||
}
|
||||
|
||||
func (s Suggestion) GetDescription() string {
|
||||
return s.Description
|
||||
}
|
||||
|
||||
func (s Suggestion) GetType() TermSuggestionType {
|
||||
return TermSuggestionTypeDefault
|
||||
}
|
||||
|
||||
func (s Subcommand) GetName() []string {
|
||||
return s.Name
|
||||
}
|
||||
|
||||
func (s Subcommand) GetDescription() string {
|
||||
return s.Description
|
||||
}
|
||||
|
||||
func (s Subcommand) GetType() TermSuggestionType {
|
||||
return TermSuggestionTypeSubcommand
|
||||
}
|
||||
+77
-65
@@ -1,7 +1,6 @@
|
||||
package autocomplete
|
||||
|
||||
import (
|
||||
"log"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
@@ -10,97 +9,113 @@ import (
|
||||
"github.com/lithammer/fuzzysearch/fuzzy"
|
||||
)
|
||||
|
||||
type match struct {
|
||||
name string
|
||||
rank int
|
||||
item model.TermSuggestion
|
||||
type matchable interface {
|
||||
GetName() []string
|
||||
GetDescription() string
|
||||
GetType() model.TermSuggestionType
|
||||
}
|
||||
|
||||
func fuzzyMatch(input string, targets []model.TermSuggestion, suggestions *[]model.TermSuggestion) {
|
||||
matchers := []match{}
|
||||
type match[M matchable] struct {
|
||||
name string
|
||||
rank int
|
||||
item M
|
||||
}
|
||||
|
||||
func fuzzyMatch[M matchable](input string, targets []M) []match[M] {
|
||||
matchers := []match[M]{}
|
||||
for _, item := range targets {
|
||||
rank := fuzzy.RankMatch(input, item.Name)
|
||||
if rank != -1 {
|
||||
matchers = append(matchers, match{
|
||||
name: item.Name,
|
||||
bestName := ""
|
||||
bestNameRank := -1
|
||||
for _, name := range item.GetName() {
|
||||
rank := fuzzy.RankMatch(input, name)
|
||||
if rank > bestNameRank {
|
||||
bestName = name
|
||||
bestNameRank = rank
|
||||
}
|
||||
}
|
||||
|
||||
if bestNameRank != -1 {
|
||||
matchers = append(matchers, match[M]{
|
||||
name: bestName,
|
||||
item: item,
|
||||
rank: rank,
|
||||
rank: bestNameRank,
|
||||
})
|
||||
}
|
||||
}
|
||||
sort.Slice(matchers, func(i, j int) bool {
|
||||
return matchers[i].rank > matchers[j].rank
|
||||
})
|
||||
for _, m := range matchers {
|
||||
*suggestions = append(*suggestions, model.TermSuggestion{
|
||||
Name: m.name,
|
||||
Description: m.item.Description,
|
||||
Type: m.item.Type,
|
||||
})
|
||||
}
|
||||
return matchers
|
||||
}
|
||||
|
||||
func getFuzzyFilteredRecommendations(input string, suggestions *[]model.TermSuggestion) {
|
||||
results := []model.TermSuggestion{}
|
||||
fuzzyMatch(input, *suggestions, &results)
|
||||
*suggestions = results
|
||||
}
|
||||
|
||||
func prefixMatch(input string, targets []model.TermSuggestion, suggestions *[]model.TermSuggestion) {
|
||||
func prefixMatch[M matchable](input string, targets []M) []match[M] {
|
||||
matches := []match[M]{}
|
||||
for _, targ := range targets {
|
||||
if strings.HasPrefix(targ.Name, input) {
|
||||
for _, name := range targ.GetName() {
|
||||
if strings.HasPrefix(name, input) {
|
||||
matches = append(matches, match[M]{
|
||||
name: name,
|
||||
item: targ,
|
||||
})
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return matches
|
||||
}
|
||||
|
||||
func filterMatch[M matchable](items []M, suggestions *[]model.TermSuggestion, input *string, filterStrategy model.FilterStrategy) {
|
||||
if input == nil {
|
||||
for _, item := range items {
|
||||
*suggestions = append(*suggestions, model.TermSuggestion{
|
||||
Name: targ.Name,
|
||||
Description: targ.Description,
|
||||
Type: targ.Type,
|
||||
Name: getShortName(item.GetName()),
|
||||
Description: item.GetDescription(),
|
||||
Type: item.GetType(),
|
||||
})
|
||||
}
|
||||
} else {
|
||||
var matches []match[M]
|
||||
switch filterStrategy {
|
||||
case model.FilterStrategyFuzzy:
|
||||
matches = fuzzyMatch[M](*input, items)
|
||||
case model.FilterStrategyEmpty, model.FilterStrategyPrefix:
|
||||
matches = prefixMatch[M](*input, items)
|
||||
}
|
||||
for _, match := range matches {
|
||||
*suggestions = append(*suggestions, model.TermSuggestion{
|
||||
Name: match.name,
|
||||
Description: match.item.GetDescription(),
|
||||
Type: match.item.GetType(),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func getPrefixFilteredRecommendations(input string, suggestions *[]model.TermSuggestion) {
|
||||
results := []model.TermSuggestion{}
|
||||
prefixMatch(input, *suggestions, &results)
|
||||
*suggestions = results
|
||||
}
|
||||
|
||||
func getGeneratorDrivenRecommendations(g *model.Generator, suggestions *[]model.TermSuggestion) {
|
||||
if g != nil {
|
||||
*suggestions = append(*suggestions, generators.Run(*g)...)
|
||||
func getGeneratorDrivenRecommendations(g *model.Generator, suggestions *[]model.TermSuggestion, input *string, filterStrategy model.FilterStrategy) {
|
||||
if g == nil {
|
||||
return
|
||||
}
|
||||
|
||||
filterMatch[model.TermSuggestion](generators.Run(*g), suggestions, input, filterStrategy)
|
||||
}
|
||||
|
||||
func getTemplateDrivenRecommendations(templates []model.Template, suggestions *[]model.TermSuggestion) {
|
||||
*suggestions = append(*suggestions, generators.RunTemplates(templates)...)
|
||||
func getTemplateDrivenRecommendations(templates []model.Template, suggestions *[]model.TermSuggestion, input *string, filterStrategy model.FilterStrategy) {
|
||||
filterMatch[model.TermSuggestion](generators.RunTemplates(templates), suggestions, input, filterStrategy)
|
||||
}
|
||||
|
||||
func getSuggestionDrivenRecommendations(suggestionSet []model.Suggestion, suggestions *[]model.TermSuggestion) {
|
||||
for _, suggestion := range suggestionSet {
|
||||
*suggestions = append(*suggestions, model.TermSuggestion{
|
||||
Name: getLongName(suggestion.Name),
|
||||
Description: suggestion.Description,
|
||||
Type: model.TermSuggestionTypeDefault,
|
||||
})
|
||||
}
|
||||
func getSuggestionDrivenRecommendations(suggestionSet []model.Suggestion, suggestions *[]model.TermSuggestion, input *string, filterStrategy model.FilterStrategy) {
|
||||
filterMatch[model.Suggestion](suggestionSet, suggestions, input, filterStrategy)
|
||||
}
|
||||
|
||||
func getSubcommandDrivenRecommendations(spec model.Subcommand, suggestions *[]model.TermSuggestion) {
|
||||
for _, sub := range spec.Subcommands {
|
||||
*suggestions = append(*suggestions, model.TermSuggestion{
|
||||
Name: getLongName(sub.Name),
|
||||
Description: sub.Description,
|
||||
Type: model.TermSuggestionTypeSubcommand,
|
||||
})
|
||||
}
|
||||
func getSubcommandDrivenRecommendations(spec model.Subcommand, suggestions *[]model.TermSuggestion, input *string, filterStrategy model.FilterStrategy) {
|
||||
filterMatch[model.Subcommand](spec.Subcommands, suggestions, input, filterStrategy)
|
||||
}
|
||||
|
||||
func getOptionDrivenRecommendations(options []model.Option, suggestions *[]model.TermSuggestion, processedTokens []model.ProcessedToken) {
|
||||
log.Println(processedTokens)
|
||||
func getOptionDrivenRecommendations(options []model.Option, suggestions *[]model.TermSuggestion, processedTokens []model.ProcessedToken, input *string, filterStrategy model.FilterStrategy) {
|
||||
usedTokens := make(map[string]struct{})
|
||||
for _, processedToken := range processedTokens {
|
||||
usedTokens[processedToken.Token] = struct{}{}
|
||||
}
|
||||
validOptions := []model.Option{}
|
||||
for _, op := range options {
|
||||
hasBeenExcluded := false
|
||||
for _, exclusiveToken := range op.ExclusiveOn {
|
||||
@@ -111,12 +126,9 @@ func getOptionDrivenRecommendations(options []model.Option, suggestions *[]model
|
||||
if hasBeenExcluded {
|
||||
continue
|
||||
}
|
||||
*suggestions = append(*suggestions, model.TermSuggestion{
|
||||
Name: getShortName(op.Name),
|
||||
Description: op.Description,
|
||||
Type: model.TermSuggestionTypeOption,
|
||||
})
|
||||
validOptions = append(validOptions, op)
|
||||
}
|
||||
filterMatch[model.Option](validOptions, suggestions, input, filterStrategy)
|
||||
}
|
||||
|
||||
func removeDuplicateRecommendation(suggestions *[]model.TermSuggestion, processedTokens []model.ProcessedToken) {
|
||||
|
||||
Reference in New Issue
Block a user