unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#65736: 30.0.50; Extending the use of format-prompt
@ 2023-09-04 16:31 Stephen Berman
  0 siblings, 0 replies; only message in thread
From: Stephen Berman @ 2023-09-04 16:31 UTC (permalink / raw)
  To: 65736

[-- Attachment #1: Type: text/plain, Size: 2868 bytes --]

0. emacs -Q
1. Invoke read-buffer with a prompt containg grave-style quoting and
   with no default buffer argument, e.g.:
   M-: (read-buffer "Enter `buffer': ")
=> This displays the prompt in the minibuffer with grave-style quoting,
   i.e. as it appears in the invocation.
2. Repeat step 1 but add a default buffer argument, e.g.:
   M-: (read-buffer "Enter `buffer': " "*scratch*")
=> This displays the prompt in the minibuffer with curve-style quoting:
   Enter ‘buffer’ (default *scratch*):  

The different appearances of the prompt with and without the presence of
a default argument is due to commit 50512e36c7, which passes the prompt
string to format-prompt when read-buffer has a non-nil default argument
DEF, but not when DEF is nil.  (The purpose of that commit was to
replace occurrences of prompts containing the string "(default %s)" by
invocations of the then recently introduced function format-prompt; the
fact that this function also calls substitute-command-keys was not a
concern for that commit and its effect was presumably for that reason
overlooked.)

I think the simplest fix is to pass PROMPT to format-prompt regardless
of the presence of a default argument of read-buffer, as in the first
attached patch.

But having substitute-command-keys always apply to the prompt string of
read-buffer raises the question whether it should apply more generally
to prompt strings.  In fact, commit 50512e36c7 did change numerous
mostly mode-specific prompts in several Lisp libraries to pass the
prompt to format-prompt, but in almost all cases those prompts are fixed
strings where applying substitute-command-keys makes no difference.  But
with read-buffer the prompt string is provided by the caller, so its
appearance could be affected by substitute-command-keys.

By default, read-buffer calls (in C) completing-read, which by default
calls read-from-minibuffer, and indeed most, if not all, other functions
that prompt for minibuffer input end up calling read-from-minibuffer.
So passing the prompt string to format-prompt in read-from-minibuffer,
as in the second attached patch (which should be applied instead of the
first patch), would achieve a higher degree of consistency and
simplicity in Emacs in the handling of prompts for minibuffer input, at
least by default.  (With functions that accept a user-defined function,
like read-buffer-function with read-buffer, it would be up to the user
to decide whether or not to use format-prompt, if the function does not
invoke read-from-minibuffer.)

If this change (the second patch) is accepted, it will probably require
adjustments in the Emacs code base, e.g. to avoid double invocations of
format-prompt.  This would partly undo the changes made in 50512e36c7.
I'd be willing to make the needed adjustments in Emacs.

Steve Berman


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: read-buffer patch --]
[-- Type: text/x-patch, Size: 2106 bytes --]

diff --git a/src/minibuf.c b/src/minibuf.c
index 58adde1bf66..a1cbf4747f5 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -1502,34 +1502,30 @@ DEFUN ("read-buffer", Fread_buffer, Sread_buffer, 1, 4, 0,
   specbind (Qcompletion_ignore_case,
 	    read_buffer_completion_ignore_case ? Qt : Qnil);

-  if (NILP (Vread_buffer_function))
-    {
-      if (!NILP (def))
-	{
-	  /* A default value was provided: we must change PROMPT,
-	     editing the default value in before the colon.  To achieve
-	     this, we replace PROMPT with a substring that doesn't
-	     contain the terminal space and colon (if present).  They
-	     are then added back using Fformat.  */
+  /* For backward compatibility we accept prompt strings ending with a
+     colon and a space, but we have to delete them, if present, before
+     passing PROMPT to `format-prompt', which automatically appends
+     these characters to PROMPT.  */

-	  if (STRINGP (prompt))
-	    {
-	      s = SSDATA (prompt);
-	      len = SBYTES (prompt);
-	      if (len >= 2 && s[len - 2] == ':' && s[len - 1] == ' ')
-		len = len - 2;
-	      else if (len >= 1 && (s[len - 1] == ':' || s[len - 1] == ' '))
-		len--;
-
-	      prompt = make_specified_string (s, -1, len,
-					      STRING_MULTIBYTE (prompt));
-	    }
+  if (STRINGP (prompt))
+    {
+      s = SSDATA (prompt);
+      len = SBYTES (prompt);
+      if (len >= 2 && s[len - 2] == ':' && s[len - 1] == ' ')
+	len = len - 2;
+      else if (len >= 1 && (s[len - 1] == ':' || s[len - 1] == ' '))
+	len--;
+
+      prompt = make_specified_string (s, -1, len,
+				      STRING_MULTIBYTE (prompt));
+    }

-	  prompt = CALLN (Ffuncall, intern("format-prompt"),
-			  prompt,
-			  CONSP (def) ? XCAR (def) : def);
-	}
+  prompt = CALLN (Ffuncall, intern("format-prompt"),
+		  prompt,
+		  CONSP (def) ? XCAR (def) : def);

+  if (NILP (Vread_buffer_function))
+    {
       result = Fcompleting_read (prompt, intern ("internal-complete-buffer"),
 				 predicate, require_match, Qnil,
 				 Qbuffer_name_history, def, Qnil);

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: read-from-minibuffer patch --]
[-- Type: text/x-patch, Size: 4216 bytes --]

diff --git a/src/minibuf.c b/src/minibuf.c
index 58adde1bf66..4318cab04cb 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -1343,10 +1343,34 @@ DEFUN ("read-from-minibuffer", Fread_from_minibuffer,
   (Lisp_Object prompt, Lisp_Object initial_contents, Lisp_Object keymap, Lisp_Object read, Lisp_Object hist, Lisp_Object default_value, Lisp_Object inherit_input_method)
 {
   Lisp_Object histvar, histpos, val;
+  char *s;
+  ptrdiff_t len;

   barf_if_interaction_inhibited ();

   CHECK_STRING (prompt);
+
+  /* For backward compatibility we accept prompt strings ending with a
+     colon and a space, but we have to delete them, if present, before
+     passing PROMPT to `format-prompt', which automatically appends
+     these characters to PROMPT.  */
+
+  if (STRINGP (prompt))
+    {
+      s = SSDATA (prompt);
+      len = SBYTES (prompt);
+      if (len >= 2 && s[len - 2] == ':' && s[len - 1] == ' ')
+	len = len - 2;
+      else if (len >= 1 && (s[len - 1] == ':' || s[len - 1] == ' '))
+	len--;
+
+      prompt = make_specified_string (s, -1, len,
+				      STRING_MULTIBYTE (prompt));
+    }
+
+  prompt = CALLN (Ffuncall, intern("format-prompt"), prompt,
+		  CONSP (default_value) ? XCAR (default_value) : default_value);
+
   if (NILP (keymap))
     keymap = Vminibuffer_local_map;
   else
@@ -1473,8 +1497,7 @@ DEFUN ("read-variable", Fread_variable, Sread_variable, 1, 2, 0,

 DEFUN ("read-buffer", Fread_buffer, Sread_buffer, 1, 4, 0,
        doc: /* Read the name of a buffer and return it as a string.
-Prompt with PROMPT, which should be a string ending with a colon and a space.
-Provides completion on buffer names the user types.
+Prompt with string PROMPT.  Provides completion on buffer names the user types.
 Optional second arg DEF is value to return if user enters an empty line,
  instead of that empty string.
  If DEF is a list of default values, return its first element.
@@ -1492,8 +1515,6 @@ DEFUN ("read-buffer", Fread_buffer, Sread_buffer, 1, 4, 0,
    Lisp_Object predicate)
 {
   Lisp_Object result;
-  char *s;
-  ptrdiff_t len;
   specpdl_ref count = SPECPDL_INDEX ();

   if (BUFFERP (def))
@@ -1503,37 +1524,9 @@ DEFUN ("read-buffer", Fread_buffer, Sread_buffer, 1, 4, 0,
 	    read_buffer_completion_ignore_case ? Qt : Qnil);

   if (NILP (Vread_buffer_function))
-    {
-      if (!NILP (def))
-	{
-	  /* A default value was provided: we must change PROMPT,
-	     editing the default value in before the colon.  To achieve
-	     this, we replace PROMPT with a substring that doesn't
-	     contain the terminal space and colon (if present).  They
-	     are then added back using Fformat.  */
-
-	  if (STRINGP (prompt))
-	    {
-	      s = SSDATA (prompt);
-	      len = SBYTES (prompt);
-	      if (len >= 2 && s[len - 2] == ':' && s[len - 1] == ' ')
-		len = len - 2;
-	      else if (len >= 1 && (s[len - 1] == ':' || s[len - 1] == ' '))
-		len--;
-
-	      prompt = make_specified_string (s, -1, len,
-					      STRING_MULTIBYTE (prompt));
-	    }
-
-	  prompt = CALLN (Ffuncall, intern("format-prompt"),
-			  prompt,
-			  CONSP (def) ? XCAR (def) : def);
-	}
-
-      result = Fcompleting_read (prompt, intern ("internal-complete-buffer"),
-				 predicate, require_match, Qnil,
-				 Qbuffer_name_history, def, Qnil);
-    }
+    result = Fcompleting_read (prompt, intern ("internal-complete-buffer"),
+			       predicate, require_match, Qnil,
+			       Qbuffer_name_history, def, Qnil);
   else
     result = (NILP (predicate)
 	      /* Partial backward compatibility for older read_buffer_functions
@@ -1978,7 +1971,7 @@ DEFUN ("all-completions", Fall_completions, Sall_completions, 2, 4, 0,
 \f
 DEFUN ("completing-read", Fcompleting_read, Scompleting_read, 2, 8, 0,
        doc: /* Read a string in the minibuffer, with completion.
-PROMPT is a string to prompt with; normally it ends in a colon and a space.
+PROMPT is a string to prompt with.
 COLLECTION can be a list of strings, an alist, an obarray or a hash table.
 COLLECTION can also be a function to do the completion itself.
 PREDICATE limits completion to a subset of COLLECTION.

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2023-09-04 16:31 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-09-04 16:31 bug#65736: 30.0.50; Extending the use of format-prompt Stephen Berman

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).