PosTip

The standard library tooltip.el provides the function for displaying a tooltip at mouse position which allows users to easily show it. However, locating tooltip at arbitrary buffer position in window is not easy. This program provides such function to be used by other frontend programs.

This program is tested on GNU Emacs 22, 23 under X window system and Emacs 23 for MS-Windows.

Downloading

Lisp:pos-tip.el
Bazaar branch in Launchpad

Installation

To use pos-tip.el, save this file in a directory listed in load-path together with the programs which use this library, and put the following in your .emacs file:

 (require 'pos-tip)

To use the full features of this program on MS-Windows, put the additional setting in .emacs file:

 (pos-tip-w32-max-width-height)   ; Maximize frame temporarily

or

 (pos-tip-w32-max-width-height t) ; Keep frame maximized

Sample program 1: Describe function in tooltip

Code

 (require 'pos-tip)
 (defun my-describe-function (function)
   "Display the full documentation of FUNCTION (a symbol) in tooltip."
   (interactive (list (function-called-at-point)))
   (if (null function)
       (pos-tip-show
        "** You didn't specify a function! **" '("red"))
     (pos-tip-show
      (with-temp-buffer
        (let ((standard-output (current-buffer))
              (help-xref-following t))
          (prin1 function)
          (princ " is ")
          (describe-function-1 function)
          (buffer-string)))
      nil nil nil 0)))
 (define-key emacs-lisp-mode-map (kbd "C-;") 'my-describe-function)

You can also try the package clippy.el. It does the same thing with a little twist ☺

Screenshot

PosTipScreenshotDescFun

Sample program 2: Show quick help of popup.el by real tooltip

popup.el, written by Matsuyama, is a library which provides useful functions to easily show popup menu using overlays and is used by auto-complete.el etc.

popup.el itself can show tooltip to display annotation of the menu items, but it’s unreadable when window is small. Here are two solutions for this problem.

Solution 1

Put the following to your .emacs file:

 (require 'pos-tip)
 (defadvice popup-menu-show-quick-help
   (around pos-tip-popup-menu-show-quick-help () activate)
   "Show quick help using `pos-tip-show'."
   (if (eq window-system 'x)
       (let ((doc (popup-menu-document
                   menu (or item
                            (popup-selected-item menu)))))
         (when (stringp doc)
           (pos-tip-show doc nil
                         (if (popup-hidden-p menu)
                             (or (plist-get args :point)
                                 (point))
                           (overlay-end (popup-line-overlay
                                         menu (+ (popup-offset menu)
                                                 (popup-selected-line menu)))))
                         nil 0)
           nil))
     ad-do-it))

Solution 2 (popup-pos-tip.el)

popup-pos-tip.el is pos-tip.el wrapper library for programs using popup.el.

Lisp:popup-pos-tip.el

Save this file as popup-pos-tip.el in a directory that is listed in load-path, and add the following to .emacs:

 (require 'popup-pos-tip)
 (defadvice popup-tip
   (around popup-pos-tip-wrapper (string &rest args) activate)
   (if (eq window-system 'x)
       (apply 'popup-pos-tip string args)
     ad-do-it))

Screenshot

PosTipScreenshotAutoComplete

Sample program 3: sdic-inline-pos-tip.el

This program provides the tooltip showing word meanings at cursor position like `rikaichan’ Firefox extension, using Lisp:sdic-inline.el which was written by khiker.

Downloading

Lisp:sdic-inline-pos-tip.el

Screenshot

PosTipScreenshot

Setting

 (require 'sdic-inline-pos-tip)
 ;; *Change the following lines according to your environment*
 (setq sdic-inline-eiwa-dictionary "/usr/share/dict/gene.sdic")
 (setq sdic-inline-waei-dictionary "/usr/share/dict/jedict.sdic")
 ;; The following is optional. Uncomment if necessary.
 ;; (mapc (lambda (mode)
 ;;         (add-to-list 'sdic-inline-enable-modes mode))
 ;;       '(help-mode Info-mode))
 ;; (mapc (lambda (face)
 ;;         (add-to-list 'sdic-inline-enable-faces face))
 ;;       '(font-lock-doc-face))
 (setq sdic-inline-search-func 'sdic-inline-search-word-with-stem)
 (setq sdic-inline-display-func 'sdic-inline-pos-tip-show)
 (define-key sdic-inline-map "\C-c\C-p" 'sdic-inline-pos-tip-show)
 (sdic-inline-mode 1)

Discussion

Some unsolicited feedback. ;-)

  • Doesn’t work for me. This is what I have in buffer *xwininfo*, after the ‘call-process’: /usr/bin/bash: xwininfo: command not found. I’m using Cygwin (and Windows). Please state in the file’s Commentary what the prerequisites are (and which Emacs versions are supported).
  • Just out of curiosity, why not just add some optional parameters left and top to ‘tooltip-show’ (calling it, e.g. ‘my-tooltip-show’), and then add this to the body:
        (when left (setq params  (tooltip-set-param params 'left left)))
        (when top  (setq params  (tooltip-set-param params 'top top)))
That’s simple and seems to work. And you could also convert between window/buffer position and pixels, if you like.

I agree that it is too bad that there is no simple way to show a tooltip at a specified position. The code should not be tightly coupled to a mouse position, as it is currently. Perhaps you can suggest a change to the Emacs developers, to allow passing the display position explicitly. – DrewAdams

I think your solution for ‘tooltip-show’ is insufficient because tooltip immediately vanishes if it overlaps with mouse pointer. ‘pos-tip-show’ can move out mouse pointer. – irie
There is apparently an Emacs 23 bug – I just filed a report (#5703). It works fine in Emacs 22, but Emacs 23 ignores the specified ‘left’ and ‘top’ locations, contradicting the doc strings of both ‘tooltip-show’ and ‘tooltip-frame-parameters’. In Emacs 23, it always uses the mouse pointer location, which is wrong. – DrewAdams
Hmm… I can’t reproduce such bug.
Anyway, Emacs should provide functions which return absolute coordinates of buffer position or window origin. Otherwise the ‘left’ and ‘top’ properties of tooltip are useless in non-X environments. – irie
It’s probably a Windows-specific bug.
(frame-parameters) in a console (i.e. non-graphic) frame does not have ‘left’ and ‘top’ to let you know where it is or let you position it. I suppose there’s no way to let you (Emacs) control this.
Function ‘window-edges’ will give you the location of a window wrt its frame, and ‘frame-parameters’ will give you the location of the frame (except for a console frame). – DrewAdams
Of course I’ve known them. To calculate absolute coordinates under X window system, users must also obtain the pixel height of menu-bar and tool-bar and the pixel width of frame extents, because ‘window-edges’ returns the location of window relative to a X window corresponding to ‘window-id’, but ‘frame-parameter’ returns the location of a X window corresponding to ‘outer-window-id’ or ‘parent-id’. That is, these two functions regard the different X windows as ‘frame’. Unfortunately, there is no way to obtain the tool-bar height etc. without calling external programs like xwininfo. – irie
Agreed. Consider filing a bug (enhancement request): M-x report-emacs-bugDrewAdams

There is a simple function point-to-coord in ourcomments-util.el in nXhtml that I have suggested adding to Emacs (without success yet) which I have been using for poping up a menu at point. Maybe this can be merged with pos-tip-compute-pixel-position here? – LennartBorgman

It seems that ‘point-to-coord’ returns the pixel position relative to top left corner of frame, but tooltip must be specified it relative to top left corner of display because tooltip itself is a small frame. – irie

Yes, but shouldn’t it be easy to translate to that format? – LennartBorgman

No, it’s probably impossible. I investigated the behaviors of ‘frame-parameters’, ‘window-pixel-edges’ and ‘posn-at-point’ in Emacs for MS-Windows by using Wine, and found that the calculation of absolute coordinates need additional information, the menu-bar height and the width of frame extents (including the title-bar height). At least Emacs doesn’t provide functions which return these amounts. – irie

Maybe you can propose some new function for Emacs that would make it possible?


Since pos-tip.el uses UTF-8, the first line should read

    pos-tip.el -- Show tooltip at point -*- coding: utf-8 -*-

VegardOye

Thanks. I modified. – irie

The function ‘pos-tip-show-no-propertize’ passes a ‘foreground-color’ property to ‘x-show-tip’ (line 364), but it has no effect at all, at least in my system. So I’m using this temporal fix:

    (defadvice pos-tip-show-no-propertize (before fix-pos-tip-foreground-color)
       (let ((fg (...)))
       (ad-set-arg 0 (propertize (ad-get-arg 0)
                              'face `(cons (foreground-color . ,fg) 'pos-tip-temp)))))

Is this a real bug? or is there any better solution? – SeungcheolJung?

Hmm… I can’t reproduce such problem. Can you describe more detail? Anyway, your solution isn’t good, because it overrides the faces of STRING and ‘pos-tip-show-no-propertize’ always shows tooltip text with ‘default’ face. – irie
Sorry for disturbing you. It works fine when I launch Emacs with ‘-q’… I’m not sure what other elisps mess up it.
It seems that ‘foreground-color’ in ‘default-frame-alist’ affects foreground color of tooltips made by ‘x-show-tip’. Am I right? – SeungcheolJung?
Thanks, I confirmed it and released new version in which the problem is fixed. – irie
I can actually reproduce the problem with foreground colour. The problem seems to be that when you apply a colour theme, changing properties of ‘default’ face, the foreground colour of the frame is no longer used for drawing text, and instead the colour from the ‘default’ face is used. So, essentially, there’s no way to set foreground colour of tooltip text using ‘pos-tip-show’.
I have looked at tooltip.el, and it seems that it not only sets frame parameters passed to ‘x-show-tip’, but also face property of the text to display. I used the same approach, and seems to have fixed the issue. However, I also had problem with showing the first tooltip after launching Emacs that seemed to be related with pos-tip using ‘make-face’ to create a temporary face for use inside ‘pos-tip-show’. I have replaced that with passing a list of face attributes to ‘propertize’, but I have no idea if I haven’t just broken backwards compatibility.
Any idea how should I contribute back those patches/get them reviewed by someone with more experience in programming Emacs libraries? They are currently available at https://github.com/pitkali/pos-tip/tree/fix/fg-color-and-themes (forked from emacsmirror repository). – pitkali
On windows 7 the display is very slow, it seems to be related to the fact that pos-tip-calibrate-frame-offset always returns nil because delete-frame-functions is explicitly not called for tooltip frames. This means that pos-tip-w32-max-width-height doesn’t work either. I inserted the following after (sit-for 0):
    (mapc (lambda (frame) (if (equal (frame-parameter frame 'name) "tooltip")
                         (setq pos-tip-frame-offset
                               (cons (eval (frame-parameter frame 'left))
                                     (eval (frame-parameter frame 'top)))))) (visible-frame-list))

Which fixed that problem, but things still seem slow


CategoryWindows CategoryFrames