diff --git a/bash-abbr b/bash-abbr index 599c3d7..a0c8b78 100644 --- a/bash-abbr +++ b/bash-abbr @@ -4,13 +4,16 @@ # put into the bashrc drop-in directory ~/.bashrc.d/ # and then sourced from ~/.bashrc. -# WARNING: 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) +# Disable plugin by uncommenting this line +# return -# Regexes for (heuristically) determining whether we're abbreviating the first word. +# 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) + +# Regexes for heuristically determining whether we're abbreviating the first word. # Construction put into functions to prevent global namespace pollution -# and increase readability. +# and to increase readability. _control_op () { declare -r _newline=$'\n' \ _bg_proc_or_and_and='[^&;]&&?' \ @@ -27,7 +30,7 @@ _control_op () { unset -f _control_op } # shellcheck disable=SC2155 -declare _control_op="$(_control_op)" +declare _control_op="$(_control_op)" # TODO use bash 5.3 `${}` command substitution syntax to avoid subshells _redir_or_assign_word () { # shellcheck disable=SC2016 @@ -66,7 +69,7 @@ _redir_or_assign_word () { unset -f _redir_or_assign_word } # shellcheck disable=SC2155 -declare -r _redir_or_assign_word="$(_redir_or_assign_word)" +declare -r _redir_or_assign_word="$(_redir_or_assign_word)" # TODO use bash 5.3 `${}` command substitution syntax to avoid subshells declare -r is_first_word_prefix="($_control_op)[[:space:]]*((($_redir_or_assign_word)[[:space:]])*)" # If the regex leads to problems/performance issues, you may try this simpler regex @@ -170,14 +173,14 @@ _try_abbrev_internal () { } _try_abbrev () { # For use within bind -x. - # Perform abbreviation lookup and interactive expansion on the shell-word left to the cursor (no quote parsing). + # Perform abbreviation lookup and interactive expansion on the word left to the cursor (no quote parsing). # Takes a single argument which is the character to self-insert (usually space or another shell metacharacter). # To prevent infinite recursion, we need to keep track - # of which aliases have been expanded. This function re-initializes the associative array (used as a hash set) + # of which aliases have been expanded. This function re-initializes the global associative array (used as a hash set) declare -gA _expanded_aliases=() - # Calls the implementation and pass necessary arguments + # Calls the implementation and passes necessary arguments _try_abbrev_internal "$READLINE_LINE" "$READLINE_POINT" "$READLINE_MARK" READLINE_LINE READLINE_POINT READLINE_MARK "$@" # Don't pollute global namespace @@ -201,16 +204,16 @@ bash_abbr () { # we need to implement recursive alias expansion on the entire line # like bash does. Basically something like alias-expand-line but # called as many times as possible before recursion would happen. + # This is pretty hard, and surely even harder to do efficiently, + # so it will probably never be implemented. bind -x '"\e\C-an": _try_abbrev ""' bind '"\e\C-j": accept-line' bind '"\C-m": "\e\C-an\e^\e\C-j"' bind '"\C-j": "\C-m"' } -# Disable plugin by commenting this line and uncommenting the line below that -# This function name shall never change, so that script that source -# this plugin can detect for it. I.e., in your .bashrc, you may do -# `type bash_abbr &>/dev/null && shopt -u expand_aliases` -# after sourcing this plugin. bash_abbr -# unset -f bash_abbr + +# If the plugin is enabled, we usually don't want regular alias expansion, +# since it can lead to undesirable "double expansions" if an alias is defined recursively. +type bash_abbr &>/dev/null && shopt -u expand_aliases