I am using popup-tip and popup-menu* from the http://melpa.org/#/popup library in my extension, but I'd like to use something in stock Emacs so that I can remain zero dependencies.

The built in popup-menu (i.e. x-popup-menu) and x-show-tip don't work for me because they are mouse-centric (i.e. they show the popup at the mouse location) but I need point centric (i.e. popup where the point is) because that's where the user's gaze is centered when the popup appears.

  • 1
    One option might be to use a child-frame, see posframe which makes it easier to create those. But you could also roll you own using make-frame
    – clemera
    Oct 26 '19 at 12:02
  • that interesting but that's just trading one extension for another, I am looking for stock only solutions.
    – fommil
    Oct 26 '19 at 12:36
  • As I mentioned you can use make-frame without using an extension but it requires a bit of work to position and size it correctly.
    – clemera
    Oct 26 '19 at 13:41
  • it's very disappointing that emacs doesn't come with this kind of feature out of the box. I'll certainly take a look at how it looks. In terms of customising, I could also look into positioning the stock popup stuff but it's so very difficult to get it right.
    – fommil
    Oct 26 '19 at 15:03
  • There is also tooltip-show which I totally forgot about.
    – clemera
    Oct 26 '19 at 15:06

The only problem you mention with the "stock" solutions are the positioning. For popup-menu you can provide the position you got from posn-at-point so it appears "at point" instead of "at mouse position". For x-show-tip you need a bit more plumbing to take out the x/y position out of the "posn" and pass it to x-show-tip.

  • What is popup-frame? I can't find a function or variable with that name.
    – jue
    Oct 28 '19 at 9:19
  • It was what we call "a typo" ;-) Thanks for the heads up.
    – Stefan
    Oct 28 '19 at 16:55
  • I'll have a look at trying that! I actually wrote some logic to try and figure out the point but couldn't get it to work. Another small niggle I have with the default look and feel is the appearance of an icon, I'd like it to be just the text not a warning sign.
    – fommil
    Oct 30 '19 at 9:29
  • @fommil: I have no idea what icon or warning sign you're referring to, I'm afraid. Better make it a separate question.
    – Stefan
    Oct 30 '19 at 12:21
  • that's a gtk thing, it looks much better when turned off.
    – fommil
    Oct 30 '19 at 13:43

I did a little POC that I derived from showtip. It does not depend on any external libs:

(defvar tip-timeout 1)

(defvar tip-parameters
  '((name . "tip")
    (internal-border-width . 2)
    (border-width . 1)
    (no-special-glyphs . t)
    (foreground-color . "white")
    (border-color . "white")
    (background-color . "gray")))

(defun tip-frame-parameter (&rest args)
  (let ((fp (apply #'frame-parameter args)))
    ;; this seems to be a bug on my system
    ;; (frame-parameter nil 'left) => (+ -1)
    (if (numberp fp) fp 0)))

(defun tip-posn-at-point (&optional pos window)
  "Return xy positions of top left corner of glyph a POS.

POS is relative to top left corner of frame containing WINDOW and
defaults to the pos of point in the selected window."
  (let* ((window (or window (selected-window)))
         (xy (posn-x-y (posn-at-point pos window)))
         (edges (window-inside-pixel-edges window)))
    (cons (+ (car xy) (car  edges))
          (+ (cdr xy) (cadr edges)))))

(defun tip (text &optional pos timeout window fg bg)
  "Show TEXT in tooltip.

Show tooltip at buffer position POS which defaults to point in
WINDOW which defaults to the selected one.

Hide tooltip after TIMEOUT which defaults to `tip-timeout'.

FG, BG can be used to override foreground and background color
parameters of `tip-parameters'."
  (let* ((xy (tip-posn-at-point pos window))
         (params tip-parameters)
         (left (+ (tip-frame-parameter nil 'left)
                  (car xy)))
         (top (+ (tip-frame-parameter nil 'top)
                 (cdr xy)
                 (- (+ (if menu-bar-mode 25 0)
                       (if tool-bar-mode 35 0)
                       ;; WHY?
                    (if header-line-format
                        (frame-char-height) 0)))))
    (when (stringp fg)
      (setf (alist-get 'foreground-color params) fg)
      (setf (alist-get 'border-color params) fg))
    (when (stringp bg)
      (setf (alist-get 'background-color params) bg))
    (x-show-tip text
                (append params `((left . ,left)
                                 (top . ,top)))
                (or timeout tip-timeout))))
  • White on grey is somewhat unreadable.
    – jue
    Oct 28 '19 at 9:31
  • that's interesting, but rolling a minimal alternative to popup is not exactly what I had in mind. I'm looking for something that already exists in stock.
    – fommil
    Oct 30 '19 at 13:48

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.