GNU bug report logs -
#77312
[PATCH] Add uniquify-get-unique-names
Previous Next
To reply to this bug, email your comments to 77312 AT debbugs.gnu.org.
Toggle the display of automated, internal messages from the tracker.
Report forwarded
to
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.
Acknowledgement sent
to
Spencer Baugh <sbaugh <at> janestreet.com>
:
New bug report received and forwarded. Copy sent to
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):
[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)]
Information forwarded
to
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):
[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
Information forwarded
to
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):
[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)]
This bug report was last modified 3 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.