golang命令行参数自动补全生成插件库carapace的使用

golang命令行参数自动补全生成插件库carapace的使用

简介

Carapace 是一个为 Cobra 命令行工具生成参数自动补全的库。它支持多种 shell 环境,包括:

  • Bash
  • Cmd (实验性)
  • Elvish
  • Fish
  • Ion (实验性)
  • Nushell
  • Oil
  • Powershell
  • Tcsh (实验性)
  • Xonsh
  • Zsh

快速开始

安装

import "github.com/carapace-sh/carapace"

基本示例

下面是一个使用 Carapace 为 Cobra 命令添加自动补全功能的完整示例:

package main

import (
	"github.com/carapace-sh/carapace"
	"github.com/carapace-sh/carapace-bin/pkg/actions/tools/git"
	"github.com/spf13/cobra"
)

func main() {
	var rootCmd = &cobra.Command{
		Use:   "mygit",
		Short: "A simple git-like command with autocompletion",
	}

	var checkoutCmd = &cobra.Command{
		Use:   "checkout",
		Short: "Checkout a branch",
		Run: func(cmd *cobra.Command, args []string) {
			// 命令逻辑
		},
	}

	// 为checkout命令添加自动补全
	carapace.Gen(checkoutCmd).PositionalCompletion(
		git.ActionBranches(), // 自动补全git分支
	)

	rootCmd.AddCommand(checkoutCmd)
	rootCmd.Execute()
}

更复杂的示例

package main

import (
	"fmt"
	"os"

	"github.com/carapace-sh/carapace"
	"github.com/carapace-sh/carapace-bin/pkg/actions"
	"github.com/carapace-sh/carapace-bin/pkg/actions/os"
	"github.com/carapace-sh/carapace/pkg/style"
	"github.com/spf13/cobra"
)

func main() {
	var rootCmd = &cobra.Command{
		Use:   "demo",
		Short: "Demo command with advanced autocompletion",
	}

	var fileCmd = &cobra.Command{
		Use:   "file",
		Short: "File operations",
	}

	var editCmd = &cobra.Command{
		Use:   "edit",
		Short: "Edit a file",
		Run: func(cmd *cobra.Command, args []string) {
			fmt.Printf("Editing file: %v\n", args)
		},
	}

	// 为edit命令添加文件自动补全
	carapace.Gen(editCmd).PositionalCompletion(
		carapace.ActionFiles().Style(style.Blue), // 蓝色显示文件
	)

	var userCmd = &cobra.Command{
		Use:   "user",
		Short: "User operations",
	}

	var listCmd = &cobra.Command{
		Use:   "list",
		Short: "List users",
		Run: func(cmd *cobra.Command, args []string) {
			fmt.Println("Listing users...")
		},
	}

	// 为list命令添加用户自动补全
	carapace.Gen(listCmd).PositionalCompletion(
		os.ActionUsers().Style(style.Red), // 红色显示用户
	)

	fileCmd.AddCommand(editCmd)
	userCmd.AddCommand(listCmd)
	rootCmd.AddCommand(fileCmd, userCmd)

	if err := rootCmd.Execute(); err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
}

支持的补全类型

Carapace 提供了多种内置的补全动作,例如:

  • ActionFiles() - 文件系统补全
  • ActionDirectories() - 目录补全
  • ActionValues() - 静态值补全
  • git.ActionBranches() - Git分支补全
  • os.ActionUsers() - 系统用户补全

自定义补全

你可以创建自定义补全动作:

carapace.Gen(myCmd).PositionalCompletion(
	carapace.ActionCallback(func(c carapace.Context) carapace.Action {
		// 自定义补全逻辑
		return carapace.ActionValues("value1", "value2", "value3")
	}),
)

样式设置

可以为补全值设置样式:

carapace.ActionValues(
	"success",
	"warning",
	"danger",
).StyleF(func(s string, sc style.Context) string {
	switch s {
	case "success":
		return style.Green
	case "warning":
		return style.Yellow
	case "danger":
		return style.Red
	default:
		return style.Default
	}
})

通过以上示例,你可以快速为你的 Golang 命令行工具添加强大的自动补全功能。


更多关于golang命令行参数自动补全生成插件库carapace的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang命令行参数自动补全生成插件库carapace的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


使用Carapace实现Golang命令行参数自动补全

Carapace是一个强大的Golang库,用于为命令行应用程序生成自动补全功能。它支持bash、zsh、fish和powershell等多种shell,并且与cobra、urfave/cli等流行CLI框架集成良好。

安装Carapace

