zsh-workers
 help / color / mirror / code / Atom feed
* Limitations of menuselect
@ 2013-02-25 21:49 Olivier Teuliere
  2013-02-27 17:27 ` Oliver Kiddle
  2013-03-01 23:59 ` Oliver Kiddle
  0 siblings, 2 replies; 9+ messages in thread
From: Olivier Teuliere @ 2013-02-25 21:49 UTC (permalink / raw)
  To: zsh-workers

Hi,

I recently discovered the menu selection feature and I would like to
use it. Unfortunately, it doesn't work as well as I expected (using
zsh 5.0.0), so here are some bug reports and suggestions.

1) Custom bindings don't work. You can try it with the following:
    my-widget() { zle down-line-or-history }; zle -N my-widget;
bindkey -M menuselect k my-widget
(replacing "my-widget" with "down-line-or-history" in the bindkey
command works as expected).
Someone told me on IRC that in menuselect a hard-coded table is used
to lookup the widget names. So, could you add support for custom
widgets in menuselect? This would allow many cool things, in
particular, I think it would let me work-around items 2, 3 and 4
below.

2) Moving the selected menu item line by line is nice, but scrolling
several lines at a time would be nicer (that's what I would expect
PageUp and PageDown to do by default in menuselect, for example). I
couldn't find an existing widget for that.

3) When using the reverse-menu-complete widget to open menuselect, I
would like to select the last result, not the first one (otherwise I
can use menu-complete directly...). It doesn't sem to be possible at
the moment.

4) When moving the selection in the menu, the inserted text changes.
But for some reason, the accept-line widget only closes the menu,
without accepting the line. So to really accept the line I have to
call accept-line again (basically, I have to hit Enter twice). This
behavior seems a bit backwards: if I wanted to accept the current
selection, which is already inserted, I could simply go on typing, I
don't need an extra validation step. So, would it be possible to have
accept-line really accept the line? :) If the current behavior is
still wanted, it could maybe be called "accept-selection", because the
current name is misleading...

5) Apparently, menuselect always inserts the selected text. But if
there was a way (maybe using a style) to select a menu entry without
inserting the corresponding text, it could allow a killer feature:
typing characters could shrink the list of results (for example, by
binding individual letter keys to an appropriate widget...
accept-line-and-infer-history maybe?), while still allowing to select
an item using the arrow keys. Users would get the best of the 2
worlds: if the completion list is too long, typing letters would
shrink it until it's small enough to use arrow keys. Currently, it's
really annoying to open the menu, realize that there are way too many
entries to complete using movement keys, and then undo, type a few
more letters, hoping that this time the menu will not be too long...
:)
Of course, I could use a list instead of a menu, to avoid undoing the
completion if there are too many results. But this wouldn't really
solve the problem: if I use the list-choices widget
In case my description is not clear, you can have a look at the
AutoComplPop plugin for Vim [1], which does exactly that by default
(except that in addition it opens the menu automatically). It's really
a huge time saver.
Would that be possible to implement this feature (optional
non-insertion of selected text)?

I hope that these remarks make sense and that I haven't overlooked
some existing features...

Please Cc: me in the replies, as I didn't subscribe to the list.

Cheers,
-- 
Olivier
[1] http://www.vim.org/scripts/script.php?script_id=1879


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

* Re: Limitations of menuselect
  2013-02-25 21:49 Limitations of menuselect Olivier Teuliere
@ 2013-02-27 17:27 ` Oliver Kiddle
  2013-02-27 17:53   ` Peter Stephenson
                     ` (2 more replies)
  2013-03-01 23:59 ` Oliver Kiddle
  1 sibling, 3 replies; 9+ messages in thread
From: Oliver Kiddle @ 2013-02-27 17:27 UTC (permalink / raw)
  To: Olivier Teuliere; +Cc: zsh-workers

Olivier Teuliere wrote:
> 1) Custom bindings don't work. You can try it with the following:
>     my-widget() { zle down-line-or-history }; zle -N my-widget;
> bindkey -M menuselect k my-widget
> (replacing "my-widget" with "down-line-or-history" in the bindkey
> command works as expected).

Yes, unfortunately it isn't possible.

> Someone told me on IRC that in menuselect a hard-coded table is used
> to lookup the widget names.

