[Top][All Lists]

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

RE: propose adding Icicles to Emacs

From: Drew Adams
Subject: RE: propose adding Icicles to Emacs
Date: Thu, 14 Jun 2007 17:39:17 -0700

This mail is about how to handle Icicles code that redefines standard Emacs
functions. It details the case for each such function. It provides some
solutions and clarifies some open questions.

> > I gave concrete examples for `completing-read' and pointed to
> > the code for the others as well. Each of the functions has
> > different additional things added, which cannot be done on
> > `minibuffer-setup-hook'. Initializations etc. that are
> > appropriate for only one function (e.g. `completing-read')
> > cannot be put on a hook that is run when every function
> > activates the minibuffer.
> Saying "can't do that" is not helpful. Please explain why you
> think you can't do that. What would you need to do be able to do?

If code is specific to one function only, and you put it on the setup hook,
then it will also be executed for other functions for which it might not be
appropriate. Even in cases where that doesn't cause immediate harm, it
doesn't seem like a clean way to proceed, IMO. Things that are logically
local to a function should be contained inside it.

`minibuffer-setup-hook' is called all the time - even when completion is not
being done, as in `M-:', for instance. Trying to do something that is
specific to a particular minibuffer-reading function in the general setup
hook would be applying a sledge hammer, IMO.

Second, it is not just a matter of initialization before calling a built-in
function such as `completing-read'. If you look at the code, you'll see that
the result of `old-completing-read' is used, and there is a top-level catch
wrapped around it in some cases. This is to allow, in certain contexts, a
recursive minibuffer entry to return the result to the top level, so the
user doesn't have to keep hitting RET to get there.

In any case, Richard appears to prefer to implement Icicles-like features
directly in Emacs, including in the C code, so perhaps these kinds of things
can be moved directly to the original functions (e.g. `completing-read) - to
the extent that they might still be relevant in his design. That would be
the best approach, IMO.

For instance, here are some code-fragment candidates for outright removal if
Icicles features are integrated with Emacs:

1. The treatment of the prompt in my `completing-read' and `read-file-name'
can be eliminated. It simply adds a reminder to the prompt about some basic
Icicles bindings. If Icicles is part of Emacs, that will become sufficiently
known by the doc etc. Even in Icicles, unless you act explicitly to prevent
it, the reminder is removed after a certain number of Emacs sessions.

2. The treatment of `icicle-init-value-flag' can be eliminated, along with
that option. It does not jibe with the Emacs policy of deprecating the
INIT-VALUE argument. I like it, but Emacs developers will no doubt rule it
out. Alternatively, perhaps you could consider adding such an option, to
allow those users who, like me, would like the default value to always be
inserted as an init value. In any case, Icicles is not dependent on this.

3. The call to `icicle-fix-default-directory' (in my `read-file-name') can
be eliminated, along with that function, if this fix is moved into the Emacs
C code somewhere. This is a hack to convert any backslashes in
`default-directory' to slashes. Icicles needs it because Icicles lets you
use backslashes for regexp syntax during completion. This is important for
Icicles, and I don't think such a fix would in any way be harmful to Emacs.

4. My `completing-read' also removes the *Completions* window, at the end.
This was added because the window was not being removed when REQUIRE-MATCH
is non-nil. I'm not 100% sure this is still needed. If it is, then you can
think of this as a bug fix to `completing-read'.

Here are some fragments that would be candidates for integration directly
into the vanilla Emacs code:

1. The treatment of `icicle-require-match-flag' can be discussed. I already
spoke about this. This variable lets code that calls completion functions
such as `completing-read' override the REQUIRE-MATCH argument. Code can bind
this so that any contained calls for completion will respect the binding. I
think this is a good addition and such a variable should be available, but
others might disagree.

I already mentioned the need for a global variable that records (holds) the
value of the passed REQUIRE-MATCH argument. Perhaps these two variables can
be combined. The need for the latter variable, for Icicles, is, as I said,
to be able to call for another completion with the same argument. That is a
requirement for doing progressive completion (as it it is implemented
today). Progressive completion is using `M-*' to be able to input another
completion pattern to also match against the current set of candidates.

2. My `completing-read' also converts an alist of candidates that are
so-called "multi-completions" to the standard alist form. This too could be
added directly to Emacs `completing-read', just as Emacs 22 added the
ability to pass a flat list of strings instead of an alist.

Multi-completions let you provide several strings for each completion
candidate when you call a completion function. That is, a candidate can be a
list of strings. The strings are joined using a user-defined join string and
terminated with a user-defined end string. Icicles can also transform the
resulting string for presentation purposes etc. This is a useful feature
that allows, for instance, the displayed candidate to differ from the
returned candidate in a user-controlled way.

See these for an explanation of this feature:



