feat(ui): Comprehensive UI improvements - colors, syntax, and interactive enhancements

- Fix ASCII banner color display (no more escape code leakage)
- Add syntax display to all modes (explain, interactive, direct)
- Update COMMANDS array with syntax for all 84 commands
- Enhance interactive mode with syntax preview in fzf
- Improve show_flags() to match explain mode format with SYNTAX section
- Enhance filter logic to search both flag names and descriptions
- Update list_commands() to show syntax alongside descriptions
- Consistent color-coded display across all modes
- Better user experience with clear syntax and command reference

Format: cmd:Description | Syntax
Example: ls:List directory contents | ls [OPTION]... [FILE]...

All modes now show:
- Command name
- Syntax/usage pattern
- Description
- Detailed flags with improved filtering
This commit is contained in:
2025-10-28 00:52:23 -07:00
parent f152c9647c
commit ceae38a705
+228 -114
View File
@@ -17,13 +17,12 @@ NC='\033[0m' # No Color
# ASCII Banner
show_banner() {
echo -e "${CYAN}"
echo " ____ __ ____ __ __"
echo " / __ )____ ______/ /_ / __ )__ ______/ /___/ /_ __"
echo " / __ / __ \`/ ___/ __ \\ / __ / / / / __ / __ / / / /"
echo " / /_/ / /_/ (__ ) / / / / /_/ / /_/ / /_/ / /_/ / /_/ /"
echo "/_____/\\__,_/____/_/ /_/ /_____/\\__,_/\\__,_/\\__,_/\\__, /"
echo " /____/"
echo -e "${CYAN} ____ __ ____ __ __"
echo -e " / __ )____ ______/ /_ / __ )__ ______/ /___/ /_ __"
echo -e " / __ / __ \`/ ___/ __ \\ / __ / / / / __ / __ / / / /"
echo -e " / /_/ / /_/ (__ ) / / / / /_/ / /_/ / /_/ / /_/ / /_/ /"
echo -e "/_____/\\__,_/____/_/ /_/ /_____/\\__,_/\\__,_/\\__,_/\\__, /"
echo -e " /____/${NC}"
echo -e "${YELLOW} Your Intelligent CLI Assistant for Bash${NC}"
echo ""
}
@@ -477,25 +476,83 @@ mode_explain() {
echo -e "${BLUE}═══════════════════════════════════════════════════════════${NC}"
}
# Get quick syntax for a command
get_quick_syntax() {
local cmd="$1"
local syntax=""
if type "$cmd" 2>/dev/null | grep -q "shell builtin"; then
syntax=$(help "$cmd" 2>/dev/null | head -1 | sed 's/^[[:space:]]*//' | cut -c1-60)
else
# Try to get first line from man page SYNOPSIS
syntax=$(man "$cmd" 2>/dev/null | col -b | sed -n '/^SYNOPSIS/,/^DESCRIPTION/p' | sed -n '2p' | sed 's/^[[:space:]]*//' | cut -c1-60)
if [ -z "$syntax" ]; then
# Fallback to --help
syntax=$("$cmd" --help 2>&1 | grep -i "usage" | head -1 | sed 's/^[Uu]sage: //' | cut -c1-60)
fi
if [ -z "$syntax" ]; then
syntax="$cmd [options]"
fi
fi
echo "$syntax"
}
show_flags() {
CMD_NAME=$1
FILTER=$2
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "${YELLOW}Flags for: ${GREEN}$CMD_NAME${NC}"
echo -e "${YELLOW}Command Details: ${GREEN}$CMD_NAME${NC}"
if [ -n "$FILTER" ]; then
echo -e "${YELLOW}Filter: ${GREEN}$FILTER${NC}"
fi
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo ""
# Display SYNTAX section
if command -v "$CMD_NAME" &> /dev/null || type "$CMD_NAME" 2>/dev/null | grep -q "shell builtin"; then
echo -e "${CYAN}${BOLD}SYNTAX:${NC}"
if type "$CMD_NAME" 2>/dev/null | grep -q "shell builtin"; then
# For builtins, get the first line of help
local syntax=$(help "$CMD_NAME" 2>/dev/null | head -1 | sed 's/^[[:space:]]*//')
if [ -n "$syntax" ]; then
echo -e " ${GREEN}$syntax${NC}"
else
echo -e " ${GREEN}$CMD_NAME [options]${NC}"
fi
else
# For regular commands, extract SYNOPSIS section from man page
local synopsis=$(man "$CMD_NAME" 2>/dev/null | col -b | sed -n '/^SYNOPSIS/,/^DESCRIPTION/p' | head -15 | tail -n +2 | head -n -1 | sed 's/^[[:space:]]*/ /')
if [ -n "$synopsis" ]; then
echo -e "${GREEN}$synopsis${NC}"
else
# Fallback: try to get usage from command itself
local usage=$("$CMD_NAME" --help 2>&1 | grep -i "usage" | head -1 | sed 's/^[Uu]sage: / /')
if [ -n "$usage" ]; then
echo -e " ${GREEN}$usage${NC}"
else
echo -e " ${GREEN}$CMD_NAME [options]${NC}"
fi
fi
fi
echo ""
fi
# Display FLAGS/OPTIONS section
echo -e "${YELLOW}${BOLD}FLAGS/OPTIONS:${NC}"
echo ""
# Try to get flags from man page
if type "$CMD_NAME" 2>/dev/null | grep -q "shell builtin"; then
# Shell builtin - use help command
if [ -n "$FILTER" ]; then
help "$CMD_NAME" 2>/dev/null | grep -E '^\s*-' | grep -i "$FILTER"
help "$CMD_NAME" 2>/dev/null | grep -iE "(^|\s)-.*$FILTER" | head -30
else
help "$CMD_NAME" 2>/dev/null | grep -E '^\s*-'
help "$CMD_NAME" 2>/dev/null | grep -E '^\s*-' | head -30
fi
elif command -v "$CMD_NAME" &> /dev/null; then
# External command - use man page
@@ -516,9 +573,10 @@ show_flags() {
fi
if [ -n "$FILTER" ]; then
echo "$options_section" | grep -i "$FILTER" | head -30
# Improved filter logic: match flag name or description
echo "$options_section" | grep -iE "(^|\s)-.*$FILTER|$FILTER.*-" | head -40
else
echo "$options_section" | head -30
echo "$options_section" | head -40
fi
else
echo -e "${RED}Could not find help for: $CMD_NAME${NC}"
@@ -527,6 +585,8 @@ show_flags() {
return 1
fi
echo ""
echo -e "${DIM}Tip: Use the filter to search for specific flags or keywords${NC}"
echo ""
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
}
@@ -536,8 +596,16 @@ list_commands() {
echo ""
for cmd in "${COMMANDS[@]}"; do
CMD_NAME=${cmd%%:*}
DESC=${cmd#*:}
printf " %-10s - %s\n" "$CMD_NAME" "$DESC"
REST=${cmd#*:}
# Extract description (before pipe) and syntax (after pipe)
if [[ "$REST" =~ (.+)\ \|\ (.+) ]]; then
DESC="${BASH_REMATCH[1]}"
SYNTAX="${BASH_REMATCH[2]}"
printf " %-10s - %-40s | %s\n" "$CMD_NAME" "$DESC" "$SYNTAX"
else
printf " %-10s - %s\n" "$CMD_NAME" "$REST"
fi
done
}
@@ -545,122 +613,127 @@ get_command_description() {
local search_cmd=$1
for cmd in "${COMMANDS[@]}"; do
CMD_NAME=${cmd%%:*}
DESC=${cmd#*:}
REST=${cmd#*:}
if [ "$CMD_NAME" = "$search_cmd" ]; then
echo "$DESC"
# Extract just the description part (before the pipe)
if [[ "$REST" =~ (.+)\ \|\ (.+) ]]; then
echo "${BASH_REMATCH[1]}"
else
echo "$REST"
fi
return 0
fi
done
echo "Command help"
}
# Command definitions for interactive mode
# Command definitions for interactive mode (format: "cmd:Description | Syntax")
COMMANDS=(
# File Operations
"ls:List directory contents"
"cd:Change the current directory"
"pwd:Print the name of the current working directory"
"cp:Copy files and directories"
"mv:Move or rename files and directories"
"rm:Remove files or directories"
"mkdir:Create a new directory"
"rmdir:Remove an empty directory"
"touch:Create empty file or update timestamp"
"cat:Concatenate and display files"
"less:View file contents with pagination"
"head:Display first lines of a file"
"tail:Display last lines of a file"
"chmod:Change file permissions"
"chown:Change file owner"
"ln:Create links between files"
"file:Determine file type"
"stat:Display file status"
"ls:List directory contents | ls [OPTION]... [FILE]..."
"cd:Change the current directory | cd [DIRECTORY]"
"pwd:Print the name of the current working directory | pwd [OPTION]"
"cp:Copy files and directories | cp [OPTION]... SOURCE DEST"
"mv:Move or rename files and directories | mv [OPTION]... SOURCE DEST"
"rm:Remove files or directories | rm [OPTION]... FILE..."
"mkdir:Create a new directory | mkdir [OPTION]... DIRECTORY..."
"rmdir:Remove an empty directory | rmdir [OPTION]... DIRECTORY..."
"touch:Create empty file or update timestamp | touch [OPTION]... FILE..."
"cat:Concatenate and display files | cat [OPTION]... [FILE]..."
"less:View file contents with pagination | less [OPTION]... [FILE]..."
"head:Display first lines of a file | head [OPTION]... [FILE]..."
"tail:Display last lines of a file | tail [OPTION]... [FILE]..."
"chmod:Change file permissions | chmod [OPTION] MODE FILE..."
"chown:Change file owner | chown [OPTION]... OWNER[:GROUP] FILE..."
"ln:Create links between files | ln [OPTION]... TARGET LINK_NAME"
"file:Determine file type | file [OPTION]... FILE..."
"stat:Display file status | stat [OPTION]... FILE..."
# Text Processing
"grep:Search for patterns in files"
"sed:Stream editor for text manipulation"
"awk:Pattern scanning and text processing"
"cut:Remove sections from lines of files"
"sort:Sort lines of text"
"uniq:Report or filter out repeated lines"
"tr:Translate or delete characters"
"wc:Count lines, words, and characters"
"diff:Compare files line by line"
"grep:Search for patterns in files | grep [OPTION]... PATTERN [FILE]..."
"sed:Stream editor for text manipulation | sed [OPTION]... SCRIPT [FILE]..."
"awk:Pattern scanning and text processing | awk [OPTION]... PROGRAM [FILE]..."
"cut:Remove sections from lines of files | cut [OPTION]... [FILE]..."
"sort:Sort lines of text | sort [OPTION]... [FILE]..."
"uniq:Report or filter out repeated lines | uniq [OPTION]... [FILE]..."
"tr:Translate or delete characters | tr [OPTION]... SET1 [SET2]"
"wc:Count lines, words, and characters | wc [OPTION]... [FILE]..."
"diff:Compare files line by line | diff [OPTION]... FILE1 FILE2"
# File Search
"find:Search for files in directory hierarchy"
"locate:Find files by name quickly"
"which:Show full path of commands"
"whereis:Locate binary, source, and manual pages"
"find:Search for files in directory hierarchy | find [PATH] [OPTIONS] [EXPRESSION]"
"locate:Find files by name quickly | locate [OPTION]... PATTERN..."
"which:Show full path of commands | which [OPTION]... COMMAND..."
"whereis:Locate binary, source, and manual pages | whereis [OPTION]... COMMAND..."
# Compression
"tar:Archive files"
"gzip:Compress files"
"gunzip:Decompress gzip files"
"zip:Package and compress files"
"unzip:Extract compressed zip files"
"tar:Archive files | tar [OPTION]... [FILE]..."
"gzip:Compress files | gzip [OPTION]... [FILE]..."
"gunzip:Decompress gzip files | gunzip [OPTION]... [FILE]..."
"zip:Package and compress files | zip [OPTION]... ZIPFILE FILES..."
"unzip:Extract compressed zip files | unzip [OPTION]... FILE..."
# Network
"ping:Test network connectivity"
"curl:Transfer data from URLs"
"wget:Download files from the web"
"ssh:Secure shell remote login"
"scp:Secure copy files between hosts"
"netstat:Network statistics"
"ss:Socket statistics"
"ip:Show/manipulate routing and devices"
"ifconfig:Configure network interfaces"
"ping:Test network connectivity | ping [OPTION]... HOST"
"curl:Transfer data from URLs | curl [OPTION]... URL..."
"wget:Download files from the web | wget [OPTION]... URL..."
"ssh:Secure shell remote login | ssh [OPTION]... USER@HOST [COMMAND]"
"scp:Secure copy files between hosts | scp [OPTION]... SOURCE DEST"
"netstat:Network statistics | netstat [OPTION]..."
"ss:Socket statistics | ss [OPTION]..."
"ip:Show/manipulate routing and devices | ip [OPTION]... OBJECT {COMMAND}"
"ifconfig:Configure network interfaces | ifconfig [INTERFACE] [OPTIONS]"
# System Info
"top:Display system processes"
"htop:Interactive process viewer"
"ps:Report process status"
"df:Show disk space usage"
"du:Estimate file space usage"
"free:Display memory usage"
"uname:Print system information"
"uptime:Show how long system has been running"
"top:Display system processes | top [OPTION]..."
"htop:Interactive process viewer | htop [OPTION]..."
"ps:Report process status | ps [OPTION]..."
"df:Show disk space usage | df [OPTION]... [FILE]..."
"du:Estimate file space usage | du [OPTION]... [FILE]..."
"free:Display memory usage | free [OPTION]..."
"uname:Print system information | uname [OPTION]..."
"uptime:Show how long system has been running | uptime [OPTION]..."
# Process Management
"kill:Send signal to a process"
"pkill:Kill processes by name"
"killall:Kill processes by name"
"bg:Put job in background"
"fg:Bring job to foreground"
"jobs:List active jobs"
"kill:Send signal to a process | kill [OPTION]... PID..."
"pkill:Kill processes by name | pkill [OPTION]... PATTERN"
"killall:Kill processes by name | killall [OPTION]... NAME..."
"bg:Put job in background | bg [JOB_SPEC]"
"fg:Bring job to foreground | fg [JOB_SPEC]"
"jobs:List active jobs | jobs [OPTION]..."
# System Control
"sudo:Execute command as another user"
"systemctl:Control systemd services"
"service:Control system services"
"reboot:Reboot the system"
"shutdown:Shut down the system"
"sudo:Execute command as another user | sudo [OPTION]... COMMAND"
"systemctl:Control systemd services | systemctl [OPTION]... COMMAND"
"service:Control system services | service COMMAND [OPTIONS]"
"reboot:Reboot the system | reboot [OPTION]..."
"shutdown:Shut down the system | shutdown [OPTION]... [TIME]"
# Package Management
"apt:Package manager (Debian/Ubuntu)"
"apt-get:APT package handling utility"
"dpkg:Debian package manager"
"snap:Snap package manager"
"apt:Package manager (Debian/Ubuntu) | apt [OPTION]... COMMAND"
"apt-get:APT package handling utility | apt-get [OPTION]... COMMAND"
"dpkg:Debian package manager | dpkg [OPTION]... ACTION"
"snap:Snap package manager | snap [OPTION]... COMMAND"
# User Management
"useradd:Create new user"
"userdel:Delete user account"
"passwd:Change user password"
"su:Switch user"
"whoami:Print current username"
"w:Show who is logged in"
"who:Show who is logged in"
"useradd:Create new user | useradd [OPTION]... LOGIN"
"userdel:Delete user account | userdel [OPTION]... LOGIN"
"passwd:Change user password | passwd [OPTION]... [USER]"
"su:Switch user | su [OPTION]... [USER]"
"whoami:Print current username | whoami"
"w:Show who is logged in | w [OPTION]... [USER]"
"who:Show who is logged in | who [OPTION]..."
# Misc Utilities
"echo:Display a line of text"
"date:Display or set system date and time"
"cal:Display calendar"
"history:Show command history"
"alias:Create command aliases"
"export:Set environment variables"
"env:Display environment variables"
"man:Display manual pages"
"watch:Execute command periodically"
"echo:Display a line of text | echo [OPTION]... [STRING]..."
"date:Display or set system date and time | date [OPTION]... [+FORMAT]"
"cal:Display calendar | cal [OPTION]... [[MONTH] YEAR]"
"history:Show command history | history [n]"
"alias:Create command aliases | alias [NAME[=VALUE]...]"
"export:Set environment variables | export [NAME[=VALUE]...]"
"env:Display environment variables | env [OPTION]... [NAME=VALUE]... [COMMAND]"
"man:Display manual pages | man [OPTION]... [SECTION] PAGE"
"watch:Execute command periodically | watch [OPTION]... COMMAND"
)
# Parse arguments
@@ -750,16 +823,38 @@ if [ "$INTERACTIVE" = true ]; then
exit 1
fi
FZF_COMMAND=$(printf "%s\n" "${COMMANDS[@]}" | fzf --height 40% --border --preview 'echo {}' --preview-window=up:1:wrap)
# Enhanced preview showing command, description, and syntax
FZF_COMMAND=$(printf "%s\n" "${COMMANDS[@]}" | fzf --height 60% --border \
--preview 'echo -e "\033[0;36mCommand:\033[0m {1}\n\033[0;36mDescription:\033[0m {2}\n\033[0;36mSyntax:\033[0m {3}"' \
--preview-window=up:3:wrap \
--delimiter ':|\|' \
--with-nth 1,2,3)
if [ -n "$FZF_COMMAND" ]; then
# Parse the selected command: "cmd:description | syntax"
CMD=${FZF_COMMAND%%:*}
DESC=${FZF_COMMAND#*:}
REST=${FZF_COMMAND#*:}
# Extract description and syntax
if [[ "$REST" =~ (.+)\ \|\ (.+) ]]; then
DESC="${BASH_REMATCH[1]}"
SYNTAX="${BASH_REMATCH[2]}"
else
DESC="$REST"
SYNTAX="$CMD [options]"
fi
echo ""
echo -e "\033[0;34m═══════════════════════════════════════════════════════════\033[0m"
echo -e "\033[0;32mCommand:\033[0m $CMD"
echo -e "\033[0;32mDescription:\033[0m $DESC"
echo -e "\033[0;34m═══════════════════════════════════════════════════════════\033[0m"
echo -e "${BLUE}═══════════════════════════════════════════════════════════${NC}"
echo -e "${YELLOW}Command:${NC} ${MAGENTA}$CMD${NC}"
echo -e "${BLUE}═══════════════════════════════════════════════════════════${NC}"
echo ""
echo -e "${CYAN}${BOLD}SYNTAX:${NC}"
echo -e " ${GREEN}$SYNTAX${NC}"
echo ""
echo -e "${GREEN}Description:${NC} $DESC"
echo ""
echo -e "${BLUE}═══════════════════════════════════════════════════════════${NC}"
echo ""
read -p "Filter flags (optional, press Enter to skip): " FILTER
echo ""
@@ -772,11 +867,23 @@ if [ "$INTERACTIVE" = true ]; then
elif [ -n "$COMMAND" ]; then
# Validate command exists in our list
FOUND=false
DESC_PART=""
SYNTAX_PART=""
for cmd in "${COMMANDS[@]}"; do
CMD_NAME=${cmd%%:*}
if [ "$CMD_NAME" = "$COMMAND" ]; then
FOUND=true
DESC=${cmd#*:}
REST=${cmd#*:}
# Extract description and syntax
if [[ "$REST" =~ (.+)\ \|\ (.+) ]]; then
DESC_PART="${BASH_REMATCH[1]}"
SYNTAX_PART="${BASH_REMATCH[2]}"
else
DESC_PART="$REST"
SYNTAX_PART="$COMMAND [options]"
fi
break
fi
done
@@ -788,15 +895,22 @@ elif [ -n "$COMMAND" ]; then
echo ""
echo "Attempting to show flags anyway..."
echo ""
DESC_PART=$(get_command_description "$COMMAND")
SYNTAX_PART="$COMMAND [options]"
fi
# Show command info
DESC=$(get_command_description "$COMMAND")
# Show command info in enhanced format
echo ""
echo -e "\033[0;34m═══════════════════════════════════════════════════════════\033[0m"
echo -e "\033[0;32mCommand:\033[0m $COMMAND"
echo -e "\033[0;32mDescription:\033[0m $DESC"
echo -e "\033[0;34m═══════════════════════════════════════════════════════════\033[0m"
echo -e "${BLUE}═══════════════════════════════════════════════════════════${NC}"
echo -e "${YELLOW}Command:${NC} ${MAGENTA}$COMMAND${NC}"
echo -e "${BLUE}═══════════════════════════════════════════════════════════${NC}"
echo ""
echo -e "${CYAN}${BOLD}SYNTAX:${NC}"
echo -e " ${GREEN}$SYNTAX_PART${NC}"
echo ""
echo -e "${GREEN}Description:${NC} $DESC_PART"
echo ""
echo -e "${BLUE}═══════════════════════════════════════════════════════════${NC}"
echo ""
show_flags "$COMMAND" "$FILTER"