From ccd2346960a76672ebe750b5e12efa4903c92da1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 15 Nov 2023 16:35:37 +0800 Subject: [PATCH] fastfetch: initial commit --- completers/fastfetch_completer/cmd/root.go | 133 +++++++++++++++++++++ completers/fastfetch_completer/main.go | 7 ++ 2 files changed, 140 insertions(+) create mode 100644 completers/fastfetch_completer/cmd/root.go create mode 100644 completers/fastfetch_completer/main.go diff --git a/completers/fastfetch_completer/cmd/root.go b/completers/fastfetch_completer/cmd/root.go new file mode 100644 index 0000000000..265a2c847b --- /dev/null +++ b/completers/fastfetch_completer/cmd/root.go @@ -0,0 +1,133 @@ +package cmd + +import ( + "os/exec" + "regexp" + "strings" + + "github.com/rsteube/carapace" + "github.com/rsteube/carapace/pkg/style" + "github.com/spf13/cobra" +) + +var rootCmd = &cobra.Command{ + Use: "fastfetch", + Short: "A neofetch-like tool for fetching system information and displaying them in a pretty way", + Long: "https://github.com/fastfetch-cli/fastfetch", + Run: func(cmd *cobra.Command, args []string) {}, +} + +func Execute() error { + return rootCmd.Execute() +} +func init() { + carapace.Gen(rootCmd).Standalone() + var lines []string; + if out, err := exec.Command("fastfetch", "--help").Output(); err == nil { + lines = map_( + filter( + strings.Split(string(out), "\n"), + func(s string) bool { return strings.HasPrefix(s, " -") }, + ), + func(s string) string { return s[4:] }, + ) + } + + re, _ := regexp.Compile(`<\??\w+>$`) + for _, line := range lines { + kv := strings.SplitN(line, ":", 2) + if len(kv) != 2 { + continue + } + left := strings.Trim(kv[0], " ") + right := strings.Trim(kv[1], " ") + + if left == "" || strings.HasPrefix(left, "--<") { // ignore ---* + continue + } + type_ := "" + + if typeLoc := re.FindStringIndex(left); typeLoc != nil { + type_ = strings.TrimLeft(left[typeLoc[0] + 1:typeLoc[1] - 1], "?") + left = strings.TrimRight(left[:typeLoc[0]], " ") + } + + args := map_(strings.Split(left, ","), func(s string) string { return strings.Trim(s, "- ") }) + + switch type_ { + case "bool": + if len(args) == 1 { // long only + rootCmd.Flags().Bool(args[0], false, right) + } else { // short, long + rootCmd.Flags().BoolP(args[1], args[0], false, right) + } + + case "num": + if len(args) == 1 { // long only + rootCmd.Flags().Int(args[0], 0, right) + } else { // short, long + rootCmd.Flags().IntP(args[1], args[0], 0, right) + } + + default: + if len(args) == 1 { // long only + rootCmd.Flags().String(args[0], "", right) + } else { // short, long + rootCmd.Flags().StringP(args[1], args[0], "", right) + } + } + } + + var modules []string + if out, err := exec.Command("fastfetch", "--list-modules").Output(); err == nil { + modules = map_( + strings.Split(strings.TrimRight(string(out), "\n"), "\n"), + func(s string) string { return strings.ToLower(s[4:]) }, + ) + } + + var presets []string + if out, err := exec.Command("fastfetch", "--list-presets", "false").Output(); err == nil { + presets = strings.Split(strings.TrimRight(string(out), "\n"), "\n") + } + + var builtinLogos []string + if out, err := exec.Command("fastfetch", "--list-logos-autocompletion").Output(); err == nil { + builtinLogos = strings.Split(strings.TrimRight(string(out), "\n"), "\n") + } + + actionColors := carapace.ActionValues( + "black", "red", "green", "yellow", "blue", "magenta", "cyan", "white", "default", + ) + carapace.Gen(rootCmd).FlagCompletion(carapace.ActionMap{ + "help": carapace.ActionValues(append([]string{"color", "format", "config"}, modules...)...).StyleF(style.ForKeyword), + "config": carapace.ActionValues(presets...), + "logo": carapace.ActionValues(append([]string{"none, small"}, builtinLogos...)...).StyleF(style.ForKeyword), + "structure": carapace.ActionValues(modules...).StyleF(style.ForKeyword), + "color-keys": actionColors, + "color-title": actionColors, + "color": actionColors, + "title-color-user": actionColors, + "title-color-at": actionColors, + "title-color-host": actionColors, + }) + + carapace.Gen(rootCmd).PositionalAnyCompletion( + carapace.ActionDirectories(), + )} + +func filter[T any](ss []T, test func(T) bool) (ret []T) { + for _, s := range ss { + if test(s) { + ret = append(ret, s) + } + } + return +} + +func map_[T any, U any](ss []T, f func(T) U) (ret []U) { + for _, s := range ss { + ret = append(ret, f(s)) + } + return +} diff --git a/completers/fastfetch_completer/main.go b/completers/fastfetch_completer/main.go new file mode 100644 index 0000000000..94ebbcbd39 --- /dev/null +++ b/completers/fastfetch_completer/main.go @@ -0,0 +1,7 @@ +package main + +import "github.com/rsteube/carapace-bin/completers/fastfetch_completer/cmd" + +func main() { + cmd.Execute() +}