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: Wed, 13 Jun 2007 12:00:20 -0700 Message-ID: References: NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset="ISO-8859-15" Content-Transfer-Encoding: 7bit X-Trace: sea.gmane.org 1181761256 21135 80.91.229.12 (13 Jun 2007 19:00:56 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Wed, 13 Jun 2007 19:00:56 +0000 (UTC) Cc: emacs-devel@gnu.org To: Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Wed Jun 13 21:00:53 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 1HyY5M-0007hP-Uc for ged-emacs-devel@m.gmane.org; Wed, 13 Jun 2007 21:00:53 +0200 Original-Received: from localhost ([127.0.0.1] helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1HyY5M-0002Oe-IQ for ged-emacs-devel@m.gmane.org; Wed, 13 Jun 2007 15:00:52 -0400 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1HyY5I-0002OY-W3 for emacs-devel@gnu.org; Wed, 13 Jun 2007 15:00:49 -0400 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1HyY5I-0002OM-8v for emacs-devel@gnu.org; Wed, 13 Jun 2007 15:00:48 -0400 Original-Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1HyY5I-0002OJ-1X for emacs-devel@gnu.org; Wed, 13 Jun 2007 15:00:48 -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 1HyY5E-0000p2-Ma; Wed, 13 Jun 2007 15:00:45 -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 l5DJ0fLd022596; Wed, 13 Jun 2007 13:00:41 -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 l5DIu0MI022182; Wed, 13 Jun 2007 13:00:40 -0600 Original-Received: from dhcp-4op11-4op12-west-130-35-178-179.us.oracle.com by acsmt351.oracle.com with ESMTP id 2894827901181761221; Wed, 13 Jun 2007 12:00:21 -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-Whitelist: TRUE X-Whitelist: TRUE X-Brightmail-Tracker: AAAAAQAAAAI= 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:72800 Archived-At: I'm not sure it's worth going into each of your comments, but I'll try. Please see my previous email (with Plan A and Plan B). That is my position and a starting point for discussion about how to proceed. (I received this mail after sending my previous mail, BTW.) > I'd propose adding Icicles first as an optional library, > without trying to integrate any of it deeply with Emacs. > Later, we could look into a possible > tighter integration. > > That is a very bad idea. "Temporary" solutions tend to become > permanent, and to prevent that from occurring requires insistence. No > software developer should install code meant to be temporary unless it > is essential to do so. Icicles features are nice, but installing them > is not essential. Installing Icicles features is not essential to Emacs. We agree on that. Evolution, even planned evolution, can proceed in stages. A stage that includes Icicles as an optional package is not equivalent to ugly hacking or sneaking in a trojan horse under the pretense or belief that it is only temporary. I gave good reasons for my recommendation. It is not a good idea to lay waste to everything first, IMO, but that is your call. You are welcome to prefer plan B. In plan B, Icicles is a quarry of ideas, you are the implementor, and I can be consulted if you have questions. > Therefore we will put the code into the form we want to keep > permanently and then install it. > > > Why does it do this? > > Because those replacements are enhanced versions. They are typically > multi-commands that 1) keep the same behavior as the > original, as long as you don't use any special Icicles minibuffer > bindings, but also 2) let you take advantage of those minibuffer > bindings (e.g. `C-RET') to get the multi-command behavior. > > Let's suppose I can magically implement multi-command behavior without > the need to define separate multi-commands to do it. (I think I can, > and I explained how.) You did _not_ explain how, beyond some hand waving. At least not to my satisfaction. I don't understand your magic solution, and I think you don't fully understand Icicles multi-command behavior. But if you choose plan B, I don't necessarily need to understand your design, except to be able to answer questions about the existing Icicles features. If you don't want to explain it, you can implement it and we can then talk about how it fits with Icicles features and what parts of Icicles could perhaps be eliminated because of it. Creating a multi-command is a programmer decision. Different multi-commands work differently. The simplest just do what you have understood. But even in the simplest cases, which can be handled by the Icicles definition macros, a programmer can (and will sometimes need to) provide extra bindings or extra code. > Is there any other reason in icicles to define new commands > to replace the existing ones? Speaking of replacement is off the mark. Multi-commands and the ability to define them as appropriate for a given use are one thing. Deciding to bind `C-x C-f' to a multi-command file-finding function instead of vanilla `find-file' file is another thing - a separate consideration. Forget the latter, if you will; it's not necessary. You seem bent on automatically converting all commands to multi-commands. That might be useful, in a limited way. But programmers will still need to be able to define multi-commands that go beyond the simple case. I gave `icicle-search' as an example. I do agree that much of the error and context handling that I add to a multi-command definition via the definition macros could instead be built into Emacs somehow, and that would be great. Only please do that carefully, if you do it, and please still let programmers bind their own candidate action function when they design a custom multi-command. Without that feature, a lot is lost. As I said before, you have only to look at the commands that explicitly bind `icicle-candidate-action-fn' or `icicle-candidate-alt-action-fn' to get an idea why this is needed. Again, `icicle-search' is a good example. IOW, if you decide to build some magic into Emacs to implement some of the multi-command functionality, please keep it flexible, so that Emacs-Lisp programmers can build custom multi-commands that use different action functions etc. You know, there are other things that could also be moved into vanilla Emacs as well (outside of using an Icicles package). Multi-commands depend on candidate cycling (to be more precise, they cry out for it, but it is not a strict logical requirement). The cycling logic is another thing that could be provided by Emacs outside of Icicles. We are moving in the direction of Plan B here. > If so, what is it? > Maybe I can find a better way to implement that, too. Not sure what this means. I've said that we need not automatically replace any command bindings. If users want to bind `C-x C-f' to a different command, they can always do so. Even in Icicles, I don't force this on anyone: a user option controls such command remapping. > The need to replace commands is a complexity, and the code will > be much better if we avoid that complexity. There is no need to replace any commands. Keep them all. > Yes, you must define a new command, in order to adapt a given > existing command to multi-command use. This is a good thing, as > some commands might not lend themselves well to multi-command > use (i.e. it might make no sense for them, adding nothing). > > That is no argument against making multi-command behavior magic. > Just respond, "If it isn't useful there, don't use it there." Multi-commandness being inappropriate for a given command is one thing. Yes, it should be possible to optionally not use multi-commandness, when that is appropriate. That is what happens anyway now: by default, no action function is defined, and C-RET provides candidate help (just as C-M-RET does). The more important consideration is the following: > And, more often, it is appropriate for some commands to have a > slightly different action function for candidates during > completion than after completion (for instance, because the > buffer/window/frame context or the use context might be different). > > This might be a real issue. Can you please give an example or two? I did. `icicle-search'. And the other multi-commands that are defined by explicitly binding an action function, alternate action function, or candidate-help function, instead of being defined using a definition macro. There are several multi-commands that are, themselves, built using `icicle-search'. You can read about Icicles search here: http://www.emacswiki.org/cgi-bin/wiki/Icicles_-_Search_Commands%2c_Overview http://www.emacswiki.org/cgi-bin/wiki/Icicles_-_Search-And-Replace http://www.emacswiki.org/cgi-bin/wiki/Icicles_-_Other_Search_Commands The `icicle-search' code is here: http://www.emacswiki.org/cgi-bin/wiki/icicles-cmd.el > If Icicles does not break anything, and it does not have a > lasting effect when you leave Icicle mode, then I think how > it is implemented should not be a concern. > > That is true if you distribute it separately. > If it is part of Emacs, that changes everything. > We want Emacs to be modular. My proposed implememtation > of multi-command behavior is totally modular. I think we > can make it work with NO changes in any specific command. No one is against modularity. I have not seen a "proposed implementation", beyond some vague hand-waving. I'm not against simplification. I'm asking for details, so I can understand you. My ideas are detailed in the implementation. You can examine exactly how it is done now and propose alternatives. Your proposal so far is, for me, something indeterminate and uncommunicated. > The macro expansion of a multi-command defined using #1 or #2 > is quite complex. Some of its definition implements context > management (window, frame, buffer), and some of it implements > treatment of possible errors from application of the action > function. For example, the original buffer, window, or frame, > to which we often want to return, might have been deleted > by application of the action to a particular candidate (e.g. > if the action is to kill the buffer, and the candidate acted on is > the original buffer). And we usually want to keep the focus after > action application on the minibuffer's frame, so that we can > possibly keep using `C-RET' etc. on other candidates. > > The code in call-interactively may need to deal with such cases. I > think it can do so in ways that are independent of the specific > command that was run. I agree that some of what is currently done in the definition macros (hence, in the code of each multi-command defined with them) could be built into Emacs - perhaps to handle all commands. However, that needs to be done carefully and fully. For example, use of a standalone minibuffer and non-nil pop-up-frames should also work. I agree about "independent of the specific command that was run", but only in the case of run-of-the-mill multi-commands. For some multi-commands you want the frame focus to end up in a different place when you are done, for example. You might typically work in the buffer of application after using a multi-command, or you might instead typically want the minibuffer frame to continue to have the focus so you can use it again - different commands have different use cases. There needs to be some flexibility. A programmer needs to be able to build a custom multi-command in the sense I have described. I had my multi-command definition macros available for my own use, yet I did not use them to define some of the multi-commands. Why? Because they are not flexible enough - they cannot be flexible enough. There is no substitute for being able to code what is needed in a particular case. > Wrt prefix args: C-u is treated specially during completion, > so that, for instance, you can apply it to individual candidates > that you act on using `C-RET'. That is, you can use a different > prefix argument each time you act on a candidate, if you like. > > I just assumed it was the other way. We could handle the prefix this > way just as easily. Yes, this is the kind of thing that could advantageously be handled automatically within the command loop (or whatever) of Emacs itself. I think what I'm trying to say is that, yes, the infrastructure to interpret multi-command definitions and handle multi-command bindings such as `C-RET' could be built into Emacs, simplifying or eliminating, for example, the need for the multi-command definition macros. But programmers will still need a flexible way to direct and inform that infrastructure, so that they can define custom multi-commands that DTRT in different contexts. They need, at a minimum, a way to define the action function, the alternative action function, the candidate-help function, and object deletion for a given multi-command. There can be default behavior, such as using the same action for both C-RET and RET and having an empty alternative action, but programmers need to be able to override this default behavior and provide their own functions for these things. > Remember, that, by default, you can act on the > same candidate multiple times. Sometimes that makes sense, > sometimes it does not. > > Can you give me an example where it does not make sense? Practically every place where I have used a non-nil value for `icicle-use-candidates-only-once' is an example. It is not so much that multiple invocation would be harmful (though perhaps that can also be true for some commands). It is that, in many cases, it is handy for the user to remove the candidate from the list of available candidates, once it has been acted on. That is the purpose of `icicle-use-candidates-only-once'. This does not definitively prevent using the candidate again in the same multi-command invocation; it simply removes it from the candidate list for the time being, so that you don't see it and you cannot cycle to it. If you complete again (TAB or S-TAB), however, then you see the candidate again. This is exactly the same behavior a user gets if s?he explictly uses the `delete' key or `S-mouse-2' on the current completion candidate: it is simply removed as a candidate (until you complete again). For instance, command `icicle-set-option-to-t' reads the name of a binary user option and sets it to t. It doesn't make much sense to do this more than once to the same option in the same command invocation. Removing that option from the list of candidates makes it easier to see the remaining options that you can act on. A case such as `icicle-delete-windows' is more along the lines of "if it's done, it's done". Once you have deleted the windows showing a buffer, it makes sense to remove that buffer name from the list of candidates, because it makes no sense to choose it again. `icicle-delete-file' is similar: if the file has been deleted, you should no longer see it as a candidate. (Some multi-commands remove a used candidate directly, without employing `icicle-use-candidates-only-once' to do that.) BTW, it might seem that commands such as `icicle-find-file' might also want to bind this option to non-nil. But a user might, in the same `icicle-find-file' invocation, navigate among different files using `C-RET' - that is, return to choose the same file name more than once. To bind this option in any given context, it should not be the case that a user might want to return to a given candidate and use it again. BTW2: There is a difference between removing a candidate as a candidate and removing (deleting) the object that the candidate names. If the candidate is a file name for `icicle-delete-file', then the associated file is deleted by the action function. In Icicles, you can also provide any multi-command with a separate deletion action (invoked by `S-delete'), which deletes some object associated with the candidate (name). Command `icicle-buffer', for instance, uses `switch-to-buffer' as its action function and `icicle-kill-a-buffer' as its deletion action - `C-RET' invokes the former and `S-delete' invokes the latter. FYI - wrt clicking the `delete' key to remove a candidate - I've recently defined a complementary feature, to save a candidate for later consideration. I haven't yet uploaded this feature to the wiki, but I'll do so soon, after testing things a bit more. This new feature lets you act more carefully than you might be prone to using multi-command actions. You can choose a set of candidates (in several ways, including choosing individual candidates to add) and then, later, take a good look at that set and then act on all candidates at once. Think of this as filling out a checklist and then later submitting it for action - the way that Dired marked files work, for instance. In Icicles, you have always been able to save the current set of matching candidates (to a variable or a cache file) and to act on all set members. What I've added recently is the ability to add additional members to such a saved set (individually or as a set union). > 2. It's appropriate, for many commands, to specialize the > action behavior during completion. See the commands that > explicitly bind `icicle-candidate-action-fn', as opposed > to just using `icicle-define-command'. Command > `icicle-search', for instance, could not be > defined using `icicle-define-command'. > > Can you please explain an example of this specialization? > Then I can think about its consequences. It's best to read about what Icicles search offers and how it works, and then look at the code for `icicle-search' as an example. I'll be glad to answer questions, but I don't want to repeat here what is already written elsewhere. Please see the links above.