about summary refs log tree commit diff
path: root/Completion
diff options
context:
space:
mode:
Diffstat (limited to 'Completion')
-rw-r--r--Completion/Unix/Command/_date97
-rw-r--r--Completion/Unix/Type/_date_formats17
2 files changed, 77 insertions, 37 deletions
diff --git a/Completion/Unix/Command/_date b/Completion/Unix/Command/_date
index ff3bac398..16b34d7d6 100644
--- a/Completion/Unix/Command/_date
+++ b/Completion/Unix/Command/_date
@@ -1,57 +1,98 @@
 #compdef date gdate
 
-local -a args alts
+local curcontext="$curcontext" state state_descr line ret=1
+local -A opt_args
+local -a opts args
+
+opts=( -s -w -C )
 
 if _pick_variant gnu="Free Software Foundation" unix --version; then
+  local d='(-d --date -f --file -r --reference -s --set)'
+  local f='(-I --iso-8601 -R --rfc-2822 --rfc-3339)'
   args=(
-    '-d[output specified date]:time string'
-    '-f[output dates specified in file]:file:_files'
-    '-I-[iso-8601]:precision:(date hours minutes seconds)'
-    '-r[reference]:file:_files'
-    '-R[RFC2822 format]'
-    '-s[set]:time string'
-    '--rfc-3339=-[output date and time in RFC 3339 format]:output type:(date seconds ns)'
-    --
-    '*=FILE*:file:_files'
-    '*=DATEFILE*:date file:_files'
+    $d{-d+,--date=}'[output date specified by string]:time string'
+    $d{-f+,--file=}'[output dates specified in file]:file:_files'
+    $d{-r+,--reference=}'[output last modification time of specified file]:file:_files'
+    $d{-s+,--set=}'[set time]:time string'
+    $f{-I-,--iso-8601=-}'[display in ISO 8601 format]::precision:(date hours minutes seconds ns)'
+    $f{-R,--rfc-2822}'[display in RFC2822 format]'
+    $f'--rfc-3339=-[display in RFC 3339 format]:precision:(date seconds ns)'
+    '(-u --utc --universal)'{-u,--utc,--universal}'[display or set time in UTC]'
+    '(- :)--help[output help and exit]'
+    '(- :)--version[output version info and exit]'
   )
 else
+  args=( '-u[display or set time in UTC]' )
   case "$OSTYPE" in
     solaris*)
-      args=( '-a:adjustment' )
+      args+=( '-a:adjustment' )
     ;;
-    darwin*|dragonfly*|netbsd*|openbsd*)
-      args+=( '-r[specify reference time]:seconds since epoch' )
-    ;|
-    freebsd*|darwin*|dragonfly*|netbsd*|openbsd*)
-      args=(
-	'-n[only set time on current machine]'
-	'-d:daylight saving time value'
+    freebsd*|dragonfly*|darwin*|netbsd*|openbsd*)
+      opts+=( -A '-*' )
+      args+=(
 	'-j[do not try to set date]'
-	'-t:minutes west of GMT'
+	'2:format or date:->fmt_date'
+      )
+    ;|
+    freebsd*|dragonfly*|darwin*|netbsd*)
+      args+=( '-n[only set time on current machine]' )
+    ;|
+    freebsd*|dragonfly*|darwin*|openbsd*)
+      args+=(
+	'-d+:daylight saving time value'
+	'-t+:minutes west of GMT'
+      )
+    ;|
+    dragonfly*|darwin*|netbsd*|openbsd*)
+      args+=(
+	'-r+[output date specified by reference time]:seconds since epoch'
       )
     ;|
     freebsd*)
+      local -a alts
       alts=(
 	'seconds:sec:_guard "(0x[0-9a-fA-F]#|[0-9]#)" "seconds since epoch"'
 	'files:file:_files'
       )
       args+=(
-	'-r[reference time: file modification or literal time]:reference: _alternative $alts'
-	'-R[RFC2822 format]'
+	'-r+[reference time: file modification or literal time]:reference: _alternative $alts'
       )
     ;|
     freebsd*|dragonfly*|darwin*)
