Render help through command aliases
This commit is contained in:
98
help_view.go
Normal file
98
help_view.go
Normal file
@@ -0,0 +1,98 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user