Expand aliases when point is on word
The self-insertion character has to be empty for that to work This is usually the case when pressing enter
This commit is contained in:
parent
94f8211b87
commit
fb37d2b89e
1 changed files with 20 additions and 8 deletions
28
bash-abbr
28
bash-abbr
|
|
@ -10,6 +10,8 @@
|
|||
# WARNING 1: This plugin creates and overwrites various readline bindings.
|
||||
# Therefore, it might interfere with other plugins/custom bindings.
|
||||
# Some bindings may be changed (e.g. \e\C-a...) while others should not (e.g. \C-m)
|
||||
# WARNING 2: This plugin needs and enables extended globbing.
|
||||
shopt -s extglob
|
||||
|
||||
# Regexes for heuristically determining whether we're abbreviating the first word.
|
||||
# Construction put into functions to prevent global namespace pollution
|
||||
|
|
@ -82,18 +84,28 @@ _try_abbrev_internal () {
|
|||
# Recursively perform abbrevation on the line defined by $1, taking $2 as the point and $3 as the mark.
|
||||
# Set the vars defined by $4, $5 and $6 to the updated values (line, point and mark).
|
||||
# $7 is the character/string to self-insert.
|
||||
declare -r line=$1 point=$2 mark=$3 new_line=$4 new_point=$5 new_mark=$6 \
|
||||
level=${#FUNCNAME[@]}
|
||||
declare -r line=$1 mark=$3 new_line=$4 new_point=$5 new_mark=$6 \
|
||||
level=${#FUNCNAME[@]}
|
||||
declare point=$2
|
||||
declare self_insertion=$7
|
||||
# `level` is needed to keep track of the recursion, because we don't have a return value but rather
|
||||
# set a variable defined in the calling context. This level is just appended to the identifier to make it unique
|
||||
# across all the recursive calls.
|
||||
|
||||
declare -r line_until_point=${line::point}
|
||||
# If the self-insertion character is null (i.e. when pressing enter/accepting a line),
|
||||
# then we also want to expand aliases if the cursor/point is *on* the word instead of just *after* the word.
|
||||
if [[ -z $self_insertion ]]; then
|
||||
line_from_point=${line:point}
|
||||
line_from_point_without_partial_word=${line_from_point##*([^<>&;()|[:space:]])} # extglob must be enabled!
|
||||
# Move point forward to right after the word. Keep mark where it is.
|
||||
point=${#line}-${#line_from_point_without_partial_word}
|
||||
fi
|
||||
declare -r point line_until_point=${line::point}
|
||||
|
||||
if
|
||||
# Check if the character at point is a shell metacharacter or EOL
|
||||
[[ $point -eq ${#line} || "${line:point:1}" = [\<\>\&\;\(\)\|[:space:]] ]] &&
|
||||
# [[ $point -eq ${#line} || "${line:point:1}" = [\<\>\&\;\(\)\|[:space:]] ]] &&
|
||||
# NOTE: Above line commented out, it's actually not that useful.
|
||||
|
||||
# Determine word to complete
|
||||
# Uses the same word separators as bash (| & ; ( ) space tab newline) (aka "shell metacharacters")
|
||||
|
|
@ -141,7 +153,7 @@ _try_abbrev_internal () {
|
|||
declare tmp=" $replacement"
|
||||
[[ $tmp =~ ^([[:space:]]*$is_first_word_prefix) ]] && tmp=${tmp#"${BASH_REMATCH[1]}"}
|
||||
declare -r word_to_expand=${tmp%%[<>&;()|[:space:]]*}
|
||||
if [[ ! ${_expanded_aliases[$word_to_expand]-} ]]; then
|
||||
if [[ -z ${_expanded_aliases[$word_to_expand]-} ]]; then
|
||||
declare -r point_for_replacement=$((${#BASH_REMATCH[1]}+${#word_to_expand}))
|
||||
declare -g "ret_$level"
|
||||
declare -n recursively_expanded_replacement="ret_$level"
|
||||
|
|
@ -149,7 +161,7 @@ _try_abbrev_internal () {
|
|||
replacement=${recursively_expanded_replacement# }
|
||||
fi
|
||||
# Eval if it has a trailing exclamation point and strip trailing \n and \r
|
||||
[[ $eval_expansion = true ]] && replacement=$(eval "${replacement%!}")
|
||||
"$eval_expansion" && replacement=$(eval "${replacement%!}")
|
||||
|
||||
# Calculate point and mark offset.
|
||||
declare -ir offset=${#replacement}-${#word_at_point}+${#self_insertion}
|
||||
|
|
@ -164,8 +176,8 @@ _try_abbrev_internal () {
|
|||
eval "$new_line"'=${line_until_point}${self_insertion}${line:point}'
|
||||
fi
|
||||
|
||||
# Advance mark if it's right of (or on) the point.
|
||||
[[ $mark && $mark -ge "$point" ]] && eval "$new_mark"'=$((mark+offset))'
|
||||
# Advance mark if it's set and right of (or on) the point.
|
||||
[[ $mark && mark -ge point ]] && eval "$new_mark"'=$((mark+offset))'
|
||||
|
||||
# Advance point.
|
||||
eval "$new_point"'=$((point+offset))'
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue