feat(ui): Add flag descriptions and fix flush-right alignment
Major improvements to interactive UI:
1. Enhanced Flag Descriptions:
- Completely rewrote extract_all_flags() function
- Now extracts full descriptions from man pages
- Format: "FLAG — description" (e.g., "-a, --all — do not ignore entries starting with .")
- Handles both OPTIONS and DESCRIPTION sections (GNU coreutils use DESCRIPTION)
- Uses portable AWK to parse multi-line descriptions
- Supports two man page formats:
* Flag and description on same line
* Flag on one line, description on next (indented)
2. Fixed Flush-Right Alignment:
- Corrected spacing calculation for interactive menu
- Removed extra -1 that caused 1-char gap
- Now exactly flush to terminal edge (80 chars = 80 chars)
- Formula: LEFT_WIDTH + FILL_SPACE + SYNTAX_LEN = TERM_WIDTH
3. Color Rendering:
- Already working from previous fix
- colorize_syntax() returns raw \033 codes
- Caller uses printf %b for proper rendering
Testing:
- ✓ All flag descriptions working (ls, grep, tar tested)
- ✓ Right-alignment exactly flush (80/80 chars)
- ✓ Color coordination working ([OPTIONS] yellow, FILE magenta)
User-requested features:
- ✓ "is there a way to have an explanation for the flags appear"
- ✓ "the right justification on the fuzzy search interactive menu is still not working properly"
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
+113
-18
@@ -628,21 +628,116 @@ colorize_syntax() {
|
||||
printf "%s" "$colored_syntax"
|
||||
}
|
||||
|
||||
# Extract all flags from man page or help
|
||||
# Extract flags with descriptions from man pages
|
||||
# New enhanced version that includes what each flag does
|
||||
extract_all_flags() {
|
||||
local cmd_name="$1"
|
||||
local flags_list=""
|
||||
local flags_output=""
|
||||
|
||||
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*-')
|
||||
# Shell builtin - use help command (basic format)
|
||||
flags_output=$(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)
|
||||
# External command - extract from man page OPTIONS or DESCRIPTION section with descriptions
|
||||
local man_content=$(man "$cmd_name" 2>/dev/null | col -b)
|
||||
|
||||
# Try OPTIONS section first, then DESCRIPTION (GNU coreutils use DESCRIPTION)
|
||||
# Exclude the section headers themselves to prevent early AWK exit
|
||||
local options_section=$(echo "$man_content" | sed -n '/^OPTIONS/,/^[A-Z][A-Z]/{/^OPTIONS/d; /^[A-Z][A-Z]/d; p;}' | head -300)
|
||||
|
||||
if [ -z "$options_section" ]; then
|
||||
# Try DESCRIPTION section instead
|
||||
options_section=$(echo "$man_content" | sed -n '/^DESCRIPTION/,/^[A-Z][A-Z]/{/^DESCRIPTION/d; /^[A-Z][A-Z]/d; p;}' | head -300)
|
||||
fi
|
||||
|
||||
if [ -n "$options_section" ]; then
|
||||
# Parse flags with their descriptions using portable AWK
|
||||
# Man pages have two formats:
|
||||
# 1. " --help Output..." (description on same line)
|
||||
# 2. " -a, --all\n description..." (description on next line, deeply indented)
|
||||
flags_output=$(echo "$options_section" | awk '
|
||||
BEGIN { flag=""; desc=""; }
|
||||
|
||||
/^[[:space:]]*-/ {
|
||||
# Print previous flag if exists
|
||||
if (flag != "") {
|
||||
gsub(/^[[:space:]]+|[[:space:]]+$/, "", desc)
|
||||
if (desc != "") {
|
||||
printf "%s — %s\n", flag, desc
|
||||
} else {
|
||||
printf "%s\n", flag
|
||||
}
|
||||
}
|
||||
|
||||
# New flag line - extract flag and check for inline description
|
||||
line = $0
|
||||
gsub(/^[[:space:]]+/, "", line) # Remove leading whitespace
|
||||
|
||||
# Check if there is content after the flag (separated by multiple spaces/tabs)
|
||||
# Flag pattern: starts with -, may have comma and long form
|
||||
# Look for 2+ spaces/tabs separating flag from description
|
||||
if (match(line, /^[^[:space:]]+([[:space:]]+[^[:space:]]+)?[[:space:]][[:space:]]+/)) {
|
||||
# Description on same line
|
||||
flag_end = RSTART + RLENGTH - 1
|
||||
flag = substr(line, 1, flag_end)
|
||||
gsub(/[[:space:]]+$/, "", flag) # Trim trailing spaces
|
||||
desc = substr(line, flag_end + 1)
|
||||
gsub(/^[[:space:]]+/, "", desc) # Trim leading spaces from description
|
||||
} else {
|
||||
# No inline description, will be on next line(s)
|
||||
flag = line
|
||||
desc = ""
|
||||
}
|
||||
next
|
||||
}
|
||||
|
||||
/^[[:space:]]+[^-]/ {
|
||||
# Description continuation line (indented, no leading dash)
|
||||
if (flag != "") {
|
||||
line = $0
|
||||
gsub(/^[[:space:]]+|[[:space:]]+$/, "", line)
|
||||
if (desc == "") {
|
||||
desc = line
|
||||
} else {
|
||||
desc = desc " " line
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/^[A-Z][A-Z]/ {
|
||||
# Major section header - end of options
|
||||
if (flag != "") {
|
||||
gsub(/^[[:space:]]+|[[:space:]]+$/, "", desc)
|
||||
if (desc != "") {
|
||||
printf "%s — %s\n", flag, desc
|
||||
} else {
|
||||
printf "%s\n", flag
|
||||
}
|
||||
}
|
||||
exit
|
||||
}
|
||||
|
||||
END {
|
||||
# Print last flag
|
||||
if (flag != "") {
|
||||
gsub(/^[[:space:]]+|[[:space:]]+$/, "", desc)
|
||||
if (desc != "") {
|
||||
printf "%s — %s\n", flag, desc
|
||||
} else {
|
||||
printf "%s\n", flag
|
||||
}
|
||||
}
|
||||
}
|
||||
' | head -150)
|
||||
fi
|
||||
|
||||
# Fallback: if no OPTIONS section, just get flag lines
|
||||
if [ -z "$flags_output" ]; then
|
||||
flags_output=$(echo "$man_content" | grep -E '^[[:space:]]*-' | head -100)
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "$flags_list"
|
||||
echo "$flags_output"
|
||||
}
|
||||
|
||||
# Interactive flag browser with fuzzy search
|
||||
@@ -1018,22 +1113,22 @@ if [ "$INTERACTIVE" = true ]; then
|
||||
DESC_LEN=${#DESC_PART}
|
||||
SYNTAX_LEN=${#SYNTAX_PART} # Use original length, not colorized
|
||||
|
||||
# Calculate spaces needed for flush right-alignment
|
||||
# Account for: cmd + ": " + desc + spaces + syntax
|
||||
# Reduce safety padding from 8 to 2 for tighter right-alignment
|
||||
VISIBLE_WIDTH=$((CMD_LEN + 2 + DESC_LEN + SYNTAX_LEN))
|
||||
NEEDED_SPACES=$((TERM_WIDTH - VISIBLE_WIDTH - 2)) # Minimal padding for flush right
|
||||
# For tighter right-alignment, calculate remaining space and fill it
|
||||
# Terminal width - command - ": " - description = space for syntax
|
||||
LEFT_SIDE_WIDTH=$((CMD_LEN + 2 + DESC_LEN))
|
||||
REMAINING_WIDTH=$((TERM_WIDTH - LEFT_SIDE_WIDTH)) # Exact flush-right alignment
|
||||
|
||||
# Ensure minimum spacing
|
||||
[ $NEEDED_SPACES -lt 2 ] && NEEDED_SPACES=2
|
||||
# Create padding to push syntax all the way right
|
||||
# Fill space between description and syntax
|
||||
FILL_WIDTH=$((REMAINING_WIDTH - SYNTAX_LEN))
|
||||
[ $FILL_WIDTH -lt 1 ] && FILL_WIDTH=1
|
||||
|
||||
# Create spacing string
|
||||
SPACES=$(printf '%*s' "$NEEDED_SPACES" '')
|
||||
SPACES=$(printf '%*s' "$FILL_WIDTH" '')
|
||||
|
||||
# Format with colors:
|
||||
# - Bright cyan for command name
|
||||
# - White for description
|
||||
# - Colorized syntax (right-aligned with cyan cmd, yellow [OPTIONS], magenta FILE, etc.)
|
||||
# - Colorized syntax (absolutely right-aligned)
|
||||
formatted_line="\033[0;36m${CMD_NAME}\033[0m: ${DESC_PART}${SPACES}${COLORIZED_SYNTAX}"
|
||||
|
||||
FORMATTED_COMMANDS+=("$formatted_line")
|
||||
|
||||
Reference in New Issue
Block a user