Multi-completions are not to be confused with Icicles multi-commands, Emacs
`completing-read-multiple', or Emacs completion-candidate annotation.

If we find a way to handle the needed initializations (which are a bit
different for the different completion functions) and the top-level `catch',
then this pretty much handles everything that is currently in the Icicles
version of `completing-read', `read-file-name', `read-from-minibuffer', and

File icicles-fn.el also redefines some other standard Emacs functions:

1. As I mentioned, my `read-face-name' just shows face names in
*Completions* using their own faces. IMO, that should also be done in Emacs,
but it is 100% independent of the rest of Icicles.

2. Same thing for `face-valid-attribute-values': It shows color names using
the colors they name. Good to add to Emacs, and independent of the rest of

3. My `choose-completion-string' has the minor tweak of not exiting the
minibuffer if this is just a `lisp-complete-symbol' completion. This was
done long ago, and I'm not sure it is still relevant. Again, if it is useful
it can be added to Emacs independently of the rest of Icicles - Icicles does
not depend on this.

4. My `completion-setup-function' and `display-completion-list' - see what I
wrote before (about fitting the *Completions* window to the buffer etc.).
This would mean modifying the definitions of `completion-setup-function' and
`display-completion-list' in ways that I think would be good anyway. For
instance, my `display-completion-list' does not remove text properties from
candidates, and it adjusts the number of displayed columns and their widths.
I personally would prefer to see `display-completion-list' be a Lisp
function, but I will survive without that. My enhancements to it are
independent of the rest of Icicles, but they do matter to the Icicles
experience ;-).

That covers all of the replacements of standard Emacs functions that I do in
icicles-fn.el. I also replace some standard functions in icicle-cmd.el and

In icicle-mcmd.el:

1. My `exit-minibuffer', my `minibuffer-complete-and-exit', and my
`mouse-choose-completion' are enhanced to also remove the *Completions*
window. I think this should also be done in Emacs. This removal deletes all
windows anywhere that show *Completions*.

2. My `mouse-choose-completion' also records the number of the current
completion candidate in a global variable. This is so that Icicles functions
that work with the candidate number will also work when you choose a
candidate with the mouse, not just by cycling. The candidate number is very
important for Icicles, some functionality being dependent on it.

3. My `switch-to-completions' selects the *Completions* window, even if it
is on another frame. This could be added to Emacs independently of Icicles.

In icicle-cmd.el:

1. My `dabbrev-completion' and my `lisp-complete-symbol' also select the
*Completions* window, even if it is on another frame. This is not very

2. My `customize-apropos', `customize-apropos-faces',
`customize-apropos-groups', `customize-apropos-options', and
`repeat-complex-command' all use `completing-read' to read the regexp. Note
that using completion means not only that you can use regexp matching but
also that you can sort the candidates in different ways (important for
cycling order). This is not just key remapping; it is definition replacement
(via `defalias') and then restoration when you exit Icicle mode. I would
like to see something like this done in Emacs, but it is independent of the
rest of Icicles.

3. I also redefine some standard user options, overriding them with Icicles
versions: `search-ring-max', `regexp-search-ring-max', and
`kmacro-ring-max'. I do this so that Icicles users can have a different
value (typically much larger) for Icicles than they use for vanilla Emacs
use. I didn't want Icicles to be intrusive, so I let them have separate
values for these things, assuming they might want to use Icicle mode only

I'm not sure how this should be handled. Icicles facilitates using much
larger such rings, so it makes sense for Icicles users to have large values.
I suppose that we could just expect that users of Icicles (or Icicles-like
optional Emacs features) would always use it and so would customize their
standard options accordingly. In that case, we can get rid of the Icicles
versions of these options and the mode entry/exit redefinition/restoration.

I think that covers ALL of the replacements I do of standard Emacs functions
and options.

> E.g. you can probably distinguish from minibuffer-setup-hook
> between most of the possible situations by looking at which keymap
> is used locally, what are the settings for the various
> minibuffer-<foobar> variables, etc...

Ouch! That does not sound good to me. The idea is to reduce the use of ugly
hacks, not increase it ;-).

> Maybe these solutions are just as ugly (e.g. comparing (current-local-map)
> with minibuffer-local-completion-map would definitely count as an ugly
> hack), but at least they may give us some idea of what might be needed.
> Maybe other things just can't be done in minibuffer-setup-hook or
> minibuffer-exit-hook because they need to be run at some completely
> different moment.
> Let's try to be constructive.

I really don't see `minibuffer-setup-hook' as offering help here.

I think that, depending on the general approach to be taken for integrating,
the best solution is to modify `completing-read' so that it does what is
needed - where "what is needed" might be something different from what I do
now, depending on the chosen design for these features.

Hopefully, some of the information above will help in this direction.

reply via email to

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