More or less. It seems any keybinding picked up from the main keymap
will work though menu selection is exited first. For anything from the
menuselect keymap, it hard codes the actions with various widgets being
overloaded from their original meanings. I'm not sure that I get the
point of this. If it meant that your existing key-bindings would do
something appropriate it might make sense but you do have to duplicate
them in the menuselect keymap. Was this perhaps a bug introduced later
such as when local keymaps were added? In any case, I'd have thought it
was simpler if there were separate widgets - e.g. menu-up-entry instead
of up-line-or-history being overloaded.

> 2) Moving the selected menu item line by line is nice, but scrolling
> several lines at a time would be nicer (that's what I would expect
> PageUp and PageDown to do by default in menuselect, for example). I
> couldn't find an existing widget for that.

You can do some hacks with bindkey -s. For example:
  bindkey -M menuselect j down-line-or-history
  bindkey -M menuselect -s n 'jj'
What you can do with that is limited. Also, it doesn't cope well with putting
escapes in the latter string.

> 3) When using the reverse-menu-complete widget to open menuselect, I
> would like to select the last result, not the first one (otherwise I
> can use menu-complete directly...). It doesn't sem to be possible at
> the moment.

That seems like a bug to me.

> 4) When moving the selection in the menu, the inserted text changes.
> But for some reason, the accept-line widget only closes the menu,
> without accepting the line. So to really accept the line I have to
> call accept-line again (basically, I have to hit Enter twice). This
> behavior seems a bit backwards: if I wanted to accept the current
> selection, which is already inserted, I could simply go on typing, I
> don't need an extra validation step. So, would it be possible to have
> accept-line really accept the line? :) If the current behavior is
> still wanted, it could maybe be called "accept-selection", because the
> current name is misleading...

This probably wouldn't be hard to implement if we keep to the scheme of
overloading existing widgets.

You can abuse the behaviour I described earlier to make Enter really
accept the line:
  bindkey -M menuselect -r '^M'
  zle -N new-accept-line
  new-accept-line() {
    zle .accept-line
  }
  bindkey '^M' new-accept-line

But don't do this because it'll break the enter key in other contexts
(reading from the mini-buffer). To replace accept-line without breaking
things you need to use zle -A but that won't work here.

> 5) Apparently, menuselect always inserts the selected text. But if
> there was a way (maybe using a style) to select a menu entry without
> inserting the corresponding text, it could allow a killer feature:
> typing characters could shrink the list of results (for example, by
> binding individual letter keys to an appropriate widget...

Actually, this is possible. Bind a key to vi-insert in menuselect and
you get "interactive" mode which does this. Still, there is a lot of
ways this could be better. Unfortunately, you stay in the menuselect
keymap at this point which is irritating if you've, for example, bound /
to history-incremental-search-forward.

I can't think of a way to go straight into this mode. The bindkey -s
trick stuck it in an infinite loop.

> accept-line-and-infer-history maybe?), while still allowing to select

That also does something similar already:
  bindkey -M menuselect '^M' accept-and-infer-next-history
then enter will keep in menu selection.

> I hope that these remarks make sense and that I haven't overlooked
> some existing features...

It certainly makes sense and is quite thought provoking. I'm only sorry
that my answers aren't especially helpful.

Oliver


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

* Re: Limitations of menuselect
  2013-02-27 17:27 ` Oliver Kiddle
@ 2013-02-27 17:53   ` Peter Stephenson
  2013-02-27 18:09     ` Peter Stephenson
  2013-02-28  1:07   ` Oliver Kiddle
  2013-02-28  1:59   ` Bart Schaefer
  2 siblings, 1 reply; 9+ messages in thread
From: Peter Stephenson @ 2013-02-27 17:53 UTC (permalink / raw)
  To: zsh-workers; +Cc: Olivier Teuliere

On Wed, 27 Feb 2013 18:27:31 +0100
Oliver Kiddle <okiddle@yahoo.co.uk> wrote:
> It seems any keybinding picked up from the main keymap
> will work though menu selection is exited first. For anything from the
> menuselect keymap, it hard codes the actions with various widgets being
> overloaded from their original meanings. I'm not sure that I get the
> point of this. If it meant that your existing key-bindings would do
> something appropriate it might make sense but you do have to duplicate
> them in the menuselect keymap. Was this perhaps a bug introduced later
> such as when local keymaps were added?

Hmm, I think the main keymap is supposed to show through the menu
selection map in places where nothing's explicitly set, so you don't
need to rebind the widget.  So that probably is a bug.

pws


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

* Re: Limitations of menuselect
  2013-02-27 17:53   ` Peter Stephenson
