Fix display of minibuffer prompt in ido.el

* lisp/minibuffer.el (minibuffer--message-overlay-pos): New
function.
(set-minibuffer-message): Use it to determine where to show the
overlay with the temporary message.
* lisp/ido.el (ido-exhibit): Revert "Render Ido suggestions using
an overlay"; this restores the original code which inserted the
match-status information into the minibuffer, instead of
displaying it in an overlay with an after-string.  Put the special
'minibuffer-message' text property at the beginning of the
inserted text.  (Bug#39379)

* etc/NEWS:
* doc/lispref/display.texi (Displaying Messages):
* doc/lispref/text.texi (Special Properties): Document the
'minibuffer-message' text property and its effect.
This commit is contained in:
Eli Zaretskii 2020-02-12 21:39:44 +02:00
parent 5a21aaff46
commit 027da652a4
5 changed files with 45 additions and 17 deletions

View file

@ -319,7 +319,10 @@ the echo area. See also @code{clear-message-function} that can be
used to clear the message displayed by this function.
The default value is the function that displays the message at the end
of the minibuffer when the minibuffer is active.
of the minibuffer when the minibuffer is active. However, if the text
shown in the active minibuffer has the @code{minibuffer-message} text
property (@pxref{Special Properties}) on some character, the message
will be displayed before the first character having that property.
@end defvar
@defvar clear-message-function
@ -332,8 +335,8 @@ after displaying an echo-area message. The function is expected to
clear the message displayed by its counterpart function specified by
@code{set-message-function}.
The default value is the function that clears the message displayed at
the end of the minibuffer when the minibuffer is active.
The default value is the function that clears the message displayed in
an active minibuffer.
@end defvar
@defvar inhibit-message

View file

@ -3741,6 +3741,16 @@ single glyph composed from components. But the value of the property
itself is completely internal to Emacs and should not be manipulated
directly by, for instance, @code{put-text-property}.
@item minibuffer-message
@kindex minibuffer-message @r{(text property)}
This text property tells where to display temporary messages in an
active minibuffer. Specifically, the first character of the
minibuffer text which has this property will have the temporary
message displayed before it. The default is to display temporary
messages at the end of the minibuffer text. This text property is
used by the function that is the default value of
@code{set-message-function} (@pxref{Displaying Messages}).
@end table
@defvar inhibit-point-motion-hooks

View file

@ -3590,6 +3590,12 @@ in other packages are now obsolete aliases of 'xor'.
Setting this on the first character of a help string disables
conversions via 'substitute-command-keys'.
+++
** New text property 'minibuffer-message'.
Setting this on a character of the minibuffer text will display the
temporary echo messages before that character, when messages need to
be displayed while minibuffer is active.
+++
** 'undo' can be made to ignore the active region for a command
by setting 'undo-inhibit-region' symbol property of that command to

View file

@ -4492,8 +4492,6 @@ For details of keybindings, see `ido-find-file'."
(ido-tidy))
(throw 'ido contents))))
(defvar ido--overlay nil)
(defun ido-exhibit ()
"Post command hook for Ido."
;; Find matching files and display a list in the minibuffer.
@ -4728,16 +4726,13 @@ For details of keybindings, see `ido-find-file'."
(let ((inf (ido-completions contents)))
(setq ido-show-confirm-message nil)
(ido-trace "inf" inf)
(when ido--overlay
(delete-overlay ido--overlay))
(let ((o (make-overlay (point-max) (point-max) nil t t)))
(when (> (length inf) 0)
;; For hacks that redefine ido-completions function (bug#39379)
(when (eq (aref inf 0) ?\n)
(setq inf (concat " " inf)))
(put-text-property 0 1 'cursor t inf))
(overlay-put o 'after-string inf)
(setq ido--overlay o)))
(let ((pos (point)))
(insert inf)
(if (< pos (point-max))
;; Tell set-minibuffer-message where to display the
;; overlay with temporary messages.
(put-text-property pos (1+ pos) 'minibuffer-message t)))
)
))))
(defun ido-completions (name)

View file

@ -763,8 +763,21 @@ and `clear-minibuffer-message' called automatically via
(defvar minibuffer-message-timer nil)
(defvar minibuffer-message-overlay nil)
(defun minibuffer--message-overlay-pos ()
"Return position where `set-minibuffer-message' shall put message overlay."
;; Starting from point, look for non-nil 'minibuffer-message'
;; property, and return its position. If none found, return the EOB
;; position.
(let* ((pt (point))
(propval (get-text-property pt 'minibuffer-message)))
(if propval pt
(next-single-property-change pt 'minibuffer-message nil (point-max)))))
(defun set-minibuffer-message (message)
"Temporarily display MESSAGE at the end of the minibuffer.
If some part of the minibuffer text has the `minibuffer-message' property,
the message will be displayed before the first such character, instead of
at the end of the minibuffer.
The text is displayed for `minibuffer-message-clear-timeout' seconds
\(if the value is a number), or until the next input event arrives,
whichever comes first.
@ -784,8 +797,9 @@ via `set-message-function'."
(clear-minibuffer-message)
(setq minibuffer-message-overlay
(make-overlay (point-max) (point-max) nil t t))
(let ((ovpos (minibuffer--message-overlay-pos)))
(setq minibuffer-message-overlay
(make-overlay ovpos ovpos nil t t)))
(unless (zerop (length message))
;; The current C cursor code doesn't know to use the overlay's
;; marker's stickiness to figure out whether to place the cursor