emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: [External] : Re: Smarter M-x that filters on major-mode


From: Drew Adams
Subject: RE: [External] : Re: Smarter M-x that filters on major-mode
Date: Thu, 11 Feb 2021 06:11:23 +0000

> > It would indeed be very useful to provide a
> > mechanism to exclude commands from M-x that
> > are useless outside of their major mode.

Commands that are useless outside of a particular
mode/package/etc. typically have some part
of their name that indicates that mode/pkg/etc.

A simple way of filtering out such names is more
useful than trying to otherwise guess association
of a mode/pkg/etc. with command names.  You can
often recognize such contexts by the command names.

Icicles lets you (1) match only names you want
to exclude, then (2) use `C-~' to remove them as
candidates.  (Repeat, matching different name
parts, to narrow further.)

> Similarly, you may mark some commands so they're
> just never available to `M-x`.  This could apply
> to some major and minor modes which are only
> meant to be used "internally", or to commands
> which only work when provided with a mouse event, or ...
> 
> That should be a very easy change to
> `execute-extended-command`.

No, that shouldn't happen by default, at least.
Not helpful and not needed.

There's a naming convention for "internal" -
simple to avoid.

Also, even if the main purpose of `M-x' is to
invoke a command, it provides sets of command
names that match your input at any time, and
some completion "systems" let you do more with
a set of matches than just reduce it to one
command and invoke that.

E.g., you can get the doc for particular matching
candidates, on the fly.  If `M-x' automatically
excludes some categories of command then those
commands are excluded also for such ancillary
purposes.

> > I've had a related idea to make `M-X' (a.k.a.
> > `M-S-x') run a version of `M-x' that *includes*
> > only commands that are specifically relevant to
> > the current major mode.

See above, about names being the way to tell
whether a command is relevant to a given mode.

Otherwise, you need some filter function that
knows/judges such relevance - and that might
itself be specific to the particular mode.

> > This would be used when I specifically want
> > to do something in my major mode, as opposed
> > to looking at the gazillion different entry
> > points for things like calendar, gnus, or tetris.

YAGNI.  Command names should themselves indicate
this kind of thing.  What you need is a good way
to filter command names.

> Yes, there's clearly a lot of room for improvement.
> I moved that function to ELisp to make it easier
> to hack on it, and I'm still hopeful that Someone™
> will make use of it.

I don't agree that `M-x' should try to be "smart"
in these ways - not without some user control (on
the fly, not just via user option).

Just which commands a particular user, at a
particular time, for whatever reason, wants to be
able to invoke with `M-x' is not something that's
accurately predefined.

Instead, it's smarter to leave it up to the user,
but provide ways to filter on the fly. E.g., show
me only commands of a particular kind (e.g. for
the current mode or whatever).
___

As one point of reference, in Icicles, during
`M-x' completion, you can use `M-i $' to toggle
whether candidates should be limited to commands
that are currently bound to keys.

That's the only on-the-fly filtering I've offered
for `M-x', but other filtering could be provided.
(E.g., exclude mouse-invoked commands, as you
mentioned.)  What's important is not to do any
such filtering in any hardcoded kind of way.  Let
users do it when they want.

`M-x' is a command that provides command-name
completion.  Yes, commands can be associated with
buffer modes, packages, keys, etc.  And such
associations could be used for command-name
filtering.

But the associations need to be defined (known)
somehow (explicitly or implicitly), in order to
be exploited.

Again, the command names themselves already
provide such associations to some extent.  Supple
interactive narrowing according just to name
matching goes a long way toward realizing what
you've suggested.

___

But by way of example wrt providing other,
non-name, filtering on the fly:

For commands that prompt for a _buffer_ name,
Icicles lets you use a prefix arg to limit
the buffer-name candidates to complete against,
in various ways:

* Plain ‘C-u’: only buffers whose mode is derived
  from the current buffer's mode are candidates

* ‘C-u C-u’ (double): only displayed buffers

* ‘C-u C-u C-u’ (triple): only buffers not displayed

* ‘-’ (plain ‘-’): only modified (unsaved) buffers

* = 0: buffers with the same mode as current buffer

* > 0: buffers visiting files

* < 0 (and not plain ‘-’): buffers associated with
      the selected frame

(Those are the default behaviors, but you can
change them with a user option.)
___

Besides those buffer-command prefix-arg behaviors,
which you need to decide on before you invoke the
command, you can also filter buffer candidates on
the fly during completion:

* ‘C-x F’: toggle whether to include cached files
  as candidates

* ‘C-x R’: toggle whether to include recently
  accessed files as candidates

* ‘C-x m’: only bookmarked buffers

* ‘C-x C-m -’: remove buffers whose major mode is
  derived from a given mode (for which you're
  prompted).  Repeat to remove more modes.

* ‘C-x C-m +’: (opposite of ‘C-x C-m -’.) keep
  only candidates with a derived major mode

* ‘C-x M -’: same as ‘C-x C-m -’, but exclude
  ancestor modes

* ‘C-x M +’: same as `C-x C-m +’, but exclude
  ancestor modes

* ‘C-x * -’: remove modified buffers

* ‘C-x * +’: keep only modified buffers

* ‘C-x i -’: remove indirect buffers

* ‘C-x i +’: keep only indirect buffers

* ‘C-x v -’: remove visible (displayed) buffers

* ‘C-x v +’: keep only visible (displayed) buffers
___

Similar functionality is available for commands
that use file-name completion.

https://www.emacswiki.org/emacs/Icicles_-_Buffer-Name_Input

reply via email to

[Prev in Thread] Current Thread [Next in Thread]