@ 2013-02-27 18:09     ` Peter Stephenson
  0 siblings, 0 replies; 9+ messages in thread
From: Peter Stephenson @ 2013-02-27 18:09 UTC (permalink / raw)
  To: zsh-workers; +Cc: Olivier Teuliere

On Wed, 27 Feb 2013 17:53:30 +0000
Peter Stephenson <p.stephenson@samsung.com> wrote:
> On Wed, 27 Feb 2013 18:27:31 +0100
> Oliver Kiddle <okiddle@yahoo.co.uk> wrote:
> > It seems any keybinding picked up from the main keymap
> > will work though menu selection is exited first. For anything from the
> > menuselect keymap, it hard codes the actions with various widgets being
> > overloaded from their original meanings. I'm not sure that I get the
> > point of this. If it meant that your existing key-bindings would do
> > something appropriate it might make sense but you do have to duplicate
> > them in the menuselect keymap. Was this perhaps a bug introduced later
> > such as when local keymaps were added?
> 
> Hmm, I think the main keymap is supposed to show through the menu
> selection map in places where nothing's explicitly set, so you don't
> need to rebind the widget.  So that probably is a bug.

Actually, I think this *does* work, it's just hard to find a widget that
isn't overloaded, but now I have, it does cause exit from menu select
and then the widget's normal effect, without any additional binding
required.

(Unless you meant overloading widgets was a bug, but that's been there
all along.)

pws


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

* Re: Limitations of menuselect
  2013-02-27 17:27 ` Oliver Kiddle
  2013-02-27 17:53   ` Peter Stephenson
@ 2013-02-28  1:07   ` Oliver Kiddle
  2013-02-28  9:34     ` Olivier Teuliere
  2013-02-28  1:59   ` Bart Schaefer
  2 siblings, 1 reply; 9+ messages in thread
From: Oliver Kiddle @ 2013-02-28  1:07 UTC (permalink / raw)
  To: Olivier Teuliere, zsh-workers

I wrote:
> Was this perhaps a bug introduced later
> such as when local keymaps were added?

It does work correctly as mentioned by Peter so sorry for the
misinformation. I think I got mixed up between
accept-line-and-down-history and accept-and-infer-next-history. It then
seems that the intention is to enable the features on logical keys from
the main keymap.

> > 3) When using the reverse-menu-complete widget to open menuselect, I
> > would like to select the last result, not the first one (otherwise I
> > can use menu-complete directly...). It doesn't sem to be possible at
> > the moment.

This doesn't seem to be easy to solve. It seems to be in the
REVERSEMENUHOOK where it fixes things to go backwards but the initial
call to reversemenucomplete is not returning from menucomplete() until
it is too late.

> Actually, this is possible. Bind a key to vi-insert in menuselect and
> you get "interactive" mode which does this. Still, there is a lot of
> ways this could be better. Unfortunately, you stay in the menuselect
> keymap at this point which is irritating if you've, for example, bound /
> to history-incremental-search-forward.
> 
> I can't think of a way to go straight into this mode. The bindkey -s
> trick stuck it in an infinite loop.

Actually, it turns out this is as simple as including the word
"interactive" in the menu style. For example:
  zstyle ':completion*:default' menu select=0 interactive

Oliver


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

* Re: Limitations of menuselect
  2013-02-27 17:27 ` Oliver Kiddle
  2013-02-27 17:53   ` Peter Stephenson
  2013-02-28  1:07   ` Oliver Kiddle
@ 2013-02-28  1:59   ` Bart Schaefer
  2 siblings, 0 replies; 9+ messages in thread
From: Bart Schaefer @ 2013-02-28  1:59 UTC (permalink / raw)
  To: zsh-workers

On Feb 27,  6:27pm, Oliver Kiddle wrote:
} Subject: Re: Limitations of menuselect
}
} Olivier Teuliere wrote:
} > Someone told me on IRC that in menuselect a hard-coded table is used
} > to lookup the widget names.
} 
} More or less. It seems any keybinding picked up from the main keymap
} will work though menu selection is exited first. For anything from the
} menuselect keymap, it hard codes the actions with various widgets being
} overloaded from their original meanings. I'm not sure that I get the
} point of this.

At the time menuselect was added, the "local keymaps" implementation had
not yet been done.  So menuselect was implemented as a self-contained
widget (just like the incremental search widgets, etc.) that does all
its own key interpretation.

The reason for overloading widgets from the main keymap was because the
keystroke interpretation code always mapped everything directly to a
known widget object.  (I'm not sure user-defined widgets even existed
yet at that time.)  So the only way to have [say] ENTER mean one thing
in the main keymap and another in menuselect was to overload the widget
to which ENTER was mapped.

