I have two overlays that are initially in the same position.

(defvar-local minibuffer-overlay nil)
(defvar-local minibuffer-overlay2 nil)

(defun minibuffer-advice (fn &rest args)
  (minibuffer-with-setup-hook #'minibuffer-setup (apply fn args)))

(defun minibuffer-setup ()
  (setq minibuffer-overlay (make-overlay (point-min) (point-min) nil t nil))
  (setq minibuffer-overlay2 (make-overlay (point-min) (point-min) nil t t))
  (add-hook 'post-command-hook #'minibuffer-exhibit nil 'local))

(defun minibuffer-exhibit ()
  (move-overlay minibuffer-overlay (minibuffer-prompt-end) (minibuffer-prompt-end))
  (overlay-put minibuffer-overlay 'before-string "!")
  (move-overlay minibuffer-overlay2 (point-max) (point-max))
  (overlay-put minibuffer-overlay2 'after-string "?"))

(advice-add #'completing-read-default :around #'minibuffer-advice)

M-x looks like M-x ?!| where | is the cursor. If I type foo then it becomes M-x !foo?|. How do I make M-x initially look like M-x !?| instead?


Example for a *scratch* buffer since it may be confusing having it in the minibuffer:

(let ((overlay1 (make-overlay (point-min) (point-min)))
      (overlay2 (make-overlay (point-min) (point-min))))
  (move-overlay overlay1 (point-min) (point-min))
  (overlay-put overlay1 'before-string "!")
  (move-overlay overlay2 (point-min) (point-min))
  (overlay-put overlay2 'after-string "?"))

The beginning of the buffer will look like ?!. Why does the second overlay come first and how can I change that?

  • The question is about overlays. But 99% of it is with code about the minibuffer, which is presumably irrelevant to the question. You've even got hooks and advice mixed in here. Please remove everything unrelated to the actual question. Thx. – Drew May 8 at 14:33
  • I'm specifically interested in making overlays in the minibuffer, so that's an example for it. Updated with simpler code. Where the overlay lives is kinda irrelevant since the behaviour will be the same. – Plow May 8 at 15:54
  • If where the overlay lives is irrelevant, as you say, then please remove the irrelevant minibuffer example. If it instead is relevant then make clear what the relevance to your question is. – Drew May 8 at 23:41

Your two overlays have coincident beginning and end; that is, the beginning and end position are the same. So regardless of the order of what is displayed by properties before-string' and after-string', the definitions of those properties hold.

The Elisp manual, node Overlay Properties tells us:

‘before-string’ This property’s value is a string to add to the display at the beginning of the overlay. The string does not appear in the buffer in any sense—only on the screen.

‘after-string’ This property’s value is a string to add to the display at the end of the overlay. The string does not appear in the buffer in any sense—only on the screen.

Both of those hold, because the beginning and end positions are the same. Your ? is after that position and your ! is before it. Nothing about the definitions is violated. Those descriptions hint that you shouldn't (can't) depend on the apparent order of those displayed strings when beginning and end coincide.

You can remove the overlay-move sexps from your minimal example, as they do nothing.

I suspect this may be an X-Y question. What's the question behind your question - what is it that you are really trying to do? (Ask that in a separate question - don't edit this one to change this one.) Why are you trying to use before-string and after-string on empty overlays?

  • Yes, in C-code the overlays are hold in two lists overlays_before and overlays_after with respect to the some position overlay_center. A new overlay is knowingly put into the wrong list and the two lists are corrected by recenter_overlay_lists afterwards. That means they are re-ordered. Because of lack of time I didn't check thoroughly whether this sorting is stable. But, if it is not, the order of overlays with the same begin and end is undefined. – Tobias May 9 at 4:41
  • @Drew I want to know how can I order overlays defined in the same position. I used before-string and after-string but the question holds for several overlays with the same property (e.g. before-string). Since the position is empty before-string and after-string are irrelevant. @Tobias if the order is undefined and cannot be set that would be an actual answer for my question. – Plow May 9 at 8:23
  • The doc string seems pretty clear in suggesting that you have no control over the apparent order of those display strings the both their beginning and end coincide. – Drew May 9 at 17:37
  • You haven't addressed my question to you about the use case - what you're really trying to do. Why are you using overlays here whose beginning and end coincide? What's that for? – Drew May 9 at 17:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.