From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED.blaine.gmane.org!not-for-mail From: Karl Fogel Newsgroups: gmane.emacs.devel Subject: Re: PATCH: isearch-yank-until-char Date: Mon, 26 Aug 2019 12:51:05 -0500 Message-ID: <874l23ak8m.fsf@red-bean.com> References: <87tvakfnv4.fsf@red-bean.com> <87lfvvjxjs.fsf@mail.linkov.net> <87sgq1r9rb.fsf@red-bean.com> <87lfvt6m1e.fsf@mail.linkov.net> <877e7256uc.fsf@red-bean.com> <604cbbef-7e25-486a-a97a-9bc1adf23928@default> <871rx87b9h.fsf@red-bean.com> <77205e15-f38a-46dc-9451-4030a318900a@default> Reply-To: Karl Fogel Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: blaine.gmane.org; posting-host="blaine.gmane.org:195.159.176.226"; logging-data="101133"; mail-complaints-to="usenet@blaine.gmane.org" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux) Cc: Emacs developers To: Drew Adams Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Mon Aug 26 19:51:22 2019 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([209.51.188.17]) by blaine.gmane.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89) (envelope-from ) id 1i2J9F-000Q9w-Gc for ged-emacs-devel@m.gmane.org; Mon, 26 Aug 2019 19:51:21 +0200 Original-Received: from localhost ([::1]:56290 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i2J9E-0002Uy-Er for ged-emacs-devel@m.gmane.org; Mon, 26 Aug 2019 13:51:20 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:52786) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i2J94-0002Ul-Th for emacs-devel@gnu.org; Mon, 26 Aug 2019 13:51:12 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i2J93-0003ej-1S for emacs-devel@gnu.org; Mon, 26 Aug 2019 13:51:10 -0400 Original-Received: from mail-io1-xd2c.google.com ([2607:f8b0:4864:20::d2c]:45483) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1i2J92-0003dY-Os for emacs-devel@gnu.org; Mon, 26 Aug 2019 13:51:08 -0400 Original-Received: by mail-io1-xd2c.google.com with SMTP id t3so39295811ioj.12 for ; Mon, 26 Aug 2019 10:51:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:references:reply-to:date:in-reply-to :message-id:user-agent:mime-version; bh=Z/d0su1zQ4mESHPonJkiZI3fk34WX+xLKBkGE7MmN/I=; b=aKtEo6VuJlCSdaXKzvACYBDhuQVpN1JKTmCWBJYlO5+KZNr3zZVhDJ3y/VEmJb7Yha QPccOziD04Rk9OWOzRDN5YTuyfEtwdaLOKg/7Y5RAWJjXjoIAH3tKc/22ahH2FTD9VWd lXEB+I+0MEuRG2mhWeedNy6mkCot762ihFJ3SsHghc5fMA43WqdNzhVbqn/Kl117cdkw e/p48AerD/VMowsb9o7/JEGfYN84VYVSMPp4HmFQAg/uiHu+Ab0QXYQ3yiQmK4Qh2KkO jt7QrpWPiQpmXku9zzNyc4EbuHkXnv/obMIn7fTEB6gNzLHtYL6hDhrh+QV8tnEz42fG QLCQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:references:reply-to :date:in-reply-to:message-id:user-agent:mime-version; bh=Z/d0su1zQ4mESHPonJkiZI3fk34WX+xLKBkGE7MmN/I=; b=cL0DS1L6RNf4n+BOG2yRcuyUayafBV3HUeNYpLDiRLDzT/+frHATy9+5E7K4g1fKWJ 6da6Cn7GFXVM+ADgQkBYnxhdHNp8ZZ4Ner+0ly2AmUd5+dVoukNLkyn/wND60iy1ZgIe mofWv+827Ggk9hcUuVcklZCZ/67b9TipSL8APy/MTYNw7e/6ZdeirP4xmkLVGS/jBiSm pJBwiYN9MOfUclgrVJWGJijJLgf/nCJ7dGJ3X4ZJqh8ApfqdsvrmQDG8/bByiVHf8gEm 3UcGdOyxdyHqABZfAMMCmIwhZMdAdlFgYkj6A76iiwz+f14ZDeyuj3vGnaMf1mHCW5Oo CMkA== X-Gm-Message-State: APjAAAUwVCtsiz1OA7WvlnLxJFOIh164OGVArMmMIyz25e4X4x4jv9yX bNiEHK0zaN2L00ScZxgEvEbEaw/q X-Google-Smtp-Source: APXvYqzk+B0enVv7bNM7cbDYkCa6/A0N/y7yfW40kzslBnW7KyPv4wgV3m7T/Z/QNT1pjT3r2MZJdA== X-Received: by 2002:a6b:ee14:: with SMTP id i20mr1783507ioh.241.1566841867495; Mon, 26 Aug 2019 10:51:07 -0700 (PDT) Original-Received: from kwork (74-92-190-114-Illinois.hfc.comcastbusiness.net. [74.92.190.114]) by smtp.gmail.com with ESMTPSA id w5sm15298130iom.33.2019.08.26.10.51.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 26 Aug 2019 10:51:06 -0700 (PDT) In-Reply-To: <77205e15-f38a-46dc-9451-4030a318900a@default> (Drew Adams's message of "Mon, 26 Aug 2019 07:50:32 -0700 (PDT)") X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::d2c X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.org gmane.emacs.devel:239581 Archived-At: --=-=-= Content-Type: text/plain On 26 Aug 2019, Drew Adams wrote: >> It sounds like your patch does two conceptually >> distinct things: >> >> 1) Implement one or more new commands > [which work with backward search]. >> 2) Make a bunch of isearch commands work >> with backward search. > >Yes, if you want to look at it that way. But >switch the order, and then see if you still see >them as so different/separate. The ordering matters in terms of workload to me, though. If I install my patch, which is fairly small and self-contained, then all the other things in your patch could be installed on top of it (following discussion, consensus, etc). If we arrange the dependency flow this way, then my further participation becomes optional -- which is good, because I have only very limited time to work on Emacs. >But my patch subsumes your patch (except that it >doesn't address the manuals or News). > >It seemed appropriate to fix your command at the >same time as the others, especially since it was >still being discussed. Right. So let's have it subsume my patch by coming after my patch :-). Hence my "do one thing at a time" preference: that significantly reduces the amount of work for me, while not increasing it (or only increasing it a tiny amount) for you or anyone else. >> However, I would still say your patch should be >> divided into two conceptually distinct patches, >> one for (1) and one for (2). This is not a >> judgement about the technical merits or the UX >> merits of your patch. I'm just saying that we >> should do one thing at a time. > >I could do that. But they're not so separate. > >I added the Boolean option because Juri requested >it for the existing commands, to not change their >default behavior. (I don't think such an option >is needed, but I respected that request.) > >I could also split the patch into 3, splitting >off the command-defining macro and the two >commands it defines. Or I could split it into 4. > >Different approaches are possible. I thought >(and think) it makes more sense to present all >of those changes together with a general >explanation of the feature - they all go together. > >If someone wants to understand the behavior and >rationale, it makes sense to have code that >demonstrates it. > >But if you want to try the patch and ignore the >changes to existing commands, that's possible, >just by setting the option value to nil. Or if >you want to try it and ignore the new commands, >you can do that too. > >If you consider them "conceptually distinct" >then just use the option to separate them. > >And if it really helps to split the patch, I >can do that. That's an interesting discussion, but not one I have time to get into. If I install my original patch (with an updated keybinding), then those who have time to have that discussion can do so, and it will be the same discussion as it would be otherwise. >> Your patch suggested "C-M-." for >> 'isearch-yank-until-char', which seems good. >> Another possibility, to keep the "c" for "char" >> mnemonic, is to use M-c. > >I'm open on the key for `isearch-yank-until-char', >except that I think it makes sense to save `C-M-c' >in case we have a command that involves using that >to end recursive editing. I agree. >There are keys available. The usual problem with >Isearch is that people will argue, with reason, >that they like to use such-and-such a key to exit >Isearch and act on the buffer text. > >As you say, in Isearch `M-c' is currently for >toggling case. If it were not, I could imagine >someone saying that s?he wants to continue using >`M-c' as `capitalize-word', to end search and >capitalize the word at the destination. I don't really know if people still exit isearch by directly starting their next command. For many years now, I have always exited it explicitly with RET, because there are so many keybindings already claimed by isearch-mode that it's not worth it to me any more to keep track of which ones aren't yet claimed -- even ones that aren't claimed now might be claimed tomorrow, so I figured it was best to just get in the habit of using the designated exit binding, RET, to leave the search. However, maybe other people might do something like M-c to exit and capitalize-word all at once. The global binding for "C-M-." is `xref-find-apropos', which is extremely unlikely to be the command with which someone exits isearch (indeed, it is at least *possible* that no one in history has ever exited isearch that way), so I think I like it as a keybinding. Thanks for the suggestion. An updated patch is attached. The only new changes in this patch are: * Updated the keybinding in isearch-mode-map to C-M-. * Make the search for the character case-sensitive. (Seems like a pretty obvious improvement, given the use cases: when the goal character is a letter at all, one is either looking at that letter on the screen *or* the letter is some known syntactic delimiter and its case is therefore known as well even if the letter is off the screen right now.) >I like the fact that you provide reasons, and you >discuss openly and with details. > >I suggest that we run a discussion about possible >key bindings for this command and others in >parallel with the overall discussion that's begun >about Isearch yank commands. If "in parallel" means "separately but in parallel", then yes. I'll probably only take part in the first discussion. And that discussion may be done already, as I have now updated the keybinding to M-C-. for the (good) reason you gave. >As opposed, e.g., to trying to first decide about >a key for `isearch-yank-until-char'. Let's work >out the commands first - including consideration >of my proposed commands, and then figure out what >keys to use. Just a suggestion. Oh, you meant "in parallel and together". I'd like to avoid that. My goal is to keep the discussions as separate as possible, and I believe they are separate now that the keybinding issue is resolved. >And given that we're discussing adding to the set >of yank commands, maybe we want to consider >putting them all on some prefix key. That would >certainly give us more options. That's way more change than I wanted to get into, and I don't think it's necessary (for my original patch), since M-C-. is not taking away a likely isearch exit. If there is a discussion to be had about having an isearch-mode prefix key, let's please keep it separate. It is related to your larger patch, perhaps, but not to my original small one. New patch attached. Best regards, -Karl --=-=-= Content-Type: text/plain Content-Disposition: attachment; filename=isearch-yank-until-char-20190826.txt [[[ Add `isearch-yank-until-char' * lisp/isearch.el (isearch-yank-until-char): New function. (isearch-mode-map, isearch-menu-bar-yank-map): Add it. (isearch-forward): Document the new binding. * doc/emacs/search.texi (Isearch Yanking): Document the feature. * etc/NEWS: Mention the above. ]]] --- doc/emacs/search.texi +++ doc/emacs/search.texi @@ -262,11 +262,17 @@ Isearch Yank @kindex M-s C-e @r{(Incremental search)} @findex isearch-yank-line - Similarly, @kbd{M-s C-e} (@code{isearch-yank-line}) appends the rest + @kbd{M-s C-e} (@code{isearch-yank-line}) appends the rest of the current line to the search string. If point is already at the end of a line, it appends the next line. With a prefix argument @var{n}, it appends the next @var{n} lines. +@kindex C-M-c @r{(Incremental search)} +@findex isearch-yank-until-char + Similarly, @kbd{C-M-c} (@code{isearch-yank-until-char}) appends to +the search string everything from point until the next occurence of +a specified character (not including that character). + @kindex C-y @r{(Incremental search)} @kindex M-y @r{(Incremental search)} @kindex mouse-2 @r{in the minibuffer (Incremental search)} --- etc/NEWS +++ etc/NEWS @@ -1202,6 +1202,10 @@ highlight in one iteration while processing the full buffer. +++ *** New isearch bindings. +'C-M-c' invokes new function 'isearch-yank-until-char', which yanks +everything from point to the specified character into the search +string. + 'C-M-w' in isearch changed from 'isearch-del-char' to the new function 'isearch-yank-symbol-or-char'. 'isearch-del-char' is now bound to 'C-M-d'. --- lisp/isearch.el +++ lisp/isearch.el @@ -514,6 +514,9 @@ isearch-menu-bar-yank-map (define-key map [isearch-yank-kill] '(menu-item "Current kill" isearch-yank-kill :help "Append current kill to search string")) + (define-key map [isearch-yank-until-char] + '(menu-item "Until char..." isearch-yank-until-char + :help "Yank from point to specified character into search string")) (define-key map [isearch-yank-line] '(menu-item "Rest of line" isearch-yank-line :help "Yank the rest of the current line on search string")) @@ -705,6 +708,7 @@ isearch-mode-map (define-key map "\M-\C-d" 'isearch-del-char) (define-key map "\M-\C-y" 'isearch-yank-char) (define-key map "\C-y" 'isearch-yank-kill) + (define-key map [?\C-\M-.] 'isearch-yank-until-char) (define-key map "\M-s\C-e" 'isearch-yank-line) (define-key map "\M-s\M-<" 'isearch-beginning-of-buffer) @@ -998,6 +1002,8 @@ isearch-forward Type \\[isearch-del-char] to delete character from end of search string. Type \\[isearch-yank-char] to yank char from buffer onto end of search\ string and search for it. +Type \\[isearch-yank-until-char] to yank from point until the next instance\ + of a specified character onto end of search string and search for it. Type \\[isearch-yank-line] to yank rest of line onto end of search string\ and search for it. Type \\[isearch-yank-kill] to yank the last string of killed text. @@ -2562,6 +2568,22 @@ isearch-yank-word (interactive "p") (isearch-yank-internal (lambda () (forward-word arg) (point)))) +(defun isearch-yank-until-char (char) + "Pull everything until next instance of CHAR from buffer into search string. +Interactively, prompt for CHAR." + (interactive "cYank until character: ") + (isearch-yank-internal + (lambda () (let ((inhibit-field-text-motion t) + (case-fold-search nil)) + (condition-case nil + (progn + (search-forward (char-to-string char)) + (forward-char -1)) + (search-failed + (message "`%c' not found" char) + (sit-for 2))) + (point))))) + (defun isearch-yank-line (&optional arg) "Pull rest of line from buffer into search string. If optional ARG is non-nil, yank the next ARG lines." --=-=-=--