summaryrefslogtreecommitdiff
path: root/Completion/Core/_expand
diff options
context:
space:
mode:
Diffstat (limited to 'Completion/Core/_expand')
-rw-r--r--Completion/Core/_expand149
1 files changed, 149 insertions, 0 deletions
diff --git a/Completion/Core/_expand b/Completion/Core/_expand
new file mode 100644
index 000000000..9172b6cbf
--- /dev/null
+++ b/Completion/Core/_expand
@@ -0,0 +1,149 @@
+#autoload
+
+# This completer function is intended to be used as the first completer
+# function and allows one to say more explicitly when and how the word
+# from the line should be expanded than expand-or-complete.
+# This function will allow other completer functions to be called if
+# the expansions done produce no result or do not change the original
+# word from the line.
+#
+# Configuration keys:
+#
+# expand_substitute
+# If this is unset or set to the empty string, the code will first
+# try to expand all substitutions in the string (such as $(...) and
+# ${...}). If this is set to an non-empty string it should be
+# an expression usable inside a $[...] arithmetical expression.
+# In this case, expansion of substitutions will be done if the
+# expression evaluates to `1'. For example, with
+#
+# compconf expand_substitute='NUMERIC != 1'
+#
+# substitution will be performed only if given an explicit numeric
+# argument other than `1', as by typing ESC 2 TAB.
+#
+# expand_glob
+# If this is unset or set to an empty string, globbing will be
+# attempted on the word resulting from substitution or the
+# original string. The values accepted for this key are the same
+# as for expand_substitute.
+#
+# expand_menu
+# If this is unset or set to the empty string, the words resulting
+# from expansion (if any) will simply be inserted in the ommand line,
+# replacing the original string. However, if this key is set to an
+# non-empty string, the user can cycle through the expansion as in
+# a menucompletion. Unless the value contains the sub-string `only',
+# the user will still be offered all expansions at once as one of
+# the strings to insert in the command line. Also, if the value
+# contains the sub-string `last', the string with all expansion will
+# be offered first, whereas normally it is offered as the last string
+# to insert. Finally, if the value contains the sub-string `sort',
+# the expansions will be sorted alphabetically, normally they are
+# kept in the order the expansion produced them in.
+#
+# expand_original
+# If this is set to an non-empty string, the original string from the
+# line will be included in the list of strings the user can cycle
+# through as in a menucompletion. If the value contains the sub-string
+# `last', the original string will appear as the last string, with
+# other values it is inserted as the first one (so that the command
+# line does not change immediatly).
+#
+# expand_prompt
+# This may be set to a string that should be displayed before the
+# possible expansions. This is given to the -X option and thus may
+# contain the control sequences `%n', `%B', etc. Also, the sequence
+# `%o' in this string will be replaced by the original string.
+
+local exp word="$PREFIX$SUFFIX" group=-V
+
+# Do this only for the first global matcher.
+
+[[ "$compstate[matcher]" -le 1 ]] || return 1
+
+# In exp we will collect the expansion.
+
+exp=("$word")
+
+# First try substitution. That weird thing spanning multiple lines
+# changes quoted spaces, tabs, and newlines into spaces.
+
+[[ -z "$compconfig[expand_substitute]" ||
+ "${(e):-\$[$compconfig[expand_substitute]]}" -eq 1 ]] &&
+ exp=( "${(e)exp//\\[
+]/ }" )
+
+# If the array is empty, store the original string again.
+
+[[ -z "$exp" ]] && exp=("$word")
+
+# Now try globbing.
+
+[[ -z "$compconfig[expand_glob]" ||
+ "${(e):-\$[$compconfig[expand_glob]]}" -eq 1 ]] &&
+ exp=( ${~exp}(N) )
+
+# If we don't have any expansions or only one and that is the same
+# as the original string, we let other completers run.
+
+[[ $#exp -eq 0 ||
+ ( $#exp -eq 1 && "$exp[1]" = "$word" ) ]] && return 1
+
+# We have expansions, should we menucomplete them?
+
+if [[ -z "$compconfig[expand_menu]" ]]; then
+
+ # No, so if the user only wants a list, we add the strings
+ # separately. Otherwise we add the whole array as one string,
+ # probably also adding the original string.
+
+ if [[ -z "$compstate[insert]" ]]; then
+ compadd -U -V _expand -Q - "$exp[@]"
+ else
+ [[ -n "$compconfig[expand_original]" &&
+ "$compconfig[expand_original]" != *last* ]] &&
+ compadd -UnQ -V _expand_original - "$word"
+
+ compadd -UQ -V _expand - "$exp"
+
+ [[ -n "$compconfig[expand_original]" &&
+ "$compconfig[expand_original]" = *last* ]] &&
+ compadd -UnQ -V _expand_original - "$word"
+
+ compstate[insert]=menu
+ fi
+else
+ # Sorting? We just use a different group type then.
+
+ [[ "$compconfig[expand_menu]" = *sort* ]] && group=-J
+
+ # Now add the expansion string, probably also adding the original
+ # and/or the string containing all expanded string.
+
+ [[ -n "$compconfig[expand_original]" &&
+ "$compconfig[expand_original]" != *last* ]] &&
+ compadd -UnQ -V _expand_original - "$word"
+
+ [[ "$compconfig[expand_menu]" = *last* &&
+ "$compconfig[expand_menu]" != *only* ]] &&
+ compadd -UnQ -V _expand_all - "$exp"
+
+ if [[ -z "$compconfig[expand_prompt]" ]]; then
+ compadd -UQ $group _expand - "$exp[@]"
+ else
+ compadd -UQ -X "${compconfig[expand_prompt]//\%o/$word}" \
+ $group _expand - "$exp[@]"
+ fi
+ [[ "$compconfig[expand_menu]" != *last* &&
+ "$compconfig[expand_menu]" != *only* ]] &&
+ compadd -UnQ -V _expand_all - "$exp"
+
+ [[ -n "$compconfig[expand_original]" &&
+ "$compconfig[expand_original]" = *last* ]] &&
+ compadd -UnQ -V _expand_original - "$word"
+
+ compstate[insert]=menu
+fi
+
+return 0