首先安装Carapace库:

go get github.com/rsteube/carapace

基本用法

1. 独立使用Carapace

下面是一个简单的独立使用Carapace的例子:

package main

import (
	"fmt"
	"os"

	"github.com/rsteube/carapace"
)

func main() {
	rootCmd := &carapace.Command{
		Use: "myapp",
		Run: func(cmd *carapace.Command, args []string) {},
	}

	// 添加子命令
	rootCmd.AddCommand(&carapace.Command{
		Use: "greet",
		Run: func(cmd *carapace.Command, args []string) {
			fmt.Println("Hello,", args[0])
		},
		Args: carapace.Arg{
			"name": carapace.ActionValues("Alice", "Bob", "Charlie"),
		},
	})

	// 执行命令
	if err := rootCmd.Execute(); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
}

2. 与Cobra集成

Carapace与Cobra框架集成非常方便:

package main

import (
	"fmt"
	"os"

	"github.com/rsteube/carapace-bin/pkg/actions/tools/git"
	"github.com/rsteube/carapace-bridge/pkg/actions/bridge"
	"github.com/spf13/cobra"
)

func main() {
	rootCmd := &cobra.Command{
		Use:   "git-wrapper",
		Short: "A git wrapper with autocompletion",
		Run: func(cmd *cobra.Command, args []string) {
			fmt.Println("Running git with args:", args)
		},
	}

	// 添加子命令
	cloneCmd := &cobra.Command{
		Use:   "clone",
		Short: "Clone a repository",
		Run: func(cmd *cobra.Command, args []string) {
			fmt.Println("Cloning repository:", args[0])
		},
	}
	rootCmd.AddCommand(cloneCmd)

	// 为clone命令添加自动补全
	carapace.Gen(cloneCmd).PositionalCompletion(
		git.ActionRepositorySearch(git.SearchOpts{}.Default()),
	)

	// 为根命令添加自动补全
	carapace.Gen(rootCmd).PositionalAnyCompletion(
		bridge.ActionCarapaceBin("git"),
	)

	if err := rootCmd.Execute(); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
}

高级功能

1. 自定义补全动作

package main

import (
	"github.com/rsteube/carapace"
	"github.com/rsteube/carapace/pkg/style"
)

func main() {
	rootCmd := &carapace.Command{
		Use: "file",
		Run: func(cmd *carapace.Command, args []string) {},
	}

	rootCmd.Flags().String("color", "", "color option")
	carapace.Gen(rootCmd).FlagCompletion(carapace.ActionMap{
		"color": carapace.ActionStyledValues(
			"red", style.Red,
			"green", style.Green,
			"blue", style.Blue,
		),
	})

	rootCmd.Execute()
}

2. 动态补全

package main

import (
	"github.com/rsteube/carapace"
	"github.com/rsteube/carapace/pkg/cache"
)

func main() {
	rootCmd := &carapace.Command{
		Use: "dynamic",
		Run: func(cmd *carapace.Command, args []string) {},
	}

	rootCmd.Flags().String("env", "", "environment variable")
	carapace.Gen(rootCmd).FlagCompletion(carapace.ActionMap{
		"env": carapace.ActionCallback(func(c carapace.Context) carapace.Action {
			// 动态获取环境变量列表
			envs := make([]string, 0)
			for _, env := range os.Environ() {
				envs = append(envs, strings.Split(env, "=")[0])
			}
			return carapace.ActionValues(envs...)
		}),
	})

	rootCmd.Execute()
}

3. 使用缓存提高性能

package main

import (
	"github.com/rsteube/carapace"
	"github.com/rsteube/carapace/pkg/cache"
)

func main() {
	rootCmd := &carapace.Command{
		Use: "cached",
		Run: func(cmd *carapace.Command, args []string) {},
	}

	rootCmd.Flags().String("user", "", "system user")
	carapace.Gen(rootCmd).FlagCompletion(carapace.ActionMap{
		"user": carapace.ActionCallback(func(c carapace.Context) carapace.Action {
			return carapace.ActionExecCommand("sh", "-c", "cut -d: -f1 /etc/passwd")(func(output []byte) carapace.Action {
				users := strings.Split(string(output), "\n")
				return carapace.ActionValues(users[:len(users)-1]...)
			})
		}).Cache(24*time.Hour, cache.File("/tmp/users_cache")),
	})

	rootCmd.Execute()
}

生成补全脚本

安装补全脚本到系统中:

package main

import (
	"github.com/rsteube/carapace"
	"github.com/rsteube/carapace-bin/pkg/actions/tools/carapace"
)