When the local keymaps were introduced, nobody ever undertook to refit
menuselect to use real widgets; it got its own keymap but the overload
implementation was never ripped out and rebuilt.

} > 3) When using the reverse-menu-complete widget to open menuselect, I
} > would like to select the last result, not the first one (otherwise I
} > can use menu-complete directly...). It doesn't sem to be possible at
} > the moment.
} 
} That seems like a bug to me.

I think it was punted as requiring too much implementation effort, given
that up-arrow from the first result in menu-selection will cycle to the
last result.
 
} It certainly makes sense and is quite thought provoking. I'm only sorry
} that my answers aren't especially helpful.

Ditto ...


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

* Re: Limitations of menuselect
  2013-02-28  1:07   ` Oliver Kiddle
@ 2013-02-28  9:34     ` Olivier Teuliere
  2013-02-28 10:15       ` Bart Schaefer
  0 siblings, 1 reply; 9+ messages in thread
From: Olivier Teuliere @ 2013-02-28  9:34 UTC (permalink / raw)
  To: zsh-workers

Hi,

On Wed, Feb 27, 2013 at 6:27 PM, Oliver Kiddle <okiddle@yahoo.co.uk> wrote:
>> 1) Custom bindings don't work. You can try it with the following:
>>     my-widget() { zle down-line-or-history }; zle -N my-widget;
>> bindkey -M menuselect k my-widget
>> (replacing "my-widget" with "down-line-or-history" in the bindkey
>> command works as expected).
>
> Yes, unfortunately it isn't possible.

Are there plans to implement this in the future?

On Thu, Feb 28, 2013 at 2:07 AM, Oliver Kiddle <okiddle@yahoo.co.uk> wrote:
> I wrote:
> > Was this perhaps a bug introduced later
> > such as when local keymaps were added?
>
> It does work correctly as mentioned by Peter so sorry for the
> misinformation. I think I got mixed up between
> accept-line-and-down-history and accept-and-infer-next-history. It then
> seems that the intention is to enable the features on logical keys from
> the main keymap.

I understand the intention, but IMVHO this adds a lot of complexity
(and confusion), just to avoid a few explicit bindings. And I wonder
what the '.' widgets (e.g.: .up-line-or-history) would mean, if custom
widgets could be used in menuselect mode: would they refer to the
menuselect "original override" or to the original version from main?

>> 2) Moving the selected menu item line by line is nice, but scrolling
>> several lines at a time would be nicer (that's what I would expect
>> PageUp and PageDown to do by default in menuselect, for example). I
>> couldn't find an existing widget for that.
>
> You can do some hacks with bindkey -s. For example:
>   bindkey -M menuselect j down-line-or-history
>   bindkey -M menuselect -s n 'jj'
> What you can do with that is limited. Also, it doesn't cope well with putting
> escapes in the latter string.

That's a great idea! It works fine for this case.

> > > 3) When using the reverse-menu-complete widget to open menuselect, I
> > > would like to select the last result, not the first one (otherwise I
> > > can use menu-complete directly...). It doesn't sem to be possible at
> > > the moment.
>
> This doesn't seem to be easy to solve. It seems to be in the
> REVERSEMENUHOOK where it fixes things to go backwards but the initial
> call to reversemenucomplete is not returning from menucomplete() until
> it is too late.

The clean fix in zsh may not be easy, but bindkey -s gives a rather
simple work-around (sacrificing the ^P binding):
bindkey "^P" reverse-menu-complete
bindkey -s "\e[Z" "^P^P"
bindkey -M menuselect "\e[Z" reverse-menu-complete

The last line is there to restore the expected behavior of
reverse-menu-complete in menuselect mode, otherwise the selection
moves 2 lines at a time.
Unfortunately, this is a bit invasive if you don't use menu completion
all the time, since "\e[Z" is bound unconditionally.

>> 4) [...]
>
> This probably wouldn't be hard to implement if we keep to the scheme of
> overloading existing widgets.
>
> You can abuse the behaviour I described earlier to make Enter really
> accept the line:
>   bindkey -M menuselect -r '^M'
>   zle -N new-accept-line
>   new-accept-line() {
>     zle .accept-line
>   }
>   bindkey '^M' new-accept-line
>
> But don't do this because it'll break the enter key in other contexts
> (reading from the mini-buffer). To replace accept-line without breaking
> things you need to use zle -A but that won't work here.

Inspired by your idea, I got a working solution:
really-accept-line() {
    zle .accept-line
}
zle -N really-accept-line
bindkey -M menuselect '^M' really-accept-line

Binding "^M" only in menuselect avoids the problem you mentioned.

> > > 5) [...]
>>
>> Actually, this is possible. Bind a key to vi-insert in menuselect and
>> you get "interactive" mode which does this. Still, there is a lot of
>> ways this could be better. Unfortunately, you stay in the menuselect
>> keymap at this point which is irritating if you've, for example, bound /
>> to history-incremental-search-forward.
>>
>> I can't think of a way to go straight into this mode. The bindkey -s
>> trick stuck it in an infinite loop.
>
> Actually, it turns out this is as simple as including the word
> "interactive" in the menu style. For example:
>   zstyle ':completion*:default' menu select=0 interactive

I need to play more with it, but it looks very promising.
Minor usability suggestion: a accept-selection-or-line widget could be
handy here. It would accept the selection (i.e. insert text and leave
menuselect) when no text has been inserted, and it would leave
menuselect and accept the line, as described in item 4 above, when the
selected text is already inserted (in pure menuselect mode, or when
moving the selection around in "interactive" mode). At the moment,
this behavior seems impossible to achieve.

>> accept-line-and-infer-history maybe?), while still allowing to select
>
> That also does something similar already:
>   bindkey -M menuselect '^M' accept-and-infer-next-history
> then enter will keep in menu selection.
>
>> I hope that these remarks make sense and that I haven't overlooked
>> some existing features...
>
> It certainly makes sense and is quite thought provoking. I'm only sorry
> that my answers aren't especially helpful.

They turned out to be very helpful, thanks.

What are the next steps here? The work-arounds given in this thread
are mostly enough for my needs, but IMHO several things should be
improved in zsh itself. Should I file formal bug reports and/or
feature requests somewhere?

Best regards,
--
Olivier


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

* Re: Limitations of menuselect
  2013-02-28  9:34     ` Olivier Teuliere
