zsh-workers
 help / color / mirror / code / Atom feed
* _multi_parts and -q
@ 2011-06-17 21:50 Danek Duvall
  2011-06-18 19:44 ` Bart Schaefer
  2011-06-18 19:52 ` Peter Stephenson
  0 siblings, 2 replies; 9+ messages in thread
From: Danek Duvall @ 2011-06-17 21:50 UTC (permalink / raw)
  To: zsh-workers

I was hoping that this

    _wanted dataset expl "$expl_type" _multi_parts "$@" -q / datasetlist

would add slashes as auto-removable suffixes, but it doesn't appear to.
That is, if I type a slash immediately after a slash, it gets swallowed,
but the slash doesn't disappear after hitting space or return.  Is this an
issue with _multi_parts, or something I'm doing wrong?  I tried putting in
-S/ explicitly, but that didn't seem to make a difference.

Thanks,
Danek


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

* Re: _multi_parts and -q
  2011-06-17 21:50 _multi_parts and -q Danek Duvall
@ 2011-06-18 19:44 ` Bart Schaefer
  2011-06-18 19:52 ` Peter Stephenson
  1 sibling, 0 replies; 9+ messages in thread
From: Bart Schaefer @ 2011-06-18 19:44 UTC (permalink / raw)
  To: Danek Duvall, zsh-workers

On Jun 17,  2:50pm, Danek Duvall wrote:
} Subject: _multi_parts and -q
}
} I was hoping that this
} 
}     _wanted dataset expl "$expl_type" _multi_parts "$@" -q / datasetlist
} 
} would add slashes as auto-removable suffixes, but it doesn't appear to.

There are a couple of things going on here, neither of which I entirely
understand.

The options passed to _multi_parts are only passed through to compadd in
the event that there is exactly one possible match.  So in the case of
ambiguity, the -q is ignored and the suffix is never autoremovable.

Even more confusing, though, is that on lines 169, 173, and 176 the
separator is passed through to compadd with -S (still ignoring -q) but
on lines 191, 211, 244, 249 and 253 an explicit -S '' is passed, even
though a separator may be included in the partial match to be inserted
on the line.

I suspect there's an underlying assumption that the strings passed to
_multi_parts (in this case, the values in $datasetlist) represent ALL
possible strings that could appear in a valid command line at that
position; so that it would never make sense to stop completing in the
middle and remove the separator.  Either the separator will always be
needed in order to form a valid command line, or the ambiguity occurs
before reaching the separator and it won't appear in the completion.


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

* Re: _multi_parts and -q
  2011-06-17 21:50 _multi_parts and -q Danek Duvall
  2011-06-18 19:44 ` Bart Schaefer
@ 2011-06-18 19:52 ` Peter Stephenson
  2011-06-18 20:03   ` Bart Schaefer
  1 sibling, 1 reply; 9+ messages in thread
From: Peter Stephenson @ 2011-06-18 19:52 UTC (permalink / raw)
  To: zsh-workers

On Fri, 17 Jun 2011 14:50:08 -0700
Danek Duvall <duvall@comfychair.org> wrote:
> I was hoping that this
> 
>     _wanted dataset expl "$expl_type" _multi_parts "$@" -q / datasetlist
> 
> would add slashes as auto-removable suffixes, but it doesn't appear to.
> That is, if I type a slash immediately after a slash, it gets swallowed,
> but the slash doesn't disappear after hitting space or return.  Is this an
> issue with _multi_parts, or something I'm doing wrong?  I tried putting in
> -S/ explicitly, but that didn't seem to make a difference.

_multi_parts is completely impenetrable, with no fewer than *18* calls
to compadd, but there is some evidence it is handling the -q and -S
options (the zparseopts at the start) and using the resulting $sopts in
some places, which is what the documentation says it does, although
reading the documentation didn't entirely fill me with confidence that I
understood everything that was going on. 

Anyway I think the following is working as I expect:

  _wanted dataset expl "$expl_type" _multi_parts -S/ -q / datasetlist;  

in that:

- if I complete something ambiguous I don't get the suffix
- if I complete something unambiguous I do
- the suffix is removable with the usual features:
-- it's highlighted if you're using Mikael's autoremove highlighting
   feature
-- if I type a "/" it replaces the autoremovable "/"
-- if I type a " " the "/" goes and the " " stays
-- if I type a letter the "/" stays and the letter appears immediately
   after.

That's pretty much all I'm expecting.

Note that I use menu completion, which shouldn't make a difference at
this level but might do.

I was testing with this entirely spurious function:

_tst() {
  local expl_type="stuff"
  local -a datasetlist
  datasetlist=(foo bar rod stuff)
  local pref
  [[ $PREFIX = */* ]] && pref=${PREFIX%/*} 
  [[ -n $pref ]] && datasetlist=($pref/${^datasetlist})
  _wanted dataset expl "$expl_type" _multi_parts -S/ -q / datasetlist;
}                     

simply to get strings to compile.  I don't think that should matter.

-- 
Peter Stephenson <p.w.stephenson@ntlworld.com>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/


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

* Re: _multi_parts and -q
  2011-06-18 19:52 ` Peter Stephenson
