From e6d98980c5bcde496b06408ad201a51b8c732400 Mon Sep 17 00:00:00 2001 From: rsteube Date: Sat, 24 Sep 2022 14:29:44 +0200 Subject: [PATCH] ActionPathExecutables: improve performance --- .gitignore | 2 + cmd/carapace/cmd/completers/description.go | 475 +++++++++++++++++++++ cmd/carapace/cmd/root.go | 29 +- cmd/generate/gen.go | 10 +- pkg/actions/bridge/carapace.go | 29 +- pkg/actions/os/executable.go | 73 ++++ pkg/actions/os/os.go | 34 -- 7 files changed, 595 insertions(+), 57 deletions(-) create mode 100644 cmd/carapace/cmd/completers/description.go create mode 100644 pkg/actions/os/executable.go diff --git a/.gitignore b/.gitignore index 72836cfe06..31df79818f 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,8 @@ cmd/carafmt/carafmt cmd/caralint/caralint cmd/carapace/carapace cmd/carapace/cmd/completers.go +cmd/carapace/cmd/completers/name.go +cmd/carapace/cmd/completers/description.go cmd/carapace/cmd/completers_release.go cmd/carapace/cmd/macros.go cmd/caraparse/caraparse diff --git a/cmd/carapace/cmd/completers/description.go b/cmd/carapace/cmd/completers/description.go new file mode 100644 index 0000000000..c25b057f9a --- /dev/null +++ b/cmd/carapace/cmd/completers/description.go @@ -0,0 +1,475 @@ +package completers + +var Descriptions = map[string]string{ + "acpi": "Shows information from the /proc filesystem", + "acpid": "Advanced Configuration and Power Interface event daemon", + "adb": "Android Debug Bridge", + "alsamixer": "soundcard mixer for ALSA soundcard driver, with ncurses interface", + "ant": "software tool for automating software build processes", + "aplay": "command-line sound recorder and player for ALSA soundcard driver", + "apropos": "search the manual page names and descriptions", + "apt-cache": "query the APT cache", + "apt-get": "APT package handling utility", + "arecord": "command-line sound recorder and player for ALSA soundcard driver", + "asciinema": "Record and share your terminal sessions, the right way.", + "autoconf": "Generate a configuration script from a TEMPLATE-FILE", + "avdmanager": "create and manage Android Virtual Devices", + "awk": "pattern scanning and processing language", + "aws": "Universal Command Line Interface for Amazon Web Services", + "az": "Azure Command-Line Interface", + "baobab": "A graphical disk usage analyzer for the GNOME deskto", + "basename": "strip directory and suffix from filenames", + "bash": "GNU Bourne-Again SHell", + "bat": "a cat clone with syntax highlighting and Git integration", + "batdiff": "Diff a file against the current git index, or display the diff between two files", + "batgrep": "Quickly search through and highlight files using ripgrep", + "batman": "Read system manual pages (man) using bat", + "bats": "Bash Automated Testing System", + "bc": "An arbitrary precision calculator language", + "black": "The uncompromising code formatter", + "boundary": "Boundary enables identity-based access management for dynamic infrastructure", + "brew": "The missing package manager for macOS", + "brotli": "compress or decompress files", + "calibre": "Comprehensive e-book software", + "carapace": "multi-shell multi-command argument completer", + "cargo-clippy": "Checks a package to catch common mistakes and improve your Rust code", + "cargo-fmt": "format all bin and lib files of the current crate", + "cargo-watch": "Watches over your Cargo project’s source", + "cargo": "Rust's package manager", + "cat": "concatenate files and print on the standard output", + "cfdisk": "display or manipulate a disk partition table", + "cheese": "tool to take pictures and videos from your webcam", + "chgrp": "change group ownership", + "chmod": "change file mode bits", + "chown": "change file owner and group", + "chpasswd": "update passwords in batch mode", + "chromium": "chromium browser", + "chroot": "run command or interactive shell with special root directory", + "chsh": "Change your login shell", + "circleci": "Use CircleCI from the command line", + "cksum": "checksum and count the bytes in a file", + "clamav-config": "clamav config", + "clamav-milter": "milter compatible scanner", + "clambc": "Bytecode Analysis and Testing Tool", + "clamconf": "Clam AntiVirus configuration utility", + "clamd": "an anti-virus daemon", + "clamdscan": "scan files and directories for viruses using Clam AntiVirus Daemon", + "clamdtop": "monitor the Clam AntiVirus Daemon", + "clamonacc": "an anti-virus on-access scanning daemon and clamd client", + "clamscan": "scan files and directories for viruses", + "clamsubmit": "File submission utility for ClamAV", + "cmus": "Curses based music player", + "code-insiders": "Visual Studio Code Insiders", + "code": "Visual Studio Code", + "codecov": "codecov uploader", + "comm": "compare two sorted files line by line", + "conda": "conda is a tool for managing and deploying applications, environments and packages", + "conky": "A system monitor for X originally based on the torsmo code", + "consul": "Consul automates networking for simple and secure application delivery", + "coredumpctl": "List or retrieve coredumps from the journal", + "cp": "copy files and directories", + "csplit": "split a file into sections determined by context lines", + "csview": "A high performance csv viewer with cjk/emoji support", + "cura": "Powerful, easy-to-use 3D printing software", + "curl": "transfer a URL", + "cut": "remove sections from each line of files", + "darktable-cli": "a command line darktable variant", + "darktable": "a digital photography workflow application", + "dart": "A command-line utility for Dart development", + "date": "print or set the system date and time", + "dc": "an arbitrary precision calculator", + "dd": "convert and copy a file", + "deno": "A modern JavaScript and TypeScript runtime", + "df": "report file system disk space usage", + "dfc": "report file system space usage information with style", + "dict": "Query a dictd server for the definition of a word", + "diff3": "compare three files line by line", + "diff": "compare files line by line", + "dig": "DNS lookup utility", + "dir": "list directory contents", + "dircolors": "color setup for ls", + "direnv": "unclutter your .profile", + "dirname": "strip last component from file name", + "dlv": "Delve is a debugger for the Go programming language.", + "dmenu": "dynamic menu", + "dmesg": "Display or control the kernel ring buffer", + "dms": "A UPnP DLNA Digital Media Server", + "dnsmasq": "A lightweight DHCP and caching DNS server", + "docker-buildx": "Docker Buildx", + "docker-compose": "Define and run multi-container applications with Docker", + "docker-scan": "A tool to scan your images", + "docker": "Docker image and container command line interface", + "dockerd": "A self-sufficient runtime for containers", + "doctl": "doctl is a command line interface (CLI) for the DigitalOcean API", + "dos2unix": "DOS/Mac to Unix and vice versa text file format converter", + "downgrade": "Downgrade Arch Linux packages", + "du": "estimate file space usage", + "ebook-convert": "Convert an e-book from one format to another", + "egrep": "print lines that match patterns", + "electron": "Build cross platform desktop apps with JavaScript, HTML, and CSS", + "elvish": "expressive programming language and a versatile interactive shell", + "env": "run a program in a modified environment", + "envsubst": "Substitutes the values of environment variables", + "exa": "a modern replacement for ls", + "expand": "convert tabs to spaces", + "expr": "evaluate expressions", + "faas-cli": "Manage your OpenFaaS functions from the command line", + "factor": "factor numbers", + "fakechroot": "gives a fake chroot environment", + "fakeroot": "run a command in an environment faking root privileges for file manipulation", + "fc-cache": "Build font information caches", + "fc-cat": "read font information cache files", + "fc-conflist": "list the configuration files processed by Fontconfig", + "fc-list": "list available fonts", + "fd": "find entries in the filesystem", + "fdisk": "manipulate disk partition table", + "ffmpeg": "Hyper fast Audio and Video encoder", + "fgrep": "print lines that match patterns", + "file": "determine file type", + "find": "search for files in a directory hierarchy", + "firefox": "Firefox Browser", + "fish": "the friendly interactive shell", + "flutter": "Manage your Flutter app development", + "fmt": "simple optimal text formatter", + "fold": "wrap each input line to fit in specified width", + "ftp": "File Transfer Protocol client", + "ftpd": "File Transfer Protocol daemon", + "fzf": "a command-line fuzzy finder", + "gatsby": "Build blazing fast, modern apps and websites with React", + "gcloud": "manage Google Cloud Platform resources and developer workflow", + "gdb": "This is the GNU debugger", + "gdu": "Pretty fast disk usage analyzer written in Go", + "gftp": "file transfer client for *NIX based machines", + "gh-dash": "A beautiful CLI dashboard for GitHub", + "gh": "GitHub CLI", + "gimp": "an image manipulation and paint program", + "git-abort": "Abort current rebase, merge or cherry-pick, without the need to find exact command in history", + "git-alias": "Define, search and show aliases", + "git-clang-format": "run clang-format on lines that differ", + "git-extras": "Awesome GIT utilities", + "git-standup": "Recall the commit history", + "git": "the stupid content tracker", + "gitk": "The Git repository browser", + "glab": "A GitLab CLI Tool", + "glow": "Render markdown on the CLI, with pizzazz!", + "gnome-keyring-daemon": "The Gnome Keyring Daemon", + "gnome-keyring": "The gnome-keyring commandline tool", + "gnome-maps": "A map application for GNOME", + "gnome-terminal": "A terminal emulator for GNOME", + "go-carpet": "show test coverage for Go source files", + "go": "Go is a tool for managing Go source code", + "gocyclo": "Calculate cyclomatic complexities of Go functions", + "gofmt": "format Go source code", + "google-chrome": "chrome browser", + "goreleaser": "Deliver Go binaries as fast and easily as possible", + "goweight": "A tool to analyze and troubleshoot a Go binary size", + "gparted": "GNOME Partition Editor for manipulating disk partitions", + "gpasswd": "administer /etc/group and /etc/gshadow", + "gpg-agent": "Secret key management for GnuPG", + "gpg": "OpenPGP encryption and signing tool", + "gradle": "Gradle Build Tool", + "grep": "print lines that match patterns", + "groupadd": "create a new group", + "groupdel": "delete a group", + "groupmems": "administer members of a user's primary group", + "groupmod": "modify a group definition on the system", + "groups": "display current group names", + "gulp": "Command Line Interface for gulp", + "gunzip": "Uncompress files", + "gzip": "Compress or uncompress files", + "halt": "halt the machine", + "head": "output the first part of files", + "helix": "A post-modern text editor", + "helm": "The Helm package manager for Kubernetes.", + "helmsman": "Helmsman is a Helm Charts as Code tool", + "hexchat": "IRC Client", + "hexdump": "Display file contents in hexadecimal, decimal, octal, or ascii", + "hostid": "print the numeric identifier for the current host", + "hostname": "show or set system host name", + "htop": "interactive process viewer", + "http": "command-line HTTP client for the API era", + "https": "command-line HTTP client for the API era", + "hugo": "hugo builds your site", + "hwinfo": "Probe for hardware", + "hx": "A post-modern text editor", + "i3-scrot": "simple screenshot script", + "i3": "an improved dynamic, tiling window manager", + "i3exit": "exit-script for i3", + "i3lock": "improved screen locker", + "i3status-rs": "A feature-rich and resource-friendly replacement for i3status, written in Rust", + "i3status": "Generates a status line for i3bar, dzen2, xmobar or lemonbar", + "id": "Print user and group information", + "inkscape": "an SVG (Scalable Vector Graphics) editing program", + "install": "copy files and set attributes", + "ion": "The Ion Shell", + "jar": "create an archive for classes and resources", + "java": "Launches a Java application", + "javac": "Reads Java class and interface definitions and compiles them into bytecode and class files", + "join": "join lines of two files on a common field", + "journalctl": "Query the journal", + "jq": "Command-line JSON processor", + "julia": "high-level, high-performance dynamic programming language for technical computing", + "just": "Just a command runner", + "kak-lsp": "Kakoune Language Server Protocol Client", + "kak": "a vim-inspired, selection oriented code editor", + "kill": "Forcibly terminate a process", + "killall": "kill processes by name", + "kmonad": "an onion of buttons", + "kompose": "A tool helping Docker Compose users move to Kubernetes", + "kotlin": "run Kotlin programs, scripts or REPL", + "kotlinc": "Kotlin command-line compiler", + "ktlint": "An anti-bikeshedding Kotlin linter with built-in formatter", + "kubeadm": "kubeadm: easily bootstrap a secure Kubernetes cluster", + "kubectl": "kubectl controls the Kubernetes cluster manager", + "lazygit": "simple terminal UI for git commands", + "lf": "terminal file manager", + "light": "a program to control backlight controllers", + "lightdm": "a display manager", + "link": "call the link function to create a link to a file", + "ln": "make links between files", + "lnav": "ncurses-based log file viewer", + "lncrawl": "Generate and download e-books from online sources", + "locale": "Get locale-specific information", + "localectl": "Query or change system locale and keyboard settings", + "logname": "print user's login name", + "ls": "list directory contents", + "lsb_release": "prints certain LSB (Linux Standard Base) and Distribution information", + "lsblk": "list block devices", + "lscpu": "display information about the CPU architecture", + "lslocks": "List local system locks", + "lslogins": "Display information about known users in the system", + "lsmem": "list the ranges of available memory with their online status", + "lsns": "List system namespaces", + "lsusb": "list USB devices", + "lua": "Lua interpreter", + "lzcat": "Compress or decompress .xz and .lzma files", + "lzma": "Compress or decompress .xz and .lzma files", + "make": "GNU make utility to maintain groups of programs", + "makepkg": "make packages compatible for use with pacman", + "man": "an interface to the system reference manuals", + "mcomix": "GTK Comic Book Viewer", + "md5sum": "compute and check MD5 message digest", + "mdbook": "Creates a book from markdown files", + "meld": "Meld is a file and directory comparison tool", + "micro": "A modern and intuitive terminal-based text editor", + "minikube": "minikube quickly sets up a local Kubernetes cluster", + "mitmproxy": "interactive, SSL/TLS-capable intercepting proxy", + "mkdir": "make directories", + "mkfifo": "make FIFOs (named pipes)", + "mkfs": "Make a Linux filesystem", + "mknod": "make block or character special files", + "mkswap": "Set up a Linux swap area", + "mktemp": "create a temporary file or directory", + "modinfo": "Show information about a Linux Kernel module", + "modprobe": "Add and remove modules from the Linux Kernel", + "more": "file perusal filter for crt viewing", + "mosh": "mobile shell with roaming and intelligent local echo", + "mount": "mount a filesystem", + "mousepad": "Mousepad is a simple text editor for the Xfce desktop environment", + "mpv": "a media player", + "mv": "move (rename) files", + "mvn": "Apache Maven is a software project management and comprehension tool", + "nano": "Nano's ANOther editor, inspired by Pico", + "nc": "simple Unix utility which reads and writes data across network connections", + "ncdu": "NCurses Disk Usage", + "neomutt": "The NeoMutt Mail User Agent", + "netcat": "simple Unix utility which reads and writes data across network connections", + "newman": "Newman is a command-line collection runner for Postman", + "nfpm": "Packages apps on RPM, Deb and APK formats based on a YAML configuration file", + "ng": "The Angular CLI", + "nice": "run a program with modified scheduling priority", + "nix-channel": "manage Nix channels", + "nl": "number lines of files", + "nmcli": "command-line tool for controlling NetworkManager", + "node": "server-side JavaScript runtime", + "nohup": "run a command immune to hangups, with output to a non-tty", + "nomad": "Nomad is an easy-to-use, flexible, and performant workload orchestrator", + "npm": "the package manager for JavaScript", + "ntpd": "NTP daemon program", + "nu": "Nushell", + "nvim": "edit text", + "od": "dump files in octal and other formats", + "openscad": "script file based graphical CAD environment", + "optipng": "Optimize Portable Network Graphics files", + "packer": "Create identical machine images for multiple platforms from a single source configuration.", + "pacman": "package manager utility", + "palemoon": "Pale Moon browser", + "pamac": "package manager utility", + "pandoc": "general markup converter", + "pass": "stores, retrieves, generates, and synchronizes passwords securely", + "passwd": "change user password", + "paste": "merge lines of files", + "patch": "appy a diff file to an original", + "pathchk": "check whether file names are valid or portable", + "pcmanfm": "A lightweight Gtk+ based file manager for X Window", + "pgrep": "look up processes based on name and other attributes", + "picard": "Picard is a cross-platform music tagger written in Python", + "ping": "send ICMP ECHO_REQUEST to network hosts", + "pinky": "lightweight finger", + "pip": "package manager for Python packages", + "pkg": "A tool for managing packages", + "pkill": "look up for processes based on name and other attributes", + "podman": "Simple management tool for pods, containers and images", + "poweroff": "poweroff the machine", + "powertop": "The Linux PowerTOP tool", + "pr": "convert text files for printing", + "prettybat": "Pretty-print source code and highlight it with bat", + "prettyping": "This script is a wrapper around the system's \"ping\" tool", + "printenv": "print all or part of environment", + "ps": "report a snapshot of the current processes", + "ptx": "produce a permuted index of file contents", + "pulumi": "Pulumi command line", + "pwait": "wait for processes based on name and other attributes", + "pwd": "Print the full filename of the current working directory", + "python": "an interpreted, interactive, object-oriented programming language", + "qmk": "CLI wrapper for running QMK commands", + "qrencode": "Encode input data in a QR Code and save as a PNG or EPS image", + "qutebrowser": "a keyboard-driven, vim-like browser based on PyQt5", + "ranger": "visual file manager", + "readlink": "print resolved symbolic links or canonical file names", + "reboot": "reboot the machine", + "restic": "Backup and restore files", + "resume-cli": "command line tool for JSON Resume", + "rg": "recursively search current directory for lines matching a pattern", + "rifle": "ranger's file opener", + "rm": "remove files or directories", + "rmdir": "remove empty directories", + "rmmod": "Simple program to remove a module from the Linux Kernel", + "rsync": "a fast, versatile, remote (and local) file-copying tool", + "rustc": "compiler for the Rust programming language", + "rustup": "installer for the systems programming language Rust", + "scp": "OpenSSH secure file copy", + "scrot": "command line screen capture utility", + "sdkmanager": "Android SDK manager", + "sed": "stream editor for filtering and transforming text", + "semver": "A JavaScript implementation of the https://semver.org/ specification", + "seq": "print a sequence of numbers", + "sftp": "OpenSSH secure file transfer", + "sha1sum": "compute and check SHA1 message digest", + "sha256sum": "compute and check SHA256 message digest", + "shred": "overwrite a file to hide its contents, and optionally delete it", + "shutdown": "Shut down the system", + "sleep": "delay for a specified amount of time", + "slides": "Terminal based presentation tool", + "sort": "sort lines of text files", + "speedtest-cli": "Command line interface for testing internet bandwidth using speedtest.net", + "split": "split a file into pieces", + "ssh-agent": "OpenSSH authentication agent", + "ssh-copy-id": "use locally available keys to authorise logins on a remote machine", + "ssh": "OpenSSH remote login client", + "st": "simple terminal", + "starship": "The cross-shell prompt for astronauts", + "stat": "display file or file system status", + "staticcheck": "The advanced Go linter", + "strings": "print the sequences of printable characters in files", + "stty": "change and print terminal line settings", + "su": "run a command with substitute user and group ID", + "sudo": "execute a command as another user", + "sudoedit": "edit files as another user", + "sudoreplay": "replay sudo session logs", + "sulogin": "single-user login", + "sum": "checksum and count the blocks in a file", + "supervisord": "run a set of applications as daemons", + "svg-term": "Share terminal sessions as razor-sharp animated SVG everywhere", + "sway": "An i3-compatible Wayland compositor", + "swaybar": "bar for swaywm", + "swaybg": "Background for Wayland", + "swayidle": "Idle manager for Wayland", + "swaylock": "Screen locker for Wayland", + "swaymsg": "Send messages to a running instance of sway over the IPC socket", + "swaynag": "Show a warning or error message with buttons", + "sync": "Synchronize cached writes to persistent storage", + "sysctl": "configure kernel parameters at runtime", + "systemctl": "Query or send control commands to the system manager", + "tac": "concatenate and print files in reverse", + "tail": "output the last part of files", + "tar": "tar - an archiving utility", + "task": "A task runner / simpler Make alternative written in Go", + "tee": "read from standard input and write to standard output and files", + "telnet": "User interface to TELNET", + "termux-apt-repo": "Create a repository with deb files", + "terraform": "infrastructure as code software tool", + "terragrunt": "Terragrunt is a thin wrapper for Terraform", + "tesseract": "command-line OCR engine", + "tig": "text-mode interface for Git", + "tinygo": "TinyGo is a Go compiler for small places", + "tldr": "Python command line client for tldr", + "tmate": "Instant terminal sharing", + "tmux": "terminal multiplexer", + "toit.lsp": "start the lsp server", + "toit.pkg": "The Toit package manager", + "top": "display Linux processes", + "tor-browser": "Tor Browser", + "tor-gencert": "Generate certs and keys for Tor directory authorities", + "tor-print-ed-signing-cert": "print expiration date of ed25519 signing certificate", + "tor-resolve": "resolve a hostname to an IP address via tor", + "torsocks": "Shell wrapper to simplify the use of the torsocks(8) library to transparently torify an application", + "touch": "change file timestamps", + "tr": "translate or delete characters", + "traefik": "Traefik is a modern HTTP reverse proxy and load balancer made to deploy microservices with ease", + "tree": "list contents of directories in a tree-like format", + "truncate": "Shrink or extend the size of each FILE to the specified size", + "ts": "timestamp input", + "tsc": "The TypeScript Compiler", + "tshark": "Dump and analyze network traffic", + "tsort": "perform topological sort", + "tty": "print the file name of the terminal connected to standard input", + "turbo": "The High-performance Build System for JavaScript & TypeScript Codebases", + "umount": "Unmount filesystems", + "uname": "print system information", + "unbrotli": "compress or decompress files", + "unexpand": "convert spaces to tabs", + "uniq": "report or omit repeated lines", + "unlink": "call the unlink function to remove the specified file", + "unlzma": "Compress or decompress .xz and .lzma files", + "unxz": "Compress or decompress .xz and .lzma files", + "unzip": "list, test and extract compressed files in a ZIP archive", + "upower": "UPower command line tool", + "uptime": "Tell how long the system has been running", + "upx": "compress or expand executable files", + "useradd": "create a new user or update default new user information", + "userdel": "delete a user account and related files", + "usermod": "modify a user account", + "users": "print the user names of users currently logged in to the current host", + "vagrant": "tool for building and managing virtual machine environments", + "vault": "A tool for secrets management", + "vdir": "list directory contents", + "vercel": "Develop. Preview. Ship.", + "vi": "screen oriented (visual) display editor based on ex", + "viewnior": "simple, fast and elegant image viewer", + "visudo": "safely edit the sudoers file", + "vivid": "LS_COLORS manager with multiple themes", + "vlc": "the VLC media player", + "volta": "The JavaScript Launcher", + "w": "Show who is logged on and what they are doing", + "watch": "execute a program periodically, showing output fullscreen", + "watchexec": "Execute commands when watched files change", + "watchgnupg": "Read and print logs from a socket", + "waypoint": "Easy application deployment for Kubernetes and Amazon ECS", + "wc": "print newline, word, and byte counts for each file", + "wget": "a non-interactive network retriever", + "whereis": "Locate the binary, source, and manual-page files for a command", + "which": "Write the full path of COMMAND(s) to standard output", + "who": "show who is logged on", + "whoami": "print effective userid", + "wine": "run Windows programs on Unix", + "wineboot": "perform Wine initialization, startup, and shutdown task", + "winepath": "Tool to convert Unix paths to/from Win32 paths", + "wineserver": "the Wine server", + "winetricks": "manage virtual Windows environments using Wine", + "wire": "Compile-time Dependency Injection for Go", + "wireshark": "Interactively dump and analyze network traffic", + "woeusb": "A Linux program to create a Windows USB stick installer", + "xargs": "build and execute command lines from standard input", + "xbacklight": "adjust backlight brightness using RandR extension", + "xdotool": "command-line X11 automation tool", + "xonsh": "Python-powered shell", + "xz": "Compress or decompress .xz and .lzma files", + "xzcat": "Compress or decompress .xz and .lzma files", + "yes": "output a string repeatedly until killed", + "yj": "Convert between YAML, TOML, JSON, and HCL", + "youtube-dl": "download videos from youtube.com or other video platforms", + "zathura": "a document viewer", + "zcat": "compress or expand files", + "zip": "package and compress (archive) files", +} diff --git a/cmd/carapace/cmd/root.go b/cmd/carapace/cmd/root.go index 255a6826f2..63da3bc95b 100644 --- a/cmd/carapace/cmd/root.go +++ b/cmd/carapace/cmd/root.go @@ -12,6 +12,7 @@ import ( "strconv" "strings" + "github.com/rsteube/carapace-bin/cmd/carapace/cmd/completers" spec "github.com/rsteube/carapace-spec" "github.com/rsteube/carapace/pkg/ps" "github.com/rsteube/carapace/pkg/style" @@ -75,7 +76,7 @@ var rootCmd = &cobra.Command{ Specs are loaded from [%v/carapace/specs]. `, suppressErr(os.UserCacheDir), suppressErr(os.UserConfigDir), suppressErr(os.UserConfigDir)), Args: cobra.MinimumNArgs(1), - ValidArgs: completers, + ValidArgs: completers.Names, Run: func(cmd *cobra.Command, args []string) { // since flag parsing is disabled do this manually switch args[0] { @@ -119,25 +120,25 @@ var rootCmd = &cobra.Command{ } switch shell { case "bash": - fmt.Println(bash_lazy(completers)) + fmt.Println(bash_lazy(completers.Names)) case "bash-ble": - fmt.Println(bash_ble_lazy(completers)) + fmt.Println(bash_ble_lazy(completers.Names)) case "elvish": - fmt.Println(elvish_lazy(completers)) + fmt.Println(elvish_lazy(completers.Names)) case "fish": - fmt.Println(fish_lazy(completers)) + fmt.Println(fish_lazy(completers.Names)) case "nushell": - fmt.Println(nushell_lazy(completers)) + fmt.Println(nushell_lazy(completers.Names)) case "oil": - fmt.Println(oil_lazy(completers)) + fmt.Println(oil_lazy(completers.Names)) case "powershell": - fmt.Println(powershell_lazy(completers)) + fmt.Println(powershell_lazy(completers.Names)) case "tcsh": - fmt.Println(tcsh_lazy(completers)) + fmt.Println(tcsh_lazy(completers.Names)) case "xonsh": - fmt.Println(xonsh_lazy(completers)) + fmt.Println(xonsh_lazy(completers.Names)) case "zsh": - fmt.Println(zsh_lazy(completers)) + fmt.Println(zsh_lazy(completers.Names)) default: fmt.Fprintln(os.Stderr, "could not determine shell") } @@ -159,14 +160,14 @@ func suppressErr(f func() (string, error)) string { s, _ := f(); return s } func printCompleters() { maxlen := 0 - for _, name := range completers { + for _, name := range completers.Names { if len := len(name); len > maxlen { maxlen = len } } - for _, name := range completers { - fmt.Printf("%-"+strconv.Itoa(maxlen)+"v %v\n", name, descriptions[name]) + for _, name := range completers.Names { + fmt.Printf("%-"+strconv.Itoa(maxlen)+"v %v\n", name, completers.Descriptions[name]) } } diff --git a/cmd/generate/gen.go b/cmd/generate/gen.go index 683145172d..2ed58867b4 100644 --- a/cmd/generate/gen.go +++ b/cmd/generate/gen.go @@ -56,20 +56,12 @@ func main() { import ( %v) -var completers = []string{ -%v} - -var descriptions = map[string]string{ -%v} - func executeCompleter(completer string) { switch completer { %v } } `, fmt.Sprintln(strings.Join(imports, "\n")), - fmt.Sprintln(strings.Join(formattedNames, "\n")), - fmt.Sprintln(strings.Join(formattedDescriptions, "\n")), fmt.Sprintln(strings.Join(cases, "\n")), ) @@ -80,6 +72,8 @@ func executeCompleter(completer string) { } os.WriteFile(root+"/cmd/carapace/cmd/completers.go", []byte("//go:build !release\n\n"+content), 0644) + os.WriteFile(root+"/cmd/carapace/cmd/completers/name.go", []byte(fmt.Sprintf("package completers\n\nvar Names = []string{\n%v\n}\n", strings.Join(formattedNames, "\n"))), 0644) + os.WriteFile(root+"/cmd/carapace/cmd/completers/description.go", []byte(fmt.Sprintf("package completers\n\nvar Descriptions = map[string]string{\n%v\n}\n", strings.Join(formattedDescriptions, "\n"))), 0644) os.WriteFile(root+"/cmd/carapace/cmd/completers_release.go", []byte("//go:build release\n\n"+strings.Replace(content, "/completers/", "/completers_release/", -1)), 0644) os.RemoveAll(root + "/completers_release") execabs.Command("cp", "-r", root+"/completers", root+"/completers_release").Run() diff --git a/pkg/actions/bridge/carapace.go b/pkg/actions/bridge/carapace.go index acb64eea07..bf67d3a105 100644 --- a/pkg/actions/bridge/carapace.go +++ b/pkg/actions/bridge/carapace.go @@ -1,6 +1,12 @@ package bridge -import "github.com/rsteube/carapace" +import ( + "fmt" + "os" + + "github.com/rsteube/carapace" + spec "github.com/rsteube/carapace-spec" +) // ActionCarapace bridges rsteube/carapace completion func ActionCarapace(cmd string) carapace.Action { @@ -19,6 +25,15 @@ func ActionCarapace(cmd string) carapace.Action { // ActionCarapaceBin bridges a completer provided by carapace-bin func ActionCarapaceBin(completer string) carapace.Action { + return carapace.ActionCallback(func(c carapace.Context) carapace.Action { + if a, err := actionSpec(completer); err == nil { + return a + } + return actionCarapaceBin(completer) + }) +} + +func actionCarapaceBin(completer string) carapace.Action { return carapace.ActionCallback(func(c carapace.Context) carapace.Action { args := []string{completer, "export", ""} args = append(args, c.Args...) @@ -31,3 +46,15 @@ func ActionCarapaceBin(completer string) carapace.Action { }) }) } + +func actionSpec(completer string) (carapace.Action, error) { + configDir, err := os.UserConfigDir() + if err != nil { + return carapace.ActionValues(), err + } + path := fmt.Sprintf("%v/carapace/specs/%v.yaml", configDir, completer) + if _, err := os.Stat(path); os.IsNotExist(err) { + return carapace.ActionValues(), err + } + return spec.ActionSpec(path), nil +} diff --git a/pkg/actions/os/executable.go b/pkg/actions/os/executable.go new file mode 100644 index 0000000000..1de88953d6 --- /dev/null +++ b/pkg/actions/os/executable.go @@ -0,0 +1,73 @@ +package os + +import ( + "fmt" + "os" + "strings" + + "github.com/rsteube/carapace" + "github.com/rsteube/carapace-bin/cmd/carapace/cmd/completers" + "github.com/rsteube/carapace/pkg/style" + "gopkg.in/yaml.v3" +) + +// ActionPathExecutables completes executable files from PATH +// +// nvim +// chmod +func ActionPathExecutables() carapace.Action { + return carapace.ActionCallback(func(c carapace.Context) carapace.Action { + batch := carapace.Batch() + dirs := strings.Split(os.Getenv("PATH"), string(os.PathListSeparator)) + for i := len(dirs) - 1; i >= 0; i-- { + batch = append(batch, actionDirectoryExecutables(dirs[i], c.CallbackValue)) + } + return batch.ToA() + }) +} + +func actionDirectoryExecutables(dir string, prefix string) carapace.Action { + return carapace.ActionCallback(func(c carapace.Context) carapace.Action { + if files, err := os.ReadDir(dir); err == nil { + vals := make([]string, 0) + for _, f := range files { + if strings.HasPrefix(f.Name(), prefix) { + if info, err := f.Info(); err == nil && !f.IsDir() && isExecAny(info.Mode()) { + if description, err := specDescription(f.Name()); err != nil { + vals = append(vals, f.Name(), completers.Descriptions[f.Name()], style.ForPath(dir+"/"+f.Name())) + } else { + vals = append(vals, f.Name(), description, style.ForPath(dir+"/"+f.Name())) + } + } + } + } + return carapace.ActionStyledValuesDescribed(vals...) + } + return carapace.ActionValues() + }) +} + +func isExecAny(mode os.FileMode) bool { + return mode&0111 != 0 +} + +func specDescription(name string) (string, error) { + confDir, err := os.UserConfigDir() + if err != nil { + return "", err + } + + content, err := os.ReadFile(fmt.Sprintf("%v/carapace/specs/%v.yaml", confDir, name)) + if err != nil { + return "", err + } + var s struct { + Description string + } + + err = yaml.Unmarshal(content, &s) + if err != nil { + return "", err + } + return s.Description, nil +} diff --git a/pkg/actions/os/os.go b/pkg/actions/os/os.go index 3ebde20b30..f840aa6ed1 100644 --- a/pkg/actions/os/os.go +++ b/pkg/actions/os/os.go @@ -2,11 +2,9 @@ package os import ( - "os" "strings" "github.com/rsteube/carapace" - "github.com/rsteube/carapace/pkg/style" ) // ActionShells completes available terminal shells @@ -22,38 +20,6 @@ func ActionShells() carapace.Action { }) } -// ActionPathExecutables completes executable files from PATH -// -// nvim -// chmod -func ActionPathExecutables() carapace.Action { - return carapace.ActionCallback(func(c carapace.Context) carapace.Action { - executables := make(map[string]string) - - for _, folder := range strings.Split(os.Getenv("PATH"), string(os.PathListSeparator)) { - if files, err := os.ReadDir(folder); err == nil { - for _, f := range files { - if _, ok := executables[f.Name()]; !ok { - if info, err := f.Info(); err == nil && !f.IsDir() && isExecAny(info.Mode()) { - executables[f.Name()] = style.ForPath(folder + "/" + f.Name()) - } - } - } - } - } - - vals := make([]string, 0) - for executable, _style := range executables { - vals = append(vals, executable, _style) - } - return carapace.ActionStyledValues(vals...) - }) -} - -func isExecAny(mode os.FileMode) bool { - return mode&0111 != 0 -} - // ActionCgroups completes cgroup names // // blkio