emacs-devel
[Top][All Lists]
Advanced

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

RE: Making `interactive' conditional (was: Leaving out non-applicable co


From: Drew Adams
Subject: RE: Making `interactive' conditional (was: Leaving out non-applicable commands on Mx)
Date: Mon, 11 Jan 2016 04:02:16 -0800 (PST)

I do think that there can be some value in letting commands,
such as `M-x', that provide completion for command names,
take invocation-context information into account.

I think we should be more specific about what is involved -
how this is done.  And I think we should be more flexible
than what I've heard proposed so far.  In particular, we
should be flexible about how such invocation-context info
can be provided and used.

Let me make a hopefully more constructive contribution to
the suggestions about this than what I've written so far.

Here's how I see such a new feature.

1.  It would:

    a. Provide information about a specific command
       regarding its invocation contexts.

       This info can indicate which contexts "make sense" or
       which do not.  But it can also indicate anything else
       about a context in which one might try to invoke the
       command.

       The form of the info would be a Lisp sexp, and a
       value of nil would be equivalent to an absence (no
       context information).

       Its interpretation would be up to (1b) - no fixed
       or predefined interpretation.

    b. Use this information in `M-x', and possibly in other
       contexts.

       (I'll write `M-x' for short, but this should be
       understood as any context that uses the (1a) info.
       And even when thinking of it as `M-x, understand a
       new, `M-x'-like command.)

2.  (1a) and (1b) are two different things, and we need not
    be rigid about either their relationship or just how
    `M-x' or other contexts might use the (1a) info.

3.  The (1a) info can be a predicate that `M-x' can apply to
    each completion candidate.  It can use the resulting
    value to remove the candidate or to display it
    differently or to do something else that is specific to
    it.  Likewise for any other (1b) context: it is up to
    that context to do with info (1a) whatever it wants.

4.  The (1a) info could be something other than a predicate
    and nil.  This is left unspecified, but it should not be
    assumed that it is always a function.

5.  A predicate return value of nil, or an absence of (1a)
    info for a given candidate, would mean treat the command
    candidate normally (classically).  A non-nil return
    value would mean treat it specially in some way - see (3).

6.  The predicate can test anything.  It should be possible
    to invoke it with any number of arguments, which are
    unspecified.  It can access the target command's symbol
    as the value of variable `current-cmd' (or some better
    name).  (We could require passing the command as a first
    argument, but that would make using some existing
    predicates more cumbersome.)

7.  It should be easy to add, modify, or remove info (1a)
    from a command using Lisp at any time, and without
    modifying or otherwise accessing the source code that
    defines the command.

8.  The command's `interactive' spec is not the right place
    to provide the (1a) info (e.g. predicate).  This is not
    about interactive use in general.  It is info about
    invocation contexts.  A `declare' form is also the wrong
    place for the (1a) info.

    It should be possible to create or remove such an
    association in source code but also interactively (e.g.,
    using `M-:').

9.  I propose putting info (1a) on the command symbol as a
    property.  This is a limitation only for commands not
    associated with a name (which are not used by `M-x', at
    least).  Example:

    (put 'kill-line
         'cmd-context
         (lambda (cmd) (not buffer-read-only)))

    This association is purposely separate from the defun.

10. `execute-extended-command' (`M-x') would provide its
    usual behavior by default.  A user option would let it
    take info (1a) into account.  Later, the default
    behavior (and default option value) could be switched if
    we decide that is better.

11. We can provide a minibuffer key, when `M-x' is used, to
    toggle the option value (for (a) the `M-x' duration or
    (b) definitively, so that it effects subsequent `M-x').
    A user might do this for clarity, or to see more context
    info or more candidates, or to improve performance if
    taking (1a) info into account slows things down
    appreciably.

12. When `M-x' takes info (1a) into account, it treats a
    completion-candidate command name specially if info (1a)
    is present, according to the value of a user option
    (e.g., `cmd-context').  Possible behaviors could
    include:

    . Removing the command as a completion candidate if info
      (1a) is a predicate and invoking it returns nil.

    . Showing the (1a) info (e.g., the predicate sexp or
      symbol) next to the candidate command in
      *Completions*, as an annotation.

    . Displaying the candidate in a different face according
      to the nature of info (1a).  E.g., if a predicate and
      invoking it returns nil, then dim the candidate.

13. Since a given (1b) context such as `M-x' can do anything
    it likes with (1a) info, it could, in particular, handle
    that info differently depending on the current set of
    completion candidates.  For example, it could
    automatically turn off taking (1a) info into account
    when the number of candidates is particularly large or
    small.

14. If a (1b) context such as `M-x' wants to improve
    performance by, say, byte-compiling a (1a) predicate, it
    can do so, but it must not replace the source (1a)
    value, which should remain a Lisp sexp.  This is so we
    keep things flexible and we do not shut the door on
    possible uses of info (1a).



reply via email to

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