zsh-workers
 help / color / mirror / code / Atom feed
* PATCH: completion of dates
@ 2015-07-07 15:32 Oliver Kiddle
  2015-07-07 16:32 ` Bart Schaefer
  2015-07-10  0:00 ` Mikael Magnusson
  0 siblings, 2 replies; 13+ messages in thread
From: Oliver Kiddle @ 2015-07-07 15:32 UTC (permalink / raw)
  To: Zsh workers

As far as I know, dummy matches are only used in _describe, _values and
_arguments to put matches with a common description together. I wanted
to experiment with it and came up with this. What it does is completion
of days laid out in the form of a calendar. Perhaps a bit of a gimmick
but I think it might be useful, especially in cases where a date is
specified in an obscure way such as for find's -mtime option.

There are some compromises to get this to work:

Cycling matches in order with tab is not correct: matches are added by
row then column rather than in date order.

In order to have labels for months, I've had to use separate groups -
dates-1, dates-2 etc - and a separate _message for the 'date' heading.
There may be combinations of tag-order/group-name styles which don't
work with this.

Weekday labels use dummy matches. These aren't localised because weekday
short forms are 3 characters, not two.

There's a max-matches-length style if you want to limit how much of your
terminal it will use.

There's hard-coded support for advancing to the next set of months if
called from _next_tags.

Getting the padding on the right is really quite tricky. Ideally, it'd
be possible to somehow force the line break. It doesn't manage to be
clever enough to reliably pack the dummy match beween months to be empty
so I've forced that to be two spaces resulting in 6 spaces of padding.
Having a way to reduce the padding around matches in general would allow
it to fit 3 month columns in an 80 character terminal.

I'm not entirely happy with the way it presents days in the future. Menu
selection's support for colouring isn't really flexible enough.

It doesn't parse any partial date you might have entered and with date
formats that include a time, it can be improved (do we want start of day
or whole numbers of days ago, what about at daylight savings?). May also
need an option to use UTC.

I've also patched _find and _globquals to use it. With them, I've
changed the completion of the - and + modifiers to be more compact.

Oliver

diff --git a/Completion/Unix/Command/_find b/Completion/Unix/Command/_find
index 8f80e36..aefca34 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 0000000..486a2c2
--- /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 042b274..5cdb8f7 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


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: PATCH: completion of dates
  2015-07-07 15:32 PATCH: completion of dates Oliver Kiddle
@ 2015-07-07 16:32 ` Bart Schaefer
  2015-07-07 22:09   ` Oliver Kiddle
  2015-07-10  0:00 ` Mikael Magnusson
  1 sibling, 1 reply; 13+ messages in thread
From: Bart Schaefer @ 2015-07-07 16:32 UTC (permalink / raw)
  To: Zsh workers

On Jul 7,  5:32pm, Oliver Kiddle wrote:
} Subject: PATCH: completion of dates
}
} As far as I know, dummy matches are only used in _describe, _values and
} _arguments to put matches with a common description together. I wanted
} to experiment with it and came up with this. What it does is completion
} of days laid out in the form of a calendar. Perhaps a bit of a gimmick
} but I think it might be useful, especially in cases where a date is
} specified in an obscure way such as for find's -mtime option.

This is entertaining and probably quite useful; a few remarks:

It would be nice if this only kicked in when menu-selection is active.
I know that may not be possible, but the strange ordering of the matches
is going to be baffling when only doing regular menu completion.

If one menu-selects "before" or "since" and then immediately re-enters
menu selection to choose the number of days, the +/- is removed from
the line and you return to completing exact dates (with "sense" group
available as before).  [note 1]  The only way to actually complete a
before/since date is to type the +/- as a literal before entering the
menu-selection, at which point the "sense" group disappears, or to
begin normal completion after selecting before/since and then drop
into menu-select from there.

[1] Also in this state there's a space appended at the end of the word
on the command line during the menu selection.  Probably an issue with
menu-selection in general rather than this in particular.  In fact
both behaviors may be specific to re-entering menu-select without
going through normal completion at least once in between.


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: PATCH: completion of dates
  2015-07-07 16:32 ` Bart Schaefer
@ 2015-07-07 22:09   ` Oliver Kiddle
  2015-07-07 22:38     ` Bart Schaefer
  0 siblings, 1 reply; 13+ messages in thread
