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

Re: PATCH: _ps1234, _date_formats: Complete strftime formats for %D{}



Mikael Magnusson wrote:
> 
> I've also just noticed that completion after %D\{%\# and \^ doesn't
> work, but single-quoted is fine.

That's the fault of _ps1234.

It's best to use compset -P and get to a point where _date_formats is
called with $PREFIX only containing date formats and no prompt stuff.

I finally worked out that the point of calling _default from _ps1234 is
for print -P. That's _print's job to do that.

This patch also fixes and improves other things like the positioning of
numeric arguments for ternary expressions.

> >>  Completion/Unix/Type/_ps1234       | 14 +++++--
> > Shouldn't this be in Completion/Zsh/Type?
> Possibly, but I figured we could use it for _date too?

I meant _ps1234 not _date_formats. I'll move it when applying this
patch.

Oliver

diff --git a/Completion/Unix/Type/_ps1234 b/Completion/Unix/Type/_ps1234
index b9e5166..8d3c5d8 100644
--- a/Completion/Unix/Type/_ps1234
+++ b/Completion/Unix/Type/_ps1234
@@ -1,82 +1,58 @@
 #compdef -value-,PROMPT,-default- -value-,PROMPT2,-default- -value-,PROMPT3,-default- -value-,PROMPT4,-default- -value-,RPROMPT,-default- -value-,RPROMPT2,-default- -value-,PS1,-default- -value-,PS2,-default- -value-,PS3,-default- -value-,PS4,-default- -value-,RPS1,-default- -value-,RPS2,-default- -value-,SPROMPT,-default-
 
 local -a specs
-local expl bs
+local expl bs suf pre changed=1 ret=1
 
 if [[ -z $compstate[quote] ]]; then
-  bs='\'
+  bs='\' # in patterns we use (\\|) widely as print -P handles backslashes first
 fi
 
