From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Spencer Baugh Newsgroups: gmane.emacs.devel Subject: Re: Updating *Completions* as you type Date: Tue, 28 Nov 2023 23:56:14 +0000 (UTC) Message-ID: <877cm1v3ez.fsf@catern.com> References: <87bkd3z9bi.fsf@catern.com> <87il5xlf9b.fsf@catern.com> <86y1esuajx.fsf@mail.linkov.net> <86v89ws5t3.fsf@mail.linkov.net> <86v89vzf1o.fsf@mail.linkov.net> <87pm03jn3w.fsf@catern.com> <861qcjw3ch.fsf@mail.linkov.net> <86r0ki2on3.fsf@mail.linkov.net> <86leao519y.fsf@mail.linkov.net> <87fs0wk5oq.fsf@catern.com> <86edgfin4v.fsf@mail.linkov.net> <87o7fhixzv.fsf@catern.com> <86o7fhy9ae.fsf@mail.linkov.net> <87v89ohc6f.fsf@catern.com> <86il5nhdvh.fsf@mail.linkov.net> <87plzuuend.fsf@catern.com> <837cm19ay3.fsf@gnu.org> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="2770"; mail-complaints-to="usenet@ciao.gmane.io" Cc: juri@linkov.net, sbaugh@janestreet.com, emacs-devel@gnu.org To: Eli Zaretskii Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Wed Nov 29 00:57:24 2023 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 1r87xC-0000U1-FZ for ged-emacs-devel@m.gmane-mx.org; Wed, 29 Nov 2023 00:57:23 +0100 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1r87wD-0000dl-KT; Tue, 28 Nov 2023 18:56:21 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1r87wC-0000cE-PA for emacs-devel@gnu.org; Tue, 28 Nov 2023 18:56:20 -0500 Original-Received: from s.wrqvwxzv.outbound-mail.sendgrid.net ([149.72.154.232]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1r87w8-0007h7-Pb for emacs-devel@gnu.org; Tue, 28 Nov 2023 18:56:19 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=catern.com; h=from:subject:in-reply-to:references:mime-version:to:cc:content-type: cc:content-type:from:subject:to; s=s1; bh=Pw1b/zhMjiHn+8DjKnc5y/uKSenGSs1lPXOA9+4x5tE=; b=jlXTyR0uQ5PjMfOvBfVk4dxxgQatUdz3QxKXRduFol1CUE+ZHeKjCCmqfxYApySXKjil qPJftoHd37MSWLW8AP68mRajsggCJTh8h/2lFcawYttSuFJyu0RizM/mvE/jbhVR/hm+JD ZmC7BGjTx1jhWgKiAiV1F/StBNkhz13MB0tc5NCF90WQq1XZlD4zS52OtAdmF+KnKqoH/+ EE7qmEGXwoiNO0NbsYtimUAhHFnllYYMdRpFxLHlVPBt359oguPHlVD8qul+vF3Vpaq5CS ZeTH1MtnXW5bI1GEjMzjFYjlcQJfrz+VqumdZCWxO0Dns4n/GwiP7tGyPggTC1dg== Original-Received: by filterdrecv-656b5b4c75-zckst with SMTP id filterdrecv-656b5b4c75-zckst-1-65667E1E-11 2023-11-28 23:56:14.319077834 +0000 UTC m=+3647781.247807249 Original-Received: from earth.catern.com (unknown) by geopod-ismtpd-12 (SG) with ESMTP id adu8u2dhQ2KZIzHVKbzzuw Tue, 28 Nov 2023 23:56:14.153 +0000 (UTC) Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=74.101.51.129; helo=localhost; envelope-from=sbaugh@catern.com; receiver=gnu.org Original-Received: from localhost (unknown [74.101.51.129]) by earth.catern.com (Postfix) with ESMTPSA id AE26163F88; Tue, 28 Nov 2023 18:55:32 -0500 (EST) In-Reply-To: <837cm19ay3.fsf@gnu.org> X-SG-EID: =?us-ascii?Q?GW3oCMoYnalRiojMOuLzE6x2H5kORXvlCdz1UwQVRMVT4fbh9ODEfCogOe74cO?= =?us-ascii?Q?rI4e0V+MFZgakz9Re5a6=2FCglc8jnfTCF2iXsJwk?= =?us-ascii?Q?LyqckNyza7WX9xLRgOuN8DfrhLMVpb2UDoghIAJ?= =?us-ascii?Q?eBJlegy1LShP+rWUf6jorOL51k87kwg4QXOVSp0?= =?us-ascii?Q?e6IbUFkO1GA2akV7cIzzXRmxmwdEwdWmWFk9TF2?= =?us-ascii?Q?UOpMksWRHqqvaRl+a0BRO35oKm39+K2Jafanqd?= X-Entity-ID: d/0VcHixlS0t7iB1YKCv4Q== Received-SPF: pass client-ip=149.72.154.232; envelope-from=bounces+21787432-489d-emacs-devel=gnu.org@em8926.catern.com; helo=s.wrqvwxzv.outbound-mail.sendgrid.net X-Spam_score_int: 5 X-Spam_score: 0.5 X-Spam_bar: / X-Spam_report: (0.5 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_BL_SPAMCOP_NET=1.347, RCVD_IN_MSPIKE_H2=-0.001, RCVD_IN_VALIDITY_RPBL=1.31, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01, UNPARSEABLE_RELAY=0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.29 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-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.devel:313341 Archived-At: --=-=-= Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Eli Zaretskii writes: >> From: Spencer Baugh >> Date: Tue, 28 Nov 2023 14:38:55 +0000 (UTC) >> Cc: Spencer Baugh , emacs-devel@gnu.org >> :type '(choice (const :tag "No sorting" nil) >> (const :tag "Alphabetical sorting" alphabetical) >> + (const :tag "Historical sorting" historical) > ^^^^^^^^^^^^^^^^^^ > "Chronological sorting" I think "historical sorting" is more intuitive here. "Chronological" seems more ambiguous - it could mean something different for files, for example. Fixed patch for everything else: --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0001-Add-historical-option-to-completions-sort.patch >From 326da292ef0512a518ec5ed7140c028e53cb6cd7 Mon Sep 17 00:00:00 2001 From: Spencer Baugh Date: Tue, 17 Oct 2023 09:09:55 -0400 Subject: [PATCH] Add historical option to completions-sort Support sorting candidates in *Completions* by the order they show up in the minibuffer history. Also add minibuffer-sort-alphabetically and minibuffer-sort-by-history, which are usable for both completions-sort and display-sort-function. * lisp/minibuffer.el (completions-sort): Document 'historical option. (minibuffer-completion-help): Support 'historical option. (minibuffer-sort-alphabetically) (minibuffer-completion-base, minibuffer-sort-by-history): Add. * etc/NEWS: Announce it. --- etc/NEWS | 5 ++++ lisp/minibuffer.el | 65 +++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 64 insertions(+), 6 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index fd633fad6fb..12a37176ee0 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -620,6 +620,11 @@ completions window. When the completions window is not visible, then all these keys have their usual meaning in the minibuffer. This option is supported for in-buffer completion as well. +*** New value 'historical' for user option 'completions-sort' +When 'completions-sort' is set to 'historical', completion candidates +will be sorted by their chronological order in the minibuffer history, +with more recent candidates appearing first. + ** Pcomplete --- diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index 5c12d9fc914..77703a4e330 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -1314,14 +1314,27 @@ completion-cycle-threshold (defcustom completions-sort 'alphabetical "Sort candidates in the *Completions* buffer. -The value can be nil to disable sorting, `alphabetical' for -alphabetical sorting or a custom sorting function. The sorting -function takes and returns a list of completion candidate -strings." +Completion candidates in the *Completions* buffer are sorted +depending on the value. + +If it's nil, sorting is disabled. +If it's the symbol `alphabetical', candidates are sorted by +`minibuffer-sort-alphabetically'. +If it's the symbol `historical', candidates are sorted by +`minibuffer-sort-by-history'. +If it's a function, the function is called to sort the candidates. +The sorting function takes a list of completion candidate +strings, which it may modify; it should return a sorted list, +which may be the same. + +If the completion-specific metadata provides a +`display-sort-function', that function overrides the value of +this variable." :type '(choice (const :tag "No sorting" nil) (const :tag "Alphabetical sorting" alphabetical) + (const :tag "Historical sorting" historical) (function :tag "Custom function")) - :version "29.1") + :version "30.1") (defcustom completions-group nil "Enable grouping of completion candidates in the *Completions* buffer. @@ -1647,6 +1660,44 @@ minibuffer--sort-preprocess-history (substring c base-size))) hist))))) +(defun minibuffer-sort-alphabetically (completions) + "Sort COMPLETIONS alphabetically. + +COMPLETIONS are sorted alphabetically by `string-lessp'. + +This is a suitable function to use for `completions-sort' or to +include as `display-sort-function' in completion metadata." + (sort completions #'string-lessp)) + +(defvar minibuffer-completion-base nil + "The base for the current completion. + +This is the part of the current minibuffer input which comes +before the current completion field, as determined by +`completion-boundaries'. This is primarily relevant for file +names, where this is the directory component of the file name.") + +(defun minibuffer-sort-by-history (completions) + "Sort COMPLETIONS by their position in `minibuffer-history-variable'. + +COMPLETIONS are sorted first by `minibuffer-sort-alphbetically', +then any elements occuring in the minibuffer history list are +moved to the front based on the chronological order they occur in +the history. If a history variable hasn't been specified for +this call of `completing-read', COMPLETIONS are sorted only by +`minibuffer-sort-alphbetically'. + +This is a suitable function to use for `completions-sort' or to +include as `display-sort-function' in completion metadata." + (let ((alphabetized (sort completions #'string-lessp))) + ;; Only use history when it's specific to these completions. + (if (eq minibuffer-history-variable + (default-value minibuffer-history-variable)) + alphabetized + (minibuffer--sort-by-position + (minibuffer--sort-preprocess-history minibuffer-completion-base) + alphabetized)))) + (defun minibuffer--group-by (group-fun sort-fun elems) "Group ELEMS by GROUP-FUN and sort groups by SORT-FUN." (let ((groups)) @@ -2409,6 +2460,7 @@ minibuffer-completion-help (let* ((last (last completions)) (base-size (or (cdr last) 0)) (prefix (unless (zerop base-size) (substring string 0 base-size))) + (minibuffer-completion-base (substring string 0 base-size)) (base-prefix (buffer-substring (minibuffer--completion-prompt-end) (+ start base-size))) (base-suffix @@ -2473,7 +2525,8 @@ minibuffer-completion-help (funcall sort-fun completions) (pcase completions-sort ('nil completions) - ('alphabetical (sort completions #'string-lessp)) + ('alphabetical (minibuffer-sort-alphabetically completions)) + ('historical (minibuffer-sort-by-history completions)) (_ (funcall completions-sort completions))))) ;; After sorting, group the candidates using the -- 2.42.1 --=-=-=--