From: Oliver Kiddle @ 2015-07-07 22:09 UTC (permalink / raw)
  To: Zsh workers

Bart wrote:
> It would be nice if this only kicked in when menu-selection is active.
> I know that may not be possible, but the strange ordering of the matches
> is going to be baffling when only doing regular menu completion.

Looking for select in $_def_menu_style looks like it might do that but
I'm not exactly sure.

> If one menu-selects "before" or "since" and then immediately re-enters
> menu selection to choose the number of days, the +/- is removed from
> the line and you return to completing exact dates (with "sense" group
> available as before).  [note 1]  The only way to actually complete a
> before/since date is to type the +/- as a literal before entering the
> menu-selection, at which point the "sense" group disappears, or to
> begin normal completion after selecting before/since and then drop
> into menu-select from there.

I can't reproduce this problem at all. Even from zsh -f, it works for
me. So either I've misunderstood your steps or there's something in your
setup that it isn't allowing for. I'm assuming:
  zsh -f
  autoload -U compinit;compinit
  zstyle ':completion*:default' menu 'select=0'
  find . -mtime <tab>
    <select "before"><enter (accept-line)><tab again>
That leaves the + on the command-line and resumes menu selection
without the "senses".

If you use a binding such as the following when selecting before/since,
does it work?
  bindkey -M menuselect "/" accept-and-infer-next-history

Thanks

Oliver


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: PATCH: completion of dates
  2015-07-07 22:09   ` Oliver Kiddle
@ 2015-07-07 22:38     ` Bart Schaefer
  0 siblings, 0 replies; 13+ messages in thread
From: Bart Schaefer @ 2015-07-07 22:38 UTC (permalink / raw)
  To: Zsh workers

On Jul 8, 12:09am, Oliver Kiddle wrote:
} Subject: Re: PATCH: completion of dates
}
} Bart wrote:
} > If one menu-selects "before" or "since" and then immediately re-enters
} > menu selection to choose the number of days, the +/- is removed from
} > the line and you return to completing exact dates (with "sense" group
} > available as before).
} 
} I can't reproduce this problem at all. Even from zsh -f, it works for
} me. So either I've misunderstood your steps or there's something in your
} setup that it isn't allowing for.

I'm doing

  zsh -f
  autoload -U compinit;compinit -D
  find . -ctime <ESC x>menu-select<RET>
  <select "before"><RET><ESC z><TAB>

Where that final TAB can be any movement in the menu (arrow keys, etc.).

As I said this is probably menu-selection in general -- leaving and then
entering again without passing through "normal" completion picks up the
old selection where it left off instead of starting a new selection?

} If you use a binding such as the following when selecting before/since,
} does it work?
}   bindkey -M menuselect "/" accept-and-infer-next-history

Yes, if I add that binding and then do

  <select "before"><RET><ESC z>/

and/or simply omit the <RET><ESC z> and immediately type /, the selection
does advance to the numbers and the "sense" group disappears.


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: PATCH: completion of dates
  2015-07-07 15:32 PATCH: completion of dates Oliver Kiddle
  2015-07-07 16:32 ` Bart Schaefer
@ 2015-07-10  0:00 ` Mikael Magnusson
  2015-07-10  9:11   ` Oliver Kiddle
  1 sibling, 1 reply; 13+ messages in thread
From: Mikael Magnusson @ 2015-07-10  0:00 UTC (permalink / raw)
  To: Oliver Kiddle; +Cc: Zsh workers

On Tue, Jul 7, 2015 at 5:32 PM, Oliver Kiddle <okiddle@yahoo.co.uk> wrote:
> As far as I know, dummy matches are only used in _describe, _values and
> _arguments to put matches with a common description together. I wanted
> to experiment with it and came up with this. What it does is completion
> of days laid out in the form of a calendar. Perhaps a bit of a gimmick
> but I think it might be useful, especially in cases where a date is
> specified in an obscure way such as for find's -mtime option.
>
> There are some compromises to get this to work:
[...]
> I've also patched _find and _globquals to use it. With them, I've
> changed the completion of the - and + modifiers to be more compact.

I don't really like this change. I usually forget the order for m3M+
glob qualifiers, so it's handy to just press tab to see when which is
valid, but now it starts autofilling stuff instead, and scrolling off
everything else on my terminal. It also doesn't seem to insert
anything actually sensible... but even if the bugs are fixed I would
prefer to turn the whole thing off. :)

-- 
Mikael Magnusson


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: PATCH: completion of dates
  2015-07-10  0:00 ` Mikael Magnusson
