Package: emacs;
Reported by: Spencer Baugh <sbaugh <at> janestreet.com>
Date: Thu, 27 Mar 2025 15:04:03 UTC
Severity: normal
Tags: patch
Done: Dmitry Gutov <dmitry <at> gutov.dev>
To reply to this bug, email your comments to 77312 AT debbugs.gnu.org.
There is no need to reopen the bug first.
Toggle the display of automated, internal messages from the tracker.
View this report as an mbox folder, status mbox, maintainer mbox
dmitry <at> gutov.dev, bug-gnu-emacs <at> gnu.org
:bug#77312
; Package emacs
.
(Thu, 27 Mar 2025 15:04:03 GMT) Full text and rfc822 format available.Spencer Baugh <sbaugh <at> janestreet.com>
:dmitry <at> gutov.dev, bug-gnu-emacs <at> gnu.org
.
(Thu, 27 Mar 2025 15:04:03 GMT) Full text and rfc822 format available.Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):
From: Spencer Baugh <sbaugh <at> janestreet.com> To: bug-gnu-emacs <at> gnu.org Subject: [PATCH] Add uniquify-get-unique-names Date: Thu, 27 Mar 2025 11:03:17 -0400
[Message part 1 (text/plain, inline)]
Tags: patch This new function provides an interface to uniquify.el which doesn't change the actual names of the buffers. This is useful for any commands which deal with a subset of all buffers; for example, project.el. * lisp/uniquify.el (uniquify-rationalize--generic): Add. (uniquify-rationalize, uniquify-rationalize-a-list) (uniquify-rationalize-conflicting-sublist): Explicitly pass RENAME-BUFFER-FN and GET-BUFFER-FN. (uniquify--stateless-curname, uniquify-get-unique-names): Add. In GNU Emacs 30.1.50 (build 1, x86_64-pc-linux-gnu, X toolkit, cairo version 1.15.12, Xaw scroll bars) of 2025-03-11 built on igm-qws-u22796a Repository revision: 516d1e6463a9659951f7567e038efc5ee2a19bbf Windowing system distributor 'The X.Org Foundation', version 11.0.12011000 System Description: Rocky Linux 8.10 (Green Obsidian) Configured using: 'configure --config-cache --with-x-toolkit=lucid --without-gpm --without-gconf --without-selinux --without-imagemagick --with-modules --with-gif=no --with-cairo --with-rsvg --without-compress-install --with-tree-sitter --with-native-compilation=aot --prefix=/usr/local/home/garnish/raw-emacs/30-20250311_131404'
[0001-Add-uniquify-get-unique-names.patch (text/patch, attachment)]
bug-gnu-emacs <at> gnu.org
:bug#77312
; Package emacs
.
(Fri, 28 Mar 2025 18:52:02 GMT) Full text and rfc822 format available.Message #8 received at 77312 <at> debbugs.gnu.org (full text, mbox):
From: Spencer Baugh <sbaugh <at> janestreet.com> To: 77312 <at> debbugs.gnu.org Cc: dmitry <at> gutov.dev Subject: Re: bug#77312: [PATCH] Add uniquify-get-unique-names Date: Fri, 28 Mar 2025 14:50:59 -0400
[Message part 1 (text/plain, inline)]
After some use, it seems better to return an alist rather than a hash table from this function; that alist is in the same order as the buffer list that was passed in, which is nice for completion. So here's a version which does that.
[0001-Add-uniquify-get-unique-names.patch (text/x-patch, inline)]
From 62ff7104ff2cc0ab5a258c2cd83d1278bc804961 Mon Sep 17 00:00:00 2001 From: Spencer Baugh <sbaugh <at> janestreet.com> Date: Thu, 27 Mar 2025 09:32:47 -0400 Subject: [PATCH] Add uniquify-get-unique-names This new function provides an interface to uniquify.el which doesn't change the actual names of the buffers. This is useful for any commands which deal with a subset of all buffers; for example, project.el. * lisp/uniquify.el (uniquify-rationalize--generic): Add. (uniquify-rationalize, uniquify-rationalize-a-list) (uniquify-rationalize-conflicting-sublist): Explicitly pass RENAME-BUFFER-FN and GET-BUFFER-FN. (uniquify--stateless-curname, uniquify-get-unique-names): Add. --- lisp/uniquify.el | 66 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 55 insertions(+), 11 deletions(-) diff --git a/lisp/uniquify.el b/lisp/uniquify.el index 358ae6af651..ac60228d9d8 100644 --- a/lisp/uniquify.el +++ b/lisp/uniquify.el @@ -320,14 +320,19 @@ uniquify-rerationalize-w/o-cb (defun uniquify-rationalize (fix-list) ;; Set up uniquify to re-rationalize after killing/renaming ;; if there is a conflict. + (dolist (item fix-list) + (with-current-buffer (uniquify-item-buffer item) + (setq uniquify-managed fix-list))) + (uniquify-rationalize--generic fix-list #'uniquify-rename-buffer #'get-buffer)) + +(defun uniquify-rationalize--generic (fix-list rename-buffer-fn get-buffer-fn) (dolist (item fix-list) (with-current-buffer (uniquify-item-buffer item) ;; Refresh the dirnames and proposed names. (setf (uniquify-item-proposed item) (uniquify-get-proposed-name (uniquify-item-base item) (uniquify-item-dirname item) - nil)) - (setq uniquify-managed fix-list))) + nil)))) ;; Strip any shared last directory names of the dirname. (when (and (cdr fix-list) uniquify-strip-common-suffix) (let ((strip t)) @@ -353,13 +358,13 @@ uniquify-rationalize fix-list))))) ;; If uniquify-min-dir-content is 0, this will end up just ;; passing fix-list to uniquify-rationalize-conflicting-sublist. - (uniquify-rationalize-a-list fix-list)) + (uniquify-rationalize-a-list fix-list nil rename-buffer-fn get-buffer-fn)) (defun uniquify-item-greaterp (item1 item2) (string-lessp (uniquify-item-proposed item2) (uniquify-item-proposed item1))) -(defun uniquify-rationalize-a-list (fix-list &optional depth) +(defun uniquify-rationalize-a-list (fix-list depth rename-buffer-fn get-buffer-fn) (unless depth (setq depth uniquify-min-dir-content)) (let (conflicting-sublist ; all elements have the same proposed name (old-proposed "") @@ -370,12 +375,14 @@ uniquify-rationalize-a-list (setq proposed (uniquify-item-proposed item)) (unless (equal proposed old-proposed) (uniquify-rationalize-conflicting-sublist conflicting-sublist - old-proposed depth) + old-proposed depth + rename-buffer-fn get-buffer-fn) (setq conflicting-sublist nil)) (push item conflicting-sublist) (setq old-proposed proposed)) (uniquify-rationalize-conflicting-sublist conflicting-sublist - old-proposed depth))) + old-proposed depth + rename-buffer-fn get-buffer-fn))) (defun uniquify-get-proposed-name (base dirname &optional depth) (unless depth (setq depth uniquify-min-dir-content)) @@ -427,12 +434,12 @@ uniquify-get-proposed-name ;; Deal with conflicting-sublist, all of whose elements have identical ;; "base" components. -(defun uniquify-rationalize-conflicting-sublist (conf-list old-name depth) +(defun uniquify-rationalize-conflicting-sublist (conf-list old-name depth rename-buffer-fn get-buffer-fn) (when conf-list (if (or (cdr conf-list) ;; Check that the proposed name doesn't conflict with some ;; existing buffer. - (let ((buf (get-buffer old-name))) + (let ((buf (funcall get-buffer-fn old-name))) (and buf (not (eq buf (uniquify-item-buffer (car conf-list))))))) (when uniquify-possibly-resolvable (setq uniquify-possibly-resolvable nil @@ -443,10 +450,9 @@ uniquify-rationalize-conflicting-sublist (uniquify-item-base item) (uniquify-item-dirname item) depth))) - (uniquify-rationalize-a-list conf-list depth)) + (uniquify-rationalize-a-list conf-list depth rename-buffer-fn get-buffer-fn)) (unless (string= old-name "") - (uniquify-rename-buffer (car conf-list) old-name))))) - + (funcall rename-buffer-fn (car conf-list) old-name))))) (defun uniquify-rename-buffer (item newname) (let ((buffer (uniquify-item-buffer item))) @@ -456,6 +462,44 @@ uniquify-rename-buffer ;; Pass the `unique' arg, so the advice doesn't mark it as unmanaged. (rename-buffer newname t)))))) +(defvar-local uniquify--stateless-curname nil + "The current unique name of this buffer in `uniquify-get-unique-names'.") + +(defun uniquify-get-unique-names (buffers) + "Return an alist with a unique name for each buffer in BUFFERS. + +The names are unique only among BUFFERS, and may conflict with other +buffers not in that list. + +This does not rename the buffers or change any state; the unique name is +only present in the returned alist." + (let ((buffer-names (make-hash-table :size (length buffers) :test 'equal)) + fix-lists-by-base) + (dolist (buf buffers) + (with-current-buffer buf + (setq uniquify--stateless-curname (buffer-name buf)) + (puthash (buffer-name buf) buf buffer-names) + (when uniquify-managed + (let ((base (uniquify-item-base (car uniquify-managed)))) + (push + (uniquify-make-item base (uniquify-buffer-file-name buf) buf nil) + (alist-get base fix-lists-by-base nil nil #'equal)))))) + (dolist (pair fix-lists-by-base) + (uniquify-rationalize--generic + (cdr pair) + (lambda (item name) ; rename-buffer + (with-current-buffer (uniquify-item-buffer item) + (remhash uniquify--stateless-curname buffer-names) + (setq uniquify--stateless-curname name) + (puthash name (current-buffer) buffer-names))) + (lambda (name) ; get-buffer + (gethash name buffer-names))))) + (mapcar (lambda (buf) + (with-current-buffer buf + (prog1 (cons uniquify--stateless-curname buf) + (kill-local-variable 'uniquify--stateless-curname)))) + buffers)) + ;;; Hooks from the rest of Emacs (defun uniquify-maybe-rerationalize-w/o-cb () -- 2.39.3
bug-gnu-emacs <at> gnu.org
:bug#77312
; Package emacs
.
(Mon, 31 Mar 2025 19:59:02 GMT) Full text and rfc822 format available.Message #11 received at 77312 <at> debbugs.gnu.org (full text, mbox):
From: Dmitry Gutov <dmitry <at> gutov.dev> To: Spencer Baugh <sbaugh <at> janestreet.com>, 77312 <at> debbugs.gnu.org Subject: Re: bug#77312: [PATCH] Add uniquify-get-unique-names Date: Mon, 31 Mar 2025 22:58:19 +0300
[Message part 1 (text/plain, inline)]
Hi all, On 28/03/2025 20:50, Spencer Baugh wrote: > After some use, it seems better to return an alist rather than a hash > table from this function; that alist is in the same order as the buffer > list that was passed in, which is nice for completion. So here's a > version which does that. Here's the corresponding patch to project.el to use the new function. The use of new logic is predicated on the non-nil value of uniquify-buffer-name-style. The latter doesn't necessarily imply that the user wants the former, but seems a safe enough bet.
[project--read-project-buffer-reuniquify.diff (text/x-patch, attachment)]
Dmitry Gutov <dmitry <at> gutov.dev>
:Spencer Baugh <sbaugh <at> janestreet.com>
:Message #16 received at 77312-done <at> debbugs.gnu.org (full text, mbox):
From: Dmitry Gutov <dmitry <at> gutov.dev> To: Spencer Baugh <sbaugh <at> janestreet.com>, 77312-done <at> debbugs.gnu.org Subject: Re: bug#77312: [PATCH] Add uniquify-get-unique-names Date: Fri, 6 Jun 2025 05:45:22 +0300
On 31/03/2025 22:58, Dmitry Gutov wrote: > Here's the corresponding patch to project.el to use the new function. > > The use of new logic is predicated on the non-nil value of uniquify- > buffer-name-style. The latter doesn't necessarily imply that the user > wants the former, but seems a safe enough bet. No further comments from anybody, so I've pushed the two patches and am closing the bug. If anybody dislikes the change in project-switch-to-buffer's behavior, let me know.
bug-gnu-emacs <at> gnu.org
:bug#77312
; Package emacs
.
(Sat, 07 Jun 2025 08:12:01 GMT) Full text and rfc822 format available.Message #19 received at 77312 <at> debbugs.gnu.org (full text, mbox):
From: Daniel Mendler <mail <at> daniel-mendler.de> To: 77312 <at> debbugs.gnu.org Cc: dmitry <at> gutov.dev, sbaugh <at> janestreet.com Subject: Re: bug#77312: [PATCH] Add uniquify-get-unique-names Date: Sat, 07 Jun 2025 10:11:42 +0200
Hello Dmitry! Dmitry Gutov <dmitry <at> gutov.dev> writes: > On 31/03/2025 22:58, Dmitry Gutov wrote: >> Here's the corresponding patch to project.el to use the new function. >> The use of new logic is predicated on the non-nil value of uniquify- >> buffer-name-style. The latter doesn't necessarily imply that the user wants >> the former, but seems a safe enough bet. > > No further comments from anybody, so I've pushed the two patches and am closing > the bug. > > If anybody dislikes the change in project-switch-to-buffer's behavior, let me > know. Would it be possible to attach the buffer object or the original buffer name to the completion candidate string as text property? This would make it possible to attach annotations via Marginalia or to execute buffer actions via Embark. Otherwise I don't see a possibility to access the original buffer, since they are only present in the `unique-names` alist local variable. Daniel
bug-gnu-emacs <at> gnu.org
:bug#77312
; Package emacs
.
(Sun, 08 Jun 2025 02:07:02 GMT) Full text and rfc822 format available.Message #22 received at 77312 <at> debbugs.gnu.org (full text, mbox):
From: Dmitry Gutov <dmitry <at> gutov.dev> To: Daniel Mendler <mail <at> daniel-mendler.de>, 77312 <at> debbugs.gnu.org Cc: sbaugh <at> janestreet.com Subject: Re: bug#77312: [PATCH] Add uniquify-get-unique-names Date: Sun, 8 Jun 2025 05:06:36 +0300
Hey Daniel! On 07/06/2025 11:11, Daniel Mendler wrote: > Would it be possible to attach the buffer object or the original buffer > name to the completion candidate string as text property? This would > make it possible to attach annotations via Marginalia or to execute > buffer actions via Embark. Otherwise I don't see a possibility to access > the original buffer, since they are only present in the `unique-names` > alist local variable. That makes sense. Just call the property 'buffer'? I wonder if it would make sense to alter the calling convention for uniquify-get-unique-names itself to return a list of propertized strings instead. project--read-project-buffer can do the conversion (copy each string and attach the property), but it's just extra consing. Unless some more new callers are going to prefer the current convention.
bug-gnu-emacs <at> gnu.org
:bug#77312
; Package emacs
.
(Sun, 08 Jun 2025 05:42:01 GMT) Full text and rfc822 format available.Message #25 received at 77312 <at> debbugs.gnu.org (full text, mbox):
From: Daniel Mendler <mail <at> daniel-mendler.de> To: Dmitry Gutov <dmitry <at> gutov.dev> Cc: sbaugh <at> janestreet.com, 77312 <at> debbugs.gnu.org Subject: Re: bug#77312: [PATCH] Add uniquify-get-unique-names Date: Sun, 08 Jun 2025 07:41:19 +0200
Dmitry Gutov <dmitry <at> gutov.dev> writes: > Hey Daniel! > > On 07/06/2025 11:11, Daniel Mendler wrote: >> Would it be possible to attach the buffer object or the original buffer >> name to the completion candidate string as text property? This would >> make it possible to attach annotations via Marginalia or to execute >> buffer actions via Embark. Otherwise I don't see a possibility to access >> the original buffer, since they are only present in the `unique-names` >> alist local variable. > > That makes sense. Just call the property 'buffer'? That would work. I prefer a more specific property name to ease grepping/debugging. Also see below regarding the consing. > I wonder if it would make sense to alter the calling convention for > uniquify-get-unique-names itself to return a list of propertized strings > instead. project--read-project-buffer can do the conversion (copy each string > and attach the property), but it's just extra consing. I haven't checked if the current function is already working hard to avoid unnecessary allocations. If yes, it would be wasteful to add extra string allocations. In order to avoid them, we could only attach the property if the buffer name has really changed, such that no strings have to be copied. The property could be called `uniquify-orig-buffer-name`. If the property is present, it holds the original buffer name, if it is not present the string itself is the original buffer name. > Unless some more new callers are going to prefer the current convention. Both would be fine for me. Generally I think it is nice to push functionality to the lower level API, as long as the functionality is generic enough. Btw, would you be interested in having `uniquify-get-unique-names' in Compat, such that you avoid the fboundp check? project.el would have to depend on Compat for that, but that's essentially free on Emacs 30 and newer. Daniel
bug-gnu-emacs <at> gnu.org
:bug#77312
; Package emacs
.
(Tue, 10 Jun 2025 02:52:04 GMT) Full text and rfc822 format available.Message #28 received at 77312 <at> debbugs.gnu.org (full text, mbox):
From: Dmitry Gutov <dmitry <at> gutov.dev> To: Daniel Mendler <mail <at> daniel-mendler.de> Cc: sbaugh <at> janestreet.com, 77312 <at> debbugs.gnu.org Subject: Re: bug#77312: [PATCH] Add uniquify-get-unique-names Date: Tue, 10 Jun 2025 05:51:29 +0300
On 08/06/2025 08:41, Daniel Mendler wrote: >> On 07/06/2025 11:11, Daniel Mendler wrote: >>> Would it be possible to attach the buffer object or the original buffer >>> name to the completion candidate string as text property? This would >>> make it possible to attach annotations via Marginalia or to execute >>> buffer actions via Embark. Otherwise I don't see a possibility to access >>> the original buffer, since they are only present in the `unique-names` >>> alist local variable. >> >> That makes sense. Just call the property 'buffer'? > > That would work. I prefer a more specific property name to ease > grepping/debugging. Also see below regarding the consing. All right. >> I wonder if it would make sense to alter the calling convention for >> uniquify-get-unique-names itself to return a list of propertized strings >> instead. project--read-project-buffer can do the conversion (copy each string >> and attach the property), but it's just extra consing. > > I haven't checked if the current function is already working hard to > avoid unnecessary allocations. If yes, it would be wasteful to add extra > string allocations. Also when you provide the same information via different ways, over time they tend to get out of sync. The simpler the better. > In order to avoid them, we could only attach the property if the buffer > name has really changed, such that no strings have to be copied. The > property could be called `uniquify-orig-buffer-name`. If the property is > present, it holds the original buffer name, if it is not present the > string itself is the original buffer name. Yeah, that's a good idea. > Btw, would you be interested in having `uniquify-get-unique-names' in > Compat, such that you avoid the fboundp check? project.el would have to > depend on Compat for that, but that's essentially free on Emacs 30 and > newer. I usually try to avoid extra deps, but this can make sense, at least for users of Emacs>30. Especially if it leads to simplification in multiple places. Can you see other compatibility checks we could forgo this way? Offhand, I see another fboundp in 'project-ignores' (default definition) and a version< inside 'project-list-buffers-buffer-menu'.
bug-gnu-emacs <at> gnu.org
:bug#77312
; Package emacs
.
(Tue, 10 Jun 2025 03:15:05 GMT) Full text and rfc822 format available.Message #31 received at 77312 <at> debbugs.gnu.org (full text, mbox):
From: Daniel Mendler <mail <at> daniel-mendler.de> To: Dmitry Gutov <dmitry <at> gutov.dev> Cc: sbaugh <at> janestreet.com, 77312 <at> debbugs.gnu.org Subject: Re: bug#77312: [PATCH] Add uniquify-get-unique-names Date: Tue, 10 Jun 2025 05:14:28 +0200
Dmitry Gutov <dmitry <at> gutov.dev> writes: >> Btw, would you be interested in having `uniquify-get-unique-names' in >> Compat, such that you avoid the fboundp check? project.el would have to >> depend on Compat for that, but that's essentially free on Emacs 30 and >> newer. > > I usually try to avoid extra deps, but this can make sense, at least for users > of Emacs>30. Especially if it leads to simplification in multiple places. I also find it good to avoid extra deps, in particular if they introduce their own idioms. Compat doesn't invent functionality, it just provides some APIs from the latest stable Emacs versions, so it will help keeping your code up to date. Compat is made such that the dependency cost is minimized, since it is not installed if Emacs is sufficiently new. > Can you see other compatibility checks we could forgo this way? Offhand, I see > another fboundp in 'project-ignores' (default definition) and a version< inside > 'project-list-buffers-buffer-menu'. I think these checks cannot be avoided. But you could start using some new functions or macros like `defvar-keymap'. See the Compat manual for a list of backported functionality. Daniel
bug-gnu-emacs <at> gnu.org
:bug#77312
; Package emacs
.
(Tue, 10 Jun 2025 15:06:03 GMT) Full text and rfc822 format available.Message #34 received at 77312 <at> debbugs.gnu.org (full text, mbox):
From: Spencer Baugh <sbaugh <at> janestreet.com> To: Daniel Mendler <mail <at> daniel-mendler.de> Cc: Dmitry Gutov <dmitry <at> gutov.dev>, 77312 <at> debbugs.gnu.org Subject: Re: bug#77312: [PATCH] Add uniquify-get-unique-names Date: Tue, 10 Jun 2025 11:05:06 -0400
Daniel Mendler <mail <at> daniel-mendler.de> writes: > Dmitry Gutov <dmitry <at> gutov.dev> writes: > >> Hey Daniel! >> >> On 07/06/2025 11:11, Daniel Mendler wrote: >>> Would it be possible to attach the buffer object or the original buffer >>> name to the completion candidate string as text property? This would >>> make it possible to attach annotations via Marginalia or to execute >>> buffer actions via Embark. Otherwise I don't see a possibility to access >>> the original buffer, since they are only present in the `unique-names` >>> alist local variable. >> >> That makes sense. Just call the property 'buffer'? > > That would work. I prefer a more specific property name to ease > grepping/debugging. Also see below regarding the consing. > >> I wonder if it would make sense to alter the calling convention for >> uniquify-get-unique-names itself to return a list of propertized strings >> instead. project--read-project-buffer can do the conversion (copy each string >> and attach the property), but it's just extra consing. > > I haven't checked if the current function is already working hard to > avoid unnecessary allocations. If yes, it would be wasteful to add extra > string allocations. > > In order to avoid them, we could only attach the property if the buffer > name has really changed, such that no strings have to be copied. The > property could be called `uniquify-orig-buffer-name`. If the property is > present, it holds the original buffer name, if it is not present the > string itself is the original buffer name. All else being equal, I think changing uniquify-get-unique-names to return a list of strings which have the original buffer names as a property is a reasonable and easy thing to do. uniquify.el is generally pretty allocation heavy, so I wouldn't worry about the excess allocations, just stick the property on all the returned strings. Also, some future work I was considering, which I hope we can accomodate: making this be internal functionality of read-buffer. That is, when read-buffer is passed a predicate, it could: - use the predicate to filter the buffers - then use uniquify-get-unique-names to get less-verbose buffer names - then call completing-read with those buffer names I think the text property approach would indeed work with this, but just mentioning it. Some unnecessary speculation about alternatives to the text property approach follows: One alternative to the text property approach is to have the alist returned by uniquify-get-unique-names be let-bound in some special variable around the call to completing-read. Then Embark/Marginalia could look up strings in that alist to figure out the underlying buffer that a string is referring to. Or, we could have a completion table action (ACTION='get-buffer or something) which ignores PRED and returns the buffer corresponding to the passed in STRING. No new special variables at all. I am reminded of the perennial discussions about how completing-read is an API for "read string with completion", not "select a value by its string name from a set of possible values", maybe this would be useful for that...) >> Unless some more new callers are going to prefer the current convention. > > Both would be fine for me. Generally I think it is nice to push > functionality to the lower level API, as long as the functionality is > generic enough. > > Btw, would you be interested in having `uniquify-get-unique-names' in > Compat, such that you avoid the fboundp check? project.el would have to > depend on Compat for that, but that's essentially free on Emacs 30 and > newer. I think adding uniquify-get-unique-names to compat might be difficult because it depends on non-trivial changes to the rest of the code in uniquify.el.
bug-gnu-emacs <at> gnu.org
:bug#77312
; Package emacs
.
(Tue, 10 Jun 2025 16:55:03 GMT) Full text and rfc822 format available.Message #37 received at submit <at> debbugs.gnu.org (full text, mbox):
From: Daniel Mendler <mail <at> daniel-mendler.de> To: Spencer Baugh via "Bug reports for GNU Emacs, the Swiss army knife of text editors" <bug-gnu-emacs <at> gnu.org> Cc: Spencer Baugh <sbaugh <at> janestreet.com>, 77312 <at> debbugs.gnu.org, Dmitry Gutov <dmitry <at> gutov.dev> Subject: Re: bug#77312: [PATCH] Add uniquify-get-unique-names Date: Tue, 10 Jun 2025 18:54:12 +0200
Spencer Baugh via "Bug reports for GNU Emacs, the Swiss army knife of text editors" <bug-gnu-emacs <at> gnu.org> writes: > Daniel Mendler <mail <at> daniel-mendler.de> writes: > >> Dmitry Gutov <dmitry <at> gutov.dev> writes: >> >>> Hey Daniel! >>> >>> On 07/06/2025 11:11, Daniel Mendler wrote: >>>> Would it be possible to attach the buffer object or the original buffer >>>> name to the completion candidate string as text property? This would >>>> make it possible to attach annotations via Marginalia or to execute >>>> buffer actions via Embark. Otherwise I don't see a possibility to access >>>> the original buffer, since they are only present in the `unique-names` >>>> alist local variable. >>> >>> That makes sense. Just call the property 'buffer'? >> >> That would work. I prefer a more specific property name to ease >> grepping/debugging. Also see below regarding the consing. >> >>> I wonder if it would make sense to alter the calling convention for >>> uniquify-get-unique-names itself to return a list of propertized strings >>> instead. project--read-project-buffer can do the conversion (copy each string >>> and attach the property), but it's just extra consing. >> >> I haven't checked if the current function is already working hard to >> avoid unnecessary allocations. If yes, it would be wasteful to add extra >> string allocations. >> >> In order to avoid them, we could only attach the property if the buffer >> name has really changed, such that no strings have to be copied. The >> property could be called `uniquify-orig-buffer-name`. If the property is >> present, it holds the original buffer name, if it is not present the >> string itself is the original buffer name. > > All else being equal, I think changing uniquify-get-unique-names to > return a list of strings which have the original buffer names as a > property is a reasonable and easy thing to do. uniquify.el is generally > pretty allocation heavy, so I wouldn't worry about the excess > allocations, just stick the property on all the returned strings. Okay. > Some unnecessary speculation about alternatives to the text property > approach follows: > > One alternative to the text property approach is to have the alist > returned by uniquify-get-unique-names be let-bound in some special > variable around the call to completing-read. Then Embark/Marginalia > could look up strings in that alist to figure out the underlying buffer > that a string is referring to. Yes, this would work too. Or more ideally set a local variable in the minibuffer setup hook, since then buffer unification can be detected by checking if the variable is non-nil. >>> Unless some more new callers are going to prefer the current convention. >> >> Both would be fine for me. Generally I think it is nice to push >> functionality to the lower level API, as long as the functionality is >> generic enough. >> >> Btw, would you be interested in having `uniquify-get-unique-names' in >> Compat, such that you avoid the fboundp check? project.el would have to >> depend on Compat for that, but that's essentially free on Emacs 30 and >> newer. > > I think adding uniquify-get-unique-names to compat might be difficult > because it depends on non-trivial changes to the rest of the code in > uniquify.el. That's unfortunate. I have not looked in detail at it, but if the effort is disproportionate, and half of uniquify.el would need to be replicated, then we cannot port it back as part of Compat. Daniel
bug-gnu-emacs <at> gnu.org
:bug#77312
; Package emacs
.
(Tue, 10 Jun 2025 16:55:04 GMT) Full text and rfc822 format available.bug-gnu-emacs <at> gnu.org
:bug#77312
; Package emacs
.
(Tue, 10 Jun 2025 17:05:02 GMT) Full text and rfc822 format available.Message #43 received at 77312 <at> debbugs.gnu.org (full text, mbox):
From: Spencer Baugh <sbaugh <at> janestreet.com> To: Daniel Mendler <mail <at> daniel-mendler.de> Cc: dmitry <at> gutov.dev, 77312 <at> debbugs.gnu.org Subject: Re: bug#77312: [PATCH] Add uniquify-get-unique-names Date: Tue, 10 Jun 2025 13:03:53 -0400
Daniel Mendler <mail <at> daniel-mendler.de> writes: > Spencer Baugh via "Bug reports for GNU Emacs, the Swiss army knife of > text editors" <bug-gnu-emacs <at> gnu.org> writes: > >> Daniel Mendler <mail <at> daniel-mendler.de> writes: >> >>> Dmitry Gutov <dmitry <at> gutov.dev> writes: >>> >>>> Hey Daniel! >>>> >>>> On 07/06/2025 11:11, Daniel Mendler wrote: >>>>> Would it be possible to attach the buffer object or the original buffer >>>>> name to the completion candidate string as text property? This would >>>>> make it possible to attach annotations via Marginalia or to execute >>>>> buffer actions via Embark. Otherwise I don't see a possibility to access >>>>> the original buffer, since they are only present in the `unique-names` >>>>> alist local variable. >>>> >>>> That makes sense. Just call the property 'buffer'? >>> >>> That would work. I prefer a more specific property name to ease >>> grepping/debugging. Also see below regarding the consing. >>> >>>> I wonder if it would make sense to alter the calling convention for >>>> uniquify-get-unique-names itself to return a list of propertized strings >>>> instead. project--read-project-buffer can do the conversion (copy each string >>>> and attach the property), but it's just extra consing. >>> >>> I haven't checked if the current function is already working hard to >>> avoid unnecessary allocations. If yes, it would be wasteful to add extra >>> string allocations. >>> >>> In order to avoid them, we could only attach the property if the buffer >>> name has really changed, such that no strings have to be copied. The >>> property could be called `uniquify-orig-buffer-name`. If the property is >>> present, it holds the original buffer name, if it is not present the >>> string itself is the original buffer name. >> >> All else being equal, I think changing uniquify-get-unique-names to >> return a list of strings which have the original buffer names as a >> property is a reasonable and easy thing to do. uniquify.el is generally >> pretty allocation heavy, so I wouldn't worry about the excess >> allocations, just stick the property on all the returned strings. > > Okay. Er, sorry, crucial typo/miscommunication here: I think uniquify-get-unique-names should return a list of strings, each of which has a text property containing the original *buffer*. Not the original buffer name - the buffer itself. That would just be slightly more efficient. > >> Some unnecessary speculation about alternatives to the text property >> approach follows: >> >> One alternative to the text property approach is to have the alist >> returned by uniquify-get-unique-names be let-bound in some special >> variable around the call to completing-read. Then Embark/Marginalia >> could look up strings in that alist to figure out the underlying buffer >> that a string is referring to. > > Yes, this would work too. Or more ideally set a local variable in the > minibuffer setup hook, since then buffer unification can be detected by > checking if the variable is non-nil. Ah right, because otherwise a recursive edit could cause problems... so a local variable set in the minibuffer setup hook would indeed be bettter. >>>> Unless some more new callers are going to prefer the current convention. >>> >>> Both would be fine for me. Generally I think it is nice to push >>> functionality to the lower level API, as long as the functionality is >>> generic enough. >>> >>> Btw, would you be interested in having `uniquify-get-unique-names' in >>> Compat, such that you avoid the fboundp check? project.el would have to >>> depend on Compat for that, but that's essentially free on Emacs 30 and >>> newer. >> >> I think adding uniquify-get-unique-names to compat might be difficult >> because it depends on non-trivial changes to the rest of the code in >> uniquify.el. > > That's unfortunate. I have not looked in detail at it, but if the effort > is disproportionate, and half of uniquify.el would need to be > replicated, then we cannot port it back as part of Compat. Yep. Maybe about 120 lines would need to be replicated.
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.