Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: PATCH: completion



In article <rsqbtc1wmru.fsf@xxxxxxxxxxxxxxxxx>,
  Tanaka Akira <akr@xxxxxxxxxxx> writes:

> Oops. I found that already _arguments can handle options started with
> "--" without _long_options.  But also I fount that it is bit
> problematic with -s.

This is more refinement for -s. I reduced {,d,od}mopts to {,d,od}opts
because I thought it's too redundant.

Also, I found the problem about associative array with rcexpandparam.

Z(2):akr@is27e1u11% zsh -f
is27e1u11% typeset -A arr 
is27e1u11% arr[a]=
is27e1u11% print -lr - "A${(@)^arr[(I)b]}B"
AB

This should be empty.  Because of this problem, completions for
single-letter option doesn't work well.

Index: Completion/Base/_arguments
===================================================================
RCS file: /projects/zsh/zsh/Completion/Base/_arguments,v
retrieving revision 1.1.1.6
diff -u -F^( -r1.1.1.6 _arguments
--- _arguments	1999/08/21 08:40:24	1.1.1.6
+++ _arguments	1999/08/21 17:35:59
@@ -6,11 +6,12 @@
 setopt localoptions extendedglob
 
 local long args rest ws cur nth def nm expl descr action opt arg tmp
-local single uns ret=1 soptseq soptseq1 sopts
+local single uns ret=1 soptseq soptseq1 sopts prefix
 
 # Associative arrays used to collect information about the options.
 
-typeset -A opts mopts dopts dmopts odopts odmopts
+typeset -A opts dopts odopts
+typeset -A oneshot
 
 # See if we are using single-letter options.
 
@@ -46,30 +47,40 @@
       # is in the next word.
 
       if [[ "$1" = [^:]##-:* ]]; then
-        dopts[${${1%%:*}[1,-2]}]="${1#*:}"
+	tmp="${${1%%:*}[1,-2]}"
+        dopts[$tmp]="${1#*:}"
       elif [[ "$1" = [^:]##+:* ]]; then
-        odopts[${${1%%:*}[1,-2]}]="${1#*:}"
+	tmp="${${1%%:*}[1,-2]}"
+        odopts[$tmp]="${1#*:}"
       else
-        opts[${1%%:*}]="${1#*:}"
+        tmp="${1%%:*}"
+        opts[$tmp]="${1#*:}"
       fi
     else
-      opts[$1]=''
+      tmp="$1"
+      opts[$tmp]=''
     fi
+    oneshot[$tmp]=yes
   elif [[ "$1" = \*[-+]* ]]; then
 
     # The same for options that may appear more than once.
 
     if [[ "$1" = *:* ]]; then
       if [[ "$1" = [^:]##-:* ]]; then
-        dmopts[${${1[2,-1]%%:*}[1,-2]}]="${1#*:}"
+        tmp="${${1[2,-1]%%:*}[1,-2]}"
+        dopts[$tmp]="${1#*:}"
       elif [[ "$1" = [^:]##+:* ]]; then
-        odmopts[${${1[2,-1]%%:*}[1,-2]}]="${1#*:}"
+        tmp="${${1[2,-1]%%:*}[1,-2]}"
+        odopts[$tmp]="${1#*:}"
       else
-        mopts[${1[2,-1]%%:*}]="${1#*:}"
+        tmp="${1[2,-1]%%:*}"
+        opts[$tmp]="${1#*:}"
       fi
     else
-      mopts[${1[2,-1]}]=''
+      tmp="${1[2,-1]}"
+      opts[$tmp]=''
     fi
+    unset "oneshot[$tmp]"
   elif [[ "$1" = \*:* ]]; then
 
     # This is `*:...', describing `all other arguments'.
@@ -91,7 +102,7 @@
 done
 
 if [[ -n "$single" ]]; then
-  soptseq="${(@j::)${(@M)${(@k)opts[(R)]}:#[-+]?}#[-+]}${(@j::)${(@M)${(@k)mopts[(R)]}:#[-+]?}#[-+]}"
+  soptseq="${(@j::)${(@M)${(@k)opts[(R)]}:#[-+]?}#[-+]}"
   if [[ -n "$soptseq" ]]; then
     soptseq="[$soptseq]#"
     soptseq1="$soptseq#"
@@ -99,7 +110,7 @@
     soptseq=''
     soptseq1=''
   fi
-  sopts="${(@j::)${(@M)${(@k)opts}:#[-+]?}#[-+]}${(@j::)${(@M)${(@k)mopts}:#[-+]?}#[-+]}${(@j::)${(@M)${(@k)dopts}:#[-+]?}#[-+]}${(@j::)${(@M)${(@k)dmopts}:#[-+]?}#[-+]}${(@j::)${(@M)${(@k)odopts}:#[-+]?}#[-+]}${(@j::)${(@M)${(@k)odmopts}:#[-+]?}#[-+]}"
+  sopts="${(@j::)${(@M)${(@k)opts}:#[-+]?}#[-+]}${(@j::)${(@M)${(@k)dopts}:#[-+]?}#[-+]}${(@j::)${(@M)${(@k)odopts}:#[-+]?}#[-+]}"
 else
   soptseq=''
   soptseq1=''
@@ -168,26 +179,21 @@
         # associative array so that we don't offer them again.
 
         def="$opts[$ws[1]]"
-        unset "opts[$ws[1]]"
-      elif (( $+mopts[$ws[1]] )); then
-        def="$mopts[$ws[1]]"
+        [[ -n "$oneshot[$ws[1]]" ]] && unset "opts[$ws[1]]"
       else
         uns=''
         if [[ -n "$sopts" && "$ws[1]" = [-+]${~soptseq}[$sopts] ]]; then
-	  if (( $+opts[${ws[1][1]}${ws[1][-1]}] )); then
-	    def="$opts[${ws[1][1]}${ws[1][-1]}]"
+	  tmp="${ws[1][1]}${ws[1][-1]}"
+	  if (( $+opts[$tmp] )); then
+	    def="$opts[$tmp]"
 	    uns="${ws[1][2,-1]}"
 	    opt=''
-	  elif (( $+mopts[${ws[1][1]}${ws[1][-1]}] )); then
-	    def="$mopts[${ws[1][1]}${ws[1][-1]}]"
-	    uns="${ws[1][2,-1]}"
-	    opt=''
 	  fi
         fi
 
         # If the word is none of the simple options, test for those
         # whose first argument has to or may come directly after the
-        # option. This is done in four loops looking very much alike.
+        # option. This is done in two loops looking very much alike.
 
         if [[ -n "$opt" && $#dopts -ne 0 ]]; then
 
@@ -218,7 +224,7 @@
 
 	    opt=''
 	    def="$dopts[$tmp[1]]"
-	    unset "dopts[$tmp[1]]"
+	    [[ -n "$oneshot[$tmp[1]]" ]] && unset "dopts[$tmp[1]]"
 	    if [[ "$def" = ?*:*:* ]]; then
               def="${def#?*:*:}"
             else
@@ -226,30 +232,6 @@
 	    fi
           fi
         fi
-	if [[ -n "$opt" && $#dmopts -ne 0 ]]; then
-	  tmp=( "${(@k)dmopts}" )
-	  while (( $#tmp )); do
-            if [[ -n "$sopts" && $tmp[1] = [-+]? ]]; then
-	      if [[ "$ws[1]" = ${tmp[1][1]}${~soptseq}${tmp[1][2]}* ]]; then
-	        uns="${ws[1][2,-1]%%${tmp[1][2]}*}${tmp[1][2]}"
-		break;
-	      fi
-	    elif [[ "$ws[1]" = ${tmp[1]}* ]]; then
-	      break
-	    fi
-	    shift 1 tmp
-	  done
-
-	  if (( $#tmp )); then
-	    opt=''
-	    def="$dmopts[$tmp[1]]"
-	    if [[ "$def" = ?*:*:* ]]; then
-              def="${def#?*:*:}"
-            else
-              def=''
-            fi
-          fi
-	fi
         if [[ -n "$opt" && $#odopts -ne 0 ]]; then
 	  tmp=( "${(@k)odopts}" )
 	  while (( $#tmp )); do
@@ -267,14 +249,15 @@
 	  if (( $#tmp )); then
 	    opt=''
 	    def="$odopts[$tmp[1]]"
-	    unset "odopts[$tmp[1]]"
+	    [[ -n "$oneshot[$tmp[1]]" ]] && unset "odopts[$tmp[1]]"
 
 	    # For options whose first argument *may* come after the
 	    # option, we skip over the first description only if there
 	    # is something after the option name on the line.
 
 	    if [[ ( -z "$sopts" && "$ws[1]" != "$tmp[1]" ) ||
-                  ( -n "$sopts" && $tmp[1] = [-+]? && "$ws[1]" != ${tmp[1][1]}${~soptseq}${tmp[1][2]} ) ]]; then
+                  ( -n "$sopts" && ( ( $tmp[1] = [-+]? && "$ws[1]" != "${tmp[1][1]}"${~soptseq}"${tmp[1][2]}" ) ||
+		  		     ( $tmp[1] != [-+]? && "$ws[1]" != "$tmp[1]" ) ) ) ]]; then
 	      if [[ "$def" = ?*:*:* ]]; then
                 def="${def#?*:*:}"
               else
@@ -283,41 +266,16 @@
 	    fi
           fi
         fi
-	if [[ -n "$opt" && $#odmopts -ne 0 ]]; then
-	  tmp=( "${(@k)odmopts}" )
-	  while (( $#tmp )); do
-            if [[ -n "$sopts" && $tmp[1] = [-+]? ]]; then
-	      if [[ "$ws[1]" = ${tmp[1][1]}${~soptseq}${tmp[1][2]}* ]]; then
-	        uns="${ws[1][2,-1]%%${tmp[1][2]}*}${tmp[1][2]}"
-		break;
-	      fi
-	    elif [[ "$ws[1]" = ${tmp[1]}* ]]; then
-	      break
-	    fi
-	    shift 1 tmp
-	  done
-
-	  if (( $#tmp )); then
-	    opt=''
-	    def="$odmopts[$tmp[1]]"
-	    if [[ ( -z "$sopts" && "$ws[1]" != "$tmp[1]" ) ||
-                  ( -n "$sopts" && $tmp[1] = [-+]? && "$ws[1]" != ${tmp[1][1]}${~soptseq}${tmp[1][2]} ) ]]; then
-	      if [[ "$def" = ?*:*:* ]]; then
-                def="${def#?*:*:}"
-              else
-                def=''
-              fi
-            fi
-          fi
-	fi
 
         [[ -n "$sopts" && -n "$opt" && "$ws[1]" = [-+]${~soptseq} ]] && \
             uns="${ws[1][2,-1]}"
 
-        [[ -n "$uns" ]] &&
+	if [[ -n "$uns" ]]; then
+	  uns="${(j::)${(@k)oneshot[(I)${ws[1][1]}[$uns]]#[-+]}}"
 	  unset "opts[${(@)^opts[(I)${ws[1][1]}[$uns]]}]" \
 	        "dopts[${(@)^dopts[(I)${ws[1][1]}[$uns]]}]" \
 	        "odopts[${(@)^odopts[(I)${ws[1][1]}[$uns]]}]"
+	fi
 
 	# If we didn't find a matching option description and we were
 	# told to use normal argument descriptions, just increase
@@ -356,7 +314,7 @@
 
     # In any case, we have to complete option names here, but we may
     # be in a string that starts with an option names and continues with
-    # the first argument, test that (again, four loops).
+    # the first argument, test that (again, two loops).
 
     opt=yes
     if (( $#dopts )); then
@@ -364,11 +322,12 @@
       # Get the option names.
 
       tmp=( "${(@k)dopts}" )
+      prefix="$PREFIX"
       while (( $#tmp )); do
         if [[ -n "$sopts" && $tmp[1] = [-+]? ]] && compset -P "${tmp[1][1]}${~soptseq}${tmp[1][2]}"; then
           def="$dopts[$tmp[1]]"
 	  opt=''
-	  uns="${PREFIX[2,-1]%%${tmp[1][2]}*}${tmp[1][2]}"
+	  uns="${prefix[2,-1]%%${tmp[1][2]}*}${tmp[1][2]}"
 	  break
         elif compset -P "$tmp[1]"; then
 
@@ -382,29 +341,14 @@
 	shift 1 tmp
       done
     fi
-    if [[ -n "$opt" && $#dmopts -ne 0 ]]; then
-      tmp=( "${(@k)dmopts}" )
-      while (( $#tmp )); do
-        if [[ -n "$sopts" && $tmp[1] = [-+]? ]] && compset -P "${tmp[1][1]}${~soptseq}${tmp[1][2]}"; then
-          def="$dmopts[$tmp[1]]"
-	  opt=''
-	  uns="${PREFIX[2,-1]%%${tmp[1][2]}*}${tmp[1][2]}"
-	  break
-        elif compset -P "$tmp[1]"; then
-	  def="$dmopts[$tmp[1]]"
-	  opt=''
-	  break
-        fi
-	shift 1 tmp
-      done
-    fi
     if [[ -n "$opt" && $#odopts -ne 0 ]]; then
       tmp=( "${(@k)odopts}" )
+      prefix="$PREFIX"
       while (( $#tmp )); do
         if [[ -n "$sopts" && $tmp[1] = [-+]? ]] && compset -P "${tmp[1][1]}${~soptseq}${tmp[1][2]}"; then
           def="$odopts[$tmp[1]]"
 	  opt=''
-	  uns="${PREFIX[2,-1]%%${tmp[1][2]}*}${tmp[1][2]}"
+	  uns="${prefix[2,-1]%%${tmp[1][2]}*}${tmp[1][2]}"
 	  break
         elif compset -P "$tmp[1]"; then
 	  def="$odopts[$tmp[1]]"
@@ -414,30 +358,16 @@
 	shift 1 tmp
       done
     fi
-    if [[ -n "$opt" && $#odmopts -ne 0 ]]; then
-      tmp=( "${(@k)odmopts}" )
-      while (( $#tmp )); do
-        if [[ -n "$sopts" &&  $tmp[1] = [-+]? ]] && compset -P "${tmp[1][1]}${~soptseq}${tmp[1][2]}"; then
-          def="$odmopts[$tmp[1]]"
-	  opt=''
-	  uns="${PREFIX[2,-1]%%${tmp[1][2]}*}${tmp[1][2]}"
-	  break
-        elif compset -P "$tmp[1]"; then
-	  def="$odmopts[$tmp[1]]"
-	  opt=''
-	  break
-        fi
-	shift 1 tmp
-      done
-    fi
 
-    [[ -n "$sopts" && -n "$opt" && "$PREFIX" = [-+]* ]] && \
+    [[ -n "$sopts" && -n "$opt" && "$PREFIX" = [-+]${~soptseq}[$sopts] ]] && \
         uns="${PREFIX[2,-1]}"
 
-    [[ -n "$uns" ]] &&
-        unset "opts[${(@)^opts[(I)${pre[1]}[$uns]]}]" \
-	      "dopts[${(@)^dopts[(I)${pre[1]}[$uns]]}]" \
-	      "odopts[${(@)^odopts[(I)${pre[1]}[$uns]]}]"
+    if [[ -n "$uns" ]]; then
+      uns="${(j::)${(@k)oneshot[(I)${ws[1][1]}[$uns]]#[-+]}}"
+      unset "opts[${(@)^opts[(I)${pre[1]}[$uns]]}]" \
+	    "dopts[${(@)^dopts[(I)${pre[1]}[$uns]]}]" \
+	    "odopts[${(@)^odopts[(I)${pre[1]}[$uns]]}]"
+    fi
 
     if [[ -n "$opt" ]]; then
 
@@ -447,12 +377,18 @@
       if [[ "$compconfig[option_prefix]" != *(short|all)* ||
             "$PREFIX" = [-+]* ]]; then
         _description expl option
-	if [[ -n "$sopts" && -n "$PREFIX" && -n "$soptseq" && "$PREFIX" = [-+]${~soptseq1} ]]; then
-	  compadd "$expl[@]" -Q - "$PREFIX" && ret=0
+	if [[ -n "$sopts" && -n "$PREFIX" && "$PREFIX" = [-+]${~soptseq}[$sopts] ]]; then
+	  if [[ "$PREFIX" = [-+]${~soptseq1} ]]; then
+	    compadd "$expl[@]" -Q - "${PREFIX}${(@k)^opts[(I)${PREFIX[1]}?]#?}" \
+				    "${PREFIX}${(@k)^dopts[(I)${PREFIX[1]}?]#?}" \
+				    "${PREFIX}${(@k)^odopts[(I)${PREFIX[1]}?]#?}" && ret=0
+	  else
+	    # The last option takes an argument in next word.
+	    compadd "$expl[@]" -Q - "${PREFIX}" && ret=0
+	  fi
 	else
-          compadd "$expl[@]" -Q - "${(@k)opts}" "${(@k)mopts}" \
-				  "${(@k)odopts}" "${(@k)odmopts}" && ret=0
-	  compadd "$expl[@]" -QS '' - "${(@k)dopts}" "${(@k)dmopts}" && ret=0
+          compadd "$expl[@]" -Q - "${(@k)opts}" "${(@k)odopts}" && ret=0
+	  compadd "$expl[@]" -QS '' - "${(@k)dopts}" && ret=0
         fi
       fi
       [[ $#long -ne 0 &&
@@ -503,5 +439,5 @@
 
   # Set the return value.
 
-  [[  nm -ne "$compstate[nmatches]" ]]
+  [[ nm -ne "$compstate[nmatches]" ]]
 fi
-- 
Tanaka Akira



Messages sorted by: Reverse Date, Date, Thread, Author