summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--Completion/Unix/Command/_find21
-rw-r--r--Completion/Unix/Type/_dates123
-rw-r--r--Completion/Zsh/Type/_globquals11
4 files changed, 150 insertions, 10 deletions
diff --git a/ChangeLog b/ChangeLog
index 1f4e3f999..0c60eedf9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2015-07-06 Oliver Kiddle <opk@zsh.org>
+
+ * 35718: Completion/Unix/Command/_find, Completion/Unix/Type/_dates,
+ Completion/Zsh/Type/_globquals: new calendar style date completion
+
2015-07-07 Peter Stephenson <p.stephenson@samsung.com>
* unposted: Src/Zle/complete.c: remove compiler warning.
diff --git a/Completion/Unix/Command/_find b/Completion/Unix/Command/_find
index 8f80e36cf..aefca34f2 100644
--- a/Completion/Unix/Command/_find
+++ b/Completion/Unix/Command/_find
@@ -1,6 +1,7 @@
#compdef find gfind
-local variant args
+local curcontext="$curcontext" state_descr variant
+local -a state line args alts
_pick_variant -r variant gnu=GNU $OSTYPE -version
@@ -114,11 +115,11 @@ case $variant in
;;
esac
-_arguments $args \
+_arguments -C $args \
'(-L -P)-H[only follow symlinks when resolving command-line arguments]' \
'(-H -P)-L[follow symlinks]' \
- '*-atime:access time (days)' \
- '*-ctime:inode change time (days)' \
+ '*-atime:access time (days):->times' \
+ '*-ctime:inode change time (days):->times' \
'*-depth' \
'*-exec:program: _command_names -e:*\;::program arguments: _normal' \
'*-follow' \
@@ -128,7 +129,7 @@ _arguments $args \
'*-links:number of links:' \
'*-ls' \
'*-mount' \
- '*-mtime:modification time (days)' \
+ '*-mtime:modification time (days):->times' \
'*-name:name pattern' \
'*-newer:file to compare (modification time):_files' \
'*-nogroup' \
@@ -143,3 +144,13 @@ _arguments $args \
'*-xdev' \
'*-a' '*-o' \
'*:directory:_files -/'
+
+if [[ $state = times ]]; then
+ if ! compset -P '[+-]' || [[ -prefix '[0-9]' ]]; then
+ disp=( 'before' 'exactly' 'since' )
+ compstate[list]+=' packed'
+ alts=( "senses:sense:compadd -V times -S '' -d disp - + '' -" )
+ fi
+ alts+=( "times:${state_descr}:_dates -f d" )
+ _alternative $alts
+fi
diff --git a/Completion/Unix/Type/_dates b/Completion/Unix/Type/_dates
new file mode 100644
index 000000000..486a2c229
--- /dev/null
+++ b/Completion/Unix/Type/_dates
@@ -0,0 +1,123 @@
+#autoload
+
+# Options:
+# -f format : specify strftime format for matches
+# -f s/m/h/d/w/M : specify relative format
+# -F : select a future rather than past date
+
+# Styles:
+# max-matches-length : maximum number or percentage of lines to use for
+# completion listing, if both are specified, the
+# lowest takes precedence.
+# format : override date format
+
+local -a disp cand expl
+local userformat format spacer=1 spacing month monstart skip match
+local d day daysecs extra preclude r ri col explain
+local -a starts skips
+local -i start now mult
+local -i columns=$(( (COLUMNS+4) / 32 )) rows=LINES-4 offset=0
+local -a days=( Mo Tu We Th Fr Sa Su )
+local future mlabel mfmt mlabels
+
+zparseopts -D -K -E f:=format F=future X:=explain
+(( future = $#future ? 1 : -1 ))
+zstyle -s ':completion:$curcontext:dates' date-format userformat
+format=${userformat:-${format[2]:-%F}}
+
+zstyle -a ':completion:$curcontext:dates' max-matches-length r
+for ri in $r; do
+ [[ $ri = [0-9]##% ]] && (( ri = LINES * .${ri%%%} ))
+ (( ri < rows )) && (( rows=ri ))
+done
+(( rows = rows / 8 ))
+zmodload -i zsh/datetime || rows=0
+
+_message -e dates ${explain[2]:-date}
+(( rows )) || return
+_description -2V -x dates expl date
+compstate[list]='packed rows'
+
+if [[ $WIDGET = _next_tags ]]; then
+ typeset -g -i _next_tags_line
+ typeset -g -i _next_tags_date=$(( HISTNO == _next_tags_line ? _next_tags_date+1 : 1))
+ _next_tags_line=HISTNO
+ (( offset = _next_tags_date*rows*columns ))
+fi
+
+(( now=EPOCHSECONDS ))
+strftime -s year '%Y' $now
+strftime -s month '%m' $now
+(( offset = future*offset + year*12 + month + ((future == 1) ? rows*columns-2 : -1) ))
+for ((;rows;rows--)); do
+ disp=() mlabels=""
+ for ((col=1;col<=columns;col++)); do
+ (( start = offset + col - rows * columns ))
+ strftime -r -s monstart '%Y%m' $(( start/12 ))$(( 1 + start % 12 ))
+ strftime -s skip '%w' $(( monstart-86400 ))
+ starts[col]=$monstart
+ skips[col]=$skip
+ disp+=( $days ' ' )
+
+ mfmt='%B'
+ strftime -s mlabel '%m' $monstart
+ [[ $mlabel = 01 ]] && mfmt+=' %Y'
+ strftime -s mlabel "$mfmt" $monstart
+
+ mlabels+="${(r.(col == columns) ? 28 : 32.):-${(l.(26-$#mlabel)/2.)}$mlabel}"
+ done
+ (( spacing = COLUMNS - 32 * columns + 2 ))
+ disp[-1]="${(l.spacing.)}"
+ (( spacing < 2 )) && spacer=0 disp[-1]=()
+ expl[1+expl[(i)-V]]=dates-$rows
+ compadd -x "$mlabels" "$expl[@]" -d disp -E $(( $#disp ))
+
+ for ((line=0;line<6;line++)); do
+ for ((col=1;col<=columns;col++)); do
+ if (( skips[col] && !line )); then
+ disp=(); disp[skips[col]]=''
+ compadd -x "$mlabels" "$expl[@]" -d disp -E $skips[col]
+ (( skip=skips[col] ))
+ else
+ skip=0
+ fi
+ disp=() cand=()
+ (( extra = (col == columns) ? spacer : 1 ))
+ (( preclude = 0 ))
+ for ((d=1;d<=7-skip;d++)); do
+ (( day = d+7*line+skip-skips[col] ))
+ (( daysecs = starts[col] + 86400 * (day - 1) ))
+ strftime -s realday '%d' $daysecs
+ if (( realday != day )); then
+ (( extra+=8-d ))
+ break
+ fi
+ (( mult = -future * (now - daysecs) + (future == 1 ? 86400 : 0) ))
+ case $format in
+ s) (( match = mult )) ;;
+ m) (( match = mult / 60 )) ;;
+ h) (( match = mult / 3600 )) ;;
+ d) (( match = mult / 86400 )) ;;
+ w) (( match = mult / 604800 )) ;;
+ M) (( match = mult / 2592000 )) ;;
+ *) strftime -s match - $format $daysecs ;;
+ esac
+ disp+=( "${(l.2.)day}" )
+ if (( future < 0 && now < daysecs )); then
+ (( extra++ ))
+ elif (( future > 0 && (now - daysecs) > 86400 )); then
+ (( preclude++ ))
+ else
+ (( (now - daysecs) < 86400 && (now - daysecs) > 0 )) &&
+ compstate[insert]=menu:$(( compstate[nmatches] + $#disp ))
+ cand+=( "$match" )
+ fi
+ done
+ if (( preclude )); then
+ compadd -x "$mlabels" "$expl[@]" -E $preclude -d disp
+ shift preclude disp
+ fi
+ compadd -x "$mlabels" -U -i "$IPREFIX" -I "$ISUFFIX" "$expl[@]" "$@" -d disp -E $extra -a cand
+ done
+ done
+done
diff --git a/Completion/Zsh/Type/_globquals b/Completion/Zsh/Type/_globquals
index 042b27400..5cdb8f7c4 100644
--- a/Completion/Zsh/Type/_globquals
+++ b/Completion/Zsh/Type/_globquals
@@ -1,7 +1,7 @@
#autoload
local state=qual expl char delim timespec
-local -a alts
+local -a alts tdisp sdisp
local -A specmap
while [[ -n $PREFIX ]]; do
@@ -117,14 +117,15 @@ while [[ -n $PREFIX ]]; do
alts=()
timespec=$PREFIX[1]
if ! compset -P '[Mwhmsd]' && [[ -z $PREFIX ]]; then
- alts+=("time-specifiers:time specifier:\
-((M\:months w\:weeks h\:hours m:\minutes s\:seconds d\:days))")
+ tdisp=( seconds minutes hours days weeks Months )
+ alts+=( "time-specifiers:time specifier:compadd -E 0 -d tdisp -S '' - s m h d w M" )
fi
if ! compset -P '[-+]' && [[ -z $PREFIX ]]; then
- alts+=("senses:sense:((-\:less\ than +\:more\ than))")
+ sdisp=( before exactly since )
+ alts+=("senses:sense:compadd -E 0 -d sdisp -S '' - + '' -")
fi
specmap=( M months w weeks h hours m minutes s seconds '(|+|-|d)' days)
- alts+=('digits:digit ('${${specmap[(K)$timespec]}:-invalid time specifier}'):' )
+ alts+=('digits:digit ('${${specmap[(K)$timespec]}:-invalid time specifier}'):_dates -f ${${timespec/[-+]/d}:-d} -S ""' )
_alternative $alts
return
fi