Index completion metadata by canonical node
This commit is contained in:
@@ -26,7 +26,7 @@ func resolveCompletionContext(snapshot *routingSnapshot, completed []string, cur
|
|||||||
context.route = resolveEnteredRoute(completed, snapshot)
|
context.route = resolveEnteredRoute(completed, snapshot)
|
||||||
switch context.route.kind {
|
switch context.route.kind {
|
||||||
case routeCanonical:
|
case routeCanonical:
|
||||||
context.command = completionCommand(snapshot.metadata, context.route.canonicalPath)
|
context.command = completionCommand(snapshot, context.route.canonicalPath)
|
||||||
if context.command == nil || len(context.route.args) < len(context.route.canonicalPath) {
|
if context.command == nil || len(context.route.args) < len(context.route.canonicalPath) {
|
||||||
context.command = nil
|
context.command = nil
|
||||||
return context
|
return context
|
||||||
@@ -42,22 +42,20 @@ func resolveCompletionContext(snapshot *routingSnapshot, completed []string, cur
|
|||||||
return context
|
return context
|
||||||
}
|
}
|
||||||
|
|
||||||
func completionCommand(root *commandmeta.Command, path commandpath.Path) *commandmeta.Command {
|
func completionCommand(snapshot *routingSnapshot, path commandpath.Path) *commandmeta.Command {
|
||||||
current := root
|
if len(path) == 0 {
|
||||||
|
return snapshot.metadata
|
||||||
|
}
|
||||||
|
children := snapshot.canonical
|
||||||
|
var node *canonicalNode
|
||||||
for _, name := range path {
|
for _, name := range path {
|
||||||
if current == nil {
|
node = children[name]
|
||||||
|
if node == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
var next *commandmeta.Command
|
children = node.children
|
||||||
for _, child := range current.Children {
|
|
||||||
if child.Name == name {
|
|
||||||
next = child
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
current = next
|
|
||||||
}
|
}
|
||||||
return current
|
return node.metadata
|
||||||
}
|
}
|
||||||
|
|
||||||
func completionChildren(snapshot *routingSnapshot, context completionContext) []commandmeta.CompletionChoice {
|
func completionChildren(snapshot *routingSnapshot, context completionContext) []commandmeta.CompletionChoice {
|
||||||
|
|||||||
@@ -73,6 +73,10 @@ func TestCompletionQueryDispatch(t *testing.T) {
|
|||||||
if outcome := app.Execute(context.Background(), []string{"__complete", "lat"}, Streams{Out: &output}); outcome.Status != 0 || !strings.Contains(output.String(), "later") {
|
if outcome := app.Execute(context.Background(), []string{"__complete", "lat"}, Streams{Out: &output}); outcome.Status != 0 || !strings.Contains(output.String(), "later") {
|
||||||
t.Fatalf("later command outcome=%#v reply=%q", outcome, output.String())
|
t.Fatalf("later command outcome=%#v reply=%q", outcome, output.String())
|
||||||
}
|
}
|
||||||
|
output.Reset()
|
||||||
|
if outcome := app.Execute(context.Background(), []string{"__complete", "later", "--qui"}, Streams{Out: &output}); outcome.Status != 0 || !strings.Contains(output.String(), "--quiet") {
|
||||||
|
t.Fatalf("later command flag outcome=%#v reply=%q", outcome, output.String())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCompletionQueryErrorsAndDelivery(t *testing.T) {
|
func TestCompletionQueryErrorsAndDelivery(t *testing.T) {
|
||||||
|
|||||||
@@ -169,7 +169,9 @@ the remaining scope. The six existing findings remain open.
|
|||||||
|
|
||||||
### 7. Look up canonical completion metadata without scanning siblings
|
### 7. Look up canonical completion metadata without scanning siblings
|
||||||
|
|
||||||
Priority: P3. Status: for consideration.
|
Priority: P3. Status: complete.
|
||||||
|
|
||||||
|
- [x] Completed: Canonical snapshot nodes now hold their neutral metadata. Completion uses one map lookup per path component; root, nested and alias context checks and a late-registration leaf query pass.
|
||||||
|
|
||||||
[completionCommand](../../completion_context.go) searches the metadata child
|
[completionCommand](../../completion_context.go) searches the metadata child
|
||||||
slice at every component of an already resolved canonical path. For depth
|
slice at every component of an already resolved canonical path. For depth
|
||||||
|
|||||||
@@ -99,13 +99,13 @@ func (a *App) buildRoutingSnapshot() *routingSnapshot {
|
|||||||
sort.Strings(names)
|
sort.Strings(names)
|
||||||
var key commandmeta.Key
|
var key commandmeta.Key
|
||||||
for _, name := range names {
|
for _, name := range names {
|
||||||
root.Children = append(root.Children, bridgeCommand(a.commands[name].command, snapshot, &key))
|
root.Children = append(root.Children, bridgeCommand(snapshot.canonical[name], snapshot, &key))
|
||||||
}
|
}
|
||||||
return snapshot
|
return snapshot
|
||||||
}
|
}
|
||||||
|
|
||||||
func bridgeCommand(command Command, snapshot *routingSnapshot, next *commandmeta.Key) *commandmeta.Command {
|
func bridgeCommand(node *canonicalNode, snapshot *routingSnapshot, next *commandmeta.Key) *commandmeta.Command {
|
||||||
record := command.record
|
record := node.command.record
|
||||||
*next = *next + 1
|
*next = *next + 1
|
||||||
declaration := &commandmeta.Command{
|
declaration := &commandmeta.Command{
|
||||||
Key: *next,
|
Key: *next,
|
||||||
@@ -114,6 +114,7 @@ func bridgeCommand(command Command, snapshot *routingSnapshot, next *commandmeta
|
|||||||
Description: record.description,
|
Description: record.description,
|
||||||
CoreFlags: commandmeta.ReportingFlags(),
|
CoreFlags: commandmeta.ReportingFlags(),
|
||||||
}
|
}
|
||||||
|
node.metadata = declaration
|
||||||
if record.payload != nil {
|
if record.payload != nil {
|
||||||
snapshot.runners[declaration.Key] = record.payload
|
snapshot.runners[declaration.Key] = record.payload
|
||||||
declaration.Runnable = record.payload.hasRun()
|
declaration.Runnable = record.payload.hasRun()
|
||||||
@@ -126,7 +127,7 @@ func bridgeCommand(command Command, snapshot *routingSnapshot, next *commandmeta
|
|||||||
if child.record == nil || child.record.absent {
|
if child.record == nil || child.record.absent {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
declaration.Children = append(declaration.Children, bridgeCommand(child, snapshot, next))
|
declaration.Children = append(declaration.Children, bridgeCommand(node.children[child.record.name], snapshot, next))
|
||||||
}
|
}
|
||||||
return declaration
|
return declaration
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
|
|
||||||
internalalias "gitea.maximumdirect.net/eric/CommandKit/internal/alias"
|
internalalias "gitea.maximumdirect.net/eric/CommandKit/internal/alias"
|
||||||
internalcobra "gitea.maximumdirect.net/eric/CommandKit/internal/cobra"
|
internalcobra "gitea.maximumdirect.net/eric/CommandKit/internal/cobra"
|
||||||
|
"gitea.maximumdirect.net/eric/CommandKit/internal/commandmeta"
|
||||||
"gitea.maximumdirect.net/eric/CommandKit/internal/commandpath"
|
"gitea.maximumdirect.net/eric/CommandKit/internal/commandpath"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -31,6 +32,7 @@ type installationCandidate struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type canonicalNode struct {
|
type canonicalNode struct {
|
||||||
|
metadata *commandmeta.Command
|
||||||
command Command
|
command Command
|
||||||
path commandpath.Path
|
path commandpath.Path
|
||||||
children map[string]*canonicalNode
|
children map[string]*canonicalNode
|
||||||
|
|||||||
Reference in New Issue
Block a user