@ 2011-06-18 20:03   ` Bart Schaefer
  2011-06-18 21:07     ` Peter Stephenson
  0 siblings, 1 reply; 9+ messages in thread
From: Bart Schaefer @ 2011-06-18 20:03 UTC (permalink / raw)
  To: zsh-workers

On Jun 18,  8:52pm, Peter Stephenson wrote:
} 
} _tst() {
}   local expl_type="stuff"
}   local -a datasetlist
}   datasetlist=(foo bar rod stuff)
}   local pref
}   [[ $PREFIX = */* ]] && pref=${PREFIX%/*} 
}   [[ -n $pref ]] && datasetlist=($pref/${^datasetlist})
}   _wanted dataset expl "$expl_type" _multi_parts -S/ -q / datasetlist;
} }                     
} 
} simply to get strings to compile.  I don't think that should matter.

I get Danek's reported behavior if the strings in datasetlist actually
contain the separator.  Try the above with

datasetlist=(xy/foo xy/bar yx/rod stuff xy/yx/xy)

So perhaps Danek's problem is with the input data?


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

* Re: _multi_parts and -q
  2011-06-18 20:03   ` Bart Schaefer
@ 2011-06-18 21:07     ` Peter Stephenson
  2011-06-20 15:44       ` Danek Duvall
  2011-06-21  5:03       ` Bart Schaefer
  0 siblings, 2 replies; 9+ messages in thread
From: Peter Stephenson @ 2011-06-18 21:07 UTC (permalink / raw)
  To: zsh-workers

On Sat, 18 Jun 2011 13:03:34 -0700
Bart Schaefer <schaefer@brasslantern.com> wrote:
 On Jun 18,  8:52pm, Peter Stephenson wrote:
> } 
> } _tst() {
> }   local expl_type="stuff"
> }   local -a datasetlist
> }   datasetlist=(foo bar rod stuff)
> }   local pref
> }   [[ $PREFIX = */* ]] && pref=${PREFIX%/*} 
> }   [[ -n $pref ]] && datasetlist=($pref/${^datasetlist})
> }   _wanted dataset expl "$expl_type" _multi_parts -S/ -q / datasetlist;
> } }                     
> } 
> } simply to get strings to compile.  I don't think that should matter.
> 
> I get Danek's reported behavior if the strings in datasetlist actually
> contain the separator.  Try the above with
> 
> datasetlist=(xy/foo xy/bar yx/rod stuff xy/yx/xy)
> 
> So perhaps Danek's problem is with the input data?

I'm seeing something similar with the "xy/" bit with that data, i.e
completing "x" produces "xy/" with a non-removable "/".

I think the issue is that "xy/foo", "xy/bar" etc. look like a set of
ambiguous completions with "xy/" as prefix --- and in *that* case the
"/" isn't special, it's just part of the input string.  (Possibly you
can see some behaviour that disagrees with this hypothesis.)

So the reason I wasn't seeing it is that I was only offering completions
for the current level, i.e. I'd only be offering "xy", "yx" and "stuff"
at this point, after which the "/" is a suffix & separator with the
expected behaviour.

So if it's possible to generate the completions in that fashion (some
more sophisticated variant of the ${PREFIX%/*} business in the function
I was using), I think that would be a workaround.

It might be possible to wrap _multi_parts so as to get this behaviour
generically --- the doc suggests it's deliberate that _multi_parts
doesn't have quite the one-component-at-a-time behaviour you'd expect
with files.

-- 
Peter Stephenson <p.w.stephenson@ntlworld.com>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/


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

* Re: _multi_parts and -q
  2011-06-18 21:07     ` Peter Stephenson
@ 2011-06-20 15:44       ` Danek Duvall
  2011-06-21  5:03       ` Bart Schaefer
  1 sibling, 0 replies; 9+ messages in thread
From: Danek Duvall @ 2011-06-20 15:44 UTC (permalink / raw)
  To: Peter Stephenson; +Cc: zsh-workers

On Sat, Jun 18, 2011 at 10:07:23PM +0100, Peter Stephenson wrote:

> On Sat, 18 Jun 2011 13:03:34 -0700
> Bart Schaefer <schaefer@brasslantern.com> wrote:
>  On Jun 18,  8:52pm, Peter Stephenson wrote:
> > } 
> > } _tst() {
> > }   local expl_type="stuff"
> > }   local -a datasetlist
> > }   datasetlist=(foo bar rod stuff)
> > }   local pref
> > }   [[ $PREFIX = */* ]] && pref=${PREFIX%/*} 
> > }   [[ -n $pref ]] && datasetlist=($pref/${^datasetlist})
> > }   _wanted dataset expl "$expl_type" _multi_parts -S/ -q / datasetlist;
> > } }                     
> > } 
> > } simply to get strings to compile.  I don't think that should matter.
> > 
> > I get Danek's reported behavior if the strings in datasetlist actually
> > contain the separator.  Try the above with
> > 
> > datasetlist=(xy/foo xy/bar yx/rod stuff xy/yx/xy)
> > 
> > So perhaps Danek's problem is with the input data?

For context, this in my _zfs_dataset function, which at the moment passes
neither -S nor -q to _multi_parts, but I tried doing that to try to get the
slash auto-removed.

datasetlist contains the entire list of datasets on the system, mostly
because it's cheaper to generate the entire list once instead of at each
level.  So it contains data like

    xy xy/foo xy/foo/bar xy/foo/baz xy/qux xy/qux/baz

just like a directory structure.  Then if I type "x<TAB>", I get "xy/".  If
I type "/", I still have only one slash, but if I hit space or return, then
the slash stays.  And "xy/" is not valid, and the command complains.  Which
I guess is this observation:

> I'm seeing something similar with the "xy/" bit with that data, i.e
> completing "x" produces "xy/" with a non-removable "/".

> I think the issue is that "xy/foo", "xy/bar" etc. look like a set of
> ambiguous completions with "xy/" as prefix --- and in *that* case the
> "/" isn't special, it's just part of the input string.  (Possibly you
> can see some behaviour that disagrees with this hypothesis.)
> 
> So the reason I wasn't seeing it is that I was only offering completions
> for the current level, i.e. I'd only be offering "xy", "yx" and "stuff"
> at this point, after which the "/" is a suffix & separator with the
> expected behaviour.
> 
> So if it's possible to generate the completions in that fashion (some
> more sophisticated variant of the ${PREFIX%/*} business in the function
> I was using), I think that would be a workaround.

How can I do that without regenerating datasetlist multiple times --
calling zfs list over and over again is not cheap (but not really something
I want to cache using _store_cache, etc, either, if for no other reason
than I have no way of knowing whether the cache is invalid).

Thanks,
Danek


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

* Re: _multi_parts and -q
  2011-06-18 21:07     ` Peter Stephenson
  2011-06-20 15:44       ` Danek Duvall
@ 2011-06-21  5:03       ` Bart Schaefer
  2011-06-21  5:40         ` Danek Duvall
  1 sibling, 1 reply; 9+ messages in thread
From: Bart Schaefer @ 2011-06-21  5:03 UTC (permalink / raw)
  To: zsh-workers

On Jun 18, 10:07pm, Peter Stephenson wrote:
}
} I think the issue is that "xy/foo", "xy/bar" etc. look like a set of
} ambiguous completions with "xy/" as prefix --- and in *that* case the
} "/" isn't special, it's just part of the input string.  (Possibly you
} can see some behaviour that disagrees with this hypothesis.)

That's part of it, but by examination _multi_parts never passes -q to
compadd on its own, and it only passes *through* a -q from its options
($sopts) in three cases:

(1) The separator is not in the string from the command line AND there
is exactly one possible match; or

(2) The separator is not in the string from the command line AND *none*
of the possible matches contains the separator; or

(3) The matcher list found no matches AND there's no suffix on the
command line, i.e. we're completing at the end of a word.

In fact in the most obvious case _complete_debug shows the code passing
through the compadd on line 120 which passes -r $sep -S $sep but not -q
(this is the first clause of case 2 but not the second).  This happens
even when there is an exact match that does not contain the separator.

This change makes it take the compadd at line 123 (124 after the patch)
instead, and then Danek's example works:

Index: Completion/Base/Utility/_multi_parts
===================================================================
--- Completion/Base/Utility/_multi_parts	21 Dec 2010 16:41:14 -0000
+++ Completion/Base/Utility/_multi_parts	21 Jun 2011 05:00:16 -0000
@@ -116,7 +116,8 @@
 	  compadd "$group[@]" "$expl[@]" "$sopts[@]" \
                   -M "r:|${sep}=* r:|=* $matcher" - $pref$matches
         else
-	  if (( $matches[(I)${tmp1[1]}${sep}*] )); then
+	  if (( $matches[(I)${tmp1[1]}${sep}*] )) &&
+            ! (( $matches[(I)${tmp1[1]}] )); then
 	    compadd "$group[@]" "$expl[@]" -p "$pref" -r "$sep" -S "$sep"
"$opts[@]" \
                     -M "r:|${sep}=* r:|=* $matcher" - "$tmp1[1]"
           else

By the way, do NOT pass an empty separator to _multi_parts.  Infinite loop.


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

* Re: _multi_parts and -q
  2011-06-21  5:03       ` Bart Schaefer
@ 2011-06-21  5:40         ` Danek Duvall
  2011-06-21  8:02           ` Bart Schaefer
  0 siblings, 1 reply; 9+ messages in thread
From: Danek Duvall @ 2011-06-21  5:40 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: zsh-workers

On Mon, Jun 20, 2011 at 10:03:34PM -0700, Bart Schaefer wrote:

> --- Completion/Base/Utility/_multi_parts	21 Dec 2010 16:41:14 -0000
> +++ Completion/Base/Utility/_multi_parts	21 Jun 2011 05:00:16 -0000
> @@ -116,7 +116,8 @@
>  	  compadd "$group[@]" "$expl[@]" "$sopts[@]" \
>                    -M "r:|${sep}=* r:|=* $matcher" - $pref$matches
>          else
> -	  if (( $matches[(I)${tmp1[1]}${sep}*] )); then
> +	  if (( $matches[(I)${tmp1[1]}${sep}*] )) &&
> +            ! (( $matches[(I)${tmp1[1]}] )); then
>  	    compadd "$group[@]" "$expl[@]" -p "$pref" -r "$sep" -S "$sep"
> "$opts[@]" \
>                      -M "r:|${sep}=* r:|=* $matcher" - "$tmp1[1]"
>            else

This doesn't seem to do the trick for me.  The slash is auto-removed, all
right, but immediately after I hit tab.  I can backspace over that space,
put in a slash (hitting tab will do that for me), and start completing
again, but then it's weird -- the next level in the hierarchy is presented
twice -- once with a slash and once without.

Danek

> By the way, do NOT pass an empty separator to _multi_parts.  Infinite loop.

_multi_parts should be able to check for that, no?

Danek


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

* Re: _multi_parts and -q
  2011-06-21  5:40         ` Danek Duvall
@ 2011-06-21  8:02           ` Bart Schaefer
  0 siblings, 0 replies; 9+ messages in thread
From: Bart Schaefer @ 2011-06-21  8:02 UTC (permalink / raw)
  To: zsh-workers

On Jun 20, 10:40pm, Danek Duvall wrote:
} Subject: Re: _multi_parts and -q
}
} On Mon, Jun 20, 2011 at 10:03:34PM -0700, Bart Schaefer wrote:
} 
} > +	  if (( $matches[(I)${tmp1[1]}${sep}*] )) &&
} > +            ! (( $matches[(I)${tmp1[1]}] )); then
} 
} This doesn't seem to do the trick for me.  The slash is auto-removed, all
} right, but immediately after I hit tab.

Sorry, I meant to explain that wasn't really a fix -- it's just showing
that it's not possible to get _multi_parts to pass through the -q flag
consistently without some kind of tweaking.  That is, the workaround
that PWS suggested is not really a workaround in general.

-- 


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

end of thread, other threads:[~2011-06-21  8:02 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-06-17 21:50 _multi_parts and -q Danek Duvall
2011-06-18 19:44 ` Bart Schaefer
2011-06-18 19:52 ` Peter Stephenson
2011-06-18 20:03   ` Bart Schaefer
2011-06-18 21:07     ` Peter Stephenson
2011-06-20 15:44       ` Danek Duvall
2011-06-21  5:03       ` Bart Schaefer
2011-06-21  5:40         ` Danek Duvall
2011-06-21  8:02           ` 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).