* CI: disable Ubuntu 16.04 as it's EOL https://github.blog/changelog/2021-04-29-github-actions-ubuntu-16-04-lts-virtual-environment-will-be-removed-on-september-20-2021/ * main: lint false positive * install: lint * plugins/cmd-returned-notify: don't `export` * plugins/xterm: lint * plugins/git: lint * plugins/goenv: lint * plugins/alias-completion: lint false positives * plugins/alias-completion: fix SC2155, SC2154 Declare `locals` at the top of the function * completion: lint completions using `bash_completion` functions Match the style of the existing code * completion/knife: lint false positives * completion/knife: lint * completion/sdkman: lint * completion/composer: lint * Move `.shellcheckrc` under `themes/` * lib/theme: fix SC2155, SC2154, SC2034 * lib/colors: don't warn on unused variables We assign a large number of variables here and they may or may not be used anywhere else, so disable SC2034 for this file (only). Alsö disable SC2005 as the functions in this file were written before `printf` was invented and have to do some fancy metascripting to get escape sequences interpreted reliably. I’m not smart enough to fix this to use `printf`, so leave it for now. * themes/agnoster: lint * themes: disable SC2154 for colors Each one of these themes will need it’s own fix for SC2154, possibly upstream. Due to the way themes are, it's entirely normal to have a *lot* of false positives for SC2034. So much so, that I have to admit that it is probably just not worth linting for SC2034 despite my dislike of blanket ignore rules. * themes: disable SC2154, fix SC2155 Each one of these themes will need it’s own fix for SC2154, possibly upstream. Due to the way themes are, it's entirely normal to have a *lot* of false positives for SC2034. So much so, that I have to admit that it is probably just not worth linting for SC2034 despite my dislike of blanket ignore rules. * Delete `.shellcheckrc` * remove executable bit
106 lines
4.5 KiB
Bash
106 lines
4.5 KiB
Bash
# shellcheck shell=bash
|
|
# Load after the other completions to understand what needs to be completed
|
|
# BASH_IT_LOAD_PRIORITY: 365
|
|
|
|
cite about-plugin
|
|
about-plugin 'Automatic completion of aliases'
|
|
|
|
# References:
|
|
# http://superuser.com/a/437508/119764
|
|
# http://stackoverflow.com/a/1793178/1228454
|
|
|
|
# This needs to be a plugin so it gets executed after the completions and the aliases have been defined.
|
|
# Bash-it loads its components in the order
|
|
# 1) Aliases
|
|
# 2) Completions
|
|
# 3) Plugins
|
|
# 4) Custom scripts
|
|
|
|
# Automatically add completion for all aliases to commands having completion functions
|
|
function alias_completion {
|
|
local namespace="alias_completion"
|
|
local tmp_file completion_loader alias_name alias_tokens line completions
|
|
local alias_arg_words new_completion compl_func compl_wrapper
|
|
|
|
# parse function based completion definitions, where capture group 2 => function and 3 => trigger
|
|
local compl_regex='complete( +[^ ]+)* -F ([^ ]+) ("[^"]+"|[^ ]+)'
|
|
# parse alias definitions, where capture group 1 => trigger, 2 => command, 3 => command arguments
|
|
local alias_regex="alias( -- | )([^=]+)='(\"[^\"]+\"|[^ ]+)(( +[^ ]+)*)'"
|
|
|
|
# create array of function completion triggers, keeping multi-word triggers together
|
|
eval "completions=($(complete -p | sed -Ene "/$compl_regex/s//'\3'/p"))"
|
|
((${#completions[@]} == 0)) && return 0
|
|
|
|
# create temporary file for wrapper functions and completions
|
|
tmp_file="$(mktemp -t "${namespace}-${RANDOM}XXXXXX")" || return 1
|
|
|
|
completion_loader="$(complete -p -D 2> /dev/null | sed -Ene 's/.* -F ([^ ]*).*/\1/p')"
|
|
|
|
# read in "<alias> '<aliased command>' '<command args>'" lines from defined aliases
|
|
# some aliases do have backslashes that needs to be interpreted
|
|
# shellcheck disable=SC2162
|
|
while read line; do
|
|
eval "alias_tokens=($line)" 2> /dev/null || continue # some alias arg patterns cause an eval parse error
|
|
# shellcheck disable=SC2154 # see `eval` above
|
|
alias_name="${alias_tokens[0]}" alias_cmd="${alias_tokens[1]}" alias_args="${alias_tokens[2]# }"
|
|
|
|
# skip aliases to pipes, boolean control structures and other command lists
|
|
# (leveraging that eval errs out if $alias_args contains unquoted shell metacharacters)
|
|
eval "alias_arg_words=($alias_args)" 2> /dev/null || continue
|
|
# avoid expanding wildcards
|
|
read -a alias_arg_words <<< "$alias_args"
|
|
|
|
# skip alias if there is no completion function triggered by the aliased command
|
|
if ! _bash-it-array-contains-element "$alias_cmd" "${completions[@]}"; then
|
|
if [[ -n "$completion_loader" ]]; then
|
|
# force loading of completions for the aliased command
|
|
eval "$completion_loader $alias_cmd"
|
|
# 124 means completion loader was successful
|
|
[[ $? -eq 124 ]] || continue
|
|
completions+=("$alias_cmd")
|
|
else
|
|
continue
|
|
fi
|
|
fi
|
|
new_completion="$(complete -p "$alias_cmd" 2> /dev/null)"
|
|
|
|
# create a wrapper inserting the alias arguments if any
|
|
if [[ -n $alias_args ]]; then
|
|
compl_func="${new_completion/#* -F /}"
|
|
compl_func="${compl_func%% *}"
|
|
# avoid recursive call loops by ignoring our own functions
|
|
if [[ "${compl_func#_"$namespace"::}" == "$compl_func" ]]; then
|
|
compl_wrapper="_${namespace}::${alias_name}"
|
|
echo "function $compl_wrapper {
|
|
local compl_word=\$2
|
|
local prec_word=\$3
|
|
# check if prec_word is the alias itself. if so, replace it
|
|
# with the last word in the unaliased form, i.e.,
|
|
# alias_cmd + ' ' + alias_args.
|
|
if [[ \$COMP_LINE == \"\$prec_word \$compl_word\" ]]; then
|
|
prec_word='$alias_cmd $alias_args'
|
|
prec_word=\${prec_word#* }
|
|
fi
|
|
(( COMP_CWORD += ${#alias_arg_words[@]} ))
|
|
COMP_WORDS=($alias_cmd $alias_args \${COMP_WORDS[@]:1})
|
|
(( COMP_POINT -= \${#COMP_LINE} ))
|
|
COMP_LINE=\${COMP_LINE/$alias_name/$alias_cmd $alias_args}
|
|
(( COMP_POINT += \${#COMP_LINE} ))
|
|
$compl_func \"$alias_cmd\" \"\$compl_word\" \"\$prec_word\"
|
|
}" >> "$tmp_file"
|
|
new_completion="${new_completion/ -F $compl_func / -F $compl_wrapper }"
|
|
fi
|
|
fi
|
|
|
|
# replace completion trigger by alias
|
|
if [[ -n $new_completion ]]; then
|
|
new_completion="${new_completion% *} $alias_name"
|
|
echo "$new_completion" >> "$tmp_file"
|
|
fi
|
|
done < <(alias -p | sed -Ene "s/$alias_regex/\2 '\3' '\4'/p")
|
|
# shellcheck source=/dev/null
|
|
source "$tmp_file" && command rm -f "$tmp_file"
|
|
}
|
|
|
|
alias_completion
|