about summary refs log tree commit diff
path: root/Completion
diff options
context:
space:
mode:
Diffstat (limited to 'Completion')
-rw-r--r--Completion/Base/Widget/_correct_filename72
1 files changed, 72 insertions, 0 deletions
diff --git a/Completion/Base/Widget/_correct_filename b/Completion/Base/Widget/_correct_filename
new file mode 100644
index 000000000..7431a4831
--- /dev/null
+++ b/Completion/Base/Widget/_correct_filename
@@ -0,0 +1,72 @@
+#compdef -k complete-word \C-xC
+
+# Function to correct a filename.  Can be used as a completion widget,
+# or as a function in its own right, in which case it will print the
+# corrected filename to standard output.
+#
+# You can adapt max_approx to the maximum number of mistakes
+# which are allowed in total.
+#
+# If the numeric prefix is greater than 1, the maximum number of errors
+# will be set to that.
+
+# Doesn't get right special characters in the filename; should
+# strip them (e.g. "foo\ bar" -> "foo bar") and then re-insert them.
+
+emulate -LR zsh
+setopt extendedglob
+
+local file="$PREFIX$SUFFIX" trylist tilde etilde testcmd
+integer approx max_approx=6
+
+if [[ -z $WIDGET ]]; then
+  file=$1
+  local IPREFIX
+else
+  (( ${NUMERIC:-1} > 1 )) && max_approx=$NUMERIC
+fi
+
+if [[ $file = \~*/* ]]; then
+  tilde=${file%%/*}
+  etilde=${~tilde}
+  file=${file/#$tilde/$etilde}
+fi
+
+if [[ $CURRENT -eq 1 && $file != /* ]]; then
+  testcmd=1
+elif [[ $file = \=* ]]; then
+  [[ -n $WIDGET ]] && PREFIX="$PREFIX[2,-1]"
+  IPREFIX="${IPREFIX}="
+  file="$file[2,-1]"
+  testcmd=1
+fi
+
+# We need the -Q's to avoid the tilde we've put back getting quoted.
+if [[ -z $testcmd && -e "$file" ]] ||
+  { [[ -n $testcmd ]] && whence "$file" >&/dev/null }; then
+  if [[ -n $WIDGET ]]; then
+    compadd -QUf -i "$IPREFIX" -I "$ISUFFIX" "${file/#$etilde/$tilde}"
+    [[ -n "$compstate[insert]" ]] && compstate[insert]=menu
+  else
+    print "$file"
+  fi
+  return
+fi
+
+for (( approx = 1; approx <= max_approx; approx++ )); do
+  if [[ -z $testcmd ]]; then
+    trylist=( (#a$approx)"$file"(N) )
+  else
+    trylist=( "${(@)${(@f)$(whence -wm "(#a$approx)$file" 2>/dev/null)}%:*}" )
+    [[ $file = */* ]] || trylist=(${trylist##*/})
+  fi
+  (( $#trylist )) && break
+done
+(( $#trylist )) || return 1
+
+if [[ -n $WIDGET ]]; then
+  compadd -QUf -i "$IPREFIX" -I "$ISUFFIX" "${trylist[@]/#$etilde/$tilde}"
+  [[ -n "$compstate[insert]" ]] && compstate[insert]=menu
+else
+  print "$IPREFIX${^trylist[@]}"
+fi