@ 2013-02-28 10:15       ` Bart Schaefer
  0 siblings, 0 replies; 9+ messages in thread
From: Bart Schaefer @ 2013-02-28 10:15 UTC (permalink / raw)
  To: Olivier Teuliere, zsh-workers

On Feb 28, 10:34am, Olivier Teuliere wrote:
}
} Are there plans to implement this in the future?

Plans, sort of.  Anyone to actually do the work, not really.  This and
several other of the more complex parts of completion were implemented
by some (primarily one) university students who stopped working on zsh
when they completed their studies, and no one who remains on the team
has simultaneously the time and the interest to address this.  We are
in need of more C programmers willing to take this kind of thing on.
 
} What are the next steps here? The work-arounds given in this thread
} are mostly enough for my needs, but IMHO several things should be
} improved in zsh itself. Should I file formal bug reports and/or
} feature requests somewhere?

This mailing list is the place for filing reports / requests, so you've
done that as far as it goes.


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

* Re: Limitations of menuselect
  2013-02-25 21:49 Limitations of menuselect Olivier Teuliere
  2013-02-27 17:27 ` Oliver Kiddle
@ 2013-03-01 23:59 ` Oliver Kiddle
  1 sibling, 0 replies; 9+ messages in thread
From: Oliver Kiddle @ 2013-03-01 23:59 UTC (permalink / raw)
  To: Olivier Teuliere; +Cc: zsh-workers

On 25 Feb, Olivier Teuliere wrote:
> 4) When moving the selection in the menu, the inserted text changes.
> But for some reason, the accept-line widget only closes the menu,
> without accepting the line. So to really accept the line I have to
> call accept-line again (basically, I have to hit Enter twice).

Actually, you can achieve this by simply binding to .accept-line:
  bindkey -M menuselect '^M' .accept-line

Oliver


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

end of thread, other threads:[~2013-03-02  0:05 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-02-25 21:49 Limitations of menuselect Olivier Teuliere
2013-02-27 17:27 ` Oliver Kiddle
2013-02-27 17:53   ` Peter Stephenson
2013-02-27 18:09     ` Peter Stephenson
2013-02-28  1:07   ` Oliver Kiddle
2013-02-28  9:34     ` Olivier Teuliere
2013-02-28 10:15       ` Bart Schaefer
2013-02-28  1:59   ` Bart Schaefer
2013-03-01 23:59 ` Oliver Kiddle

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).