Skip to content

Commit

Permalink
lxc/completion: Add cmpInstanceSetKeys function
Browse files Browse the repository at this point in the history
This commit adds a completion function for completing config keys which
are currently set.

Signed-off-by: Kadin Sayani <[email protected]>
  • Loading branch information
kadinsayani committed Nov 26, 2024
1 parent e2f3e08 commit 63e2d12
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 1 deletion.
47 changes: 47 additions & 0 deletions lxc/completion.go
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,53 @@ func (g *cmdGlobal) cmpInstanceAllKeys(profileName string) ([]string, cobra.Shel
return configKeys, cmpDirectives | cobra.ShellCompDirectiveNoSpace
}

// cmpInstanceSetKeys provides shell completion for instance configuration keys which are currently set.
// It takes an instance name to determine instance type and returns a list of instance configuration keys along with a shell completion directive.
func (g *cmdGlobal) cmpInstanceSetKeys(instanceName string) ([]string, cobra.ShellCompDirective) {
cmpDirectives := cobra.ShellCompDirectiveNoFileComp

// Early return when completing server keys.
_, instanceNameOnly, found := strings.Cut(instanceName, ":")
if instanceNameOnly == "" && found {
return g.cmpServerAllKeys(instanceName)
}

resources, err := g.ParseServers(instanceName)
if err != nil || len(resources) == 0 {
return nil, cobra.ShellCompDirectiveError
}

resource := resources[0]
client := resource.server

instance, _, err := client.GetInstance(instanceName)
if err != nil {
return nil, cobra.ShellCompDirectiveError
}

// Pre-allocate configKeys slice capacity.
keyCount := len(instance.Config)

// Fetch all config keys that can be set by a user.
allInstanceConfigKeys, _ := g.cmpInstanceAllKeys(instanceName)

// Convert slice to map[string]struct{} for O(1) lookups.
keySet := make(map[string]struct{}, len(allInstanceConfigKeys))
for _, key := range allInstanceConfigKeys {
keySet[key] = struct{}{}
}

configKeys := make([]string, 0, keyCount)
for configKey := range instance.Config {
// We only want to return the intersection between allInstanceConfigKeys and configKeys to avoid returning the full instance config.
if _, exists := keySet[configKey]; exists {
configKeys = append(configKeys, configKey)
}
}

return configKeys, cmpDirectives | cobra.ShellCompDirectiveNoSpace
}

// cmpServerAllKeys provides shell completion for all server configuration keys.
// It takes an instance name and returns a list of all server configuration keys along with a shell completion directive.
func (g *cmdGlobal) cmpServerAllKeys(instanceName string) ([]string, cobra.ShellCompDirective) {
Expand Down
3 changes: 2 additions & 1 deletion lxc/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -918,7 +918,8 @@ func (c *cmdConfigUnset) command() *cobra.Command {
}

if len(args) == 1 {
return c.global.cmpInstanceKeys(args[0])
// Only complete config keys which are currently set.
return c.global.cmpInstanceSetKeys(args[0])
}

return nil, cobra.ShellCompDirectiveNoFileComp
Expand Down

0 comments on commit 63e2d12

Please sign in to comment.