A yay-find script vibe-coded by Gemini Pro 3.1
Features:
- fzf keyword search
- Tabulated selection list for the “hits” packages
- The user selects the package and is offered a list of optional packages to select and install.
- Options for the script:
4.1 Help
4.2 Version
4.3 Install the selected package with -noconfirn
#!/usr/bin/env bash
# Script Metadata
VERSION="1.1.0"
TIMESTAMP="2026-07-21"
# Ensure standard English output for reliable parsing
export LANG=C
# --- Color Definitions ---
C_RESET='\e[0m'
C_CYAN='\e[1;36m'
C_GREEN='\e[1;32m'
C_YELLOW='\e[1;33m'
C_RED='\e[1;31m'
C_MAGENTA='\e[1;35m'
C_BOLD='\e[1m'
# Function to display help information
show_help() {
echo -e "${C_BOLD}==================================================${C_RESET}"
echo -e " ${C_CYAN}yay-find${C_RESET} - Interactive Search & Install with Opt-Deps"
echo -e "${C_BOLD}==================================================${C_RESET}"
echo -e "${C_BOLD}Usage:${C_RESET} $(basename "$0") [OPTIONS] <keyword...>"
echo ""
echo -e "${C_BOLD}Options:${C_RESET}"
echo -e " -y, --noconfirm Bypass any and all confirmation messages"
echo -e " -h, --help Show this help message and exit"
echo -e " -v, --version Show version and timestamp information and exit"
echo ""
echo -e "${C_BOLD}Description:${C_RESET}"
echo " Searches pacman, Chaotic-AUR, and AUR for packages matching the keyword(s)."
echo " Displays a tabulated fzf list of matching packages."
echo " If packages are selected, a second panel presents their optional"
echo " dependencies for selection. Installs selected packages and optionally"
echo " selected dependencies as clean dependencies (--asdeps)."
}
# Function to display version information
show_version() {
echo -e "${C_CYAN}yay-find${C_RESET} version ${C_GREEN}$VERSION${C_RESET}"
echo "Last updated: $TIMESTAMP"
}
# Check if no arguments were provided
if [ -z "$1" ]; then
show_help
exit 1
fi
NOCONFIRM_FLAG=""
KEYWORDS=""
# Argument parsing loop
while [[ "$#" -gt 0 ]]; do
case $1 in
-h|--help)
show_help
exit 0
;;
-v|--version)
show_version
exit 0
;;
-y|--noconfirm)
NOCONFIRM_FLAG="--noconfirm"
shift
;;
-*)
echo -e "${C_RED}Error:${C_RESET} Unknown parameter passed: $1"
echo "Run '$(basename "$0") --help' for usage."
exit 1
;;
*)
# Append keywords
KEYWORDS="$KEYWORDS $1"
shift
;;
esac
done
# Trim leading/trailing whitespace from keywords
KEYWORDS=$(echo "$KEYWORDS" | xargs)
if [ -z "$KEYWORDS" ]; then
echo -e "${C_RED}Error:${C_RESET} Search keyword(s) required."
exit 1
fi
echo -e "${C_BOLD}Searching for: ${C_CYAN}$KEYWORDS${C_RESET}..."
# Fetch search results from yay
SEARCH_RAW=$(yay -Ss $KEYWORDS 2>/dev/null)
if [ -z "$SEARCH_RAW" ]; then
echo -e "${C_YELLOW}No packages found matching '$KEYWORDS'.${C_RESET}"
exit 0
fi
# Parse yay -Ss output into a strictly tabulated format for fzf
SEARCH_FZF=$(echo "$SEARCH_RAW" | awk -v c_mag="\033[1;35m" -v c_grn="\033[1;32m" -v c_yel="\033[1;33m" -v c_rst="\033[0m" '
/^[^ \t]/ {
pkg = $1
ver = $2
installed = match($0, /\(Installed\)/) ? "[Installed]" : ""
getline desc
sub(/^[ \t]+/, "", desc)
# Formatted with fixed-width columns:
# 45 chars for Package, 20 chars for Version, 12 chars for Status
printf "%s%-45s%s %s%-20s%s %s%-12s%s │ %s\n", c_mag, pkg, c_rst, c_grn, ver, c_rst, c_yel, installed, c_rst, desc
}
')
# --- Panel 1: Package Selection ---
echo -e "\n${C_BOLD}[Package Selection]${C_RESET} Use ${C_BOLD}TAB${C_RESET} to select multiple, ${C_BOLD}ENTER${C_RESET} to confirm."
SELECTED_PKGS_RAW=$(echo -e "$SEARCH_FZF" | fzf -m --ansi --header="Select packages to install (Tab to mark multiple)")
# Extract just the "repo/pkgname" or "pkgname" from the selection
SELECTED_PKGS=$(echo "$SELECTED_PKGS_RAW" | sed $'s/\033\\[[0-9;]*m//g' | awk '{print $1}')
if [ -z "$SELECTED_PKGS" ]; then
echo -e "${C_YELLOW}No packages selected. Exiting.${C_RESET}"
exit 0
fi
# Clean package names (remove 'repo/' prefix for installation and dependency checking)
SELECTED_PKGS_CLEAN=$(echo "$SELECTED_PKGS" | awk -F'/' '{print $NF}' | tr '\n' ' ')
echo -e "\n${C_BOLD}Selected Packages:${C_RESET} ${C_CYAN}$SELECTED_PKGS_CLEAN${C_RESET}"
echo -e "${C_BOLD}Gathering optional dependencies...${C_RESET}"
# --- Gather Optional Dependencies ---
ALL_OPT_DEPS_FZF=""
for PKG in $SELECTED_PKGS_CLEAN; do
INFO_CMD=""
if yay -Qi "$PKG" &>/dev/null; then
INFO_CMD="yay -Qi"
elif yay -Si "$PKG" &>/dev/null; then
INFO_CMD="yay -Si"
else
continue
fi
RAW_OPT=$($INFO_CMD "$PKG" 2>/dev/null | awk -F':' '
/^Optional Deps/ {
flag=1
sub(/^Optional Deps[ \t]*:[ \t]*/, "")
if ($0 != "") print $0
next
}
/^[A-Z]/ { flag=0 }
flag {
sub(/^[ \t]+/, "")
print $0
}
' | grep -v '^$')
if [ -n "$RAW_OPT" ] && [[ "$RAW_OPT" != *"None"* ]]; then
while IFS= read -r line; do
opt_pkg_name=$(echo "$line" | cut -d':' -f1 | xargs)
desc=$(echo "$line" | cut -d':' -f2- | xargs | sed -e 's/ \[installed\]//i' -e 's/ \[pending\]//i')
clean_pkg=$(echo "$opt_pkg_name" | sed -E 's/[<>=].*//')
# Determine text and color separately to prevent ANSI-code padding issues
if pacman -Qq "$clean_pkg" &>/dev/null; then
status_text="[Installed]"
status_color="${C_GREEN}"
else
status_text="[Pending]"
status_color="${C_YELLOW}"
fi
# Create perfectly sized columns without colors messing up the character count
padded_pkg=$(printf "%-35s" "$opt_pkg_name")
padded_status=$(printf "%-12s" "$status_text")
padded_parent=$(printf "%-25s" "(for $PKG)")
# Assemble the final string, injecting colors around the evenly padded blocks
ALL_OPT_DEPS_FZF+="${C_CYAN}${padded_pkg}${C_RESET} ${status_color}${padded_status}${C_RESET} ${C_MAGENTA}${padded_parent}${C_RESET} │ ${desc}\n"
done <<< "$RAW_OPT"
fi
done
# --- Panel 2: Optional Dependency Selection ---
SELECTED_OPT_DEPS_CLEAN=""
if [ -n "$ALL_OPT_DEPS_FZF" ]; then
echo -e "\n${C_BOLD}[Optional Dependencies]${C_RESET} Use ${C_BOLD}TAB${C_RESET} to select, ${C_BOLD}ENTER${C_RESET} to confirm, or ${C_BOLD}ESC${C_RESET} to skip."
SELECTED_OPT_RAW=$(echo -e "$ALL_OPT_DEPS_FZF" | fzf -m --ansi --header="Select optional dependencies (Tab to mark, ESC to skip)")
SELECTED_OPT_DEPS_CLEAN=$(echo "$SELECTED_OPT_RAW" | sed $'s/\033\\[[0-9;]*m//g' | awk '{print $1}' | tr '\n' ' ')
else
echo -e " ${C_YELLOW}No optional dependencies found for selected packages.${C_RESET}"
fi
# --- Execution Phase ---
echo -e "\n${C_BOLD}==================================================${C_RESET}"
echo -e "${C_BOLD}Summary of Installations:${C_RESET}"
echo -e "Packages: ${C_CYAN}${SELECTED_PKGS_CLEAN:-None}${C_RESET}"
echo -e "Opt-Depends: ${C_CYAN}${SELECTED_OPT_DEPS_CLEAN:-None}${C_RESET}"
echo -e "${C_BOLD}==================================================${C_RESET}\n"
# Install main packages
if [ -n "$SELECTED_PKGS_CLEAN" ]; then
echo -e "${C_BOLD}Installing main packages...${C_RESET}"
yay -S $NOCONFIRM_FLAG $SELECTED_PKGS_CLEAN
fi
# Install optional dependencies as dependencies (--asdeps)
if [ -n "$SELECTED_OPT_DEPS_CLEAN" ]; then
echo -e "\n${C_BOLD}Installing optional dependencies (--asdeps)...${C_RESET}"
yay -S --asdeps $NOCONFIRM_FLAG $SELECTED_OPT_DEPS_CLEAN
fi
echo -e "\n${C_GREEN}Finished!${C_RESET}"