From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Daniel Mendler Newsgroups: gmane.emacs.devel Subject: Re: Improvement proposals for `completing-read' Date: Thu, 8 Apr 2021 11:01:42 +0200 Message-ID: <264397e8-5a03-9eff-436c-639d76514775@daniel-mendler.de> References: <0342c2d5-02dd-ad9e-5b8e-dfe52f6469c6@daniel-mendler.de> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="32405"; mail-complaints-to="usenet@ciao.gmane.io" To: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Thu Apr 08 11:02:56 2021 Return-path: Envelope-to: ged-emacs-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1lUQYx-0008KS-Rp for ged-emacs-devel@m.gmane-mx.org; Thu, 08 Apr 2021 11:02:55 +0200 Original-Received: from localhost ([::1]:34612 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lUQYw-0004PL-RN for ged-emacs-devel@m.gmane-mx.org; Thu, 08 Apr 2021 05:02:54 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:50764) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lUQXw-0003SG-5z for emacs-devel@gnu.org; Thu, 08 Apr 2021 05:01:52 -0400 Original-Received: from server.qxqx.de ([2a01:4f8:121:346::180]:43135 helo=mail.qxqx.de) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lUQXr-0008Dj-PC for emacs-devel@gnu.org; Thu, 08 Apr 2021 05:01:51 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=qxqx.de; s=mail1392553390; h=Content-Transfer-Encoding:Content-Type:In-Reply-To: MIME-Version:Date:Message-ID:From:References:To:Subject:Sender:Reply-To:Cc: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=B7okMhT+vMj8LfFFc979uWqeLRnDcwQI0l+S0oPB60k=; b=DLdA5wLPXB4riNTx6RgR2QHIKU L27eh2bUVBTvwfN9OMPX3/ThRtyoFd67+1HRaQhbF4Ww9+aKJIXK9pgMuIfYwQGc+mZBx07UnJ/I0 TyLpFhxEfaW6ZI+doq4EZyUYeMYY1EF54C33wExoVOMiLqHyI/QG0xPcl7Aoc6UjVzaA=; In-Reply-To: Content-Language: en-US Received-SPF: pass client-ip=2a01:4f8:121:346::180; envelope-from=mail@daniel-mendler.de; helo=mail.qxqx.de X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action 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-mx.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.io gmane.emacs.devel:267601 Archived-At: On 4/7/21 11:26 PM, Stefan Monnier wrote: > What I meant is that I can't think of many situations where > we specifically want no history (which is where t is used) as opposed to > the many situations where we simply don't care about history (in which > case nil works just as well). > > IIRC the t case for read-from-minibuffer was added for the needs of > `read-passwd` where we really don't want the history, for security reasons. > I don't know of any other use case yet. There is one use case I found a bit useful - if you are browsing a history itself with `completing-read` then you may want to disable writing to the given or another history at the same time, such that the completion you are doing is not side-effecting. I would also like if `completing-read` is consistent with `read-from-minibuffer` in this case, since this lead to actual confusion, where the false assumption has been made that `completing-read` also accepts `t`. >>>> Proposal 3: Sort file names by history > Currently we're not even close to that. So I think the first step is to > fix the code to pay attention to boundaries. My comment was just > pointing out that this can be done right now a simple bug fix without > any extra information. Okay, I also have the code for that approach. It is a simple bug fix as you say. I dropped it from Vertico for my file name sorting for performance reasons and since I wanted to do better in the special important case of files. But no problem to prepare patches for both and fix the boundaries case first. > `flex` without sorting is *much* less usable, in my experience. > The direction of `flex` is actually to replace filtering with sorting. > E.g. I have a local completion style which I call "forgiving" because it > tries to accommodate typos in the input, so basically every member of > the completion table always matches, only its sorting position is > affected by the input text. So if you removing sorting, there's > nothing left. > > I agree with you that the current way style-based sorting works is > problematic, but I think the principle of style-based sorting is sound > because we don't want this to be specific to a UI nor to a backend. Okay, I see. I am actually not using the flex style since I find it too slow and generating too many matches. But in the Emacs completion implementation it will only be triggered if the earlier styles do not match so maybe that is okay. I am not using flex since I am using something else - the orderless style. "regexp1 regexp2 regexp3" matches the regexps in any order. Furthermore I am using "style dispatchers", "regexp flex~ !not literal=", where the "flex~" token is used to generate a flex regexp, etc. Maybe we will see the orderless package in ELPA at some point. >>>> Proposal 5: Forbid the null completions for `REQUIRE-MATCH=t' >>>> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >> Okay, I think it is reasonable to gather some data regarding the extent of >> the problem. But then I would strongly prefer to just fix the issue. That >> being said, it was not obvious to me that you can actually force require >> match by writing a proper completion table which properly handles the >> `test-completion` action. > > No, you can't force require match this way. What you can do this way is > to re-loosen the match so as to accept the empty-string again like in > the old (i.e. current) code. Thanks for clarifying. >> Yes, that is right. If you care about the actual candidate you get from >> a set of duplicates, you must use a completion UI which can handle >> duplicates. If you use an UI which cannot handle this (which rather >> completes) you cannot get the distinction. >> >> I think there is a real need for this if you look at the Swiper command and >> you want to navigate across equal lines. Then there is the >> ivy-occur/embark-export/embark-collect command which allows to export the >> lines to an occur buffer where you can again navigate over the duplicate >> items. Given how everything is implemented internally (list of candidates, >> filtering via completion-all-completions etc), it feels like an unnecessary >> restriction to remove duplicates. It would be more natural to just >> allow them. > > As long as we can offer some way (that's not too cumbersome) to select > between the different cases using things like self-insert-command + RET, > I'm fine with it. IOW I think it require reifying the "subtle > differences" as some kind of optional extra text. Okay, maybe I can come up with something. This will require experimentation. The duplicates could be deduplicated at the UI level by appending some index for example "candidate (1)", "candidate (2)", ... >>> I suspect "pass the small subset of candidates once again through >>> `completion-all-completions'" can be tricky to do (e.g. for things like >>> file-name completion with `partial-completion`). >> In `vertico--highlight` I am checking the length of the result. If it is not >> equal to the original length, the UI simply displays the original >> candidates. This is an ugly hack. Maybe it would be better to have >> a `completion-style-operation` variable which can be either `'both`, >> `'filter` or `'highlight`? > > I'm not really interested in hacking a slightly better solution, so > I think your current hack is good enough: the way I see it, the > replacement of `completion-all-completions` should return > non-highlighted candidates along with some extra opaque data, and then > a separate new function can take one of those candidates, together with > that opaque data (plus some additional optional args) to add highlight > one candidate at a time. > > This way, the highlighting in *Completions* could be applied > incrementally via jit-lock, and the "additional optional args" should > make it possible for the UI to have control over the color scheme > being used. One thing to consider - maybe returning the highlights as some extra data is not actually faster than simply propertizing the strings? I guess you only save the allocations of the strings? The idea of the proposed hack is really to avoid the entire work of computing the highlights, since it is mostly unnecessary and slow if you filter many candidates and display only a small subset. I would therefore go with the simple solution first since this provable solves the issue. But using jit-lock in buffers has appeal. Daniel Mendler