@ 2015-07-10  9:11   ` Oliver Kiddle
  2015-07-10 18:22     ` Daniel Shahaf
  2015-07-10 18:37     ` Mikael Magnusson
  0 siblings, 2 replies; 13+ messages in thread
From: Oliver Kiddle @ 2015-07-10  9:11 UTC (permalink / raw)
  To: Zsh workers

Mikael Magnusson wrote:
> I don't really like this change. I usually forget the order for m3M+
> glob qualifiers, so it's handy to just press tab to see when which is
> valid, but now it starts autofilling stuff instead, and scrolling off
> everything else on my terminal. It also doesn't seem to insert
> anything actually sensible... but even if the bugs are fixed I would
> prefer to turn the whole thing off. :)

It can be turned off with:
  zstyle ':completion:*:dates' max-matches-length 0
If the function stays, I can add some documentation for that.

The line of _dates which causes the autofilling is:
  compstate[insert]=menu:$(( compstate[nmatches] + $#disp ))

Other places where we set compstate[insert] in a similar manner include
_pids and _mpc where we have insert-ids and insert-song-numbers styles
to control this. I could do something similar here. Any thoughts
on a style name: I think it is better to reuse generic names (i.e.
insert-ids) rather than name it insert-dates? Would you be happy with
that as a way forward? I wish it was possible to simply colour the
current date but a pattern to do that would match, e.g. the 10th of
every month.

Could you elaborate on "the bugs"? Issues could be reliant on your
timezone/setup/terminal and so not obvious to me. The issue mentioned by
Bart is a general menu selection thing.

Oliver


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: PATCH: completion of dates
  2015-07-10  9:11   ` Oliver Kiddle
@ 2015-07-10 18:22     ` Daniel Shahaf
  2015-07-10 18:37     ` Mikael Magnusson
  1 sibling, 0 replies; 13+ messages in thread
From: Daniel Shahaf @ 2015-07-10 18:22 UTC (permalink / raw)
  To: Oliver Kiddle; +Cc: Zsh workers

