99 lines
2.9 KiB
Go
99 lines
2.9 KiB
Go
package commandkit
|
|
|
|
import (
|
|
"sort"
|
|
|
|
commandmeta "gitea.maximumdirect.net/eric/CommandKit/internal/commandmeta"
|
|
"gitea.maximumdirect.net/eric/CommandKit/internal/commandpath"
|
|
)
|
|
|
|
func (a *App) helpView(route routeResult, snapshot *routingSnapshot) commandmeta.HelpView {
|
|
view := commandmeta.HelpView{
|
|
EnteredPath: clonePath(route.enteredPath),
|
|
CanonicalPath: clonePath(route.canonicalPath),
|
|
Discovery: route.kind == routeDiscovery,
|
|
}
|
|
if snapshot == nil {
|
|
return view
|
|
}
|
|
if view.Discovery {
|
|
view.CommandAliases = discoveryHelpAliases(snapshot.commandAliases, route.discoveryPath)
|
|
view.FlagAliases = snapshot.discoveryFlags[route.discoveryPath.Key()].neutralRecords()
|
|
return view
|
|
}
|
|
view.FlagAliases = snapshot.flagAliases[route.canonicalPath.Key()].neutralRecords()
|
|
view.CommandAliases = routeHelpAliases(snapshot, route)
|
|
return view
|
|
}
|
|
|
|
func clonePath(path commandpath.Path) []string {
|
|
return append([]string(nil), path...)
|
|
}
|
|
|
|
func discoveryHelpAliases(aliases []commandmeta.CommandAlias, prefix commandpath.Path) []commandmeta.CommandAlias {
|
|
var result []commandmeta.CommandAlias
|
|
for _, alias := range aliases {
|
|
source := commandpath.FromTokens(alias.Source)
|
|
if len(source) <= len(prefix) || !source.HasPrefix(prefix) {
|
|
continue
|
|
}
|
|
result = append(result, commandmeta.CommandAlias{
|
|
Source: clonePath(source[len(prefix):]),
|
|
Target: append([]string(nil), alias.Target...),
|
|
})
|
|
}
|
|
return result
|
|
}
|
|
|
|
func routeHelpAliases(snapshot *routingSnapshot, route routeResult) []commandmeta.CommandAlias {
|
|
if len(route.canonicalPath) == 0 {
|
|
return append([]commandmeta.CommandAlias(nil), snapshot.commandAliases...)
|
|
}
|
|
node := traceCanonicalPath(snapshot.canonical, route.canonicalPath).exact
|
|
if node == nil || len(node.children) == 0 {
|
|
return nil
|
|
}
|
|
|
|
entered := route.enteredPath
|
|
canonical := route.canonicalPath
|
|
bySource := make(map[string]commandmeta.CommandAlias)
|
|
add := func(base commandpath.Path, includeOnlyWhenReached bool) {
|
|
for _, alias := range snapshot.commandAliases {
|
|
source := commandpath.FromTokens(alias.Source)
|
|
if len(source) <= len(base) || !source.HasPrefix(base) {
|
|
continue
|
|
}
|
|
suffix := source[len(base):]
|
|
if includeOnlyWhenReached {
|
|
enteredSource := append(entered.Clone(), suffix...)
|
|
if !snapshot.aliases.Resolve(enteredSource).Equal(commandpath.FromTokens(alias.Target)) {
|
|
continue
|
|
}
|
|
}
|
|
key := commandpath.FromTokens(suffix).Key()
|
|
if _, exists := bySource[key]; exists {
|
|
continue
|
|
}
|
|
bySource[key] = commandmeta.CommandAlias{
|
|
Source: clonePath(suffix),
|
|
Target: append([]string(nil), alias.Target...),
|
|
}
|
|
}
|
|
}
|
|
add(entered, false)
|
|
if !entered.Equal(canonical) {
|
|
add(canonical, true)
|
|
}
|
|
|
|
keys := make([]string, 0, len(bySource))
|
|
for key := range bySource {
|
|
keys = append(keys, key)
|
|
}
|
|
sort.Strings(keys)
|
|
result := make([]commandmeta.CommandAlias, 0, len(keys))
|
|
for _, key := range keys {
|
|
result = append(result, bySource[key])
|
|
}
|
|
return result
|
|
}
|