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:
Sebastian UnterschützandClaude Opus 5.5 committed 2026-10-28 11:22:18 +01:00
1 parent 7f53b90266
commit 8fb7633783
5 files changed
+172 -18

No files matched your search

+21 -8
View File
@@ -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")