-if [[ $PREFIX == *%D$bs\{[^($bs\})]# ]]; then
-  _date_formats zsh
-elif [[ $PREFIX == *%(-|)<-># ]]; then
+# first strip off any complete prompt specifications leaving only the
+# current, incomplete, one
+while (( changed )); do
+  changed=0
+  compset -P '%[DFK](\\|){[^}]#}' && changed=1 # formats with arg: %x{...}
+  compset -P '%[0-9-\\]#[^DFK(0-9-<>\\\[]' && changed=1 # normal formats
+  compset -P '%[0-9-\\]#(<[^<]#<|>[^>]#>|\[[^\]]#\])' && changed=1 # truncations
+  compset -P '%[0-9-\\]#(\\|)\(??|[^%]' && changed=1 # start of ternary
+  compset -P '[^%]##' && changed=1 # sundry other characters
+  # %D/%F/%K without a following { ... }
+  [[ $PREFIX = %(-|)<->#[DFK](\\|)[^{\\]* ]] &&
+      compset -P '%[0-9\\-]#[DFK]' && changed=1
+done
+[[ $PREFIX = %(-|)<->[FK](#e) ]] && compset -P '*' # F/K with number
+
+if compset -P '%[FK]'; then
+  # this should use -P but that somehow causes single quotes to be stripped
+  compset -P '(\\|){' || pre=( -p "$bs{" )
+  compset -S '(\\|)}*' || suf=( -S $bs\} )
   specs=(
-    'm:hostname up to first .'
-    '_:status of parser'
-    'd:current working directory'
-    '/:current working directory'
-    '~:current working directory, with ~ replacement'
-    'N:name of current script or shell function'
-    'x:name of file containing code being executed'
-    'c:deprecated'
-    '.:deprecated'
-    'C:deprecated'
-    'F:start using fg color'
-    'K:start using bg color'
-    'G:counts as extra character inside %{...%}'
+    black
+    red
+    green
+    yellow
+    blue
+    magenta
+    cyan
+    white
+    default
   )
-  if [[ $PREFIX == *% ]]; then
-    if [[ $service == -value-,SPROMPT,* ]]; then
-      specs+=(
-      'r:suggested correction'
-      'R:corrected string'
-      )
-    fi
-    specs+=(
-    '%:A %'
-    '):A )'
-    'l:current line (tty) with /dev/tty stripped'
-    'M:full hostname'
-    'n:username'
-    'y:current line (tty)'
-    '#:a # when root, % otherwise'
-    '?:return status of last command'
-    'h:current history event number'
-    '!:current history event number'
-    'i:current line number'
-    'I:current source line number'
-    'j:number of jobs'
-    'L:$SHLVL'
-    'D:date in yy-mm-dd format'
-    'T:current time of day, 24-hour format'
-    't:current time of day, 12-hour am/pm format'
-    '@:current time of day, 12-hour am/pm format'
-    '*:current time of day, 24-hour format with seconds'
-    'w:the date in day-dd format'
-    'W:the date in mm/dd/yy format'
-    'D{:format string like strftime'
-    'B:start bold'
-    'b:stop bold'
-    'E:clear to end of line'
-    'U:start underline'
-    'u:stop underline'
-    'S:start standout'
-    's:stop standout'
-    'f:reset fg color'
-    'k:reset bg color'
-    '{:start literal escape sequence'
-    '}:stop literal escape sequence'
-    'v:value from $psvar array'
-    '(:ternary expression %(x.true-string.false-string)'
-    '<<:truncation from left %len<string<'
-    '>>:truncation from right %len>string>'
-    '[]:truncation from who knows where'
-    )
+  _wanted ansi-colors expl 'ansi color' compadd $suf $pre -a specs && ret=0
+  if (( $#suf )) && compset -P "<->"; then
+    _wanted ansi-colors expl 'closing brace' compadd -S '' \} && ret=0
+  else
+    _message -e terminal-colors "number between 0 and $(( $terminfo[colors] - 1 ))"
   fi
-  compset -P "*"
-  _describe -t prompt-format-specifier 'prompt format specifier' specs -S ''
-  _message -e prompt-format-specifier number
-elif [[ $PREFIX == *%$bs\((-|)<-># ]]; then
+fi
+
+if compset -P '%[0-9-\\]#\(?'; then
+  compset -S '*'
+  _delimiters && ret=0
+elif compset -P '%[0-9-\\]#[<>\]]'; then
+  _message -e replacements 'replacement string'
+elif compset -P '%[0-9-\\]#(\\|)\('; then
+  compset -S '[.:+/-%]*' || suf=( -S . )
+  compset -S '*'
   specs=(
     '!:running with privileges'
     '#:effective uid'
@@ -100,35 +76,82 @@ elif [[ $PREFIX == *%$bs\((-|)<-># ]]; then
     'V:element n of psvar is set and non-empty'
     'w:day of week (Sunday = 0)'
   )
-  compset -P "*"
-  _describe -t ternary-prompt-expression 'ternary prompt format test character' specs -S ''
-  _message -e ternary-prompt-expression number
-elif [[ $PREFIX == *%[FK]$bs\{[0-9a-z]# ]]; then
+  _describe -t ternary-prompt-expressions 'ternary prompt format test character' specs $suf && ret=0
+elif compset -P '%D(\\|){'; then
+  compset -S '(\\|)}*'
+  _date_formats zsh && ret=0
+elif [[ -prefix '%' ]] ||
+      ! zstyle -t ":completion:${curcontext}:prompt-format-specifiers" prefix-needed
+then
   specs=(
-    black
-    red
-    green
-    yellow
-    blue
-    magenta
-    cyan
-    white
-    default
+    'm:hostname up to first .'
+    '_:status of parser'
+    '^:reversed status of parser'
+    'd:current working directory'
+    '/:current working directory'
+    '~:current working directory, with ~ replacement'
+    'N:name of current script or shell function'
+    'x:name of file containing code being executed'
+    'c:deprecated'
+    '.:deprecated'
+    'C:deprecated'
+    'F:start using fg color'
+    'K:start using bg color'
+    'G:counts as extra character inside %{...%}'
+    '(:ternary expression %(x.true-string.false-string)'
   )
-  compset -P "*{"
-  _describe -t ansi-color-name 'ansi color' specs -S $bs\}
-  if compset -P "<->"; then
-    _wanted ansi-color-number expl 'close brace' compadd -S '' \}
-  else
-    _message -e ansi-color-number "number between 0 and $(( $terminfo[colors] - 1 ))"
-  fi
-else
-  _default "$@"
-  specs=(%)
-  if compset -P "*%D"; then
-    specs+=(\{)
-  else
-    compset -P "*"
+  compset -P '%' || pre=( -p '%' )
+  if ! compset -P '(-|)<->'; then
+    if [[ $service == -value-,SPROMPT,* ]]; then
+      specs+=(
+	'r:suggested correction'
+	'R:corrected string'
+      )
+    fi
+    specs+=(
+      '%:A %'
+      '):A )'
+      'l:current line (tty) with /dev/tty stripped'
+      'M:full hostname'
+      'n:username'
+      'y:current line (tty)'
+      '#:a # when root, % otherwise'
+      '?:return status of last command'
+      'h:current history event number'
+      '!:current history event number'
+      'i:current line number'
+      'I:current source line number'
+      'j:number of jobs'
+      'L:$SHLVL'
+      'D:date in yy-mm-dd format'
+      'T:current time of day, 24-hour format'
+      't:current time of day, 12-hour am/pm format'
+      '@:current time of day, 12-hour am/pm format'
+      '*:current time of day, 24-hour format with seconds'
+      'w:the date in day-dd format'
+      'W:the date in mm/dd/yy format'
+      'D{:format string like strftime'
+      'B:start bold'
+      'b:stop bold'
+      'E:clear to end of line'
+      'U:start underline'
+      'u:stop underline'
+      'S:start standout'
+      's:stop standout'
+      'f:reset fg color'
+      'k:reset bg color'
+      '{:start literal escape sequence'
+      '}:stop literal escape sequence'
+      'v:value from $psvar array'
+      '<:truncation from left %len<string<'
+      '>:truncation from right %len>string>'
+      '[:truncation from who knows where'
+    )
   fi
-  _describe -t prompt-format-specifier 'prompt format specifier' specs -S ''
+  _describe -t prompt-format-specifiers 'prompt format specifier' \
+      specs -S '' $pre && ret=0
+  (( ! $#pre )) && [[ -prefix '(-|)<->' ]] &&
+      _message -e prompt-format-specifiers number
 fi
+
+return ret
diff --git a/Completion/Zsh/Command/_print b/Completion/Zsh/Command/_print
index 4053933..1eba13e 100644
--- a/Completion/Zsh/Command/_print
+++ b/Completion/Zsh/Command/_print
@@ -11,7 +11,7 @@ if [[ $service = print ]]; then
     pflag='(-s -u -z)-p[print arguments to input of coprocess]'
 
   if [[ -n ${words[1,CURRENT][(r)-*P*]} ]]; then
-    rest='*: :_ps1234'
+    rest='*: :->prompt'
   else
     rest='*: :_default'
   fi
@@ -48,16 +48,17 @@ if [[ $state = printf ]]; then
 fi
 
 if [[ $state = printfformat ]]; then
-  if [[ ${(Q)PREFIX} = *%((-|)<->|[-#0 +*.])# ]]; then
+  if [[ ${(Q)PREFIX} = *%[0-9\$#\ +*.\'-]# ]]; then
     local -a specs
       specs=(
         '#:alternate form'
-        '0:zeropad to length n'
+        '0:zero pad to length'
         '-:left adjust result'
         ' :leave one space in front of positive number from signed conversion'
         '+:always place sign before a number from signed conversion'
         '*:field width in next argument'
         '.:precision'
+	"':thousand separators"
         'c:print the first character of the argument'
         's:print the argument as a string'
         {d,i}':signed decimal number or with leading " numeric value of following character'
@@ -73,12 +74,16 @@ if [[ $state = printfformat ]]; then
         'q:as %s but shell quote result'
       )
     compset -P "*"
-    _describe -t print-format-specifier 'print format specifier' specs -S ''
-    _message -e print-format-specifier 'number'
+    _describe -t print-format-specifiers 'print format specifier' specs -S ''
+    _message -e print-format-specifiers 'number'
   else
-    _describe -t print-format-specifier 'print format specifier' '(%)' -S ''
+    _wanted print-format-specifiers expl 'print format specifier' compadd -S '' %
   fi
   ret=0
+elif [[ $state = prompt ]]; then
+  _default && ret=0
+  # complete prompt specifiers without interfering too much with default completion
+  (( $#compstate[unambiguous] <= $#PREFIX || ! $#PREFIX )) && _ps1234 && ret=0
 fi
 
 return ret



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