mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-12-30 19:30:58 +01:00
35718: new calendar style date completion
This commit is contained in:
parent
04675eca4c
commit
396f68971f
4 changed files with 150 additions and 10 deletions
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
123
Completion/Unix/Type/_dates
Normal file
123
Completion/Unix/Type/_dates
Normal file
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue