GNU bug report logs - #62621
29.0.60; uniquify can't make buffers unique based on things other than filename

Previous Next

Package: emacs;

Reported by: Spencer Baugh <sbaugh <at> janestreet.com>

Date: Sun, 2 Apr 2023 17:38:02 UTC

Severity: normal

Found in version 29.0.60

Done: Eli Zaretskii <eliz <at> gnu.org>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 62621 in the body.
You can then email your comments to 62621 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#62621; Package emacs. (Sun, 02 Apr 2023 17:38:02 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 bug-gnu-emacs <at> gnu.org. (Sun, 02 Apr 2023 17:38:02 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: 29.0.60; uniquify can't make buffers unique based on things other
 than filename
Date: Sun, 02 Apr 2023 13:37:36 -0400
I have a lot of buffers visiting files with the same basename, in
directory paths which have long meaningless numeric identifiers.  This
means that with uniquify, I get buffers named things like:

foo<ahlai5Ei>, foo<IHoano7o>, foo<yoeWo3ae>

This is not much better than foo<1>, foo<2>, foo<3> for me.

What would be great is if uniquify could use things other than the
filename when making unique buffer names.

For example, project-name from project.el is something that *is*
unique for these files, because of my custom project.el integration.
Then I'd get something like:

foo<proj-emacs>, foo<proj-vi>, foo<proj-nano>

However, uniquify is currently not customizable in this way.  Could we
add support for including additional attributes into the things which
uniquify will use?  Then I could add project-name as one of those
attributes in my configuration, and I'd be happy.

I would be happy to implement this feature in uniquify myself, if this
is an interesting feature for upstream.  Or if you'd prefer some other
approach, I'd be happy to hear it and I can implement it.



In GNU Emacs 29.0.60 (build 3, x86_64-pc-linux-gnu, X toolkit, cairo
 version 1.15.12, Xaw scroll bars) of 2023-03-13 built on
 igm-qws-u22796a
Repository revision: e759905d2e0828eac4c8164b09113b40f6899656
Repository branch: emacs-29
Windowing system distributor 'The X.Org Foundation', version 11.0.12011000
System Description: CentOS Linux 7 (Core)

Configured using:
 'configure --with-x-toolkit=lucid --with-modules
 --with-gif=ifavailable'

Configured features:
CAIRO DBUS FREETYPE GLIB GMP GNUTLS GSETTINGS HARFBUZZ JPEG JSON
LIBSELINUX LIBXML2 MODULES NOTIFY INOTIFY PDUMPER PNG RSVG SECCOMP SOUND
SQLITE3 THREADS TIFF TOOLKIT_SCROLL_BARS X11 XDBE XIM XINPUT2 XPM LUCID
ZLIB

Important settings:
  value of $LANG: en_US.UTF-8
  locale-coding-system: utf-8-unix




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#62621; Package emacs. (Sun, 02 Apr 2023 17:57:02 GMT) Full text and rfc822 format available.

Message #8 received at 62621 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Spencer Baugh <sbaugh <at> janestreet.com>
Cc: 62621 <at> debbugs.gnu.org
Subject: Re: bug#62621: 29.0.60;
 uniquify can't make buffers unique based on things other than filename
Date: Sun, 02 Apr 2023 20:57:08 +0300
> From: Spencer Baugh <sbaugh <at> janestreet.com>
> Date: Sun, 02 Apr 2023 13:37:36 -0400
> 
> 
> I have a lot of buffers visiting files with the same basename, in
> directory paths which have long meaningless numeric identifiers.  This
> means that with uniquify, I get buffers named things like:
> 
> foo<ahlai5Ei>, foo<IHoano7o>, foo<yoeWo3ae>
> 
> This is not much better than foo<1>, foo<2>, foo<3> for me.
> 
> What would be great is if uniquify could use things other than the
> filename when making unique buffer names.
> 
> For example, project-name from project.el is something that *is*
> unique for these files, because of my custom project.el integration.
> Then I'd get something like:
> 
> foo<proj-emacs>, foo<proj-vi>, foo<proj-nano>
> 
> However, uniquify is currently not customizable in this way.  Could we
> add support for including additional attributes into the things which
> uniquify will use?  Then I could add project-name as one of those
> attributes in my configuration, and I'd be happy.
> 
> I would be happy to implement this feature in uniquify myself, if this
> is an interesting feature for upstream.

Sounds like a useful feature indeed, provided that the customization
will allow more or less arbitrary uniquification, not just by project
names.  Also, please keep in mind that a single project could have
files named the same in different directories.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#62621; Package emacs. (Sun, 02 Apr 2023 18:26:01 GMT) Full text and rfc822 format available.

Message #11 received at 62621 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: Spencer Baugh <sbaugh <at> janestreet.com>
Cc: 62621 <at> debbugs.gnu.org
Subject: Re: bug#62621: 29.0.60; uniquify can't make buffers unique based on
 things other than filename
Date: Sun, 02 Apr 2023 21:25:08 +0300
> However, uniquify is currently not customizable in this way.  Could we
> add support for including additional attributes into the things which
> uniquify will use?  Then I could add project-name as one of those
> attributes in my configuration, and I'd be happy.

This was discussed recently in bug#59502, but I don't remember
why the patch was never applied.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#62621; Package emacs. (Sun, 02 Apr 2023 22:01:02 GMT) Full text and rfc822 format available.

Message #14 received at 62621 <at> debbugs.gnu.org (full text, mbox):

From: Drew Adams <drew.adams <at> oracle.com>
To: Eli Zaretskii <eliz <at> gnu.org>, Spencer Baugh <sbaugh <at> janestreet.com>
Cc: "62621 <at> debbugs.gnu.org" <62621 <at> debbugs.gnu.org>
Subject: RE: [External] : bug#62621: 29.0.60; uniquify can't make buffers
 unique based on things other than filename
Date: Sun, 2 Apr 2023 21:59:52 +0000
> > However, uniquify is currently not customizable in this way.  Could we
> > add support for including additional attributes into the things which
> > uniquify will use?  Then I could add project-name as one of those
> > attributes in my configuration, and I'd be happy.
> >
> > I would be happy to implement this feature in uniquify myself, if this
> > is an interesting feature for upstream.
> 
> Sounds like a useful feature indeed, provided that the customization
> will allow more or less arbitrary uniquification, not just by project
> names.  Also, please keep in mind that a single project could have
> files named the same in different directories.

+1.
_____

Off the top of my head (not thought through)...

User-definable, e.g., based on some defcustom
choice combinations; i.e., different name pieces
that can contribute to the overall name.

The current behavior of using the dir-name pieces
could be one such choice, which could then be
combined with other choices.
 
`file-attributes' values (at least some of them)
could also be candidates for such combinations.

Or useful abbreviations of file-attribute values;
e.g., use a relative last-<whatever> number
instead of a full last-<whatver> value, to reflect
just recency, not bothering about what the absolute
values are.

Ability to assign arbitrary labels (one or more
"tags") to a given buffer would be good as another
combining choice.

In addition, as an alternative maybe a user-defined
function value to compute the overall name.
____

Anyway, any enhancement at all that might be made
wrt the naming would be welcome.





Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#62621; Package emacs. (Fri, 14 Apr 2023 16:09:02 GMT) Full text and rfc822 format available.

Message #17 received at 62621 <at> debbugs.gnu.org (full text, mbox):

From: Spencer Baugh <sbaugh <at> janestreet.com>
To: 62621 <at> debbugs.gnu.org
Subject: Re: bug#62621: 29.0.60; uniquify can't make buffers unique based on
 things other than filename
Date: Fri, 14 Apr 2023 12:08:37 -0400
FWIW, here is the (unpolished) patch I'm currently using.

This is correct but it's not what I think the final form of this should
look like.

For better or for worse, I have now Deeply Understood uniquify, and I
have various ideas for things to do to fix bugs in it and simplify it
and add new features... see bug#62732 for my first step.  (Which adds
tests, even!)

After some of those, then I can do this bug.

One sneak peak of a feature which I think I can manage to add with some
improvements to uniquify.el: a user customization which causes a new
behavior in read-buffer, so that when it's running on a subset of
buffers (by passing PREDICATE), it reads buffer names which are only
uniquified among that subset.  (So the buffer names will be shorter when
that doesn't cause ambiguity).  This would be really cool for
project-switch-to-buffer, so that if you have two projects working on
the same source repo with the same files open, you don't have to see the
extra uniquify cruft at the start of the buffer name when you just want
to look at buffers in a single project.

diff --git a/lisp/uniquify.el b/lisp/uniquify.el
index dee9ecba2ea..53b39920820 100644
--- a/lisp/uniquify.el
+++ b/lisp/uniquify.el
@@ -210,8 +210,8 @@ uniquify-rationalize-file-buffer-names
   (with-current-buffer newbuf (setq uniquify-managed nil))
   (when dirname
     (setq dirname (expand-file-name (directory-file-name dirname)))
-    (let ((fix-list (list (uniquify-make-item base dirname newbuf
-                                              nil dirname)))
+    (let ((fix-list (list (let ((dirname (uniquify-buffer-file-name newbuf dirname)))
+                            (uniquify-make-item base dirname newbuf nil dirname))))
 	  items)
       (dolist (buffer (buffer-list))
 	(when (and (not (and uniquify-ignore-buffers-re
@@ -258,20 +258,26 @@ uniquify-rationalize-file-buffer-names
       (uniquify-rationalize fix-list))))
 
 ;; uniquify's version of buffer-file-name; result never contains trailing slash
-(defun uniquify-buffer-file-name (buffer)
+(require 'project)
+(defun uniquify-buffer-file-name (buffer &optional dirname)
   "Return name of directory, file BUFFER is visiting, or nil if none.
 Works on ordinary file-visiting buffers and buffers whose mode is mentioned
 in `uniquify-list-buffers-directory-modes', otherwise returns nil."
   (with-current-buffer buffer
-    (let ((filename
-	   (or buffer-file-name
-	       (if (memq major-mode uniquify-list-buffers-directory-modes)
-		   list-buffers-directory))))
-      (when filename
-	(directory-file-name
-	 (file-name-directory
-	  (expand-file-name
-	   (directory-file-name filename))))))))
+    (let* ((filename
+	    (or buffer-file-name
+	        (if (memq major-mode uniquify-list-buffers-directory-modes)
+		    list-buffers-directory)))
+           (dir (or dirname
+                    (directory-file-name
+	             (file-name-directory
+	              (expand-file-name
+	               (directory-file-name filename)))))))
+      (if-let (pr (project-current nil dir))
+          (let* ((pr-dir (project-root pr))
+                 (pr-rel (file-relative-name dir pr-dir)))
+            (file-name-concat pr-dir (project-name pr) pr-rel))
+        dir))))
 
 (defun uniquify-rerationalize-w/o-cb (fix-list)
   "Re-rationalize the buffers in FIX-LIST, but ignoring `current-buffer'."




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#62621; Package emacs. (Thu, 13 Jul 2023 22:53:02 GMT) Full text and rfc822 format available.

Message #20 received at 62621 <at> debbugs.gnu.org (full text, mbox):

From: sbaugh <at> catern.com
To: Spencer Baugh <sbaugh <at> janestreet.com>
Cc: 62621 <at> debbugs.gnu.org
Subject: Re: bug#62621: 29.0.60; uniquify can't make buffers unique based on
 things other than filename
Date: Thu, 13 Jul 2023 22:51:53 +0000 (UTC)
[Message part 1 (text/plain, inline)]
OK, after resolving bug#62732, now at last my nice and short patch for
this feature.

I've thought quite a bit about how to make this configurable, and I
think just letting people write their own arbitrary transformation
functions, as I do in this patch, is what we should provide.  Making
things any more modular is fairly difficult.  Packages can come along
and provide other fancy functions if they like.

[0001-Support-transforming-the-dirname-used-by-uniquify.patch (text/x-patch, inline)]
From 5e6260951b31fbd9da826cc2ff56bfbecdbbe7eb Mon Sep 17 00:00:00 2001
From: Spencer Baugh <sbaugh <at> catern.com>
Date: Sun, 9 Jul 2023 22:21:03 -0400
Subject: [PATCH] Support transforming the dirname used by uniquify

By transforming the dirname, we can add additional information to use
during uniquifying.  A basic one: uniquifying buffer names based on
the project name.

* lisp/progmodes/project.el (project-uniquify-dirname-transform): Add.
* lisp/uniquify.el (uniquify-dirname-transform-default)
(uniquify-dirname-transform): Add. (bug#62621)
(uniquify-rationalize-file-buffer-names, uniquify-buffer-file-name):
Use uniquify-dirname-transform.
* test/lisp/uniquify-tests.el (uniquify-home,
uniquify-project-transform): Add tests.
---
 lisp/progmodes/project.el   | 12 ++++++++++++
 lisp/uniquify.el            | 22 +++++++++++++++++-----
 test/lisp/uniquify-tests.el | 33 +++++++++++++++++++++++++++++++++
 3 files changed, 62 insertions(+), 5 deletions(-)

diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el
index 03ed966cc45..11fa93fb70d 100644
--- a/lisp/progmodes/project.el
+++ b/lisp/progmodes/project.el
@@ -1887,5 +1887,17 @@ project-switch-project
     (let ((project-current-directory-override dir))
       (call-interactively command))))
 
+;;;###autoload
+(defun project-uniquify-dirname-transform (dirname)
+  "Include `project-name' in DIRNAME if in a project."
+  (if-let (proj (project-current nil dirname))
+      (let ((root (project-root proj)))
+        (expand-file-name
+         (file-name-concat
+          (file-name-directory root)
+          (project-name proj)
+          (file-relative-name dirname root))))
+    dirname))
+
 (provide 'project)
 ;;; project.el ends here
diff --git a/lisp/uniquify.el b/lisp/uniquify.el
index d1ca455b673..bd49346da45 100644
--- a/lisp/uniquify.el
+++ b/lisp/uniquify.el
@@ -168,6 +168,16 @@ uniquify-list-buffers-directory-modes
 That means that when `buffer-file-name' is set to nil, `list-buffers-directory'
 contains the name of the directory which the buffer is visiting.")
 
+(defcustom uniquify-dirname-transform #'identity
+  "A function to transform the dirname used to uniquify a buffer.
+
+It takes a single argument: the directory of the buffer.  It
+should return a string filename (which does not need to actually
+exist in the filesystem) to use for uniquifying the buffer name."
+  :type '(choice (function-item :tag "Don't change the dirname" identity)
+                 function)
+  :group 'uniquify)
+
 ;;; Utilities
 
 ;; uniquify-fix-list data structure
@@ -209,7 +219,8 @@ uniquify-rationalize-file-buffer-names
   ;; this buffer.
   (with-current-buffer newbuf (setq uniquify-managed nil))
   (when dirname
-    (setq dirname (expand-file-name (directory-file-name dirname)))
+    (setq dirname (funcall uniquify-dirname-transform
+                           (expand-file-name (directory-file-name dirname))))
     (let ((fix-list (list (uniquify-make-item base dirname newbuf
                                               nil)))
 	  items)
@@ -268,10 +279,11 @@ uniquify-buffer-file-name
 	       (if (memq major-mode uniquify-list-buffers-directory-modes)
 		   list-buffers-directory))))
       (when filename
-	(directory-file-name
-	 (file-name-directory
-	  (expand-file-name
-	   (directory-file-name filename))))))))
+	 (funcall uniquify-dirname-transform
+	          (directory-file-name
+	          (file-name-directory
+	           (expand-file-name
+	            (directory-file-name filename)))))))))
 
 (defun uniquify-rerationalize-w/o-cb (fix-list)
   "Re-rationalize the buffers in FIX-LIST, but ignoring `current-buffer'."
diff --git a/test/lisp/uniquify-tests.el b/test/lisp/uniquify-tests.el
index abd61fa3504..e533c4b644c 100644
--- a/test/lisp/uniquify-tests.el
+++ b/test/lisp/uniquify-tests.el
@@ -88,6 +88,21 @@ uniquify-dirs
                        '("a/dir/" "b/dir/")))
         (mapc #'kill-buffer bufs)))))
 
+(ert-deftest uniquify-home ()
+  "uniquify works, albeit confusingly, in the presence of directories named \"~\""
+  (let (bufs)
+    (save-excursion
+      (push (find-file-noselect "~") bufs)
+      (push (find-file-noselect "./~") bufs)
+      (should (equal (mapcar #'buffer-name bufs)
+                     '("~<test>" "~<>")))
+      (push (find-file-noselect "~/foo") bufs)
+      (push (find-file-noselect "./~/foo") bufs)
+      (should (equal (mapcar #'buffer-name bufs)
+                     '("foo<~>" "foo</nonexistent>" "~<test>" "~<>")))
+      (while bufs
+        (kill-buffer (pop bufs))))))
+
 (ert-deftest uniquify-rename-to-dir ()
   "Giving a buffer a name which matches a directory doesn't rename the buffer"
   (let ((uniquify-buffer-name-style 'forward)
@@ -125,5 +140,23 @@ uniquify-space-prefix
     (should (equal (buffer-name) "| foo"))
     (kill-buffer)))
 
+(require 'project)
+(ert-deftest uniquify-project-transform ()
+  "`project-uniquify-dirname-transform' works"
+  (let ((uniquify-dirname-transform #'project-uniquify-dirname-transform)
+        (project-vc-name "foo1/bar")
+        bufs)
+    (save-excursion
+      (should (file-exists-p "../README"))
+      (push (find-file-noselect "../README") bufs)
+      (push (find-file-noselect "other/README") bufs)
+      (should (equal (mapcar #'buffer-name bufs)
+                     '("README<other>" "README<bar>")))
+      (push (find-file-noselect "foo2/bar/README") bufs)
+      (should (equal (mapcar #'buffer-name bufs)
+                     '("README<foo2/bar>" "README<other>" "README<foo1/bar>")))
+      (while bufs
+        (kill-buffer (pop bufs))))))
+
 (provide 'uniquify-tests)
 ;;; uniquify-tests.el ends here
-- 
2.41.0


Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#62621; Package emacs. (Fri, 14 Jul 2023 06:30:02 GMT) Full text and rfc822 format available.

Message #23 received at 62621 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: sbaugh <at> catern.com
Cc: sbaugh <at> janestreet.com, 62621 <at> debbugs.gnu.org
Subject: Re: bug#62621: 29.0.60;
 uniquify can't make buffers unique based on things other than filename
Date: Fri, 14 Jul 2023 09:29:38 +0300
> Cc: 62621 <at> debbugs.gnu.org
> From: sbaugh <at> catern.com
> Date: Thu, 13 Jul 2023 22:51:53 +0000 (UTC)
> 
> I've thought quite a bit about how to make this configurable, and I
> think just letting people write their own arbitrary transformation
> functions, as I do in this patch, is what we should provide.  Making
> things any more modular is fairly difficult.  Packages can come along
> and provide other fancy functions if they like.

If there are a couple of simpler alternatives which could be offered
via simple symbolic values, we should not force everyone to write
functions, IMNSHO.  IOW, we should NOT immediately generalize to
functions only because such generalization could make sense in some
use cases.  Repeat after me: Use options whose values are functions
are hard on our users, because they require them to be Lisp
programmers.

> +(defcustom uniquify-dirname-transform #'identity
> +  "A function to transform the dirname used to uniquify a buffer.

"Function to transform buffer's `default-directory' for uniquifying its name."

> +It takes a single argument: the directory of the buffer.  It
> +should return a string filename (which does not need to actually
> +exist in the filesystem) to use for uniquifying the buffer name."
> +  :type '(choice (function-item :tag "Don't change the dirname" identity)
> +                 function)
> +  :group 'uniquify)

The :version tag is missing.

Also, the doc string should state that the default is to use the
buffer's default-directory without any transformations.  It should
also include a link to uniquify-buffer-file-name, so that users could
consult the uniquify facilities if they need to.

Thanks.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#62621; Package emacs. (Fri, 14 Jul 2023 11:29:02 GMT) Full text and rfc822 format available.

Message #26 received at 62621 <at> debbugs.gnu.org (full text, mbox):

From: sbaugh <at> catern.com
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: sbaugh <at> janestreet.com, 62621 <at> debbugs.gnu.org
Subject: Re: bug#62621: 29.0.60; uniquify can't make buffers unique based on
 things other than filename
Date: Fri, 14 Jul 2023 11:28:13 +0000 (UTC)
Eli Zaretskii <eliz <at> gnu.org> writes:

>> Cc: 62621 <at> debbugs.gnu.org
>> From: sbaugh <at> catern.com
>> Date: Thu, 13 Jul 2023 22:51:53 +0000 (UTC)
>> 
>> I've thought quite a bit about how to make this configurable, and I
>> think just letting people write their own arbitrary transformation
>> functions, as I do in this patch, is what we should provide.  Making
>> things any more modular is fairly difficult.  Packages can come along
>> and provide other fancy functions if they like.
>
> If there are a couple of simpler alternatives which could be offered
> via simple symbolic values, we should not force everyone to write
> functions, IMNSHO.  IOW, we should NOT immediately generalize to
> functions only because such generalization could make sense in some
> use cases.  Repeat after me: Use options whose values are functions
> are hard on our users, because they require them to be Lisp
> programmers.

I agree, and I'm happy to change it to use a simple symbolic value
'project instead for the transform I wrote, but I'm not sure how best to
handle the dependencies: uniquify.el is in loadup.el, is it OK for it to
rely on project-uniquify-dirname-transform being autoloaded?

>> +(defcustom uniquify-dirname-transform #'identity
>> +  "A function to transform the dirname used to uniquify a buffer.
>
> "Function to transform buffer's `default-directory' for uniquifying its name."

Unfortunately, this isn't quite right.  uniquify never uses
default-directory, counterintuitively - by default, it uses the
directory of buffer-file-name, which can differ from default-directory.

>> +It takes a single argument: the directory of the buffer.  It
>> +should return a string filename (which does not need to actually
>> +exist in the filesystem) to use for uniquifying the buffer name."
>> +  :type '(choice (function-item :tag "Don't change the dirname" identity)
>> +                 function)
>> +  :group 'uniquify)
>
> The :version tag is missing.
>
> Also, the doc string should state that the default is to use the
> buffer's default-directory without any transformations.  It should
> also include a link to uniquify-buffer-file-name, so that users could
> consult the uniquify facilities if they need to.

Will include that in the next version.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#62621; Package emacs. (Fri, 14 Jul 2023 12:02:02 GMT) Full text and rfc822 format available.

Message #29 received at 62621 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: sbaugh <at> catern.com
Cc: sbaugh <at> janestreet.com, 62621 <at> debbugs.gnu.org
Subject: Re: bug#62621: 29.0.60; uniquify can't make buffers unique based on
 things other than filename
Date: Fri, 14 Jul 2023 15:01:58 +0300
> From: sbaugh <at> catern.com
> Date: Fri, 14 Jul 2023 11:28:13 +0000 (UTC)
> Cc: sbaugh <at> janestreet.com, 62621 <at> debbugs.gnu.org
> 
> Eli Zaretskii <eliz <at> gnu.org> writes:
> 
> > If there are a couple of simpler alternatives which could be offered
> > via simple symbolic values, we should not force everyone to write
> > functions, IMNSHO.  IOW, we should NOT immediately generalize to
> > functions only because such generalization could make sense in some
> > use cases.  Repeat after me: Use options whose values are functions
> > are hard on our users, because they require them to be Lisp
> > programmers.
> 
> I agree, and I'm happy to change it to use a simple symbolic value
> 'project instead for the transform I wrote, but I'm not sure how best to
> handle the dependencies: uniquify.el is in loadup.el, is it OK for it to
> rely on project-uniquify-dirname-transform being autoloaded?

I don't understand the difficulty.  If the function value could be
defined in uniquify.el, why cannot a symbolic value be defined there?

If the symbolic values are specific to project, simply let-bind
uniquify-dirname-transform to the value of the appropriate project.el
defcustom when project.el calls uniquify.

> >> +(defcustom uniquify-dirname-transform #'identity
> >> +  "A function to transform the dirname used to uniquify a buffer.
> >
> > "Function to transform buffer's `default-directory' for uniquifying its name."
> 
> Unfortunately, this isn't quite right.  uniquify never uses
> default-directory, counterintuitively - by default, it uses the
> directory of buffer-file-name, which can differ from default-directory.

That's a minor issue, just use "buffer's directory" instead.

But I wonder why uniquify does something counterintuitive like that.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#62621; Package emacs. (Fri, 14 Jul 2023 12:21:01 GMT) Full text and rfc822 format available.

Message #32 received at 62621 <at> debbugs.gnu.org (full text, mbox):

From: Spencer Baugh <sbaugh <at> janestreet.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: sbaugh <at> catern.com, 62621 <at> debbugs.gnu.org
Subject: Re: bug#62621: 29.0.60; uniquify can't make buffers unique based on
 things other than filename
Date: Fri, 14 Jul 2023 08:20:02 -0400
Eli Zaretskii <eliz <at> gnu.org> writes:

>> From: sbaugh <at> catern.com
>> Date: Fri, 14 Jul 2023 11:28:13 +0000 (UTC)
>> Cc: sbaugh <at> janestreet.com, 62621 <at> debbugs.gnu.org
>> 
>> Eli Zaretskii <eliz <at> gnu.org> writes:
>> 
>> > If there are a couple of simpler alternatives which could be offered
>> > via simple symbolic values, we should not force everyone to write
>> > functions, IMNSHO.  IOW, we should NOT immediately generalize to
>> > functions only because such generalization could make sense in some
>> > use cases.  Repeat after me: Use options whose values are functions
>> > are hard on our users, because they require them to be Lisp
>> > programmers.
>> 
>> I agree, and I'm happy to change it to use a simple symbolic value
>> 'project instead for the transform I wrote, but I'm not sure how best to
>> handle the dependencies: uniquify.el is in loadup.el, is it OK for it to
>> rely on project-uniquify-dirname-transform being autoloaded?
>
> I don't understand the difficulty.  If the function value could be
> defined in uniquify.el, why cannot a symbolic value be defined there?

I don't understand your question :)

Here's concretely the diff I would apply.  This makes uniquify.el mention a
function from project.el.  Is that OK?

diff --git a/lisp/uniquify.el b/lisp/uniquify.el
index bd49346da45..4783830b184 100644
--- a/lisp/uniquify.el
+++ b/lisp/uniquify.el
@@ -168,14 +168,10 @@ uniquify-list-buffers-directory-modes
 That means that when `buffer-file-name' is set to nil, `list-buffers-directory'
 contains the name of the directory which the buffer is visiting.")
 
-(defcustom uniquify-dirname-transform #'identity
-  "A function to transform the dirname used to uniquify a buffer.
-
-It takes a single argument: the directory of the buffer.  It
-should return a string filename (which does not need to actually
-exist in the filesystem) to use for uniquifying the buffer name."
-  :type '(choice (function-item :tag "Don't change the dirname" identity)
-                 function)
+(defcustom uniquify-dirname-transform nil
+  "How to transform the dirname used to uniquify a buffer."
+  :type '(choice (const :tag "Don't change the dirname" nil)
+                 (const :tag "Include project-name when uniquifying" 'project))
   :group 'uniquify)
 
 ;;; Utilities
@@ -279,11 +275,14 @@ uniquify-buffer-file-name
 	       (if (memq major-mode uniquify-list-buffers-directory-modes)
 		   list-buffers-directory))))
       (when filename
-	 (funcall uniquify-dirname-transform
-	          (directory-file-name
-	          (file-name-directory
-	           (expand-file-name
-	            (directory-file-name filename)))))))))
+	(funcall
+         (cond ((not uniquify-dirname-transform) #'identity)
+               ((eq uniquify-dirname-transform 'project) #'project-uniquify-dirname-transform)
+               (t (error "bad uniquify-dirname-transform: %s" uniquify-dirname-transform)))
+	 (directory-file-name
+	  (file-name-directory
+	   (expand-file-name
+	    (directory-file-name filename)))))))))
 
 (defun uniquify-rerationalize-w/o-cb (fix-list)
   "Re-rationalize the buffers in FIX-LIST, but ignoring `current-buffer'."

> If the symbolic values are specific to project, simply let-bind
> uniquify-dirname-transform to the value of the appropriate project.el
> defcustom when project.el calls uniquify.

These customizations are in effect all the time, not just when the user
is calling a project.el command.  e.g. rename-buffer triggers uniquify.

>> >> +(defcustom uniquify-dirname-transform #'identity
>> >> +  "A function to transform the dirname used to uniquify a buffer.
>> >
>> > "Function to transform buffer's `default-directory' for uniquifying its name."
>> 
>> Unfortunately, this isn't quite right.  uniquify never uses
>> default-directory, counterintuitively - by default, it uses the
>> directory of buffer-file-name, which can differ from default-directory.
>
> That's a minor issue, just use "buffer's directory" instead.
>
> But I wonder why uniquify does something counterintuitive like that.

I assume it's something like "default-directory changes (such as by M-x
cd) shouldn't change the buffer name too".

Although personally I would be totally fine with cd changing the buffer
name...

The fact that uniquify doesn't use default-directory also means it's
unable to uniquify buffers which aren't visiting files, which can be
annoying.  For example, if uniquify used default-directory then it could
uniquify *compilation* buffers for different projects, renaming them
based on the directory.  But because it can't, every package has to come
up with their own special buffer-renaming scheme... include project.el.

I could add support for making uniquify use default-directory instead,
if that's interesting.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#62621; Package emacs. (Fri, 14 Jul 2023 12:29:01 GMT) Full text and rfc822 format available.

Message #35 received at 62621 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Spencer Baugh <sbaugh <at> janestreet.com>
Cc: sbaugh <at> catern.com, 62621 <at> debbugs.gnu.org
Subject: Re: bug#62621: 29.0.60; uniquify can't make buffers unique based on
 things other than filename
Date: Fri, 14 Jul 2023 15:29:02 +0300
> From: Spencer Baugh <sbaugh <at> janestreet.com>
> Cc: sbaugh <at> catern.com,  62621 <at> debbugs.gnu.org
> Date: Fri, 14 Jul 2023 08:20:02 -0400
> 
> Eli Zaretskii <eliz <at> gnu.org> writes:
> 
> >> I agree, and I'm happy to change it to use a simple symbolic value
> >> 'project instead for the transform I wrote, but I'm not sure how best to
> >> handle the dependencies: uniquify.el is in loadup.el, is it OK for it to
> >> rely on project-uniquify-dirname-transform being autoloaded?
> >
> > I don't understand the difficulty.  If the function value could be
> > defined in uniquify.el, why cannot a symbolic value be defined there?
> 
> I don't understand your question :)
> 
> Here's concretely the diff I would apply.  This makes uniquify.el mention a
> function from project.el.  Is that OK?

No.

> > If the symbolic values are specific to project, simply let-bind
> > uniquify-dirname-transform to the value of the appropriate project.el
> > defcustom when project.el calls uniquify.
> 
> These customizations are in effect all the time, not just when the user
> is calling a project.el command.  e.g. rename-buffer triggers uniquify.

Then you can set the buffer-local value of uniquify-dirname-transform
in the project.el buffers.  Would that solve the problem?

> >> Unfortunately, this isn't quite right.  uniquify never uses
> >> default-directory, counterintuitively - by default, it uses the
> >> directory of buffer-file-name, which can differ from default-directory.
> >
> > That's a minor issue, just use "buffer's directory" instead.
> >
> > But I wonder why uniquify does something counterintuitive like that.
> 
> I assume it's something like "default-directory changes (such as by M-x
> cd) shouldn't change the buffer name too".

default-directory of a file-visiting buffer doesn't change.

> The fact that uniquify doesn't use default-directory also means it's
> unable to uniquify buffers which aren't visiting files

Exactly.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#62621; Package emacs. (Fri, 14 Jul 2023 12:47:01 GMT) Full text and rfc822 format available.

Message #38 received at 62621 <at> debbugs.gnu.org (full text, mbox):

From: Spencer Baugh <sbaugh <at> janestreet.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: sbaugh <at> catern.com, 62621 <at> debbugs.gnu.org
Subject: Re: bug#62621: 29.0.60; uniquify can't make buffers unique based on
 things other than filename
Date: Fri, 14 Jul 2023 08:46:00 -0400
Eli Zaretskii <eliz <at> gnu.org> writes:

>> From: Spencer Baugh <sbaugh <at> janestreet.com>
>> Cc: sbaugh <at> catern.com,  62621 <at> debbugs.gnu.org
>> Date: Fri, 14 Jul 2023 08:20:02 -0400
>> 
>> Eli Zaretskii <eliz <at> gnu.org> writes:
>> 
>> >> I agree, and I'm happy to change it to use a simple symbolic value
>> >> 'project instead for the transform I wrote, but I'm not sure how best to
>> >> handle the dependencies: uniquify.el is in loadup.el, is it OK for it to
>> >> rely on project-uniquify-dirname-transform being autoloaded?
>> >
>> > I don't understand the difficulty.  If the function value could be
>> > defined in uniquify.el, why cannot a symbolic value be defined there?
>> 
>> I don't understand your question :)
>> 
>> Here's concretely the diff I would apply.  This makes uniquify.el mention a
>> function from project.el.  Is that OK?
>
> No.

I figured.  So now you see the issue with the symbolic approach.

If the defcustom just takes a function, though, that solves the
dependency issue.  Because the user's config handles taking the function
from project.el and putting it in the variable from uniquify.el.

>> > If the symbolic values are specific to project, simply let-bind
>> > uniquify-dirname-transform to the value of the appropriate project.el
>> > defcustom when project.el calls uniquify.
>> 
>> These customizations are in effect all the time, not just when the user
>> is calling a project.el command.  e.g. rename-buffer triggers uniquify.
>
> Then you can set the buffer-local value of uniquify-dirname-transform
> in the project.el buffers.  Would that solve the problem?

The buffers it should affect are all file-visiting buffers.  project.el
doesn't currently have any code which runs for every new buffer.  I
guess we've considered adding that, but I'm not sure this is a good
reason...

>> >> Unfortunately, this isn't quite right.  uniquify never uses
>> >> default-directory, counterintuitively - by default, it uses the
>> >> directory of buffer-file-name, which can differ from default-directory.
>> >
>> > That's a minor issue, just use "buffer's directory" instead.
>> >
>> > But I wonder why uniquify does something counterintuitive like that.
>> 
>> I assume it's something like "default-directory changes (such as by M-x
>> cd) shouldn't change the buffer name too".
>
> default-directory of a file-visiting buffer doesn't change.

I don't think that's true.  If I open ~/.emacs.d/init.el then (cd "/")
then default-directory in that file-visiting buffer is / instead of
~/.emacs.d

>> The fact that uniquify doesn't use default-directory also means it's
>> unable to uniquify buffers which aren't visiting files
>
> Exactly.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#62621; Package emacs. (Fri, 14 Jul 2023 13:51:02 GMT) Full text and rfc822 format available.

Message #41 received at 62621 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Spencer Baugh <sbaugh <at> janestreet.com>
Cc: sbaugh <at> catern.com, 62621 <at> debbugs.gnu.org
Subject: Re: bug#62621: 29.0.60; uniquify can't make buffers unique based on
 things other than filename
Date: Fri, 14 Jul 2023 16:51:01 +0300
> From: Spencer Baugh <sbaugh <at> janestreet.com>
> Cc: sbaugh <at> catern.com,  62621 <at> debbugs.gnu.org
> Date: Fri, 14 Jul 2023 08:46:00 -0400
> 
> 
> Eli Zaretskii <eliz <at> gnu.org> writes:
> 
> >> Here's concretely the diff I would apply.  This makes uniquify.el mention a
> >> function from project.el.  Is that OK?
> >
> > No.
> 
> I figured.  So now you see the issue with the symbolic approach.

No, I don't.  Not a significant problem, anyway, and not why it's
different from using a function.

> If the defcustom just takes a function, though, that solves the
> dependency issue.  Because the user's config handles taking the function
> from project.el and putting it in the variable from uniquify.el.

Ease of implementation is an important factor, but the ease of using
Emacs takes precedence.  So saying that some implementation
alternative should be taken only because it is easier is not a winning
argument.

And I don't really understand how this will work in practice: if the
user-defined function is supposed to be in effect only for buffers
under project.el, how is this different from using symbols?

> >> > If the symbolic values are specific to project, simply let-bind
> >> > uniquify-dirname-transform to the value of the appropriate project.el
> >> > defcustom when project.el calls uniquify.
> >> 
> >> These customizations are in effect all the time, not just when the user
> >> is calling a project.el command.  e.g. rename-buffer triggers uniquify.
> >
> > Then you can set the buffer-local value of uniquify-dirname-transform
> > in the project.el buffers.  Would that solve the problem?
> 
> The buffers it should affect are all file-visiting buffers.  project.el
> doesn't currently have any code which runs for every new buffer.  I
> guess we've considered adding that, but I'm not sure this is a good
> reason...

I'm sure this can be resolved, quite easily, actually.  So I don't
think I understand what you are trying to say here.

> > default-directory of a file-visiting buffer doesn't change.
> 
> I don't think that's true.  If I open ~/.emacs.d/init.el then (cd "/")
> then default-directory in that file-visiting buffer is / instead of
> ~/.emacs.d

You can shoot yourself in the foot if you like, but why would you?

Anyway, are we still trying to reach some goal, or are we just trying
to counter each other's arguments?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#62621; Package emacs. (Fri, 14 Jul 2023 14:15:01 GMT) Full text and rfc822 format available.

Message #44 received at 62621 <at> debbugs.gnu.org (full text, mbox):

From: Spencer Baugh <sbaugh <at> janestreet.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: sbaugh <at> catern.com, 62621 <at> debbugs.gnu.org
Subject: Re: bug#62621: 29.0.60; uniquify can't make buffers unique based on
 things other than filename
Date: Fri, 14 Jul 2023 10:14:39 -0400
Eli Zaretskii <eliz <at> gnu.org> writes:

>> From: Spencer Baugh <sbaugh <at> janestreet.com>
>> Cc: sbaugh <at> catern.com,  62621 <at> debbugs.gnu.org
>> Date: Fri, 14 Jul 2023 08:46:00 -0400
>> 
>> 
>> Eli Zaretskii <eliz <at> gnu.org> writes:
>> 
>> >> Here's concretely the diff I would apply.  This makes uniquify.el mention a
>> >> function from project.el.  Is that OK?
>> >
>> > No.
>> 
>> I figured.  So now you see the issue with the symbolic approach.
>
> No, I don't.  Not a significant problem, anyway, and not why it's
> different from using a function.
>
>> If the defcustom just takes a function, though, that solves the
>> dependency issue.  Because the user's config handles taking the function
>> from project.el and putting it in the variable from uniquify.el.
>
> Ease of implementation is an important factor, but the ease of using
> Emacs takes precedence.  So saying that some implementation
> alternative should be taken only because it is easier is not a winning
> argument.

I agree.

> And I don't really understand how this will work in practice: if the
> user-defined function is supposed to be in effect only for buffers
> under project.el,

The transform is supposed to be in effect for all buffers, and
internally it runs some code to decide whether to change the buffer
name.

> how is this different from using symbols?

I can't contrast that to "using symbols" because I just don't understand
what you mean by "using symbols".

Is the diff I posted what you mean by "using symbols", or did you mean
something else?

>> >> > If the symbolic values are specific to project, simply let-bind
>> >> > uniquify-dirname-transform to the value of the appropriate project.el
>> >> > defcustom when project.el calls uniquify.
>> >> 
>> >> These customizations are in effect all the time, not just when the user
>> >> is calling a project.el command.  e.g. rename-buffer triggers uniquify.
>> >
>> > Then you can set the buffer-local value of uniquify-dirname-transform
>> > in the project.el buffers.  Would that solve the problem?
>> 
>> The buffers it should affect are all file-visiting buffers.  project.el
>> doesn't currently have any code which runs for every new buffer.  I
>> guess we've considered adding that, but I'm not sure this is a good
>> reason...
>
> I'm sure this can be resolved, quite easily, actually.  So I don't
> think I understand what you are trying to say here.
>
>> > default-directory of a file-visiting buffer doesn't change.
>> 
>> I don't think that's true.  If I open ~/.emacs.d/init.el then (cd "/")
>> then default-directory in that file-visiting buffer is / instead of
>> ~/.emacs.d
>
> You can shoot yourself in the foot if you like, but why would you?

I agree this is fairly useless but (info "(emacs) File Names") at least
mentions using M-x cd in the context of file-visiting buffers:

   When you visit a file, Emacs sets ‘default-directory’ in the visiting
buffer to the directory of its file.  When you create a new buffer that
is not visiting a file, via a command like ‘C-x b’, its default
directory is usually copied from the buffer that was current at the time
(*note Select Buffer::).  You can use the command ‘M-x pwd’ to see the
value of ‘default-directory’ in the current buffer.  The command ‘M-x
cd’ prompts for a directory’s name, and sets the buffer’s
‘default-directory’ to that directory (doing this does not change the
buffer’s file name, if any).

Nevertheless, I would be happy to make uniquify use default-directory
instead, it will change how this behaves but it's probably OK.  I can do
that in a separate bug.

> Anyway, are we still trying to reach some goal, or are we just trying
> to counter each other's arguments?

I'm not trying to counter your arguments, I just don't understand what
you mean by "using symbols".  I'm happy to have the configuration be
symbol-based but you said "No." to the approach I posted and I don't
know what other approach you are envisioning.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#62621; Package emacs. (Fri, 14 Jul 2023 16:45:02 GMT) Full text and rfc822 format available.

Message #47 received at 62621 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: Spencer Baugh <sbaugh <at> janestreet.com>
Cc: sbaugh <at> catern.com, Eli Zaretskii <eliz <at> gnu.org>, 62621 <at> debbugs.gnu.org
Subject: Re: bug#62621: 29.0.60; uniquify can't make buffers unique based on
 things other than filename
Date: Fri, 14 Jul 2023 19:31:23 +0300
> The fact that uniquify doesn't use default-directory also means it's
> unable to uniquify buffers which aren't visiting files, which can be
> annoying.  For example, if uniquify used default-directory then it could
> uniquify *compilation* buffers for different projects, renaming them
> based on the directory.  But because it can't, every package has to come
> up with their own special buffer-renaming scheme... include project.el.

Why couldn't uniquify use default-directory?  It would be nice to have
such buffer names based on default-directory:

  *compilation*<project-1>
  *compilation*<project-2>




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#62621; Package emacs. (Fri, 14 Jul 2023 17:31:02 GMT) Full text and rfc822 format available.

Message #50 received at 62621 <at> debbugs.gnu.org (full text, mbox):

From: Spencer Baugh <sbaugh <at> catern.com>
To: Juri Linkov <juri <at> linkov.net>
Cc: Spencer Baugh <sbaugh <at> janestreet.com>, Eli Zaretskii <eliz <at> gnu.org>,
 62621 <at> debbugs.gnu.org
Subject: Re: bug#62621: 29.0.60; uniquify can't make buffers unique based on
 things other than filename
Date: Fri, 14 Jul 2023 17:30:31 +0000 (UTC)
[Message part 1 (text/html, inline)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#62621; Package emacs. (Fri, 14 Jul 2023 19:11:02 GMT) Full text and rfc822 format available.

Message #53 received at 62621 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Spencer Baugh <sbaugh <at> janestreet.com>
Cc: sbaugh <at> catern.com, 62621 <at> debbugs.gnu.org
Subject: Re: bug#62621: 29.0.60; uniquify can't make buffers unique based on
 things other than filename
Date: Fri, 14 Jul 2023 22:10:24 +0300
> From: Spencer Baugh <sbaugh <at> janestreet.com>
> Cc: sbaugh <at> catern.com,  62621 <at> debbugs.gnu.org
> Date: Fri, 14 Jul 2023 10:14:39 -0400
> 
> Eli Zaretskii <eliz <at> gnu.org> writes:
> 
> > And I don't really understand how this will work in practice: if the
> > user-defined function is supposed to be in effect only for buffers
> > under project.el,
> 
> The transform is supposed to be in effect for all buffers, and
> internally it runs some code to decide whether to change the buffer
> name.

Still unclear why you thought functions can do what other values
cannot.

> > how is this different from using symbols?
> 
> I can't contrast that to "using symbols" because I just don't understand
> what you mean by "using symbols".

It means the defcustom's value is a symbol, like 'numbered or
'append-directory, not a function.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#62621; Package emacs. (Fri, 14 Jul 2023 19:16:01 GMT) Full text and rfc822 format available.

Message #56 received at 62621 <at> debbugs.gnu.org (full text, mbox):

From: sbaugh <at> catern.com
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: Spencer Baugh <sbaugh <at> janestreet.com>, 62621 <at> debbugs.gnu.org
Subject: Re: bug#62621: 29.0.60; uniquify can't make buffers unique based on
 things other than filename
Date: Fri, 14 Jul 2023 19:15:50 +0000 (UTC)
Eli Zaretskii <eliz <at> gnu.org> writes:

>> From: Spencer Baugh <sbaugh <at> janestreet.com>
>> Cc: sbaugh <at> catern.com,  62621 <at> debbugs.gnu.org
>> Date: Fri, 14 Jul 2023 10:14:39 -0400
>> 
>> Eli Zaretskii <eliz <at> gnu.org> writes:
>> 
>> > And I don't really understand how this will work in practice: if the
>> > user-defined function is supposed to be in effect only for buffers
>> > under project.el,
>> 
>> The transform is supposed to be in effect for all buffers, and
>> internally it runs some code to decide whether to change the buffer
>> name.
>
> Still unclear why you thought functions can do what other values
> cannot.
>
>> > how is this different from using symbols?
>> 
>> I can't contrast that to "using symbols" because I just don't understand
>> what you mean by "using symbols".
>
> It means the defcustom's value is a symbol, like 'numbered or
> 'append-directory, not a function.

Yes.  But how would you implement it so that setting the defcustom to
'project causes the project-uniquify-dirname-transform logic to be used
by uniquify.el, without mentioning project-uniquify-dirname-transform or
other project functions in uniquify.el?




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#62621; Package emacs. (Sat, 15 Jul 2023 05:43:01 GMT) Full text and rfc822 format available.

Message #59 received at 62621 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: sbaugh <at> catern.com
Cc: sbaugh <at> janestreet.com, 62621 <at> debbugs.gnu.org
Subject: Re: bug#62621: 29.0.60; uniquify can't make buffers unique based on
 things other than filename
Date: Sat, 15 Jul 2023 08:42:06 +0300
> From: sbaugh <at> catern.com
> Date: Fri, 14 Jul 2023 19:15:50 +0000 (UTC)
> Cc: Spencer Baugh <sbaugh <at> janestreet.com>, 62621 <at> debbugs.gnu.org
> 
> Eli Zaretskii <eliz <at> gnu.org> writes:
> 
> >> I can't contrast that to "using symbols" because I just don't understand
> >> what you mean by "using symbols".
> >
> > It means the defcustom's value is a symbol, like 'numbered or
> > 'append-directory, not a function.
> 
> Yes.  But how would you implement it so that setting the defcustom to
> 'project causes the project-uniquify-dirname-transform logic to be used
> by uniquify.el, without mentioning project-uniquify-dirname-transform or
> other project functions in uniquify.el?

You can use autoloading, for example.  Or explicitly
(require 'project) when that value is seen.  Or any
number of other solutions we have for such situations.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#62621; Package emacs. (Sat, 15 Jul 2023 06:21:01 GMT) Full text and rfc822 format available.

Message #62 received at 62621 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: sbaugh <at> catern.com, sbaugh <at> janestreet.com
Cc: 62621 <at> debbugs.gnu.org
Subject: Re: bug#62621: 29.0.60;
 uniquify can't make buffers unique based on things other than filename
Date: Sat, 15 Jul 2023 09:20:41 +0300
> Cc: sbaugh <at> janestreet.com, 62621 <at> debbugs.gnu.org
> Date: Sat, 15 Jul 2023 08:42:06 +0300
> From: Eli Zaretskii <eliz <at> gnu.org>
> 
> > From: sbaugh <at> catern.com
> > Date: Fri, 14 Jul 2023 19:15:50 +0000 (UTC)
> > Cc: Spencer Baugh <sbaugh <at> janestreet.com>, 62621 <at> debbugs.gnu.org
> > 
> > Yes.  But how would you implement it so that setting the defcustom to
> > 'project causes the project-uniquify-dirname-transform logic to be used
> > by uniquify.el, without mentioning project-uniquify-dirname-transform or
> > other project functions in uniquify.el?
> 
> You can use autoloading, for example.  Or explicitly
> (require 'project) when that value is seen.  Or any
> number of other solutions we have for such situations.

Or even add a setter to this new defcustom which would set the
uniquify variable to a project-specific function, and you already had
that situation solved, right?

IOW, we have a lot of possible solutions for this kind of problems,
just select one of them.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#62621; Package emacs. (Tue, 18 Jul 2023 00:21:02 GMT) Full text and rfc822 format available.

Message #65 received at 62621 <at> debbugs.gnu.org (full text, mbox):

From: Dmitry Gutov <dmitry <at> gutov.dev>
To: sbaugh <at> catern.com, Eli Zaretskii <eliz <at> gnu.org>
Cc: Spencer Baugh <sbaugh <at> janestreet.com>, 62621 <at> debbugs.gnu.org
Subject: Re: bug#62621: 29.0.60; uniquify can't make buffers unique based on
 things other than filename
Date: Tue, 18 Jul 2023 03:19:54 +0300
On 14/07/2023 22:15, sbaugh <at> catern.com wrote:
>>>> how is this different from using symbols?
>>> I can't contrast that to "using symbols" because I just don't understand
>>> what you mean by "using symbols".
>> It means the defcustom's value is a symbol, like 'numbered or
>> 'append-directory, not a function.
> Yes.  But how would you implement it so that setting the defcustom to
> 'project causes the project-uniquify-dirname-transform logic to be used
> by uniquify.el, without mentioning project-uniquify-dirname-transform or
> other project functions in uniquify.el?

Yeah, that sounds odd to me too. If we allow symbolic values in a 
defcustom, somewhere in the same package there has to be a mapping 
between the symbols and the functions corresponding to them. Which would 
have to refer to a function from project.el in this case.

Of course, we could alternatively have some sort of registry for 
third-party code to jack into upon loading or etc, but that sounds like 
a massive overkill for this case.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#62621; Package emacs. (Tue, 18 Jul 2023 00:35:01 GMT) Full text and rfc822 format available.

Message #68 received at 62621 <at> debbugs.gnu.org (full text, mbox):

From: Dmitry Gutov <dmitry <at> gutov.dev>
To: Eli Zaretskii <eliz <at> gnu.org>, sbaugh <at> catern.com
Cc: sbaugh <at> janestreet.com, 62621 <at> debbugs.gnu.org
Subject: Re: bug#62621: 29.0.60; uniquify can't make buffers unique based on
 things other than filename
Date: Tue, 18 Jul 2023 03:34:06 +0300
On 14/07/2023 09:29, Eli Zaretskii wrote:
> IOW, we should NOT immediately generalize to
> functions only because such generalization could make sense in some
> use cases.

I agree with that statement. When only one or two behaviors can be 
needed or foreseen, there's no hard need to make the option open-ended 
(which it becomes when it can be set to a function).

This case, however, looks more like an exception to my eye. Similar to 
save-some-buffers-default-predicate where extensibility makes sense.

And if you also wanted to avoid a direct reference to project-* in 
uniquify.el, that's another argument in favor of extensibility.

> Repeat after me: Use options whose values are functions
> are hard on our users, because they require them to be Lisp
> programmers.

That doesn't have to be the case. If the defcustom's docstring mentions 
several functions that can be used, and the :type widget includes them 
as well, the user can decide to switch to any of them without writing 
any Lisp (or having to understand the implementations).

Examples: the aforementioned save-some-buffers-default-predicate, or 
project-prompter, or xref-history-storage, and so on.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#62621; Package emacs. (Tue, 18 Jul 2023 01:38:02 GMT) Full text and rfc822 format available.

Message #71 received at 62621 <at> debbugs.gnu.org (full text, mbox):

From: Dmitry Gutov <dmitry <at> gutov.dev>
To: Spencer Baugh <sbaugh <at> janestreet.com>, Eli Zaretskii <eliz <at> gnu.org>
Cc: sbaugh <at> catern.com, 62621 <at> debbugs.gnu.org
Subject: Re: bug#62621: 29.0.60; uniquify can't make buffers unique based on
 things other than filename
Date: Tue, 18 Jul 2023 04:37:41 +0300
On 14/07/2023 15:46, Spencer Baugh wrote:
>>>> If the symbolic values are specific to project, simply let-bind
>>>> uniquify-dirname-transform to the value of the appropriate project.el
>>>> defcustom when project.el calls uniquify.
>>> These customizations are in effect all the time, not just when the user
>>> is calling a project.el command.  e.g. rename-buffer triggers uniquify.
>> Then you can set the buffer-local value of uniquify-dirname-transform
>> in the project.el buffers.  Would that solve the problem?
> The buffers it should affect are all file-visiting buffers.  project.el
> doesn't currently have any code which runs for every new buffer.  I
> guess we've considered adding that, but I'm not sure this is a good
> reason...

I'm not sure every project.el user will want this particular behavior 
anyway. project-switch-buffer is handy, but personally, I still most 
often use 'C-x b'.

But there definitely is demand for this option, as evidenced by the 
previously mentioned bug#59502, as well as this (unexpectedly, 
years-old) thread: 
https://lists.gnu.org/archive/html/emacs-devel/2021-03/msg00083.html

Speaking of those, do you think it would be feasible to also offer these 
tweaks (as options, or for particular buffers):

- Make the presence of the buffer name mandatory. As shown in the 
examples in bug#59502, it could be useful to always see in buffers like 
*eshell* produced by project-eshell. Or project-vc-dir, for example.

- Hide the parent directory from the uniquification logic (only keeping 
the project name). So that, for example, if I call 'M-x project-eshell' 
and then 'C-u M-x project-eshell', the generated buffer names would not 
try to use the parent segment to uniquify, and just stay as 
<project-name>/*eshell* and <project-name>/*eshell-2*. There is 
currently some bespoke logic for naming these particular buffers, but if 
we could move to uniquify (and obey its custom vars), that would 
probably be an improvement.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#62621; Package emacs. (Tue, 18 Jul 2023 11:08:02 GMT) Full text and rfc822 format available.

Message #74 received at 62621 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Dmitry Gutov <dmitry <at> gutov.dev>
Cc: sbaugh <at> catern.com, 62621 <at> debbugs.gnu.org, sbaugh <at> janestreet.com
Subject: Re: bug#62621: 29.0.60; uniquify can't make buffers unique based on
 things other than filename
Date: Tue, 18 Jul 2023 14:07:29 +0300
> Date: Tue, 18 Jul 2023 03:34:06 +0300
> Cc: sbaugh <at> janestreet.com, 62621 <at> debbugs.gnu.org
> From: Dmitry Gutov <dmitry <at> gutov.dev>
> 
> > Repeat after me: Use options whose values are functions
> > are hard on our users, because they require them to be Lisp
> > programmers.
> 
> That doesn't have to be the case. If the defcustom's docstring mentions 
> several functions that can be used, and the :type widget includes them 
> as well, the user can decide to switch to any of them without writing 
> any Lisp (or having to understand the implementations).

But that was not so in this particular case.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#62621; Package emacs. (Tue, 18 Jul 2023 16:04:01 GMT) Full text and rfc822 format available.

Message #77 received at 62621 <at> debbugs.gnu.org (full text, mbox):

From: Spencer Baugh <sbaugh <at> janestreet.com>
To: Dmitry Gutov <dmitry <at> gutov.dev>
Cc: sbaugh <at> catern.com, Eli Zaretskii <eliz <at> gnu.org>, 62621 <at> debbugs.gnu.org
Subject: Re: bug#62621: 29.0.60; uniquify can't make buffers unique based on
 things other than filename
Date: Tue, 18 Jul 2023 12:03:26 -0400
Dmitry Gutov <dmitry <at> gutov.dev> writes:

> On 14/07/2023 15:46, Spencer Baugh wrote:
>>>>> If the symbolic values are specific to project, simply let-bind
>>>>> uniquify-dirname-transform to the value of the appropriate project.el
>>>>> defcustom when project.el calls uniquify.
>>>> These customizations are in effect all the time, not just when the user
>>>> is calling a project.el command.  e.g. rename-buffer triggers uniquify.
>>> Then you can set the buffer-local value of uniquify-dirname-transform
>>> in the project.el buffers.  Would that solve the problem?
>> The buffers it should affect are all file-visiting buffers.  project.el
>> doesn't currently have any code which runs for every new buffer.  I
>> guess we've considered adding that, but I'm not sure this is a good
>> reason...
>
> I'm not sure every project.el user will want this particular behavior
> anyway. project-switch-buffer is handy, but personally, I still most
> often use 'C-x b'.
>
> But there definitely is demand for this option, as evidenced by the
> previously mentioned bug#59502, as well as this (unexpectedly,
> years-old) thread:
> https://lists.gnu.org/archive/html/emacs-devel/2021-03/msg00083.html
>
> Speaking of those, do you think it would be feasible to also offer
> these tweaks (as options, or for particular buffers):
>
> - Make the presence of the buffer name mandatory. As shown in the
>   examples in bug#59502, it could be useful to always see in buffers
>   like *eshell* produced by project-eshell. Or project-vc-dir, for
>  example.

(I assume you mean "make the presence of the project name mandatory")

I think there is a good solution to this which was not mentioned in
bug#59502 only add the project name (or dirname or whatever) to the
buffer when that's necessary to give the buffer a unique name.  That
reduces overhead when working only with one project, and neatly fits in
to how uniquify already works for file-visiting buffers.

To do this, I think we'd need to change commands to use a function other
than get-buffer-create when accessing e.g. *xref* or *eshell*, which
like create-file-buffer gets a chance to uniquify the buffer name.

It's a bit tricky though: we want commands to access and reuse existing
a project-specific buffer if there is one, but commands doesn't know the
name of that buffer so can't find it that way.  find-file has solved
this same problem ages ago, of reusing an existing buffer if we
find-file a buffer-file-name which is already open.  I think we may need
something similar for non-file-visiting buffers.

Maybe some kind of mechanism to find a buffer with basename "*eshell*"
whose default-directory contains our current default-directory?  Kind of
a "locate-dominating-buffer"?

> - Hide the parent directory from the uniquification logic (only
>   keeping the project name). So that, for example, if I call 'M-x
>   project-eshell' and then 'C-u M-x project-eshell', the generated
>   buffer names would not try to use the parent segment to uniquify,
>   and just stay as <project-name>/*eshell* and
>   <project-name>/*eshell-2*. There is currently some bespoke logic for
>   naming these particular buffers, but if we could move to uniquify
>   (and obey its custom vars), that would probably be an improvement.

Hm, so if two *eshell* buffers are in the same project, they should
first be uniquified from other *eshell* buffers by adding the project
name, and then uniquified from each other by adding numbers to the end
of the buffer name.

I think I can implement this pretty easily in uniquify.el: if a set of
conflicting buffers all have the same dirname, then resolve the conflict
by adding numbers to the end.

(Actually I was a bit surprised to realize that uniquify wasn't doing
this already, but I guess it's because it previously has only worked for
file-visiting buffers, which as I mentioned above are kept unique by
buffer-file-name, so there can't be conflicts between two buffer names
if you include their entire buffer-file-name in the buffer name.)


---

Incidentally, another feature which I've been thinking about at the
intersection of project.el and uniquify.el: We could rerun uniquify on
project-buffers in a mode where it just outputs sufficiently unique
names without actually renaming the buffers, and then use that in
project-switch-to-buffer.  So then when picking the buffer, you are
picking from buffer names which are unique *in that specific project*.
It's otherwise kind of annoying to me that project-switch-to-buffer
includes a bunch of long disambiguating paths in the buffer names even
though the buffer names aren't actually ambiguous in that command.

Does that sound interesting?  I, like you, usually use C-x b.  But I
think this feature would make C-x p b much nicer and competitive with
C-x b.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#62621; Package emacs. (Tue, 18 Jul 2023 17:56:02 GMT) Full text and rfc822 format available.

Message #80 received at 62621 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: Dmitry Gutov <dmitry <at> gutov.dev>
Cc: Spencer Baugh <sbaugh <at> janestreet.com>, Eli Zaretskii <eliz <at> gnu.org>,
 62621 <at> debbugs.gnu.org, sbaugh <at> catern.com
Subject: Re: bug#62621: 29.0.60; uniquify can't make buffers unique based on
 things other than filename
Date: Tue, 18 Jul 2023 20:51:19 +0300
> - Hide the parent directory from the uniquification logic (only keeping the
>   project name). So that, for example, if I call 'M-x project-eshell' and
>   then 'C-u M-x project-eshell', the generated buffer names would not try
>   to use the parent segment to uniquify, and just stay as
>   <project-name>/*eshell* and <project-name>/*eshell-2*.

Often a project name in the buffer name is needed not for purposes
of generating a unique buffer name, but for permanent indication
which project a file/non-file buffer belongs to.

In such cases indeed a parent directory makes no sense,
but still uniquification is required for buffers inside
the same project, e.g.

  <project-name>/*eshell*<1>
  <project-name>/*eshell*<2>

So here are 2 styles combined: one for top-level project names
produced by project.el, and another style for the same project
by uniquify.el (in this case 'post-forward-angle-brackets').




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#62621; Package emacs. (Wed, 19 Jul 2023 02:24:01 GMT) Full text and rfc822 format available.

Message #83 received at 62621 <at> debbugs.gnu.org (full text, mbox):

From: Dmitry Gutov <dmitry <at> gutov.dev>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: sbaugh <at> catern.com, 62621 <at> debbugs.gnu.org, sbaugh <at> janestreet.com
Subject: Re: bug#62621: 29.0.60; uniquify can't make buffers unique based on
 things other than filename
Date: Wed, 19 Jul 2023 05:22:56 +0300
On 18/07/2023 14:07, Eli Zaretskii wrote:
>> Date: Tue, 18 Jul 2023 03:34:06 +0300
>> Cc:sbaugh <at> janestreet.com,62621 <at> debbugs.gnu.org
>> From: Dmitry Gutov<dmitry <at> gutov.dev>
>>
>>> Repeat after me: Use options whose values are functions
>>> are hard on our users, because they require them to be Lisp
>>> programmers.
>> That doesn't have to be the case. If the defcustom's docstring mentions
>> several functions that can be used, and the :type widget includes them
>> as well, the user can decide to switch to any of them without writing
>> any Lisp (or having to understand the implementations).
> But that was not so in this particular case.

That's easy to fix, as long as you don't have additional objections to 
that approach.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#62621; Package emacs. (Wed, 19 Jul 2023 02:26:02 GMT) Full text and rfc822 format available.

Message #86 received at 62621 <at> debbugs.gnu.org (full text, mbox):

From: Dmitry Gutov <dmitry <at> gutov.dev>
To: Juri Linkov <juri <at> linkov.net>
Cc: Spencer Baugh <sbaugh <at> janestreet.com>, Eli Zaretskii <eliz <at> gnu.org>,
 62621 <at> debbugs.gnu.org, sbaugh <at> catern.com
Subject: Re: bug#62621: 29.0.60; uniquify can't make buffers unique based on
 things other than filename
Date: Wed, 19 Jul 2023 05:24:58 +0300
On 18/07/2023 20:51, Juri Linkov wrote:
>> - Hide the parent directory from the uniquification logic (only keeping the
>>    project name). So that, for example, if I call 'M-x project-eshell' and
>>    then 'C-u M-x project-eshell', the generated buffer names would not try
>>    to use the parent segment to uniquify, and just stay as
>>    <project-name>/*eshell*  and <project-name>/*eshell-2*.
> Often a project name in the buffer name is needed not for purposes
> of generating a unique buffer name, but for permanent indication
> which project a file/non-file buffer belongs to.

That's what I was thinking of as well. I suppose, the question is, 
though, which place in the code should make that decision, and which one 
should be in change of formatting the buffer's name.

> In such cases indeed a parent directory makes no sense,
> but still uniquification is required for buffers inside
> the same project, e.g.
> 
>    <project-name>/*eshell*<1>
>    <project-name>/*eshell*<2>
> 
> So here are 2 styles combined: one for top-level project names
> produced by project.el, and another style for the same project
> by uniquify.el (in this case 'post-forward-angle-brackets').

...which is a bit untidy at the moment.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#62621; Package emacs. (Wed, 19 Jul 2023 02:48:02 GMT) Full text and rfc822 format available.

Message #89 received at 62621 <at> debbugs.gnu.org (full text, mbox):

From: Dmitry Gutov <dmitry <at> gutov.dev>
To: Spencer Baugh <sbaugh <at> janestreet.com>
Cc: sbaugh <at> catern.com, Eli Zaretskii <eliz <at> gnu.org>, 62621 <at> debbugs.gnu.org
Subject: Re: bug#62621: 29.0.60; uniquify can't make buffers unique based on
 things other than filename
Date: Wed, 19 Jul 2023 05:47:45 +0300
On 18/07/2023 19:03, Spencer Baugh wrote:

>> Speaking of those, do you think it would be feasible to also offer
>> these tweaks (as options, or for particular buffers):
>>
>> - Make the presence of the buffer name mandatory. As shown in the
>>    examples in bug#59502, it could be useful to always see in buffers
>>    like *eshell* produced by project-eshell. Or project-vc-dir, for
>>   example.
> 
> (I assume you mean "make the presence of the project name mandatory")

Ah yes, sorry.

> I think there is a good solution to this which was not mentioned in
> bug#59502 only add the project name (or dirname or whatever) to the
> buffer when that's necessary to give the buffer a unique name.> That
> reduces overhead when working only with one project, and neatly fits in
> to how uniquify already works for file-visiting buffers.

We never talked about such an option. It's a little less obvious, but 
might indeed fit in more smoothly for both project and non-project use 
cases (and I also often work on just one project).

Something to consider, though: if I am in a project A, and a project B 
has an eshell buffer and project A does not, 'C-x b' won't tell me that 
that eshell is in project B. But ideally, it should, I suppose.

This might have been the original reasoning to simply include the 
project name in those buffers' names.

> To do this, I think we'd need to change commands to use a function other
> than get-buffer-create when accessing e.g. *xref* or *eshell*, which
> like create-file-buffer gets a chance to uniquify the buffer name.
> 
> It's a bit tricky though: we want commands to access and reuse existing
> a project-specific buffer if there is one, but commands doesn't know the
> name of that buffer so can't find it that way.  find-file has solved
> this same problem ages ago, of reusing an existing buffer if we
> find-file a buffer-file-name which is already open.  I think we may need
> something similar for non-file-visiting buffers.
> 
> Maybe some kind of mechanism to find a buffer with basename "*eshell*"
> whose default-directory contains our current default-directory?  Kind of
> a "locate-dominating-buffer"?

Well... a straightforward way would be to have some public function in 
uniquify which, given a set of name components, would construct the 
supposed buffer name and see whether one exists. And/or return the 
newest one that matches (if there are several, sequentially enumerated). 
But I suppose uniquify doesn't have to be enabled in every session. So a 
higher-level function could be added to the core. It's hard to decouple 
this idea from using uniquify, though, so I'm not sure what we'd call 
it. Alternatively, we'd just check every time whether uniquify is on, 
and have two different code paths for yes and no.

>> - Hide the parent directory from the uniquification logic (only
>>    keeping the project name). So that, for example, if I call 'M-x
>>    project-eshell' and then 'C-u M-x project-eshell', the generated
>>    buffer names would not try to use the parent segment to uniquify,
>>    and just stay as <project-name>/*eshell* and
>>    <project-name>/*eshell-2*. There is currently some bespoke logic for
>>    naming these particular buffers, but if we could move to uniquify
>>    (and obey its custom vars), that would probably be an improvement.
> 
> Hm, so if two *eshell* buffers are in the same project, they should
> first be uniquified from other *eshell* buffers by adding the project
> name, and then uniquified from each other by adding numbers to the end
> of the buffer name.

I wonder how that's going to play with existing user expectations. Like, 
if there are no projects, then a regular parent directory name will be 
used, right? And currently eshell buffer names don't include that at 
all. But maybe they should?..

Anyway, if the new behavior is opt-in, there won't be a cause for complaint.

> I think I can implement this pretty easily in uniquify.el: if a set of
> conflicting buffers all have the same dirname, then resolve the conflict
> by adding numbers to the end.

Yes, I suppose if directory names are equal, it doesn't make sense to 
prepend further name components -- a number makes more sense.

> (Actually I was a bit surprised to realize that uniquify wasn't doing
> this already, but I guess it's because it previously has only worked for
> file-visiting buffers, which as I mentioned above are kept unique by
> buffer-file-name, so there can't be conflicts between two buffer names
> if you include their entire buffer-file-name in the buffer name.)

True enough.

> Incidentally, another feature which I've been thinking about at the
> intersection of project.el and uniquify.el: We could rerun uniquify on
> project-buffers in a mode where it just outputs sufficiently unique
> names without actually renaming the buffers, and then use that in
> project-switch-to-buffer.  So then when picking the buffer, you are
> picking from buffer names which are unique *in that specific project*.
> It's otherwise kind of annoying to me that project-switch-to-buffer
> includes a bunch of long disambiguating paths in the buffer names even
> though the buffer names aren't actually ambiguous in that command.
> 
> Does that sound interesting?  I, like you, usually use C-x b.  But I
> think this feature would make C-x p b much nicer and competitive with
> C-x b.

That does sound interesting! And actually, when initially reading a 
message from this thread, I thought it was about something like that.

It could be implemented by altering the buffers' completion table, I 
suppose. But I'm not sure how much of uniquify's code could be reused 
there. Or the performance characteristics of re-running uniquification 
every time a buffer name is read.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#62621; Package emacs. (Wed, 19 Jul 2023 06:58:02 GMT) Full text and rfc822 format available.

Message #92 received at 62621 <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: Dmitry Gutov <dmitry <at> gutov.dev>
Cc: Spencer Baugh <sbaugh <at> janestreet.com>, Eli Zaretskii <eliz <at> gnu.org>,
 62621 <at> debbugs.gnu.org, sbaugh <at> catern.com
Subject: Re: bug#62621: 29.0.60; uniquify can't make buffers unique based on
 things other than filename
Date: Wed, 19 Jul 2023 09:56:55 +0300
>> Incidentally, another feature which I've been thinking about at the
>> intersection of project.el and uniquify.el: We could rerun uniquify on
>> project-buffers in a mode where it just outputs sufficiently unique
>> names without actually renaming the buffers, and then use that in
>> project-switch-to-buffer.  So then when picking the buffer, you are
>> picking from buffer names which are unique *in that specific project*.
>> It's otherwise kind of annoying to me that project-switch-to-buffer
>> includes a bunch of long disambiguating paths in the buffer names even
>> though the buffer names aren't actually ambiguous in that command.
>> Does that sound interesting?  I, like you, usually use C-x b.  But I
>> think this feature would make C-x p b much nicer and competitive with
>> C-x b.
>
> That does sound interesting! And actually, when initially reading a message
> from this thread, I thought it was about something like that.
>
> It could be implemented by altering the buffers' completion table,
> I suppose. But I'm not sure how much of uniquify's code could be reused
> there. Or the performance characteristics of re-running uniquification
> every time a buffer name is read.

It could be implemented the same way as project--read-file-cpd-relative
removes common-parent-directory from absolute filenames.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#62621; Package emacs. (Wed, 19 Jul 2023 12:15:01 GMT) Full text and rfc822 format available.

Message #95 received at 62621 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Dmitry Gutov <dmitry <at> gutov.dev>
Cc: sbaugh <at> catern.com, 62621 <at> debbugs.gnu.org, sbaugh <at> janestreet.com
Subject: Re: bug#62621: 29.0.60; uniquify can't make buffers unique based on
 things other than filename
Date: Wed, 19 Jul 2023 15:14:56 +0300
> Date: Wed, 19 Jul 2023 05:22:56 +0300
> Cc: sbaugh <at> catern.com, sbaugh <at> janestreet.com, 62621 <at> debbugs.gnu.org
> From: Dmitry Gutov <dmitry <at> gutov.dev>
> 
> On 18/07/2023 14:07, Eli Zaretskii wrote:
> >> Date: Tue, 18 Jul 2023 03:34:06 +0300
> >> Cc:sbaugh <at> janestreet.com,62621 <at> debbugs.gnu.org
> >> From: Dmitry Gutov<dmitry <at> gutov.dev>
> >>
> >>> Repeat after me: Use options whose values are functions
> >>> are hard on our users, because they require them to be Lisp
> >>> programmers.
> >> That doesn't have to be the case. If the defcustom's docstring mentions
> >> several functions that can be used, and the :type widget includes them
> >> as well, the user can decide to switch to any of them without writing
> >> any Lisp (or having to understand the implementations).
> > But that was not so in this particular case.
> 
> That's easy to fix, as long as you don't have additional objections to 
> that approach.

I'd need to see the fix first, because I don't think I have a clear
idea of what you have in mind.

(My objections, btw, where very minor and of pure usability nature.
Frankly, I'm surprised such a simple and more-or-less agreed-upon
comment got such a long thread of discussing various loosely-related
issues.)




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#62621; Package emacs. (Wed, 19 Jul 2023 12:32:01 GMT) Full text and rfc822 format available.

Message #98 received at 62621 <at> debbugs.gnu.org (full text, mbox):

From: Spencer Baugh <sbaugh <at> janestreet.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: Dmitry Gutov <dmitry <at> gutov.dev>, 62621 <at> debbugs.gnu.org, sbaugh <at> catern.com
Subject: Re: bug#62621: 29.0.60; uniquify can't make buffers unique based on
 things other than filename
Date: Wed, 19 Jul 2023 08:31:00 -0400
[Message part 1 (text/plain, inline)]
Eli Zaretskii <eliz <at> gnu.org> writes:
>> Date: Wed, 19 Jul 2023 05:22:56 +0300
>> Cc: sbaugh <at> catern.com, sbaugh <at> janestreet.com, 62621 <at> debbugs.gnu.org
>> From: Dmitry Gutov <dmitry <at> gutov.dev>
>> 
>> On 18/07/2023 14:07, Eli Zaretskii wrote:
>> >> Date: Tue, 18 Jul 2023 03:34:06 +0300
>> >> Cc:sbaugh <at> janestreet.com,62621 <at> debbugs.gnu.org
>> >> From: Dmitry Gutov<dmitry <at> gutov.dev>
>> >>
>> >>> Repeat after me: Use options whose values are functions
>> >>> are hard on our users, because they require them to be Lisp
>> >>> programmers.
>> >> That doesn't have to be the case. If the defcustom's docstring mentions
>> >> several functions that can be used, and the :type widget includes them
>> >> as well, the user can decide to switch to any of them without writing
>> >> any Lisp (or having to understand the implementations).
>> > But that was not so in this particular case.
>> 
>> That's easy to fix, as long as you don't have additional objections to 
>> that approach.
>
> I'd need to see the fix first, because I don't think I have a clear
> idea of what you have in mind.
>
> (My objections, btw, where very minor and of pure usability nature.
> Frankly, I'm surprised such a simple and more-or-less agreed-upon
> comment got such a long thread of discussing various loosely-related
> issues.)

Like this:

[0001-Support-transforming-the-dirname-used-by-uniquify.patch (text/x-patch, inline)]
From 7fcbc7499809134104bb5dbde206094d85f48806 Mon Sep 17 00:00:00 2001
From: Spencer Baugh <sbaugh <at> catern.com>
Date: Sun, 9 Jul 2023 22:21:03 -0400
Subject: [PATCH] Support transforming the dirname used by uniquify

By transforming the dirname, we can add additional information to use
during uniquifying.  A basic one: uniquifying buffer names based on
the project name.

* lisp/progmodes/project.el (project-uniquify-dirname-transform): Add.
* lisp/uniquify.el (uniquify-dirname-transform-default)
(uniquify-dirname-transform): Add. (bug#62621)
(uniquify-rationalize-file-buffer-names, uniquify-buffer-file-name):
Use uniquify-dirname-transform.
* test/lisp/uniquify-tests.el (uniquify-home,
uniquify-project-transform): Add tests.
---
 lisp/progmodes/project.el   | 12 ++++++++++++
 lisp/uniquify.el            | 25 ++++++++++++++++++++-----
 test/lisp/uniquify-tests.el | 33 +++++++++++++++++++++++++++++++++
 3 files changed, 65 insertions(+), 5 deletions(-)

diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el
index d482cc24d70..78f9fb410c1 100644
--- a/lisp/progmodes/project.el
+++ b/lisp/progmodes/project.el
@@ -1835,5 +1835,17 @@ project-switch-project
     (let ((project-current-directory-override dir))
       (call-interactively command))))
 
+;;;###autoload
+(defun project-uniquify-dirname-transform (dirname)
+  "Include `project-name' in DIRNAME if in a project."
+  (if-let (proj (project-current nil dirname))
+      (let ((root (project-root proj)))
+        (expand-file-name
+         (file-name-concat
+          (file-name-directory root)
+          (project-name proj)
+          (file-relative-name dirname root))))
+    dirname))
+
 (provide 'project)
 ;;; project.el ends here
diff --git a/lisp/uniquify.el b/lisp/uniquify.el
index d1ca455b673..328f85bf32f 100644
--- a/lisp/uniquify.el
+++ b/lisp/uniquify.el
@@ -168,6 +168,19 @@ uniquify-list-buffers-directory-modes
 That means that when `buffer-file-name' is set to nil, `list-buffers-directory'
 contains the name of the directory which the buffer is visiting.")
 
+(defcustom uniquify-dirname-transform #'identity
+  "Function to transform buffer's directory for uniquifying its name.
+
+It takes a single argument: the directory of the buffer.  It
+should return a string filename (which does not need to actually
+exist in the filesystem) to use for uniquifying the buffer name."
+  :type '(choice (function-item :tag "Don't change the dirname" identity)
+                 (function-item :tag "Include project name in dirname"
+                                #'project-uniquify-dirname-transform)
+                 function)
+  :version "30.1"
+  :group 'uniquify)
+
 ;;; Utilities
 
 ;; uniquify-fix-list data structure
@@ -209,7 +222,8 @@ uniquify-rationalize-file-buffer-names
   ;; this buffer.
   (with-current-buffer newbuf (setq uniquify-managed nil))
   (when dirname
-    (setq dirname (expand-file-name (directory-file-name dirname)))
+    (setq dirname (funcall uniquify-dirname-transform
+                           (expand-file-name (directory-file-name dirname))))
     (let ((fix-list (list (uniquify-make-item base dirname newbuf
                                               nil)))
 	  items)
@@ -268,10 +282,11 @@ uniquify-buffer-file-name
 	       (if (memq major-mode uniquify-list-buffers-directory-modes)
 		   list-buffers-directory))))
       (when filename
-	(directory-file-name
-	 (file-name-directory
-	  (expand-file-name
-	   (directory-file-name filename))))))))
+	 (funcall uniquify-dirname-transform
+	          (directory-file-name
+	          (file-name-directory
+	           (expand-file-name
+	            (directory-file-name filename)))))))))
 
 (defun uniquify-rerationalize-w/o-cb (fix-list)
   "Re-rationalize the buffers in FIX-LIST, but ignoring `current-buffer'."
diff --git a/test/lisp/uniquify-tests.el b/test/lisp/uniquify-tests.el
index abd61fa3504..e533c4b644c 100644
--- a/test/lisp/uniquify-tests.el
+++ b/test/lisp/uniquify-tests.el
@@ -88,6 +88,21 @@ uniquify-dirs
                        '("a/dir/" "b/dir/")))
         (mapc #'kill-buffer bufs)))))
 
+(ert-deftest uniquify-home ()
+  "uniquify works, albeit confusingly, in the presence of directories named \"~\""
+  (let (bufs)
+    (save-excursion
+      (push (find-file-noselect "~") bufs)
+      (push (find-file-noselect "./~") bufs)
+      (should (equal (mapcar #'buffer-name bufs)
+                     '("~<test>" "~<>")))
+      (push (find-file-noselect "~/foo") bufs)
+      (push (find-file-noselect "./~/foo") bufs)
+      (should (equal (mapcar #'buffer-name bufs)
+                     '("foo<~>" "foo</nonexistent>" "~<test>" "~<>")))
+      (while bufs
+        (kill-buffer (pop bufs))))))
+
 (ert-deftest uniquify-rename-to-dir ()
   "Giving a buffer a name which matches a directory doesn't rename the buffer"
   (let ((uniquify-buffer-name-style 'forward)
@@ -125,5 +140,23 @@ uniquify-space-prefix
     (should (equal (buffer-name) "| foo"))
     (kill-buffer)))
 
+(require 'project)
+(ert-deftest uniquify-project-transform ()
+  "`project-uniquify-dirname-transform' works"
+  (let ((uniquify-dirname-transform #'project-uniquify-dirname-transform)
+        (project-vc-name "foo1/bar")
+        bufs)
+    (save-excursion
+      (should (file-exists-p "../README"))
+      (push (find-file-noselect "../README") bufs)
+      (push (find-file-noselect "other/README") bufs)
+      (should (equal (mapcar #'buffer-name bufs)
+                     '("README<other>" "README<bar>")))
+      (push (find-file-noselect "foo2/bar/README") bufs)
+      (should (equal (mapcar #'buffer-name bufs)
+                     '("README<foo2/bar>" "README<other>" "README<foo1/bar>")))
+      (while bufs
+        (kill-buffer (pop bufs))))))
+
 (provide 'uniquify-tests)
 ;;; uniquify-tests.el ends here
-- 
2.39.3


Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#62621; Package emacs. (Wed, 19 Jul 2023 13:26:02 GMT) Full text and rfc822 format available.

Message #101 received at 62621 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Spencer Baugh <sbaugh <at> janestreet.com>
Cc: dmitry <at> gutov.dev, 62621 <at> debbugs.gnu.org, sbaugh <at> catern.com
Subject: Re: bug#62621: 29.0.60; uniquify can't make buffers unique based on
 things other than filename
Date: Wed, 19 Jul 2023 16:25:52 +0300
> From: Spencer Baugh <sbaugh <at> janestreet.com>
> Cc: Dmitry Gutov <dmitry <at> gutov.dev>,  sbaugh <at> catern.com,  62621 <at> debbugs.gnu.org
> Date: Wed, 19 Jul 2023 08:31:00 -0400
> 
> >> >>> Repeat after me: Use options whose values are functions
> >> >>> are hard on our users, because they require them to be Lisp
> >> >>> programmers.
> >> >> That doesn't have to be the case. If the defcustom's docstring mentions
> >> >> several functions that can be used, and the :type widget includes them
> >> >> as well, the user can decide to switch to any of them without writing
> >> >> any Lisp (or having to understand the implementations).
> >> > But that was not so in this particular case.
> >> 
> >> That's easy to fix, as long as you don't have additional objections to 
> >> that approach.
> >
> > I'd need to see the fix first, because I don't think I have a clear
> > idea of what you have in mind.
> >
> > (My objections, btw, where very minor and of pure usability nature.
> > Frankly, I'm surprised such a simple and more-or-less agreed-upon
> > comment got such a long thread of discussing various loosely-related
> > issues.)
> 
> Like this:

Thanks, but it still falls short of what Dmitry described above: the
doc string doesn't "mention several functions that can be used".

> +(defcustom uniquify-dirname-transform #'identity
> +  "Function to transform buffer's directory for uniquifying its name.
> +
> +It takes a single argument: the directory of the buffer.  It
> +should return a string filename (which does not need to actually
> +exist in the filesystem) to use for uniquifying the buffer name."

Please read this carefully and try to put yourself in the shoes of a
user who needs to make sense out of this description.  The immediate
question I had is what does "transforming a buffer's directory" have
to do with "uniquifying the buffer name"?  Uniquifying a buffer's name
is not about its directory, at least not in general.  IOW, the
starting point of this description is too "inside" the implementation.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#62621; Package emacs. (Fri, 21 Jul 2023 13:35:01 GMT) Full text and rfc822 format available.

Message #104 received at 62621 <at> debbugs.gnu.org (full text, mbox):

From: Spencer Baugh <sbaugh <at> janestreet.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: dmitry <at> gutov.dev, 62621 <at> debbugs.gnu.org, sbaugh <at> catern.com
Subject: Re: bug#62621: 29.0.60; uniquify can't make buffers unique based on
 things other than filename
Date: Fri, 21 Jul 2023 09:34:28 -0400
[Message part 1 (text/plain, inline)]
Eli Zaretskii <eliz <at> gnu.org> writes:

>> From: Spencer Baugh <sbaugh <at> janestreet.com>
>> Cc: Dmitry Gutov <dmitry <at> gutov.dev>,  sbaugh <at> catern.com,  62621 <at> debbugs.gnu.org
>> Date: Wed, 19 Jul 2023 08:31:00 -0400
>> 
>> >> >>> Repeat after me: Use options whose values are functions
>> >> >>> are hard on our users, because they require them to be Lisp
>> >> >>> programmers.
>> >> >> That doesn't have to be the case. If the defcustom's docstring mentions
>> >> >> several functions that can be used, and the :type widget includes them
>> >> >> as well, the user can decide to switch to any of them without writing
>> >> >> any Lisp (or having to understand the implementations).
>> >> > But that was not so in this particular case.
>> >> 
>> >> That's easy to fix, as long as you don't have additional objections to 
>> >> that approach.
>> >
>> > I'd need to see the fix first, because I don't think I have a clear
>> > idea of what you have in mind.
>> >
>> > (My objections, btw, where very minor and of pure usability nature.
>> > Frankly, I'm surprised such a simple and more-or-less agreed-upon
>> > comment got such a long thread of discussing various loosely-related
>> > issues.)
>> 
>> Like this:
>
> Thanks, but it still falls short of what Dmitry described above: the
> doc string doesn't "mention several functions that can be used".
>
>> +(defcustom uniquify-dirname-transform #'identity
>> +  "Function to transform buffer's directory for uniquifying its name.
>> +
>> +It takes a single argument: the directory of the buffer.  It
>> +should return a string filename (which does not need to actually
>> +exist in the filesystem) to use for uniquifying the buffer name."
>
> Please read this carefully and try to put yourself in the shoes of a
> user who needs to make sense out of this description.  The immediate
> question I had is what does "transforming a buffer's directory" have
> to do with "uniquifying the buffer name"?  Uniquifying a buffer's name
> is not about its directory, at least not in general.  IOW, the
> starting point of this description is too "inside" the implementation.

OK, how about this?

[0001-Support-transforming-the-dirname-used-by-uniquify.patch (text/x-patch, inline)]
From d5d909040b04bd8d6265d5f19eb3610b6d3d87d8 Mon Sep 17 00:00:00 2001
From: Spencer Baugh <sbaugh <at> catern.com>
Date: Sun, 9 Jul 2023 22:21:03 -0400
Subject: [PATCH] Support transforming the dirname used by uniquify

By transforming the dirname, we can add additional information to use
during uniquifying.  A basic one: uniquifying buffer names based on
the project name.

* lisp/progmodes/project.el (project-uniquify-dirname-transform): Add.
* lisp/uniquify.el (uniquify-dirname-transform-default)
(uniquify-dirname-transform): Add. (bug#62621)
(uniquify-rationalize-file-buffer-names, uniquify-buffer-file-name):
Use uniquify-dirname-transform.
* test/lisp/uniquify-tests.el (uniquify-home,
uniquify-project-transform): Add tests.
---
 lisp/progmodes/project.el   | 12 ++++++++++++
 lisp/uniquify.el            | 38 ++++++++++++++++++++++++++++++++-----
 test/lisp/uniquify-tests.el | 33 ++++++++++++++++++++++++++++++++
 3 files changed, 78 insertions(+), 5 deletions(-)

diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el
index d482cc24d70..78f9fb410c1 100644
--- a/lisp/progmodes/project.el
+++ b/lisp/progmodes/project.el
@@ -1835,5 +1835,17 @@ project-switch-project
     (let ((project-current-directory-override dir))
       (call-interactively command))))
 
+;;;###autoload
+(defun project-uniquify-dirname-transform (dirname)
+  "Include `project-name' in DIRNAME if in a project."
+  (if-let (proj (project-current nil dirname))
+      (let ((root (project-root proj)))
+        (expand-file-name
+         (file-name-concat
+          (file-name-directory root)
+          (project-name proj)
+          (file-relative-name dirname root))))
+    dirname))
+
 (provide 'project)
 ;;; project.el ends here
diff --git a/lisp/uniquify.el b/lisp/uniquify.el
index d1ca455b673..eec5aefc803 100644
--- a/lisp/uniquify.el
+++ b/lisp/uniquify.el
@@ -168,6 +168,32 @@ uniquify-list-buffers-directory-modes
 That means that when `buffer-file-name' is set to nil, `list-buffers-directory'
 contains the name of the directory which the buffer is visiting.")
 
+(defcustom uniquify-dirname-transform #'identity
+  "Function to transform buffer's directory for uniquifying its name.
+
+When `uniquify-buffer-name-style' is non-nil, if a buffer's name
+would be the same as some other buffer, then components from the
+buffer's directory name are added to the buffer's name until the
+buffer's name is unique.
+
+By default, uniquifying only adds components from the buffer's
+directory name.  If you set this variable to
+`project-uniquify-dirname-transform', slash-separated components
+from `project-name' will also be added to the buffer's name when
+buffers from two different projects would otherwise have the same
+name.
+
+To include your own custom details in the unique buffer name, set
+this variable to a function taking a single argument, the
+buffer's directory, and returning a file name (which does not
+need to actually exist in the filesystem) to use components from."
+  :type '(choice (function-item :tag "Don't change the dirname" identity)
+                 (function-item :tag "Include project name in dirname"
+                                #'project-uniquify-dirname-transform)
+                 function)
+  :version "30.1"
+  :group 'uniquify)
+
 ;;; Utilities
 
 ;; uniquify-fix-list data structure
@@ -209,7 +235,8 @@ uniquify-rationalize-file-buffer-names
   ;; this buffer.
   (with-current-buffer newbuf (setq uniquify-managed nil))
   (when dirname
-    (setq dirname (expand-file-name (directory-file-name dirname)))
+    (setq dirname (funcall uniquify-dirname-transform
+                           (expand-file-name (directory-file-name dirname))))
     (let ((fix-list (list (uniquify-make-item base dirname newbuf
                                               nil)))
 	  items)
@@ -268,10 +295,11 @@ uniquify-buffer-file-name
 	       (if (memq major-mode uniquify-list-buffers-directory-modes)
 		   list-buffers-directory))))
       (when filename
-	(directory-file-name
-	 (file-name-directory
-	  (expand-file-name
-	   (directory-file-name filename))))))))
+	 (funcall uniquify-dirname-transform
+	          (directory-file-name
+	          (file-name-directory
+	           (expand-file-name
+	            (directory-file-name filename)))))))))
 
 (defun uniquify-rerationalize-w/o-cb (fix-list)
   "Re-rationalize the buffers in FIX-LIST, but ignoring `current-buffer'."
diff --git a/test/lisp/uniquify-tests.el b/test/lisp/uniquify-tests.el
index abd61fa3504..e533c4b644c 100644
--- a/test/lisp/uniquify-tests.el
+++ b/test/lisp/uniquify-tests.el
@@ -88,6 +88,21 @@ uniquify-dirs
                        '("a/dir/" "b/dir/")))
         (mapc #'kill-buffer bufs)))))
 
+(ert-deftest uniquify-home ()
+  "uniquify works, albeit confusingly, in the presence of directories named \"~\""
+  (let (bufs)
+    (save-excursion
+      (push (find-file-noselect "~") bufs)
+      (push (find-file-noselect "./~") bufs)
+      (should (equal (mapcar #'buffer-name bufs)
+                     '("~<test>" "~<>")))
+      (push (find-file-noselect "~/foo") bufs)
+      (push (find-file-noselect "./~/foo") bufs)
+      (should (equal (mapcar #'buffer-name bufs)
+                     '("foo<~>" "foo</nonexistent>" "~<test>" "~<>")))
+      (while bufs
+        (kill-buffer (pop bufs))))))
+
 (ert-deftest uniquify-rename-to-dir ()
   "Giving a buffer a name which matches a directory doesn't rename the buffer"
   (let ((uniquify-buffer-name-style 'forward)
@@ -125,5 +140,23 @@ uniquify-space-prefix
     (should (equal (buffer-name) "| foo"))
     (kill-buffer)))
 
+(require 'project)
+(ert-deftest uniquify-project-transform ()
+  "`project-uniquify-dirname-transform' works"
+  (let ((uniquify-dirname-transform #'project-uniquify-dirname-transform)
+        (project-vc-name "foo1/bar")
+        bufs)
+    (save-excursion
+      (should (file-exists-p "../README"))
+      (push (find-file-noselect "../README") bufs)
+      (push (find-file-noselect "other/README") bufs)
+      (should (equal (mapcar #'buffer-name bufs)
+                     '("README<other>" "README<bar>")))
+      (push (find-file-noselect "foo2/bar/README") bufs)
+      (should (equal (mapcar #'buffer-name bufs)
+                     '("README<foo2/bar>" "README<other>" "README<foo1/bar>")))
+      (while bufs
+        (kill-buffer (pop bufs))))))
+
 (provide 'uniquify-tests)
 ;;; uniquify-tests.el ends here
-- 
2.39.3


Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#62621; Package emacs. (Fri, 21 Jul 2023 14:38:02 GMT) Full text and rfc822 format available.

Message #107 received at 62621 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Spencer Baugh <sbaugh <at> janestreet.com>
Cc: dmitry <at> gutov.dev, 62621 <at> debbugs.gnu.org, sbaugh <at> catern.com
Subject: Re: bug#62621: 29.0.60; uniquify can't make buffers unique based on
 things other than filename
Date: Fri, 21 Jul 2023 17:37:37 +0300
> From: Spencer Baugh <sbaugh <at> janestreet.com>
> Cc: dmitry <at> gutov.dev,  62621 <at> debbugs.gnu.org,  sbaugh <at> catern.com
> Date: Fri, 21 Jul 2023 09:34:28 -0400
> 
> > Thanks, but it still falls short of what Dmitry described above: the
> > doc string doesn't "mention several functions that can be used".
> >
> >> +(defcustom uniquify-dirname-transform #'identity
> >> +  "Function to transform buffer's directory for uniquifying its name.
> >> +
> >> +It takes a single argument: the directory of the buffer.  It
> >> +should return a string filename (which does not need to actually
> >> +exist in the filesystem) to use for uniquifying the buffer name."
> >
> > Please read this carefully and try to put yourself in the shoes of a
> > user who needs to make sense out of this description.  The immediate
> > question I had is what does "transforming a buffer's directory" have
> > to do with "uniquifying the buffer name"?  Uniquifying a buffer's name
> > is not about its directory, at least not in general.  IOW, the
> > starting point of this description is too "inside" the implementation.
> 
> OK, how about this?

The explanation of what project-uniquify-dirname-transform does should
in its doc string, not in the doc string of uniquify-dirname-transform
(which should refer to the former, and that is enough).

The doc string of uniquify-dirname-transform should mention at least
'identity' as the default (what you wrote does that, but without
mentioning the function's name), otherwise this still falls short of
what Dmitry described.

And the last two paragraphs of the doc string of
uniquify-dirname-transform should be more-or-less reversed: first
describe the default, and that using some function other than
'identity' can affect the result, then describe
project-uniquify-dirname-transform as one such non-default transform.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#62621; Package emacs. (Sat, 22 Jul 2023 18:01:02 GMT) Full text and rfc822 format available.

Message #110 received at 62621 <at> debbugs.gnu.org (full text, mbox):

From: Spencer Baugh <sbaugh <at> janestreet.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: dmitry <at> gutov.dev, 62621 <at> debbugs.gnu.org, sbaugh <at> catern.com
Subject: Re: bug#62621: 29.0.60; uniquify can't make buffers unique based on
 things other than filename
Date: Sat, 22 Jul 2023 14:00:30 -0400
[Message part 1 (text/plain, inline)]
Eli Zaretskii <eliz <at> gnu.org> writes:
>> From: Spencer Baugh <sbaugh <at> janestreet.com>
>> Cc: dmitry <at> gutov.dev,  62621 <at> debbugs.gnu.org,  sbaugh <at> catern.com
>> Date: Fri, 21 Jul 2023 09:34:28 -0400
>> 
>> > Thanks, but it still falls short of what Dmitry described above: the
>> > doc string doesn't "mention several functions that can be used".
>> >
>> >> +(defcustom uniquify-dirname-transform #'identity
>> >> +  "Function to transform buffer's directory for uniquifying its name.
>> >> +
>> >> +It takes a single argument: the directory of the buffer.  It
>> >> +should return a string filename (which does not need to actually
>> >> +exist in the filesystem) to use for uniquifying the buffer name."
>> >
>> > Please read this carefully and try to put yourself in the shoes of a
>> > user who needs to make sense out of this description.  The immediate
>> > question I had is what does "transforming a buffer's directory" have
>> > to do with "uniquifying the buffer name"?  Uniquifying a buffer's name
>> > is not about its directory, at least not in general.  IOW, the
>> > starting point of this description is too "inside" the implementation.
>> 
>> OK, how about this?
>
> The explanation of what project-uniquify-dirname-transform does should
> in its doc string, not in the doc string of uniquify-dirname-transform
> (which should refer to the former, and that is enough).
>
> The doc string of uniquify-dirname-transform should mention at least
> 'identity' as the default (what you wrote does that, but without
> mentioning the function's name), otherwise this still falls short of
> what Dmitry described.
>
> And the last two paragraphs of the doc string of
> uniquify-dirname-transform should be more-or-less reversed: first
> describe the default, and that using some function other than
> 'identity' can affect the result, then describe
> project-uniquify-dirname-transform as one such non-default transform.

OK, how about this?

[0001-Support-transforming-the-dirname-used-by-uniquify.patch (text/x-patch, inline)]
From 30b6cf1961b89f12e54adeae9035036696807a38 Mon Sep 17 00:00:00 2001
From: Spencer Baugh <sbaugh <at> catern.com>
Date: Sun, 9 Jul 2023 22:21:03 -0400
Subject: [PATCH] Support transforming the dirname used by uniquify

By transforming the dirname, we can add additional information to use
during uniquifying.  A basic one: uniquifying buffer names based on
the project name.

* lisp/progmodes/project.el (project-uniquify-dirname-transform): Add.
* lisp/uniquify.el (uniquify-dirname-transform-default)
(uniquify-dirname-transform): Add. (bug#62621)
(uniquify-rationalize-file-buffer-names, uniquify-buffer-file-name):
Use uniquify-dirname-transform.
* test/lisp/uniquify-tests.el (uniquify-home,
uniquify-project-transform): Add tests.
---
 lisp/progmodes/project.el   | 12 ++++++++++++
 lisp/uniquify.el            | 37 ++++++++++++++++++++++++++++++++-----
 test/lisp/uniquify-tests.el | 33 +++++++++++++++++++++++++++++++++
 3 files changed, 77 insertions(+), 5 deletions(-)

diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el
index d482cc24d70..78f9fb410c1 100644
--- a/lisp/progmodes/project.el
+++ b/lisp/progmodes/project.el
@@ -1835,5 +1835,17 @@ project-switch-project
     (let ((project-current-directory-override dir))
       (call-interactively command))))
 
+;;;###autoload
+(defun project-uniquify-dirname-transform (dirname)
+  "Include `project-name' in DIRNAME if in a project."
+  (if-let (proj (project-current nil dirname))
+      (let ((root (project-root proj)))
+        (expand-file-name
+         (file-name-concat
+          (file-name-directory root)
+          (project-name proj)
+          (file-relative-name dirname root))))
+    dirname))
+
 (provide 'project)
 ;;; project.el ends here
diff --git a/lisp/uniquify.el b/lisp/uniquify.el
index d1ca455b673..af00c95663d 100644
--- a/lisp/uniquify.el
+++ b/lisp/uniquify.el
@@ -168,6 +168,31 @@ uniquify-list-buffers-directory-modes
 That means that when `buffer-file-name' is set to nil, `list-buffers-directory'
 contains the name of the directory which the buffer is visiting.")
 
+(defcustom uniquify-dirname-transform #'identity
+  "Function to transform buffer's directory for uniquifying its name.
+
+If `uniquify-buffer-name-style' is non-nil and a buffer's name
+would be the same as some other buffer, then components from the
+buffer's directory name are added to the buffer's name until the
+buffer's name is unique.
+
+This function is used to transform the buffer's directory name
+before the uniquifying process, allowing the unique buffer name
+to include components from other sources.  The default is
+`identity', so only the buffer's directory name is used for
+uniquifying.  This function is called with the buffer's directory
+name and should return a file name (which does not need to
+actually exist in the filesystem) to use components from.
+
+To include components from `project-name', set this variable to
+`project-uniquify-dirname-transform'."
+  :type '(choice (function-item :tag "Don't change the dirname" identity)
+                 (function-item :tag "Include project name in dirname"
+                                #'project-uniquify-dirname-transform)
+                 function)
+  :version "30.1"
+  :group 'uniquify)
+
 ;;; Utilities
 
 ;; uniquify-fix-list data structure
@@ -209,7 +234,8 @@ uniquify-rationalize-file-buffer-names
   ;; this buffer.
   (with-current-buffer newbuf (setq uniquify-managed nil))
   (when dirname
-    (setq dirname (expand-file-name (directory-file-name dirname)))
+    (setq dirname (funcall uniquify-dirname-transform
+                           (expand-file-name (directory-file-name dirname))))
     (let ((fix-list (list (uniquify-make-item base dirname newbuf
                                               nil)))
 	  items)
@@ -268,10 +294,11 @@ uniquify-buffer-file-name
 	       (if (memq major-mode uniquify-list-buffers-directory-modes)
 		   list-buffers-directory))))
       (when filename
-	(directory-file-name
-	 (file-name-directory
-	  (expand-file-name
-	   (directory-file-name filename))))))))
+	 (funcall uniquify-dirname-transform
+	          (directory-file-name
+	          (file-name-directory
+	           (expand-file-name
+	            (directory-file-name filename)))))))))
 
 (defun uniquify-rerationalize-w/o-cb (fix-list)
   "Re-rationalize the buffers in FIX-LIST, but ignoring `current-buffer'."
diff --git a/test/lisp/uniquify-tests.el b/test/lisp/uniquify-tests.el
index abd61fa3504..e533c4b644c 100644
--- a/test/lisp/uniquify-tests.el
+++ b/test/lisp/uniquify-tests.el
@@ -88,6 +88,21 @@ uniquify-dirs
                        '("a/dir/" "b/dir/")))
         (mapc #'kill-buffer bufs)))))
 
+(ert-deftest uniquify-home ()
+  "uniquify works, albeit confusingly, in the presence of directories named \"~\""
+  (let (bufs)
+    (save-excursion
+      (push (find-file-noselect "~") bufs)
+      (push (find-file-noselect "./~") bufs)
+      (should (equal (mapcar #'buffer-name bufs)
+                     '("~<test>" "~<>")))
+      (push (find-file-noselect "~/foo") bufs)
+      (push (find-file-noselect "./~/foo") bufs)
+      (should (equal (mapcar #'buffer-name bufs)
+                     '("foo<~>" "foo</nonexistent>" "~<test>" "~<>")))
+      (while bufs
+        (kill-buffer (pop bufs))))))
+
 (ert-deftest uniquify-rename-to-dir ()
   "Giving a buffer a name which matches a directory doesn't rename the buffer"
   (let ((uniquify-buffer-name-style 'forward)
@@ -125,5 +140,23 @@ uniquify-space-prefix
     (should (equal (buffer-name) "| foo"))
     (kill-buffer)))
 
+(require 'project)
+(ert-deftest uniquify-project-transform ()
+  "`project-uniquify-dirname-transform' works"
+  (let ((uniquify-dirname-transform #'project-uniquify-dirname-transform)
+        (project-vc-name "foo1/bar")
+        bufs)
+    (save-excursion
+      (should (file-exists-p "../README"))
+      (push (find-file-noselect "../README") bufs)
+      (push (find-file-noselect "other/README") bufs)
+      (should (equal (mapcar #'buffer-name bufs)
+                     '("README<other>" "README<bar>")))
+      (push (find-file-noselect "foo2/bar/README") bufs)
+      (should (equal (mapcar #'buffer-name bufs)
+                     '("README<foo2/bar>" "README<other>" "README<foo1/bar>")))
+      (while bufs
+        (kill-buffer (pop bufs))))))
+
 (provide 'uniquify-tests)
 ;;; uniquify-tests.el ends here
-- 
2.39.3


Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#62621; Package emacs. (Mon, 24 Jul 2023 19:19:02 GMT) Full text and rfc822 format available.

Message #113 received at 62621 <at> debbugs.gnu.org (full text, mbox):

From: Spencer Baugh <sbaugh <at> janestreet.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: dmitry <at> gutov.dev, 62621 <at> debbugs.gnu.org, sbaugh <at> catern.com
Subject: Re: bug#62621: 29.0.60; uniquify can't make buffers unique based on
 things other than filename
Date: Mon, 24 Jul 2023 15:18:23 -0400
[Message part 1 (text/plain, inline)]
Spencer Baugh <sbaugh <at> janestreet.com> writes:
> Eli Zaretskii <eliz <at> gnu.org> writes:
>>> From: Spencer Baugh <sbaugh <at> janestreet.com>
>>> Cc: dmitry <at> gutov.dev,  62621 <at> debbugs.gnu.org,  sbaugh <at> catern.com
>>> Date: Fri, 21 Jul 2023 09:34:28 -0400
>>> 
>>> > Thanks, but it still falls short of what Dmitry described above: the
>>> > doc string doesn't "mention several functions that can be used".
>>> >
>>> >> +(defcustom uniquify-dirname-transform #'identity
>>> >> +  "Function to transform buffer's directory for uniquifying its name.
>>> >> +
>>> >> +It takes a single argument: the directory of the buffer.  It
>>> >> +should return a string filename (which does not need to actually
>>> >> +exist in the filesystem) to use for uniquifying the buffer name."
>>> >
>>> > Please read this carefully and try to put yourself in the shoes of a
>>> > user who needs to make sense out of this description.  The immediate
>>> > question I had is what does "transforming a buffer's directory" have
>>> > to do with "uniquifying the buffer name"?  Uniquifying a buffer's name
>>> > is not about its directory, at least not in general.  IOW, the
>>> > starting point of this description is too "inside" the implementation.
>>> 
>>> OK, how about this?
>>
>> The explanation of what project-uniquify-dirname-transform does should
>> in its doc string, not in the doc string of uniquify-dirname-transform
>> (which should refer to the former, and that is enough).
>>
>> The doc string of uniquify-dirname-transform should mention at least
>> 'identity' as the default (what you wrote does that, but without
>> mentioning the function's name), otherwise this still falls short of
>> what Dmitry described.
>>
>> And the last two paragraphs of the doc string of
>> uniquify-dirname-transform should be more-or-less reversed: first
>> describe the default, and that using some function other than
>> 'identity' can affect the result, then describe
>> project-uniquify-dirname-transform as one such non-default transform.
>
> OK, how about this?

Oops, that one didn't include the updated
project-uniquify-dirname-transform docstring.  The right patch now:

[0001-Support-transforming-the-dirname-used-by-uniquify.patch (text/x-patch, inline)]
From 39e508c96ddf6bc5361542aa030f199193329fe0 Mon Sep 17 00:00:00 2001
From: Spencer Baugh <sbaugh <at> catern.com>
Date: Sun, 9 Jul 2023 22:21:03 -0400
Subject: [PATCH] Support transforming the dirname used by uniquify

By transforming the dirname, we can add additional information to use
during uniquifying.  A basic one: uniquifying buffer names based on
the project name.

* lisp/progmodes/project.el (project-uniquify-dirname-transform): Add.
* lisp/uniquify.el (uniquify-dirname-transform-default)
(uniquify-dirname-transform): Add. (bug#62621)
(uniquify-rationalize-file-buffer-names, uniquify-buffer-file-name):
Use uniquify-dirname-transform.
* test/lisp/uniquify-tests.el (uniquify-home,
uniquify-project-transform): Add tests.
---
 lisp/progmodes/project.el   | 17 +++++++++++++++++
 lisp/uniquify.el            | 37 ++++++++++++++++++++++++++++++++-----
 test/lisp/uniquify-tests.el | 33 +++++++++++++++++++++++++++++++++
 3 files changed, 82 insertions(+), 5 deletions(-)

diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el
index d482cc24d70..36c1005aef5 100644
--- a/lisp/progmodes/project.el
+++ b/lisp/progmodes/project.el
@@ -1835,5 +1835,22 @@ project-switch-project
     (let ((project-current-directory-override dir))
       (call-interactively command))))
 
+;;;###autoload
+(defun project-uniquify-dirname-transform (dirname)
+  "Include `project-name' in DIRNAME if in a project.
+
+If you set `uniquify-dirname-transform' to this function,
+slash-separated components from `project-name' will be added to
+the buffer's name when buffers from two different projects would
+otherwise have the same name."
+  (if-let (proj (project-current nil dirname))
+      (let ((root (project-root proj)))
+        (expand-file-name
+         (file-name-concat
+          (file-name-directory root)
+          (project-name proj)
+          (file-relative-name dirname root))))
+    dirname))
+
 (provide 'project)
 ;;; project.el ends here
diff --git a/lisp/uniquify.el b/lisp/uniquify.el
index d1ca455b673..af00c95663d 100644
--- a/lisp/uniquify.el
+++ b/lisp/uniquify.el
@@ -168,6 +168,31 @@ uniquify-list-buffers-directory-modes
 That means that when `buffer-file-name' is set to nil, `list-buffers-directory'
 contains the name of the directory which the buffer is visiting.")
 
+(defcustom uniquify-dirname-transform #'identity
+  "Function to transform buffer's directory for uniquifying its name.
+
+If `uniquify-buffer-name-style' is non-nil and a buffer's name
+would be the same as some other buffer, then components from the
+buffer's directory name are added to the buffer's name until the
+buffer's name is unique.
+
+This function is used to transform the buffer's directory name
+before the uniquifying process, allowing the unique buffer name
+to include components from other sources.  The default is
+`identity', so only the buffer's directory name is used for
+uniquifying.  This function is called with the buffer's directory
+name and should return a file name (which does not need to
+actually exist in the filesystem) to use components from.
+
+To include components from `project-name', set this variable to
+`project-uniquify-dirname-transform'."
+  :type '(choice (function-item :tag "Don't change the dirname" identity)
+                 (function-item :tag "Include project name in dirname"
+                                #'project-uniquify-dirname-transform)
+                 function)
+  :version "30.1"
+  :group 'uniquify)
+
 ;;; Utilities
 
 ;; uniquify-fix-list data structure
@@ -209,7 +234,8 @@ uniquify-rationalize-file-buffer-names
   ;; this buffer.
   (with-current-buffer newbuf (setq uniquify-managed nil))
   (when dirname
-    (setq dirname (expand-file-name (directory-file-name dirname)))
+    (setq dirname (funcall uniquify-dirname-transform
+                           (expand-file-name (directory-file-name dirname))))
     (let ((fix-list (list (uniquify-make-item base dirname newbuf
                                               nil)))
 	  items)
@@ -268,10 +294,11 @@ uniquify-buffer-file-name
 	       (if (memq major-mode uniquify-list-buffers-directory-modes)
 		   list-buffers-directory))))
       (when filename
-	(directory-file-name
-	 (file-name-directory
-	  (expand-file-name
-	   (directory-file-name filename))))))))
+	 (funcall uniquify-dirname-transform
+	          (directory-file-name
+	          (file-name-directory
+	           (expand-file-name
+	            (directory-file-name filename)))))))))
 
 (defun uniquify-rerationalize-w/o-cb (fix-list)
   "Re-rationalize the buffers in FIX-LIST, but ignoring `current-buffer'."
diff --git a/test/lisp/uniquify-tests.el b/test/lisp/uniquify-tests.el
index abd61fa3504..e533c4b644c 100644
--- a/test/lisp/uniquify-tests.el
+++ b/test/lisp/uniquify-tests.el
@@ -88,6 +88,21 @@ uniquify-dirs
                        '("a/dir/" "b/dir/")))
         (mapc #'kill-buffer bufs)))))
 
+(ert-deftest uniquify-home ()
+  "uniquify works, albeit confusingly, in the presence of directories named \"~\""
+  (let (bufs)
+    (save-excursion
+      (push (find-file-noselect "~") bufs)
+      (push (find-file-noselect "./~") bufs)
+      (should (equal (mapcar #'buffer-name bufs)
+                     '("~<test>" "~<>")))
+      (push (find-file-noselect "~/foo") bufs)
+      (push (find-file-noselect "./~/foo") bufs)
+      (should (equal (mapcar #'buffer-name bufs)
+                     '("foo<~>" "foo</nonexistent>" "~<test>" "~<>")))
+      (while bufs
+        (kill-buffer (pop bufs))))))
+
 (ert-deftest uniquify-rename-to-dir ()
   "Giving a buffer a name which matches a directory doesn't rename the buffer"
   (let ((uniquify-buffer-name-style 'forward)
@@ -125,5 +140,23 @@ uniquify-space-prefix
     (should (equal (buffer-name) "| foo"))
     (kill-buffer)))
 
+(require 'project)
+(ert-deftest uniquify-project-transform ()
+  "`project-uniquify-dirname-transform' works"
+  (let ((uniquify-dirname-transform #'project-uniquify-dirname-transform)
+        (project-vc-name "foo1/bar")
+        bufs)
+    (save-excursion
+      (should (file-exists-p "../README"))
+      (push (find-file-noselect "../README") bufs)
+      (push (find-file-noselect "other/README") bufs)
+      (should (equal (mapcar #'buffer-name bufs)
+                     '("README<other>" "README<bar>")))
+      (push (find-file-noselect "foo2/bar/README") bufs)
+      (should (equal (mapcar #'buffer-name bufs)
+                     '("README<foo2/bar>" "README<other>" "README<foo1/bar>")))
+      (while bufs
+        (kill-buffer (pop bufs))))))
+
 (provide 'uniquify-tests)
 ;;; uniquify-tests.el ends here
-- 
2.39.3


Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#62621; Package emacs. (Wed, 26 Jul 2023 15:18:01 GMT) Full text and rfc822 format available.

Message #116 received at 62621 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Spencer Baugh <sbaugh <at> janestreet.com>
Cc: dmitry <at> gutov.dev, 62621 <at> debbugs.gnu.org, sbaugh <at> catern.com
Subject: Re: bug#62621: 29.0.60; uniquify can't make buffers unique based on
 things other than filename
Date: Wed, 26 Jul 2023 18:18:25 +0300
> From: Spencer Baugh <sbaugh <at> janestreet.com>
> Cc: dmitry <at> gutov.dev,  62621 <at> debbugs.gnu.org,  sbaugh <at> catern.com
> Date: Mon, 24 Jul 2023 15:18:23 -0400
> 
> > OK, how about this?
> 
> Oops, that one didn't include the updated
> project-uniquify-dirname-transform docstring.  The right patch now:

Thanks, installed, with some minor changes as followup.

The new test uniquify-home fails for me on MS-Windows:

  Test uniquify-home backtrace:
    signal(ert-test-failed (((should (equal (mapcar #'buffer-name bufs)
    ert-fail(((should (equal (mapcar #'buffer-name bufs) '("~<test>" "~<
    (if (unwind-protect (setq value-27 (apply fn-25 args-26)) (setq form
    (let (form-description-29) (if (unwind-protect (setq value-27 (apply
    (let ((value-27 'ert-form-evaluation-aborted-28)) (let (form-descrip
    (let* ((fn-25 #'equal) (args-26 (condition-case err (let ((signal-ho
    (save-excursion (setq bufs (cons (find-file-noselect "~") bufs)) (se
    (let (bufs) (save-excursion (setq bufs (cons (find-file-noselect "~"
    (closure (t) nil (let (bufs) (save-excursion (setq bufs (cons (find-
    ert--run-test-internal(#s(ert--test-execution-info :test #s(ert-test
    ert-run-test(#s(ert-test :name uniquify-home :documentation "uniquif
    ert-run-or-rerun-test(#s(ert--stats :selector (not ...) :tests [...
    ert-run-tests((not (or (tag :unstable) (tag :nativecomp))) #f(compil
    ert-run-tests-batch((not (or (tag :unstable) (tag :nativecomp))))
    ert-run-tests-batch-and-exit((not (or (tag :unstable) (tag :nativeco
    eval((ert-run-tests-batch-and-exit '(not (or (tag :unstable) (tag :n
    command-line-1(("-L" ";." "-l" "ert" "-l" "lisp/uniquify-tests.el" "
    command-line()
    normal-top-level()
  Test uniquify-home condition:
      (ert-test-failed
       ((should (equal (mapcar ... bufs) '("~<test>" "~<>"))) :form
	(equal ("~" "nonexistent") ("~<test>" "~<>")) :value nil
	:explanation
	(list-elt 0
		  (arrays-of-different-length 1 7 "~" "~<test>"
					      first-mismatch-at 1))))

The idea of the test is not clear to me, so I cannot tell what could
be the reasons.  Feel free to ask me to test changes or ask questions
about what happens on this Windows system while running the test.




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#62621; Package emacs. (Thu, 03 Aug 2023 08:01:01 GMT) Full text and rfc822 format available.

Message #119 received at 62621 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: sbaugh <at> janestreet.com
Cc: dmitry <at> gutov.dev, 62621 <at> debbugs.gnu.org, sbaugh <at> catern.com
Subject: Re: bug#62621: 29.0.60;
 uniquify can't make buffers unique based on things other than filename
Date: Thu, 03 Aug 2023 11:00:43 +0300
Ping!  Can this test failure be fixed, please?

> Cc: dmitry <at> gutov.dev, 62621 <at> debbugs.gnu.org, sbaugh <at> catern.com
> Date: Wed, 26 Jul 2023 18:18:25 +0300
> From: Eli Zaretskii <eliz <at> gnu.org>
> 
> > From: Spencer Baugh <sbaugh <at> janestreet.com>
> > Cc: dmitry <at> gutov.dev,  62621 <at> debbugs.gnu.org,  sbaugh <at> catern.com
> > Date: Mon, 24 Jul 2023 15:18:23 -0400
> > 
> > > OK, how about this?
> > 
> > Oops, that one didn't include the updated
> > project-uniquify-dirname-transform docstring.  The right patch now:
> 
> Thanks, installed, with some minor changes as followup.
> 
> The new test uniquify-home fails for me on MS-Windows:
> 
>   Test uniquify-home backtrace:
>     signal(ert-test-failed (((should (equal (mapcar #'buffer-name bufs)
>     ert-fail(((should (equal (mapcar #'buffer-name bufs) '("~<test>" "~<
>     (if (unwind-protect (setq value-27 (apply fn-25 args-26)) (setq form
>     (let (form-description-29) (if (unwind-protect (setq value-27 (apply
>     (let ((value-27 'ert-form-evaluation-aborted-28)) (let (form-descrip
>     (let* ((fn-25 #'equal) (args-26 (condition-case err (let ((signal-ho
>     (save-excursion (setq bufs (cons (find-file-noselect "~") bufs)) (se
>     (let (bufs) (save-excursion (setq bufs (cons (find-file-noselect "~"
>     (closure (t) nil (let (bufs) (save-excursion (setq bufs (cons (find-
>     ert--run-test-internal(#s(ert--test-execution-info :test #s(ert-test
>     ert-run-test(#s(ert-test :name uniquify-home :documentation "uniquif
>     ert-run-or-rerun-test(#s(ert--stats :selector (not ...) :tests [...
>     ert-run-tests((not (or (tag :unstable) (tag :nativecomp))) #f(compil
>     ert-run-tests-batch((not (or (tag :unstable) (tag :nativecomp))))
>     ert-run-tests-batch-and-exit((not (or (tag :unstable) (tag :nativeco
>     eval((ert-run-tests-batch-and-exit '(not (or (tag :unstable) (tag :n
>     command-line-1(("-L" ";." "-l" "ert" "-l" "lisp/uniquify-tests.el" "
>     command-line()
>     normal-top-level()
>   Test uniquify-home condition:
>       (ert-test-failed
>        ((should (equal (mapcar ... bufs) '("~<test>" "~<>"))) :form
> 	(equal ("~" "nonexistent") ("~<test>" "~<>")) :value nil
> 	:explanation
> 	(list-elt 0
> 		  (arrays-of-different-length 1 7 "~" "~<test>"
> 					      first-mismatch-at 1))))
> 
> The idea of the test is not clear to me, so I cannot tell what could
> be the reasons.  Feel free to ask me to test changes or ask questions
> about what happens on this Windows system while running the test.
> 
> 
> 
> 




Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#62621; Package emacs. (Thu, 03 Aug 2023 11:55:02 GMT) Full text and rfc822 format available.

Message #122 received at 62621 <at> debbugs.gnu.org (full text, mbox):

From: Spencer Baugh <sbaugh <at> janestreet.com>
To: Eli Zaretskii <eliz <at> gnu.org>
Cc: Dmitry Gutov <dmitry <at> gutov.dev>, 62621 <at> debbugs.gnu.org,
 Spencer Baugh <sbaugh <at> catern.com>
Subject: Re: bug#62621: 29.0.60; uniquify can't make buffers unique based on
 things other than filename
Date: Thu, 3 Aug 2023 07:54:22 -0400
[Message part 1 (text/plain, inline)]
On reflection that specific test case is of dubious value, and since it's
failing on Windows it means the behavior isn't even consistent anyway. So
just delete it.

On Thu, Aug 3, 2023, 04:00 Eli Zaretskii <eliz <at> gnu.org> wrote:

> Ping!  Can this test failure be fixed, please?
>
> > Cc: dmitry <at> gutov.dev, 62621 <at> debbugs.gnu.org, sbaugh <at> catern.com
> > Date: Wed, 26 Jul 2023 18:18:25 +0300
> > From: Eli Zaretskii <eliz <at> gnu.org>
> >
> > > From: Spencer Baugh <sbaugh <at> janestreet.com>
> > > Cc: dmitry <at> gutov.dev,  62621 <at> debbugs.gnu.org,  sbaugh <at> catern.com
> > > Date: Mon, 24 Jul 2023 15:18:23 -0400
> > >
> > > > OK, how about this?
> > >
> > > Oops, that one didn't include the updated
> > > project-uniquify-dirname-transform docstring.  The right patch now:
> >
> > Thanks, installed, with some minor changes as followup.
> >
> > The new test uniquify-home fails for me on MS-Windows:
> >
> >   Test uniquify-home backtrace:
> >     signal(ert-test-failed (((should (equal (mapcar #'buffer-name bufs)
> >     ert-fail(((should (equal (mapcar #'buffer-name bufs) '("~<test>" "~<
> >     (if (unwind-protect (setq value-27 (apply fn-25 args-26)) (setq form
> >     (let (form-description-29) (if (unwind-protect (setq value-27 (apply
> >     (let ((value-27 'ert-form-evaluation-aborted-28)) (let (form-descrip
> >     (let* ((fn-25 #'equal) (args-26 (condition-case err (let ((signal-ho
> >     (save-excursion (setq bufs (cons (find-file-noselect "~") bufs)) (se
> >     (let (bufs) (save-excursion (setq bufs (cons (find-file-noselect "~"
> >     (closure (t) nil (let (bufs) (save-excursion (setq bufs (cons (find-
> >     ert--run-test-internal(#s(ert--test-execution-info :test #s(ert-test
> >     ert-run-test(#s(ert-test :name uniquify-home :documentation "uniquif
> >     ert-run-or-rerun-test(#s(ert--stats :selector (not ...) :tests [...
> >     ert-run-tests((not (or (tag :unstable) (tag :nativecomp))) #f(compil
> >     ert-run-tests-batch((not (or (tag :unstable) (tag :nativecomp))))
> >     ert-run-tests-batch-and-exit((not (or (tag :unstable) (tag :nativeco
> >     eval((ert-run-tests-batch-and-exit '(not (or (tag :unstable) (tag :n
> >     command-line-1(("-L" ";." "-l" "ert" "-l" "lisp/uniquify-tests.el" "
> >     command-line()
> >     normal-top-level()
> >   Test uniquify-home condition:
> >       (ert-test-failed
> >        ((should (equal (mapcar ... bufs) '("~<test>" "~<>"))) :form
> >       (equal ("~" "nonexistent") ("~<test>" "~<>")) :value nil
> >       :explanation
> >       (list-elt 0
> >                 (arrays-of-different-length 1 7 "~" "~<test>"
> >                                             first-mismatch-at 1))))
> >
> > The idea of the test is not clear to me, so I cannot tell what could
> > be the reasons.  Feel free to ask me to test changes or ask questions
> > about what happens on this Windows system while running the test.
> >
> >
> >
> >
>
[Message part 2 (text/html, inline)]

Reply sent to Eli Zaretskii <eliz <at> gnu.org>:
You have taken responsibility. (Thu, 03 Aug 2023 14:06:02 GMT) Full text and rfc822 format available.

Notification sent to Spencer Baugh <sbaugh <at> janestreet.com>:
bug acknowledged by developer. (Thu, 03 Aug 2023 14:06:02 GMT) Full text and rfc822 format available.

Message #127 received at 62621-done <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Spencer Baugh <sbaugh <at> janestreet.com>
Cc: dmitry <at> gutov.dev, 62621-done <at> debbugs.gnu.org, sbaugh <at> catern.com
Subject: Re: bug#62621: 29.0.60; uniquify can't make buffers unique based on
 things other than filename
Date: Thu, 03 Aug 2023 17:05:10 +0300
> From: Spencer Baugh <sbaugh <at> janestreet.com>
> Date: Thu, 3 Aug 2023 07:54:22 -0400
> Cc: Dmitry Gutov <dmitry <at> gutov.dev>, 62621 <at> debbugs.gnu.org, 
>  	Spencer Baugh <sbaugh <at> catern.com>
> 
> On reflection that specific test case is of dubious value, and since it's failing on Windows it means the
> behavior isn't even consistent anyway. So just delete it.

Done, and closing the bug.




bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Fri, 01 Sep 2023 11:24:05 GMT) Full text and rfc822 format available.

This bug report was last modified 210 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.