This commit is contained in:
1 parent
14d519d010
commit
34503de68e
7 files changed
+319
-1
No files matched your search
@@ -0,0 +1,116 @@
|
||||
package hook
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"git.zb-server.de/Sebi/ssh-netbox-wrapper/internal/config"
|
||||
"git.zb-server.de/Sebi/ssh-netbox-wrapper/internal/storage"
|
||||
)
|
||||
|
||||
const completionMarker = "# netssh command alias completion — generated automatically"
|
||||
|
||||
// SyncCommandCompletion installs lazy loaders for the configured command alias.
|
||||
// The loaders obtain the canonical completion from the current netssh binary,
|
||||
// so aliases configured by the wizard work without a separate completion install.
|
||||
func SyncCommandCompletion(alias string) error {
|
||||
if err := config.ValidateCommandAlias(alias); err != nil {
|
||||
return err
|
||||
}
|
||||
statePath := filepath.Join(filepath.Dir(AliasesPath()), "completion_alias")
|
||||
data, err := os.ReadFile(statePath)
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
previous := strings.TrimSpace(string(data))
|
||||
if err := config.ValidateCommandAlias(previous); err != nil {
|
||||
return fmt.Errorf("invalid completion alias state: %w", err)
|
||||
}
|
||||
if alias == "" && previous == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, shell := range []string{"bash", "zsh", "fish"} {
|
||||
if previous != "" && previous != alias {
|
||||
path := commandCompletionPath(shell, previous)
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
// Only delete files owned by netssh; preserve any user replacements.
|
||||
if strings.HasPrefix(string(data), completionMarker+"\n") || strings.HasPrefix(string(data), "#compdef "+previous+"\n"+completionMarker+"\n") {
|
||||
if err := os.Remove(path); err != nil && !os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
if alias == "" {
|
||||
continue
|
||||
}
|
||||
if shell == "fish" {
|
||||
if _, err := os.Stat(FishConfigDir()); os.IsNotExist(err) {
|
||||
continue
|
||||
} else if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
path := commandCompletionPath(shell, alias)
|
||||
script := commandCompletionScript(shell, alias)
|
||||
existing, err := os.ReadFile(path)
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
if string(existing) == script {
|
||||
continue
|
||||
}
|
||||
if err := storage.WriteFile(path, []byte(script), 0o644); err != nil {
|
||||
return fmt.Errorf("writing %s alias completion: %w", shell, err)
|
||||
}
|
||||
}
|
||||
if alias == "" {
|
||||
if err := os.Remove(statePath); err != nil && !os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return storage.WriteFile(statePath, []byte(alias+"\n"), 0o600)
|
||||
}
|
||||
|
||||
func commandCompletionPath(shell, alias string) string {
|
||||
switch shell {
|
||||
case "bash":
|
||||
return filepath.Join(os.Getenv("HOME"), ".local", "share", "bash-completion", "completions", alias)
|
||||
case "zsh":
|
||||
return filepath.Join(os.Getenv("HOME"), ".zfunc", "_"+alias)
|
||||
default:
|
||||
return filepath.Join(FishConfigDir(), "completions", alias+".fish")
|
||||
}
|
||||
}
|
||||
|
||||
func commandCompletionScript(shell, alias string) string {
|
||||
switch shell {
|
||||
case "bash":
|
||||
return fmt.Sprintf(`%s
|
||||
source <(netssh completion bash)
|
||||
if [[ $(type -t compopt) == builtin ]]; then
|
||||
complete -o default -F __start_netssh %s
|
||||
else
|
||||
complete -o default -o nospace -F __start_netssh %s
|
||||
fi
|
||||
`, completionMarker, alias, alias)
|
||||
case "zsh":
|
||||
return fmt.Sprintf(`#compdef %s
|
||||
%s
|
||||
source <(netssh completion zsh)
|
||||
compdef _netssh %s
|
||||
_netssh "$@"
|
||||
`, alias, completionMarker, alias)
|
||||
default:
|
||||
return fmt.Sprintf(`%s
|
||||
netssh completion fish | source
|
||||
complete --command %s --wraps netssh
|
||||
`, completionMarker, alias)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user