feat(completion): fast zsh completion for large host caches
Cobra's generated zsh script spawns a subshell per candidate and sends every host through _describe, so <Tab> hangs for seconds with thousands of cached hosts. netssh now ships its own script: subcommands and flags go through _describe, plain hostnames through compadd. 5000 hosts complete in ~0.08 s instead of ~4 s. Add completion.max_results to cap the number of offered hostnames and sort host candidates for a stable order. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
7f53b90266
commit
8fb7633783
5 files changed
+172
-18
No files matched your search
+21
-8
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
@@ -311,8 +312,13 @@ func rootCmd() *cobra.Command {
|
||||
c := cache.New(cfg.CachePath(), cfg.Cache.TTL)
|
||||
_ = c.Load()
|
||||
|
||||
var completions []cobra.Completion
|
||||
for _, e := range c.Search(toComplete) {
|
||||
hosts := c.Search(toComplete)
|
||||
sort.Slice(hosts, func(i, j int) bool { return hosts[i].Name < hosts[j].Name })
|
||||
if limit := cfg.Completion.MaxResults; limit > 0 && len(hosts) > limit {
|
||||
hosts = hosts[:limit]
|
||||
}
|
||||
completions := make([]cobra.Completion, 0, len(hosts))
|
||||
for _, e := range hosts {
|
||||
completions = append(completions, cobra.Completion(e.Name))
|
||||
}
|
||||
// Subcommands at the end, after all hostnames.
|
||||
@@ -332,6 +338,17 @@ func rootCmd() *cobra.Command {
|
||||
for _, cmd := range root.Commands() {
|
||||
if cmd.Name() == "completion" {
|
||||
cmd.AddCommand(completionInstallCmd(root))
|
||||
// Cobra's zsh script spawns a subshell per line and sends every host
|
||||
// through _describe, which hangs with thousands of cached hosts.
|
||||
for _, sub := range cmd.Commands() {
|
||||
if sub.Name() == "zsh" {
|
||||
sub.RunE = func(cmd *cobra.Command, args []string) error {
|
||||
_, err := io.WriteString(cmd.OutOrStdout(), hook.ZshCompletionScript)
|
||||
return err
|
||||
}
|
||||
sub.Run = nil
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -369,12 +386,8 @@ func completionInstallCmd(root *cobra.Command) *cobra.Command {
|
||||
case "zsh":
|
||||
dir = filepath.Join(os.Getenv("HOME"), ".zfunc")
|
||||
file = filepath.Join(dir, "_netssh")
|
||||
gen = func() ([]byte, error) {
|
||||
var buf strings.Builder
|
||||
err := root.GenZshCompletion(&buf)
|
||||
return []byte(buf.String()), err
|
||||
}
|
||||
note = "Make sure ~/.zfunc is in your fpath:\n fpath=(~/.zfunc $fpath)\n autoload -Uz compinit && compinit"
|
||||
gen = func() ([]byte, error) { return []byte(hook.ZshCompletionScript), nil }
|
||||
note = hook.ZshCompletionNote(dir)
|
||||
case "fish":
|
||||
dir = filepath.Join(hook.FishConfigDir(), "completions")
|
||||
file = filepath.Join(dir, "netssh.fish")
|
||||
|
||||
Reference in new issue
Block a user