-      args+=( '-f:parsing format' '-v:adjustment value' )
+      args+=(
+	'-f+[use specified format for input]:parsing format:_date_formats:new date:'
+	'*-v+[adjust and print (but not set) date]:[+-]value[ymwdHMS]:'
+      )
     ;;
+    freebsd*|dragonfly*)
+      args+=( '-R[display in RFC2822 format]' )
+    ;|
+    openbsd*|netbsd*) args=+( '-a[gradually skew]' )
+    ;|
     openbsd*)
       args+=( '-z[specify timezone for output]:time zone:_time_zone')
     ;|
-    openbsd*|netbsd*) args=( '-a[gradually skew]' ) ;;
+    netbsd*)
+      args+=( '-d[output date specified by string]:time string:' )
+    ;;
   esac
 fi
 
-_arguments \
-  '-u[display or set time in UTC]' \
-  ': :_guard "^--*" "format or date"' \
-  "$args[@]"
+_arguments $opts : $args \
+  '1:format or date:->fmt_date' && ret=0
+
+case $state in
+  (fmt_date)
+    local expl
+    if compset -P '+'; then
+      _wanted date-formats expl 'output format' _date_formats && ret=0
+    elif [[ $words[CURRENT] != -* ]]; then
+      # TODO: in most cases it should be possible to determine which
+      # (or both or neither) of the +format and/or date is allowed
+      # depending on the options already on the command line
+      _message -e date-formats '+format or date' && ret=0
+    fi
+    ;;
+esac
+
+return ret
diff --git a/Completion/Unix/Type/_date_formats b/Completion/Unix/Type/_date_formats
index 09f8cab52..45bda823f 100644
--- a/Completion/Unix/Type/_date_formats
+++ b/Completion/Unix/Type/_date_formats
@@ -19,18 +19,16 @@ compset -S '%*'
 specs=(
   'a:abbreviated day name'
   'A:full day name'
-  'b:abbreviated month name'
+  {b,h}':abbreviated month name'
   'B:full month name'
   'c:preferred locale date and time'
   'C:2-digit century'
   'd:day of month (01-31)'
   'D:american format month/day/year (%m/%d/%y)'
   'e:day of month ( 1-31)'
-  'E:alternate representation'
   'F:ISO 8601 year-month-date (%Y-%m-%d)'
   'G:4-digit ISO 8601 week-based year'
   'g:2-digit ISO 8601 week-based year'
-  'h:abbreviated month name'
   'H:hour (00-23)'
   'I:hour (01-12)'
   'j:day of year (001-366)'
@@ -39,7 +37,6 @@ specs=(
   'm:month (01-12)'
   'M:minute (00-59)'
   'n:newline'
-  'O:alternative format modifier'
   'p:locale dependent AM/PM'
   'r:locale dependent a.m. or p.m. time (%I:%M:%S %p)'
   'R:24-hour notation time (%H:%M)'
@@ -62,24 +59,26 @@ specs=(
 )
 
 case $OSTYPE in
-  freebsd*|linux-gnu|solaris2.<11->)
+  freebsd*|dragonfly*|darwin*|linux-gnu|solaris2.<11->)
     specs+=(
+      'E:alternate representation'
+      'O:alternative format modifier'
       "-:don't pad numeric values"
-      '#:swap case of alphabetic characters'
       '0:left pad numeric values with zeroes'
-      '^:convert lowercase characters to uppercase'
       '_:left pad numeric values with spaces'
     )
   ;|
   linux-gnu|solaris2.<11->)
     specs+=(
+      '#:swap case of alphabetic characters'
+      '^:convert lowercase characters to uppercase'
       'P:lower case locale dependent am/pm'
     )
   ;|
-  freebsd*)
+  freebsd*|dragonfly*|darwin*|openbsd*|netbsd*)
     specs+=( 'v:date in short form (%e-%b-%Y)' )
   ;|
-  solaris2.<11->|freebsd*)
+  solaris2.<11->|freebsd*|dragonfly*|darwin*|openbsd*)
     specs+=( '+:localized representation of date and time' )
   ;;
   solaris2.<-10>)