From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: "Drew Adams" Newsgroups: gmane.emacs.devel Subject: RE: propose adding Icicles to Emacs Date: Thu, 14 Jun 2007 17:39:17 -0700 Message-ID: References: NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit X-Trace: sea.gmane.org 1181868076 9823 80.91.229.12 (15 Jun 2007 00:41:16 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Fri, 15 Jun 2007 00:41:16 +0000 (UTC) Cc: rms@gnu.org, emacs-devel@gnu.org To: "Stefan Monnier" Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Fri Jun 15 02:41:13 2007 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.50) id 1HyzsD-00015F-GH for ged-emacs-devel@m.gmane.org; Fri, 15 Jun 2007 02:41:09 +0200 Original-Received: from localhost ([127.0.0.1] helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1HyzsC-000734-RM for ged-emacs-devel@m.gmane.org; Thu, 14 Jun 2007 20:41:08 -0400 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1Hyzs9-00072z-Hd for emacs-devel@gnu.org; Thu, 14 Jun 2007 20:41:05 -0400 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1Hyzs8-00072n-IR for emacs-devel@gnu.org; Thu, 14 Jun 2007 20:41:05 -0400 Original-Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Hyzs8-00072k-FO for emacs-devel@gnu.org; Thu, 14 Jun 2007 20:41:04 -0400 Original-Received: from rgminet01.oracle.com ([148.87.113.118]) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1Hyzs6-0002Wt-5H; Thu, 14 Jun 2007 20:41:02 -0400 Original-Received: from rgmgw3.us.oracle.com (rgmgw3.us.oracle.com [138.1.186.112]) by rgminet01.oracle.com (Switch-3.2.4/Switch-3.1.6) with ESMTP id l5F0ewbx015991; Thu, 14 Jun 2007 18:40:58 -0600 Original-Received: from acsmt350.oracle.com (acsmt350.oracle.com [141.146.40.150]) by rgmgw3.us.oracle.com (Switch-3.2.4/Switch-3.1.7) with ESMTP id l5F0evxo005438; Thu, 14 Jun 2007 18:40:57 -0600 Original-Received: from dhcp-amer-csvpn-gw2-141-144-73-175.vpn.oracle.com by acsmt351.oracle.com with ESMTP id 2899283511181867962; Thu, 14 Jun 2007 17:39:22 -0700 X-Priority: 3 (Normal) X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook IMO, Build 9.0.6604 (9.0.2911.0) In-Reply-To: X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.3138 Importance: Normal X-Brightmail-Tracker: AAAAAQAAAAI= X-Brightmail-Tracker: AAAAAQAAAAI= X-Whitelist: TRUE X-Whitelist: TRUE X-detected-kernel: Linux 2.4-2.6 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:72908 Archived-At: 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: http://www.emacswiki.org/cgi-bin/wiki/Icicles_-_Multi-Completions http://www.emacswiki.org/cgi-bin/wiki/Icicles_-_Programming_Multi-Completion s 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 `read-string'. *********** 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 Icicles. 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 icicle-mcmd.el. *********** 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 important. 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 sometimes. 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- 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.