mirror of
https://github.com/ohmyzsh/ohmyzsh.git
synced 2026-01-23 02:35:38 +01:00
Adds zsh-vi-man plugin that provides smart man page lookup for zsh vi mode and emacs mode. Press K in vi normal mode, Ctrl-X k in emacs mode, or Ctrl-K in vi insert mode on any command or option to open its man page. Features: - Smart subcommand detection (git commit → man git-commit) - Option jumping (grep -r → jumps to -r entry in man page) - Combined options support (rm -rf → finds both -r and -f) - Pipe support (cat file | grep -i → opens man grep) - Multiple pager support (less, vim, nvim)
107 lines
5.1 KiB
Bash
107 lines
5.1 KiB
Bash
# lib/pattern.zsh - Search pattern builders for different pagers
|
|
# Generates regex patterns for option search in man pages
|
|
|
|
# Build search pattern for less pager (ERE - Extended Regular Expressions)
|
|
# Patterns match option definitions: lines starting with whitespace then dash
|
|
# Supports comma-separated (GNU style) and slash-separated (jq style) options
|
|
# Input: $1 = word (the option, e.g., "-l", "--recursive", "-rf")
|
|
# Output: ERE pattern string
|
|
zvm_build_less_pattern() {
|
|
local word="$1"
|
|
local pattern=""
|
|
|
|
if [[ -z "$word" ]]; then
|
|
echo ""
|
|
return
|
|
fi
|
|
|
|
# Long option with value: --color=always -> search for --color
|
|
# Use -[^[:space:],/]* instead of -.* to prevent matching across descriptions
|
|
# Use (-[^[:space:],/]*[,/][[:space:]]+)* to allow multiple preceding options
|
|
if [[ "$word" =~ ^--[^=]+= ]]; then
|
|
local opt="${word%%=*}"
|
|
pattern="^[[:space:]]*${opt}([,/=:[[:space:]]|$)|^[[:space:]]*(-[^[:space:],/]*[,/][[:space:]]+)+${opt}([,/=:[[:space:]]|$)"
|
|
|
|
# Combined short options: -rf -> search for -[rf] to find individual options
|
|
# Also includes fallback for single-dash long options like find's -name, -type
|
|
# Use (-[^[:space:],/]*[,/][[:space:]]+)+ to allow multiple preceding options
|
|
elif [[ "$word" =~ ^-[a-zA-Z]{2,}$ ]]; then
|
|
local chars="${word:1}"
|
|
# Pattern 1: individual chars (e.g., -r or -f from -rf)
|
|
# Pattern 2: the full word as-is (e.g., -name for find)
|
|
pattern="^[[:space:]]*-[${chars}][,/:[:space:]]|^[[:space:]]*(-[^[:space:],/]*[,/][[:space:]]+)+-[${chars}][,/:[:space:]]|^[[:space:]]*${word}([,/:[:space:]]|$)|^[[:space:]]*(-[^[:space:],/]*[,/][[:space:]]+)+${word}([,/:[:space:]]|$)"
|
|
|
|
# Single short option: -r -> match at start of option definition line
|
|
# Use (-[^[:space:],/]*[,/][[:space:]]+)+ to allow multiple preceding options
|
|
elif [[ "$word" =~ ^-[a-zA-Z]$ ]]; then
|
|
pattern="^[[:space:]]*${word}[,/:[:space:]]|^[[:space:]]*(-[^[:space:],/]*[,/][[:space:]]+)+${word}([,/:[:space:]]|$)"
|
|
|
|
# Long option without value: --recursive
|
|
# Use (-[^[:space:],/]*[,/][[:space:]]+)+ to allow multiple preceding options
|
|
elif [[ "$word" =~ ^-- ]]; then
|
|
pattern="^[[:space:]]*${word}([,/=:[[:space:]]|$)|^[[:space:]]*(-[^[:space:],/]*[,/][[:space:]]+)+${word}([,/=:[[:space:]]|$)"
|
|
fi
|
|
|
|
echo "$pattern"
|
|
}
|
|
|
|
# Build search pattern for vim/neovim (Vim regex syntax)
|
|
# Matches option definitions: lines starting with whitespace then dash
|
|
# Supports comma-separated (GNU style) and slash-separated (jq style) options
|
|
# Uses word boundaries to prevent partial matches (e.g., --slurp vs --slurpfile)
|
|
# Input: $1 = word (the option, e.g., "-l", "--recursive", "-rf")
|
|
# Output: Vim search pattern string
|
|
zvm_build_nvim_pattern() {
|
|
local word="$1"
|
|
local search_term=""
|
|
|
|
if [[ -z "$word" ]]; then
|
|
echo ""
|
|
return
|
|
fi
|
|
|
|
# Long option with value: --color=always -> search for --color
|
|
# Match: at line start OR after comma/slash separator
|
|
# End: followed by delimiter (comma, slash, equals, colon, space) or EOL
|
|
# Use \(-[^[:space:],/]*[,/][[:space:]]*\)\+ to allow multiple preceding options
|
|
if [[ "$word" =~ ^--[^=]+= ]]; then
|
|
local opt="${word%%=*}"
|
|
search_term="^[[:space:]]*${opt}\\([,/=:[[:space:]]\\|$\\)\\|^[[:space:]]*\\(-[^[:space:],/]*[,/][[:space:]]*\\)\\+${opt}\\([,/=:[[:space:]]\\|$\\)"
|
|
|
|
# Combined short options: -la -> search for -l or -a
|
|
# Also includes the full word as fallback for find-style -name, -type
|
|
# Use \(-[^[:space:],/]*[,/][[:space:]]*\)\+ to allow multiple preceding options
|
|
elif [[ "$word" =~ ^-[a-zA-Z]{2,}$ ]]; then
|
|
local chars="${word:1}"
|
|
local alternation=""
|
|
# Pattern for individual chars (e.g., -r or -f from -rf)
|
|
for (( i=0; i<${#chars}; i++ )); do
|
|
local char="-${chars:$i:1}"
|
|
if [[ -n "$alternation" ]]; then
|
|
alternation="${alternation}\\|^[[:space:]]*${char}[,/:[:space:]]\\|^[[:space:]]*\\(-[^[:space:],/]*[,/][[:space:]]*\\)\\+${char}\\([,/:[:space:]]\\|$\\)"
|
|
else
|
|
alternation="^[[:space:]]*${char}[,/:[:space:]]\\|^[[:space:]]*\\(-[^[:space:],/]*[,/][[:space:]]*\\)\\+${char}\\([,/:[:space:]]\\|$\\)"
|
|
fi
|
|
done
|
|
# Add full word as fallback (for find-style -name, -exec, etc.)
|
|
alternation="${alternation}\\|^[[:space:]]*${word}\\([,/:[:space:]]\\|$\\)\\|^[[:space:]]*\\(-[^[:space:],/]*[,/][[:space:]]*\\)\\+${word}\\([,/:[:space:]]\\|$\\)"
|
|
search_term="${alternation}"
|
|
|
|
# Single short option: -r
|
|
# Match: at line start OR after comma/slash separator
|
|
# End: followed by delimiter or EOL
|
|
# Use \(-[^[:space:],/]*[,/][[:space:]]*\)\+ to allow multiple preceding options
|
|
elif [[ "$word" =~ ^-[a-zA-Z]$ ]]; then
|
|
search_term="^[[:space:]]*${word}[,/:[:space:]]\\|^[[:space:]]*\\(-[^[:space:],/]*[,/][[:space:]]*\\)\\+${word}\\([,/:[:space:]]\\|$\\)"
|
|
|
|
# Long option without value: --recursive
|
|
# Match: at line start OR after comma/slash separator
|
|
# End: followed by delimiter or EOL (prevents --slurp matching --slurpfile)
|
|
# Use \(-[^[:space:],/]*[,/][[:space:]]*\)\+ to allow multiple preceding options
|
|
elif [[ "$word" =~ ^-- ]]; then
|
|
search_term="^[[:space:]]*${word}\\([,/=:[[:space:]]\\|$\\)\\|^[[:space:]]*\\(-[^[:space:],/]*[,/][[:space:]]*\\)\\+${word}\\([,/=:[[:space:]]\\|$\\)"
|
|
fi
|
|
|
|
echo "$search_term"
|
|
}
|
|
|