about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--Completion/Zsh/Context/_brace_parameter187
-rw-r--r--Src/Zle/compcore.c16
3 files changed, 207 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index 5a727fd4e..9e6efc78e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2011-06-03  Peter Stephenson  <p.w.stephenson@ntlworld.com>
+
+	* 29452: Completion/Zsh/Context/_brace_parameter,
+	Src/Zle/compcore.c (typo corrected): allow completion
+	of parameter flags.
+
 2011-06-03  Mikael Magnusson <mikachu@gmail.com>
 
 	* 29438: Completion/Zsh/Context/_subscript: adjust pattern so
@@ -14945,5 +14951,5 @@
 
 *****************************************************
 * This is used by the shell to define $ZSH_PATCHLEVEL
-* $Revision: 1.5360 $
+* $Revision: 1.5361 $
 *****************************************************
diff --git a/Completion/Zsh/Context/_brace_parameter b/Completion/Zsh/Context/_brace_parameter
index fde6d4f0f..e6a2c4c80 100644
--- a/Completion/Zsh/Context/_brace_parameter
+++ b/Completion/Zsh/Context/_brace_parameter
@@ -1,3 +1,190 @@
 #compdef -brace-parameter-
 
+local char delim found_percent found_m exp
+local -a flags
+integer q_last n_q
+
+if [[ $PREFIX = '${('[^\)]# ]]; then
+  # Parameter flags.
+  compset -p 3
+
+  # Based on code in _globquals.
+  while [[ -n $PREFIX ]]; do
+    char=$PREFIX[1]
+    compset -p 1
+    if [[ $char = q ]]; then
+      (( q_last++, n_q++ ))
+      continue
+    else
+      (( q_last = 0 ))
+    fi
+    # Skip arguments to find what's left to complete
+    case $char in
+      (%)
+      found_percent=1
+      ;;
+
+      (m)
+      found_m=1
+      ;;
+
+      ([gIjsZ_])
+      # Single delimited argument.
+      if [[ -z $PREFIX ]]; then
+	_delimiters qualifer-$char
+	return
+      elif ! _globqual_delims; then
+	# still completing argument
+	case $char in
+	  (g)
+	  compset -P '*'
+	  flags=('o:octal escapes' 'c:expand ^X etc.' 'e:expand \M-t etc.')
+	  _describe -t format 'format option' flags -Q -S ''
+	  ;;
+
+	  (I)
+	  _message 'integer expression'
+	  ;;
+
+	  (js)
+	  _message "separator"
+	  ;;
+
+	  (Z)
+	  compset -P '*'
+	  flags=(
+	    'c:parse comments as strings (else as ordinary words)'
+	    'C:strip comments (else treat as ordinary words)'
+	    'n:treat newlines as whitespace'
+	  )
+	  _describe -t format 'format option' flags -Q -S ''
+	  ;;
+
+	  (_)
+	  _message "no useful values"
+	  ;;
+	esac
+	return
+      fi
+      ;;
+
+      ([lr])
+      # One compulsory argument, two optional.
+      if [[ -z $PREFIX ]]; then
+	_delimiters qualifer-$char
+	return
+      else
+	delim=$PREFIX[1]
+	if ! _globqual_delims; then
+	  # still completing argument
+	  _message "padding width"
+	  return
+	fi
+	# TBD if $PREFIX is empty can complete
+	# either repeat delimiter or a new qualifier.
+	# You might think it would just be easier
+	# for the user to type the delimiter at
+	# this stage, but users are astonishingly lazy.
+	if [[ $delim = $PREFIX[1] ]]; then
+	  # second argument
+	  if ! _globqual_delims; then
+	    _message "repeated padding"
+	    return
+	  fi
+	  if [[ $delim = $PREFIX[1] ]]; then
+	    if ! _globqual_delims; then
+	      _message "one-off padding"
+	      return
+	    fi
+	  fi
+	fi
+      fi
+      ;;
+    esac
+  done
+
+  if [[ -z $found_percent ]]; then
+    flags=("%:Expand prompt sequences")
+  else
+    flags=("%:Expand prompts respecting options")
+  fi
+  case $q_last in
+    (0)
+    if (( n_q == 0 )); then
+      flags+=("q:quote with backslashes")
+    fi
+    ;;
+
+    (1)
+    flags+=(
+      "q:quote with single quotes"
+      "-:quote minimally for readability"
+    )
+    ;;
+
+    (2)
+    flags+=("q:quote with double quotes")
+    ;;
+
+    (3)
+    flags+=("q:quote with \$'...'")
+    ;;
+  esac
+  if (( !n_q )); then
+    flags+=("Q:remove one level of quoting")
+  fi
+  if [[ -z $found_m ]]; then
+    flags+=("m:Count multibyte width in padding calculation")
+  else
+    flags+=("m:Count number of character code points in padding calculation")
+  fi
+  flags+=(
+    "#:Evaluate as numeric expression"
+    "@:Double-quoted splitting of scalars"
+    "A:Create array parameter"
+    "a:Sort in array index order (with O to reverse)"
+    "c:Count characters in an array (with \${(c)#...})"
+    "C:Capitalize words"
+    "D:Perform directory name abbreviation"
+    "e:Perform single-word shell expansions"
+    "f:Split the result on newlines"
+    "F:Join arrays with newlines"
+    "g:Process echo array sequences (needs options)"
+    "i:Sort case-insensitively"
+    "k:Subsitute keys of associative arrays"
+    "L:Lower case all letters"
+    "n:Sort decimal integers numerically"
+    "o:Sort in ascending order (lexically if no other sort option)"
+    "O:Sort in descending order (lexically if no other sort option)"
+    "P:Use parameter value as name of parameter for redirected lookup"
+    "t:Substitute type of parameter"
+    "u:Substitute first occurrence of each unique word"
+    "U:Upper case all letters"
+    "v:Substitute values of associative arrays (with (k))"
+    "V:Visibility enhancements for special characters"
+    "w:Count words in array or string (with \${(w)#...})"
+    "W:Count words including empty words (with \${(W)#...})"
+    "X:Report parsing errors and eXit substitution"
+    "z:Split words as if zsh command line"
+    "0:Split words on null bytes"
+    "p:Handle print escapes in parameter flag arguments"
+    "~:Treat strings in parameter flag arguments as patterns"
+    "j:Join arrays with specified string"
+    "l:Left-pad resulting words"
+    "r:Right-pad resulting words"
+    "s:Split words on specified string"
+    "Z:Split words as if zsh command line (with options)"
+    # "_:Extended flags, for future expansion"
+    "S:Search substrings in #, %, / expressions"
+    "I:Search <argument>th match in #, %, / expressions"
+    "B:Include index of beginning of match in #, %, / expressions"
+    "E:Include index of end of match in #, %, / expressions"
+    "M:Include matched portion in #, %, / expressions"
+    "N:Include length of match in #, %,  expressions"
+    "R:Include rest (unmatched portion) in #, %, / expressions"
+  )
+  _describe -t flags "parameter flag" flags -Q -S ''
+  return
+fi
+
 _parameters -e
diff --git a/Src/Zle/compcore.c b/Src/Zle/compcore.c
index 5514e2e1d..704e125bc 100644
--- a/Src/Zle/compcore.c
+++ b/Src/Zle/compcore.c
@@ -1150,7 +1150,7 @@ check_param(char *s, int set, int test)
 	p[1] != Inpar && p[1] != Inbrack && p[1] != Snull) {
 	/* This is a parameter expression, not $(...), $[...], $'...'. */
 	char *b = p + 1, *e = b, *ie;
-	int n = 0, br = 1, nest = 0;
+	int br = 1, nest = 0;
 
 	if (*b == Inbrace) {
 	    char *tb = b;
@@ -1161,7 +1161,17 @@ check_param(char *s, int set, int test)
 
 	    /* Ignore the possible (...) flags. */
 	    b++, br++;
-	    n = skipparens(Inpar, Outpar, &b);
+	    if (skipparens(Inpar, Outpar, &b) > 0) {
+		/*
+		 * We are still within the parameter flags.  There's no
+		 * point trying to do anything clever here with
+		 * parameter names.  Instead, just report that we are in
+		 * a brace parameter but let the completion function
+		 * decide what to do about it.
+		 */
+		ispar = 2;
+		return NULL;
+	    }
 
 	    for (tb = p - 1; tb > s && *tb != Outbrace && *tb != Inbrace; tb--);
 	    if (tb > s && *tb == Inbrace && (tb[-1] == String || *tb == Qstring))
@@ -1204,7 +1214,7 @@ check_param(char *s, int set, int test)
 	}
 
 	/* Now make sure that the cursor is inside the name. */
-	if (offs <= e - s && offs >= b - s && n <= 0) {
+	if (offs <= e - s && offs >= b - s) {
 	    char sav;
 
 	    if (br) {