feat(ui): Right-align syntax in interactive menu + fuzzy flag search
Major UX improvements: 1. Interactive menu now shows syntax right-aligned (clean layout) 2. Replaced broken filter prompt with fuzzy flag search 3. Simplified flag extraction (more reliable, gets all flags) Interactive Menu Enhancement: - Description on left, syntax on right - Terminal-width aware formatting - Clean, scannable display - Example: 'ls:List directory contents ls [OPTION]... [FILE]...' Fuzzy Flag Browser: - Removed filter prompt step (was broken) - Extract ALL flags from man page (up to 200) - Show in fzf with fuzzy search - Type to search through flags dynamically - Multi-select support (Ctrl-A, Ctrl-D) - Clean header with instructions Flag Extraction: - Simplified from complex awk to simple grep - More reliable: grep -E '^[[:space:]]*-' - Works for all commands with man pages - Extracts 60+ flags for common commands - Handles both long and short flags User Experience: - No more broken filter step - Instant fuzzy search through all flags - Right-aligned syntax for better readability - Consistent, professional display
This commit is contained in:
+121
-62
@@ -500,15 +500,68 @@ get_quick_syntax() {
|
||||
echo "$syntax"
|
||||
}
|
||||
|
||||
# Extract all flags from man page or help
|
||||
extract_all_flags() {
|
||||
local cmd_name="$1"
|
||||
local flags_list=""
|
||||
|
||||
if type "$cmd_name" 2>/dev/null | grep -q "shell builtin"; then
|
||||
# Shell builtin - use help command
|
||||
flags_list=$(help "$cmd_name" 2>/dev/null | grep -E '^\s*-')
|
||||
elif command -v "$cmd_name" &> /dev/null; then
|
||||
# External command - use man page
|
||||
# Get lines that start with optional whitespace and a dash (flags)
|
||||
flags_list=$(man "$cmd_name" 2>/dev/null | col -b | grep -E '^[[:space:]]*-' | head -200)
|
||||
fi
|
||||
|
||||
echo "$flags_list"
|
||||
}
|
||||
|
||||
# Interactive flag browser with fuzzy search
|
||||
browse_flags_fuzzy() {
|
||||
local cmd_name="$1"
|
||||
|
||||
echo ""
|
||||
echo -e "${CYAN}Extracting flags from man page...${NC}"
|
||||
|
||||
# Extract all flags
|
||||
local all_flags=$(extract_all_flags "$cmd_name")
|
||||
|
||||
if [ -z "$all_flags" ]; then
|
||||
echo -e "${RED}No flags found for: $cmd_name${NC}"
|
||||
echo ""
|
||||
echo "Showing basic command info..."
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Count flags
|
||||
local flag_count=$(echo "$all_flags" | wc -l)
|
||||
|
||||
echo -e "${GREEN}Found $flag_count flags. Opening fuzzy search...${NC}"
|
||||
echo ""
|
||||
sleep 1
|
||||
|
||||
# Show in fzf for fuzzy searching
|
||||
echo "$all_flags" | fzf \
|
||||
--height 80% \
|
||||
--border \
|
||||
--header "🔍 Fuzzy search through $cmd_name flags (Esc to exit)" \
|
||||
--preview 'echo {}' \
|
||||
--preview-window=up:40%:wrap \
|
||||
--prompt "Search flags: " \
|
||||
--multi \
|
||||
--bind 'ctrl-a:select-all' \
|
||||
--bind 'ctrl-d:deselect-all'
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
show_flags() {
|
||||
CMD_NAME=$1
|
||||
FILTER=$2
|
||||
|
||||
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${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 ""
|
||||
|
||||
@@ -542,51 +595,14 @@ show_flags() {
|
||||
echo ""
|
||||
fi
|
||||
|
||||
# Display FLAGS/OPTIONS section
|
||||
# Display FLAGS/OPTIONS section with fuzzy search
|
||||
echo -e "${YELLOW}${BOLD}FLAGS/OPTIONS:${NC}"
|
||||
echo -e "${DIM}Opening interactive flag browser...${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 -iE "(^|\s)-.*$FILTER" | head -30
|
||||
else
|
||||
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
|
||||
# Extract the OPTIONS section from man page
|
||||
local man_output=$(man "$CMD_NAME" 2>/dev/null | col -b)
|
||||
# Use fuzzy flag browser instead of static display
|
||||
browse_flags_fuzzy "$CMD_NAME"
|
||||
|
||||
if [ -z "$man_output" ]; then
|
||||
echo -e "${RED}No manual page available for: $CMD_NAME${NC}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Try to extract just the OPTIONS/FLAGS section
|
||||
local options_section=$(echo "$man_output" | sed -n '/^OPTIONS/,/^[A-Z][A-Z]/p' | head -100)
|
||||
|
||||
if [ -z "$options_section" ]; then
|
||||
# Fallback: get all lines that look like flags
|
||||
options_section=$(echo "$man_output" | grep -E '^\s*-' | head -50)
|
||||
fi
|
||||
|
||||
if [ -n "$FILTER" ]; then
|
||||
# Improved filter logic: match flag name or description
|
||||
echo "$options_section" | grep -iE "(^|\s)-.*$FILTER|$FILTER.*-" | head -40
|
||||
else
|
||||
echo "$options_section" | head -40
|
||||
fi
|
||||
else
|
||||
echo -e "${RED}Could not find help for: $CMD_NAME${NC}"
|
||||
echo ""
|
||||
echo "Make sure the command is installed or check the spelling."
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo -e "${DIM}Tip: Use the filter to search for specific flags or keywords${NC}"
|
||||
echo ""
|
||||
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||||
}
|
||||
@@ -823,27 +839,71 @@ if [ "$INTERACTIVE" = true ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 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)
|
||||
# Format commands for display: description on left, syntax on right
|
||||
# Get terminal width for proper alignment
|
||||
TERM_WIDTH=$(tput cols 2>/dev/null || echo 120)
|
||||
SYNTAX_WIDTH=50
|
||||
DESC_WIDTH=$((TERM_WIDTH - SYNTAX_WIDTH - 5))
|
||||
|
||||
if [ -n "$FZF_COMMAND" ]; then
|
||||
# Parse the selected command: "cmd:description | syntax"
|
||||
CMD=${FZF_COMMAND%%:*}
|
||||
REST=${FZF_COMMAND#*:}
|
||||
# Format each command with right-aligned syntax
|
||||
FORMATTED_COMMANDS=()
|
||||
for cmd in "${COMMANDS[@]}"; do
|
||||
CMD_NAME=${cmd%%:*}
|
||||
REST=${cmd#*:}
|
||||
|
||||
# Extract description and syntax
|
||||
if [[ "$REST" =~ (.+)\ \|\ (.+) ]]; then
|
||||
DESC="${BASH_REMATCH[1]}"
|
||||
SYNTAX="${BASH_REMATCH[2]}"
|
||||
DESC_PART="${BASH_REMATCH[1]}"
|
||||
SYNTAX_PART="${BASH_REMATCH[2]}"
|
||||
else
|
||||
DESC="$REST"
|
||||
SYNTAX="$CMD [options]"
|
||||
DESC_PART="$REST"
|
||||
SYNTAX_PART="$CMD_NAME [options]"
|
||||
fi
|
||||
|
||||
# Truncate if too long
|
||||
if [ ${#DESC_PART} -gt $DESC_WIDTH ]; then
|
||||
DESC_PART="${DESC_PART:0:$((DESC_WIDTH-3))}..."
|
||||
fi
|
||||
if [ ${#SYNTAX_PART} -gt $SYNTAX_WIDTH ]; then
|
||||
SYNTAX_PART="${SYNTAX_PART:0:$((SYNTAX_WIDTH-3))}..."
|
||||
fi
|
||||
|
||||
# Format with padding
|
||||
printf -v formatted_line "%-${DESC_WIDTH}s %${SYNTAX_WIDTH}s" "$CMD_NAME:$DESC_PART" "$SYNTAX_PART"
|
||||
FORMATTED_COMMANDS+=("$formatted_line")
|
||||
done
|
||||
|
||||
# Show in fzf with formatted display
|
||||
SELECTED=$(printf "%s\n" "${FORMATTED_COMMANDS[@]}" | fzf \
|
||||
--height 60% \
|
||||
--border \
|
||||
--header "Select a command (description | syntax)" \
|
||||
--prompt "🔍 Search: " \
|
||||
--preview-window=hidden \
|
||||
--ansi)
|
||||
|
||||
if [ -n "$SELECTED" ]; then
|
||||
# Extract command name from selection
|
||||
CMD=$(echo "$SELECTED" | awk -F: '{print $1}')
|
||||
|
||||
# Find the original command entry to get full details
|
||||
for cmd in "${COMMANDS[@]}"; do
|
||||
CMD_NAME=${cmd%%:*}
|
||||
if [ "$CMD_NAME" = "$CMD" ]; then
|
||||
REST=${cmd#*:}
|
||||
|
||||
# Extract description and syntax
|
||||
if [[ "$REST" =~ (.+)\ \|\ (.+) ]]; then
|
||||
DESC="${BASH_REMATCH[1]}"
|
||||
SYNTAX="${BASH_REMATCH[2]}"
|
||||
else
|
||||
DESC="$REST"
|
||||
SYNTAX="$CMD [options]"
|
||||
fi
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo -e "${BLUE}═══════════════════════════════════════════════════════════${NC}"
|
||||
echo -e "${YELLOW}Command:${NC} ${MAGENTA}$CMD${NC}"
|
||||
@@ -855,10 +915,9 @@ if [ "$INTERACTIVE" = true ]; then
|
||||
echo -e "${GREEN}Description:${NC} $DESC"
|
||||
echo ""
|
||||
echo -e "${BLUE}═══════════════════════════════════════════════════════════${NC}"
|
||||
echo ""
|
||||
read -p "Filter flags (optional, press Enter to skip): " FILTER
|
||||
echo ""
|
||||
show_flags "$CMD" "$FILTER"
|
||||
|
||||
# Directly show fuzzy flag browser (no filter prompt)
|
||||
show_flags "$CMD"
|
||||
else
|
||||
echo "No command selected"
|
||||
exit 0
|
||||
|
||||
Reference in New Issue
Block a user