Oliver Kiddle wrote on Fri, Jul 10, 2015 at 11:11:26 +0200:
> Mikael Magnusson wrote:
> > I don't really like this change. I usually forget the order for m3M+
> > glob qualifiers, so it's handy to just press tab to see when which is
> > valid, but now it starts autofilling stuff instead, and scrolling off
> > everything else on my terminal. It also doesn't seem to insert
> > anything actually sensible... but even if the bugs are fixed I would
> > prefer to turn the whole thing off. :)
> 
> It can be turned off with:
>   zstyle ':completion:*:dates' max-matches-length 0
> If the function stays, I can add some documentation for that.
> 
> The line of _dates which causes the autofilling is:
>   compstate[insert]=menu:$(( compstate[nmatches] + $#disp ))
> 
> Other places where we set compstate[insert] in a similar manner include
> _pids and _mpc where we have insert-ids and insert-song-numbers styles
> to control this. I could do something similar here. Any thoughts
> on a style name: I think it is better to reuse generic names (i.e.
> insert-ids) rather than name it insert-dates? Would you be happy with
> that as a way forward? I wish it was possible to simply colour the
> current date but a pattern to do that would match, e.g. the 10th of
> every month.

I have two cases in mind:

- A command that takes more than one kind of "id"
  e.g., 'find -mtime +3 -inode -1500' has two kinds.

- Configuring all instances of calendar completion
  (_find, _globquals, others)

Both of these argue for being clear about "This is a calendar dates
completion" somewhere in the (context, style) zstyle coordinates.  So
I think it suggests either "insert-dates" style, or an "insert-ids"
style with a "dates" or "timedelta" tag?


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: PATCH: completion of dates
  2015-07-10  9:11   ` Oliver Kiddle
  2015-07-10 18:22     ` Daniel Shahaf
@ 2015-07-10 18:37     ` Mikael Magnusson
  2015-07-10 23:37       ` Bart Schaefer
  1 sibling, 1 reply; 13+ messages in thread
From: Mikael Magnusson @ 2015-07-10 18:37 UTC (permalink / raw)
  To: Oliver Kiddle; +Cc: Zsh workers

On Fri, Jul 10, 2015 at 11:11 AM, Oliver Kiddle <okiddle@yahoo.co.uk> wrote:
> Mikael Magnusson wrote:
>> I don't really like this change. I usually forget the order for m3M+
>> glob qualifiers, so it's handy to just press tab to see when which is
>> valid, but now it starts autofilling stuff instead, and scrolling off
>> everything else on my terminal. It also doesn't seem to insert
>> anything actually sensible... but even if the bugs are fixed I would
>> prefer to turn the whole thing off. :)
>
> It can be turned off with:
>   zstyle ':completion:*:dates' max-matches-length 0
> If the function stays, I can add some documentation for that.
>
> The line of _dates which causes the autofilling is:
>   compstate[insert]=menu:$(( compstate[nmatches] + $#disp ))
>
> Other places where we set compstate[insert] in a similar manner include
> _pids and _mpc where we have insert-ids and insert-song-numbers styles
> to control this. I could do something similar here. Any thoughts
> on a style name: I think it is better to reuse generic names (i.e.
> insert-ids) rather than name it insert-dates? Would you be happy with
> that as a way forward? I wish it was possible to simply colour the
> current date but a pattern to do that would match, e.g. the 10th of
> every month.
>
> Could you elaborate on "the bugs"? Issues could be reliant on your
> timezone/setup/terminal and so not obvious to me. The issue mentioned by
> Bart is a general menu selection thing.
>
> Oliver

Before the patch, I get output like this:
% *(m<tab>
---- time specifier
M  -- months
d  -- days
h  -- hours
m  -- minutes
s  -- seconds
w  -- weeks
---- sense
+  -- more than
-  -- less than
---- digit (days)

With the patch and the max-matches-length 0 style set, I get this:
% *(m<tab>
---- time specifier
seconds  hours    weeks    seconds  hours    weeks    seconds  hours
 weeks
minutes  days     Months   minutes  days     Months   minutes  days
 Months
---- sense
before    exactly   since     before    exactly   since     before
exactly   since
---- ---- digit (days)

Pressing tab further times cycles through smhdwM three times before
moving on to +-+-+-. The output is not super helpful either since it
doesn't tell me what the syntax is without selecting the entry itself
to see what gets inserted. I suppose it does fit my stated goal of
seeing which order I should write the stuff in though.

I think the other "bug" I was thinking of was just me not knowing what
format find expects arguments to -mtime to be in.

-- 
Mikael Magnusson


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: PATCH: completion of dates
  2015-07-10 18:37     ` Mikael Magnusson
@ 2015-07-10 23:37       ` Bart Schaefer
  2015-07-11 23:25         ` Oliver Kiddle
  0 siblings, 1 reply; 13+ messages in thread
From: Bart Schaefer @ 2015-07-10 23:37 UTC (permalink / raw)
  To: Zsh workers

On Jul 10,  8:37pm, Mikael Magnusson wrote:
} Subject: Re: PATCH: completion of dates
}
} Before the patch, I get output like this:
} % *(m<tab>

I don't get any completion at all in command position for glob qualifiers,
so this depends on having AUTO_CD set.

} ---- time specifier
} M  -- months
} d  -- days
} h  -- hours
} m  -- minutes
} s  -- seconds
} w  -- weeks
} ---- sense
} +  -- more than
} -  -- less than
} ---- digit (days)

And this depends at the least on the group-name style, because I get

+  -- more than
-  -- less than
M  -- months
d  -- days
h  -- hours
m  -- minutes
s  -- seconds
w  -- weeks

so I suspect you're going to need to elaborate on your zstyle settings
if you want Oliver to debug this further.

} With the patch and the max-matches-length 0 style set, I get this:
} % *(m<tab>
} ---- time specifier
} seconds  hours    weeks    seconds  hours    weeks    seconds  hours
}  weeks
} minutes  days     Months   minutes  days     Months   minutes  days
}  Months
} ---- sense
} before    exactly   since     before    exactly   since     before
} exactly   since
} ---- ---- digit (days)

With max-matches-length 0 but without group-name, I have

torch% *(m<TAB>
seconds  hours    weeks    before   since
minutes  days     Months   exactly

After adding group-name '' I have:

torch% *(m
seconds  minutes  hours    days     weeks    Months
before            exactly           since

And after adding a "format" style:

torch% *(m
Completing time specifier
seconds  minutes  hours    days     weeks    Months 
Completing sense
before            exactly           since           
Completing Completing digit (days)

So other than the weird repetition of the word "Completing" for "digit"
which corresponds to your "---- ----" on that "digit" line, I don't
encounter the duplication that you did.  Some other style is involved.

The "Completing Completing" is because _description is being called with
a string that has already been through zformat once.  That's from _message
calling _next_label, via _dates line 36.


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: PATCH: completion of dates
  2015-07-10 23:37       ` Bart Schaefer
@ 2015-07-11 23:25         ` Oliver Kiddle
  2015-07-13  5:44           ` Bart Schaefer
  0 siblings, 1 reply; 13+ messages in thread
From: Oliver Kiddle @ 2015-07-11 23:25 UTC (permalink / raw)
  To: Zsh workers

Bart wrote:
> so I suspect you're going to need to elaborate on your zstyle settings
> if you want Oliver to debug this further.

I think I've finally guessed what the likely cause is: a file-patterns
style. _globquals then gets called for each of the file patterns that is
completed together. That is a bug in _files/_path_files.

In the past, this wasn't apparent because completion normally removes
duplicates. I used an unsorted group because I think it is better
to order the time specifiers in duration order (and I did that in a
slightly hacky way because it is in _alternative). _dates absolutely
needs to use unsorted groups with no deduplication. And having it called
three times is not useful.

I think the solution is to move the glob qualifier handling from the
beginning of _path_files to the beginning of _files. It can then be
done before the file-patterns are processed and so done once only. The
disadvantage is that glob qualifier completion wouldn't then work with
_path_files. However, _path_files is typically used instead of _files in
the type of situations where glob qualifiers aren't applicable.

Any thoughts on that solution or other ideas?

> } ---- sense

I'm not sure I really like that description. Alternatives that come to
mind include 'time span' and 'time range'. But changing the tag might break
someone's tag-order style.

> Completing Completing digit (days)

I use %B%d%b for that style so didn't notice that effect. Thanks for
pointing me in the right direction. It isn't simple to use _message -e
with reused descriptions from "$@" so the patch below takes the manual
approach.

Oliver

diff --git a/Completion/Unix/Type/_dates b/Completion/Unix/Type/_dates
index 486a2c2..83397b4 100644
--- a/Completion/Unix/Type/_dates
+++ b/Completion/Unix/Type/_dates
@@ -13,14 +13,14 @@
 
 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 d day daysecs extra preclude r ri col
 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
+zparseopts -D -K -E f:=format F=future
 (( future = $#future ? 1 : -1 ))
 zstyle -s ':completion:$curcontext:dates' date-format userformat
 format=${userformat:-${format[2]:-%F}}
@@ -33,9 +33,12 @@ done
 (( rows = rows / 8 ))
 zmodload -i zsh/datetime || rows=0
 
-_message -e dates ${explain[2]:-date}
-(( rows )) || return
+_tags dates || return 0
+_comp_mesg=yes
 _description -2V -x dates expl date
+compadd "${@:/-X/-x}" "$expl[@]" -
+[[ -n $PREFIX$SUFFIX ]] && return 0
+(( rows )) || return 0
 compstate[list]='packed rows'
 
 if [[ $WIDGET = _next_tags ]]; then


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: PATCH: completion of dates
  2015-07-11 23:25         ` Oliver Kiddle
@ 2015-07-13  5:44           ` Bart Schaefer
  2015-07-13 22:08             ` Oliver Kiddle
  0 siblings, 1 reply; 13+ messages in thread
From: Bart Schaefer @ 2015-07-13  5:44 UTC (permalink / raw)
  To: Zsh workers

On Jul 12,  1:25am, Oliver Kiddle wrote:
}
} I think I've finally guessed what the likely cause is: a file-patterns
} style. _globquals then gets called for each of the file patterns that is
} completed together. That is a bug in _files/_path_files.
} 
} I think the solution is to move the glob qualifier handling from the
} beginning of _path_files to the beginning of _files. It can then be
} done before the file-patterns are processed and so done once only. The
} disadvantage is that glob qualifier completion wouldn't then work with
} _path_files. However, _path_files is typically used instead of _files in
} the type of situations where glob qualifiers aren't applicable.

Hmm, I'm not sure that last is really true.  About two-thirds of the uses
are either (1) to pass the -/ option, which _files accepts but converts
into a pattern because it uses it to split into the "directories" tag,
and (2) to pass the -g option for much the same reason.  Glob qualifiers
for the file type don't apply in those cases, but qualifiers like (F) or 
(l+0) might apply.

Are there a lot of cases where _path_files could be replaced by _files?  
That'd introduce file-patterns and ignore handling in a bunch of places
where it doesn't happen now, among other things such as e.g. allowing
_next_tags to advance from directories to all-files.

Maybe the way to go is to handle glob qualifiers in BOTH places, and
not call down into _path_files from _files while "inside" the quals?


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: PATCH: completion of dates
  2015-07-13  5:44           ` Bart Schaefer
@ 2015-07-13 22:08             ` Oliver Kiddle
  2015-07-14  4:04               ` Bart Schaefer
  0 siblings, 1 reply; 13+ messages in thread
From: Oliver Kiddle @ 2015-07-13 22:08 UTC (permalink / raw)
  To: Zsh workers

Bart wrote:
> Are there a lot of cases where _path_files could be replaced by _files?  
Plenty. Not much fun to go through checking them, though.

> Maybe the way to go is to handle glob qualifiers in BOTH places, and
> not call down into _path_files from _files while "inside" the quals?

That seems like a good plan. 

A straight cut-and-paste from _path_files seems to work. Looking at the
copied lines, I'm inclined to think that it should use _alternative
to call both _globflags and _globquals with _globflags checking the
prefix-needed style. Directly completing a prefix as, e.g. \#:introduce\
glob\ flag is perhaps useful, however.

Oliver

diff --git a/Completion/Unix/Type/_files b/Completion/Unix/Type/_files
index e628cb3..4243ef7 100644
--- a/Completion/Unix/Type/_files
+++ b/Completion/Unix/Type/_files
@@ -1,6 +1,24 @@
 #compdef -redirect-,-default-,-default-
 
-local opts tmp glob pat pats expl tag i def descr end ign ret=1 match tried
+local -a match mbegin mend
+
+# Look for glob qualifiers. This is duplicated from _path_files because
+# we don't want to complete them multiple times (for each file pattern).
+if _have_glob_qual $PREFIX; then
+  local ret=1
+  compset -p ${#match[1]}
+  if [[ $_comp_caller_options[extendedglob] == on ]] && compset -P '\#'; then
+    _globflags && ret=0
+  else
+    if [[ $_comp_caller_options[extendedglob] == on ]]; then
+      _describe -t globflags "glob flag" '(\#:introduce\ glob\ flag)' -Q -S '' && ret=0
+    fi
+    _globquals && ret=0
+  fi
+  return ret
+fi
+
+local opts tmp glob pat pats expl tag i def descr end ign ret=1 tried
 local type sdef ignvars ignvar prepath oprefix rfiles rfile
 
 zparseopts -a opts \


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: PATCH: completion of dates
  2015-07-13 22:08             ` Oliver Kiddle
@ 2015-07-14  4:04               ` Bart Schaefer
  0 siblings, 0 replies; 13+ messages in thread
From: Bart Schaefer @ 2015-07-14  4:04 UTC (permalink / raw)
  To: Zsh workers

On Jul 14, 12:08am, Oliver Kiddle wrote:
}
} A straight cut-and-paste from _path_files seems to work.

Do you care that you've declared "local ret=1" twice?  No stray output
this time because both declarations include the assignment.

} I'm inclined to think that it should use _alternative
} to call both _globflags and _globquals with _globflags checking the
} prefix-needed style.

I have no opinion here.


^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2015-07-14  4:04 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-07-07 15:32 PATCH: completion of dates Oliver Kiddle
2015-07-07 16:32 ` Bart Schaefer
2015-07-07 22:09   ` Oliver Kiddle
2015-07-07 22:38     ` Bart Schaefer
2015-07-10  0:00 ` Mikael Magnusson
2015-07-10  9:11   ` Oliver Kiddle
2015-07-10 18:22     ` Daniel Shahaf
2015-07-10 18:37     ` Mikael Magnusson
2015-07-10 23:37       ` Bart Schaefer
2015-07-11 23:25         ` Oliver Kiddle
2015-07-13  5:44           ` Bart Schaefer
2015-07-13 22:08             ` Oliver Kiddle
2015-07-14  4:04               ` Bart Schaefer

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).