func main() {
	rootCmd := &carapace.Command{
		Use: "myapp",
		Run: func(cmd *carapace.Command, args []string) {},
	}

	// 添加生成补全脚本的子命令
	rootCmd.AddCommand(&carapace.Command{
		Use:   "completion [bash|zsh|fish|powershell]",
		Short: "Generate completion script",
		Args:  carapace.ActionValues("bash", "zsh", "fish", "powershell"),
		Run: func(cmd *carapace.Command, args []string) {
			switch args[0] {
			case "bash":
				cmd.Root().GenBashCompletion(os.Stdout)
			case "zsh":
				cmd.Root().GenZshCompletion(os.Stdout)
			case "fish":
				cmd.Root().GenFishCompletion(os.Stdout, true)
			case "powershell":
				cmd.Root().GenPowerShellCompletion(os.Stdout)
			}
		},
	})

	rootCmd.Execute()
}

实际应用示例

下面是一个更完整的示例,展示如何创建一个具有丰富自动补全功能的CLI工具:

package main

import (
	"fmt"
	"os"
	"strings"

	"github.com/rsteube/carapace"
	"github.com/rsteube/carapace-bin/pkg/actions/os"
	"github.com/rsteube/carapace-bin/pkg/actions/ps"
	"github.com/rsteube/carapace-bin/pkg/actions/time"
	"github.com/rsteube/carapace/pkg/style"
)

func main() {
	rootCmd := &carapace.Command{
		Use:   "sysinfo",
		Short: "A system information tool with autocompletion",
		Run: func(cmd *carapace.Command, args []string) {
			fmt.Println("System information tool")
		},
	}

	// 添加process子命令
	processCmd := &carapace.Command{
		Use:   "process",
		Short: "Process operations",
	}
	rootCmd.AddCommand(processCmd)

	// 添加kill子命令
	killCmd := &carapace.Command{
		Use:   "kill",
		Short: "Kill a process",
		Run: func(cmd *carapace.Command, args []string) {
			fmt.Printf("Killing process %v\n", args)
		},
		Args: carapace.Arg{
			"pid": carapace.Batch(
				ps.ActionProcessIds(),
				ps.ActionProcessExecutables(),
			).ToA(),
		},
	}
	processCmd.AddCommand(killCmd)

	// 添加datetime子命令
	datetimeCmd := &carapace.Command{
		Use:   "datetime",
		Short: "Show current datetime in different formats",
		Run: func(cmd *carapace.Command, args []string) {
			fmt.Println("Current datetime:", args[0])
		},
		Args: carapace.Arg{
			"format": time.ActionDateTimeFormats(),
		},
	}
	rootCmd.AddCommand(datetimeCmd)

	// 添加user子命令
	userCmd := &carapace.Command{
		Use:   "user",
		Short: "User information",
	}
	rootCmd.AddCommand(userCmd)

	// 添加list子命令
	listCmd := &carapace.Command{
		Use:   "list",
		Short: "List users",
		Run: func(cmd *carapace.Command, args []string) {
			fmt.Println("Listing users")
		},
		Flags: func() *carapace.FlagSet {
			fs := carapace.NewFlagSet()
			fs.String("format", "table", "output format")
			fs.Bool("system", false, "include system users")
			return fs
		}(),
	}
	userCmd.AddCommand(listCmd)

	// 为list命令添加标志补全
	carapace.Gen(listCmd).FlagCompletion(carapace.ActionMap{
		"format": carapace.ActionValues("table", "json", "yaml").StyleF(style.ForKeyword),
	})

	// 添加network子命令
	networkCmd := &carapace.Command{
		Use:   "network",
		Short: "Network operations",
	}
	rootCmd.AddCommand(networkCmd)

	// 添加interface子命令
	interfaceCmd := &carapace.Command{
		Use:   "interface",
		Short: "Network interface operations",
		Run: func(cmd *carapace.Command, args []string) {
			fmt.Println("Network interface:", args[0])
		},
		Args: carapace.Arg{
			"interface": os.ActionNetworkInterfaces(),
		},
	}
	networkCmd.AddCommand(interfaceCmd)

	if err := rootCmd.Execute(); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
}

Carapace提供了丰富的内置动作(Actions)来支持各种常见的补全场景,包括文件系统、git、docker、kubectl等工具的补全。通过组合这些动作,你可以为你的CLI工具创建出非常强大的自动补全功能。

要查看完整的可用动作列表,可以参考Carapace的文档:https://github.com/rsteube/carapace-bin

回到顶部