propose builtin: mapfind()

26 views
Skip to first unread message

Ernie Rael

unread,
Apr 21, 2022, 2:53:08 PM4/21/22
to vim...@googlegroups.com
Greetings,

Looking to print/popup a list of plugin shortcuts (extracted from map
commands); the plugin has around a dozen commands. It is currently
difficult, if not impossible, to reliably get the mappings that exist
for a command.

Suggest builtin like

mapfind(match_to: dict<any> = null): list<dict<any>>

Where each element of the returned list is a dict as described for the
return in maparg. Without "match_to" return a list of all mappings; if
match_to is present, only mappings that match are returned. For example,
match_to might be, "{rhs: 'DirDiff'}".

Hoping to squeeze this into vim9; to that end I'm thinking of
implementing no-args mapfind first. This is much simpler and avoids the
discussion, for now, of what map_to can contain and its semantics.

Looking for a "seems ok", before I embark on implementation.

-ernie

Bram Moolenaar

unread,
Apr 21, 2022, 4:24:12 PM4/21/22
to vim...@googlegroups.com, Ernie Rael
I suppose that if you want to know "what was that mapping I put in for
that command" and don't even know where you defined it, it can be hard
to find.

You can use :filter:
:filter NextCommand map

But you have to redirect the output and process it, which can be tricky
for special keys.

I can't think of another function to use for this, thus adding mapfind()
seems useful. Would we also make it possible to find using the LHS?
At least the function name should somehow indicate matching the RHS, or
be able to do both.

--
Give a man a computer program and you give him a headache,
but teach him to program computers and you give him the power
to create headaches for others for the rest of his life...
R. B. Forest

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// \\\
\\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///

Ernie Rael

unread,
Apr 21, 2022, 5:22:46 PM4/21/22
to vim...@googlegroups.com
On 4/21/22 1:24 PM, Bram Moolenaar wrote:
> Ernie Rael wrote:
>
>> Looking to print/popup a list of plugin shortcuts (extracted from map
>> commands); the plugin has around a dozen commands. It is currently
>> difficult, if not impossible, to reliably get the mappings that exist
>> for a command.
>>
>> Suggest builtin like
>>
>> mapfind(match_to: dict<any> = null): list<dict<any>>
>>
>> Where each element of the returned list is a dict as described for the
>> return in maparg. Without "match_to" return a list of all mappings; if
>> match_to is present, only mappings that match are returned. For example,
>> match_to might be, "{rhs: 'DirDiff'}".
>>
>> Hoping to squeeze this into vim9; to that end I'm thinking of
>> implementing no-args mapfind first. This is much simpler and avoids the
>> discussion, for now, of what map_to can contain and its semantics.
>>
>> Looking for a "seems ok", before I embark on implementation.
> I suppose that if you want to know "what was that mapping I put in for
> that command" and don't even know where you defined it, it can be hard
> to find.
There can be default mappings as well. Does anyone set up multiple
mappings to same command?
>
> You can use :filter:
> :filter NextCommand map
>
> But you have to redirect the output and process it, which can be tricky
> for special keys.

I did some experimenting last month using the filter approach: var ms =
split(execute('filter MS map'), '\n')

Since one of the mappings I played with is <M-<Space>> it goes beyond
tricky. While experimenting, I had multiple things that mapped to MS and
they all had a blank lhs.

> I can't think of another function to use for this, thus adding mapfind()
> seems useful. Would we also make it possible to find using the LHS?
> At least the function name should somehow indicate matching the RHS, or
> be able to do both.

The argument is a dict that specifies what should be matched. It could
develop into

* mapfind() - return all mappings
* mapfind({rhs: 'pattern'}) - mappings with command that matches pattern
* mapfind({mode: 'mode'}) - mappings for the specified mode
* mapfind({lhs: 'pattern_lhs', rhs: 'pattern_rhs', mode: 'mode'})
* ...

Not sure of the rules for pattern for lhs/rhs, like :filter?. Are the
match items applied as "and" or "or", probably "and" is more
useful/expected. Anyway, some issues. Implement mapfind() with no arg
first, file an issue for discussion on how to extend it.

-ernie

>

Gary Johnson

unread,
Apr 21, 2022, 6:07:50 PM4/21/22
to vim...@googlegroups.com
On 2022-04-21, Ernie Rael wrote:
> On 4/21/22 1:24 PM, Bram Moolenaar wrote:

> >I suppose that if you want to know "what was that mapping I put in for
> >that command" and don't even know where you defined it, it can be hard
> >to find.
> There can be default mappings as well. Does anyone set up multiple
> mappings to same command?

I depends what you mean by a "command". I have different LHSs that
map to a call to the same function, but with different arguments.

I also have a couple of different mappings in my vimrc to the
identical RHSs because I couldn't decide which key sequence I was
going to like better.

I imagine there are cases, too, where a user creates their own
mapping to plugin command that they like better than the plugin's
default mapping to that command.

> >You can use :filter:
> > :filter NextCommand map
> >
> >But you have to redirect the output and process it, which can be tricky
> >for special keys.

FWIW, you don't have to redirect the output if you use execute(),
e.g.,

:let x = execute("filter NextCommand map")

And, you can use :verbose to find where a mapping was defined, e.g.,

:let x = execute("verbose filter NextCommand map")

Regards,
Gary

Bram Moolenaar

unread,
Apr 21, 2022, 6:31:00 PM4/21/22
to vim...@googlegroups.com, Ernie Rael
With an "and" relation between those, I suppose. This seems a bit
complicated.

> Not sure of the rules for pattern for lhs/rhs, like :filter?. Are the
> match items applied as "and" or "or", probably "and" is more
> useful/expected. Anyway, some issues. Implement mapfind() with no arg
> first, file an issue for discussion on how to extend it.

That is what makes it more complicated.

Alternative: add a function that returns all mappings. It's the
simplest way. It might be a bit slower, because the result would be a
longer list, but does that matter? The ":map" command does the same,
but outputs text instead of exact info. The advantage is that this is a
simple function, which can then be combined with existing functions such
as filter(). It's the Unix philosophy to combine multiple simple
commands, instead of making one complex one.

--
My sister Cecilia opened a computer store in Hawaii.
She sells C shells by the seashore.

Ernie Rael

unread,
Apr 22, 2022, 1:30:37 AM4/22/22
to Bram Moolenaar, vim...@googlegroups.com
Sounds good to me. Working to wrap myself around the vim philosophy.

-ernie

>

Reply all
Reply to author
Forward
0 new messages