]> git.eshelyaron.com Git - emacs.git/commitdiff
Support tooltips for fringe indicators
authorVladimir Kazanov <vekazanov@gmail.com>
Sun, 24 Dec 2023 11:13:10 +0000 (11:13 +0000)
committerEshel Yaron <me@eshelyaron.com>
Sun, 14 Apr 2024 17:10:22 +0000 (19:10 +0200)
* src/xdisp.c (note_fringe_highlight): New function.
(note_mouse_highlight): Call it when the mouse is on the fringes.
* src/frame.c (syms_of_frame) <left-fringe-help>
<right-fringe-help>: DEFSYM them.

* etc/NEWS:
* doc/lispref/text.texi (Special Properties):
* doc/lispref/display.texi (Other Display Specs): Document the new
properties.
* etc/TODO: Remove the todo item about this.

(cherry picked from commit 5734047b812639c06c90eb3baf82ff502db59fb5)

doc/lispref/display.texi
doc/lispref/text.texi
etc/NEWS
etc/TODO
src/frame.c
src/xdisp.c

index 7da73c40cf6ef978eeed104427fe84260e12a6c0..88fdbe547f73dd1e180608cd86b3b0ad322e9e4b 100644 (file)
@@ -5529,6 +5529,10 @@ specification.  The optional @var{face} specifies the face whose
 colors are to be used for the bitmap display.  @xref{Fringe Bitmaps},
 for the details.
 
+It also possible to add context help for fringe bitmaps through the
+@code{show-help-function} mechanism by using @code{left-fringe-help} or
+@code{right-fringe-help} text properties (@pxref{Special Properties}).
+
 @item (space-width @var{factor})
 This display specification affects all the space characters within the
 text that has the specification.  It displays all of these spaces
index c88e03e66e5580da7248626ae53d648b05929588..a12629904b481ba228765073d79bd968fc270df6 100644 (file)
@@ -3666,6 +3666,15 @@ non-@code{nil} @code{help-echo-inhibit-substitution} property, then it
 is displayed as-is by @code{show-help-function}, without being passed
 through @code{substitute-command-keys}.
 
+@item left-fringe-help
+@itemx right-fringe-help
+@cindex help-echo text on fringes
+If any visible text of a buffer line has @code{left-fringe-help} or
+@code{right-fringe-help} string text property defined on it, then the
+string will be displayed for a corresponding line's fringe through
+@code{show-help-function} (@pxref{Help display}).  This is useful when
+used together with fringe cursors and bitmaps (@pxref{Fringes}).
+
 @item keymap
 @cindex keymap of character
 @kindex keymap @r{(text property)}
index e5dcb258511c0e43cc56b1a2f317e0bb9b4e3f79..e1b5200ddfc2015890cae17c85d93756772f1781 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1985,6 +1985,12 @@ the handler code without unwinding the stack, such that we can record
 the backtrace and other dynamic state at the point of the error.  See
 the Info node "(elisp) Handling Errors".
 
++++
+** Tooltips on fringes.
+It is now possible to provide tooltips on fringes by adding special text
+properties.  See the "Special Properties" Info node in the Emacs Lisp
+Reference Manual.
+
 +++
 ** New 'pop-up-frames' action alist entry for 'display-buffer'.
 This has the same effect as the variable of the same name and takes
index 52c77ccc28dff971883fed658f7d7805d4b0eaf3..21b504ad18bf47b8e8b132b793a0800edfda3f85 100644 (file)
--- a/etc/TODO
+++ b/etc/TODO
@@ -172,10 +172,6 @@ Change them to use report-emacs-bug.
 **** lm-report-bug
 **** tramp-bug
 **** c-submit-bug-report
-
-** Allow fringe indicators to display a tooltip
-Provide a help-echo property?
-
 ** Add a defcustom that supplies a function to name numeric backup files
 Like 'make-backup-file-name-function' for non-numeric backup files.
 
index abd6ef00901f3601796e3df4cde9f3b2e3198803..ff99b0353af2674c31318f684be3965dcdb0dbe3 100644 (file)
@@ -6383,6 +6383,7 @@ syms_of_frame (void)
   DEFSYM (Qchild_frame_border_width, "child-frame-border-width");
   DEFSYM (Qinternal_border_width, "internal-border-width");
   DEFSYM (Qleft_fringe, "left-fringe");
+  DEFSYM (Qleft_fringe_help, "left-fringe-help");
   DEFSYM (Qline_spacing, "line-spacing");
   DEFSYM (Qmenu_bar_lines, "menu-bar-lines");
   DEFSYM (Qtab_bar_lines, "tab-bar-lines");
@@ -6390,6 +6391,7 @@ syms_of_frame (void)
   DEFSYM (Qname, "name");
   DEFSYM (Qright_divider_width, "right-divider-width");
   DEFSYM (Qright_fringe, "right-fringe");
+  DEFSYM (Qright_fringe_help, "right-fringe-help");
   DEFSYM (Qscreen_gamma, "screen-gamma");
   DEFSYM (Qscroll_bar_background, "scroll-bar-background");
   DEFSYM (Qscroll_bar_foreground, "scroll-bar-foreground");
index 77d17b91607fc4a670adef4015011dbb10df1894..2bc943c88cdb943b96eccdf9a5716bbfd92cc5ac 100644 (file)
@@ -35730,6 +35730,59 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y,
 }
 
 
+/* Take proper action when mouse has moved to the window WINDOW, with
+   window-local x-position X and y-position Y. This is only used for
+   displaying user-defined fringe indicator help-echo messages.  */
+
+static void
+note_fringe_highlight (Lisp_Object window, int x, int y,
+                      enum window_part part)
+{
+  if (!NILP (help_echo_string))
+    return;
+
+  /* Find a message to display through the help-echo mechanism whenever
+     the mouse hovers over a fringe indicator.  Both text properties and
+     overlays have to be checked.  */
+
+  /* Check the text property symbol to use.  */
+  Lisp_Object sym;
+  if (part == ON_LEFT_FRINGE)
+    sym = Qleft_fringe_help;
+  else
+    sym = Qright_fringe_help;
+
+  /* Translate windows coordinates into a vertical window position.  */
+  int hpos, vpos, area;
+  struct window *w = XWINDOW (window);
+  x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, 0, 0, &area);
+
+  /* Get to the first glyph of a text row based on the vertical position
+     of the fringe.  */
+  struct glyph *glyph = MATRIX_ROW_GLYPH_START(w->current_matrix, vpos);
+  int glyph_num = MATRIX_ROW_USED(w->current_matrix, vpos);
+
+  /* Check all glyphs while looking for fringe tooltips.  */
+
+  /* NOTE: iterating over glyphs can only find text properties coming
+     from visible text.  This means that zero-length overlays and
+     invisibile text are NOT inspected.  */
+  for (;glyph_num; glyph_num--, glyph++)
+    {
+      Lisp_Object pos = make_fixnum(glyph->charpos);
+      Lisp_Object help_echo = Qnil;
+
+      if (STRINGP(glyph->object) || BUFFERP(glyph->object))
+       help_echo = get_char_property_and_overlay (pos, sym, glyph->object, NULL);
+
+      if (STRINGP (help_echo))
+       {
+         help_echo_string = help_echo;
+         break;
+       }
+    }
+}
+
 /* EXPORT:
    Take proper action when the mouse has moved to position X, Y on
    frame F with regards to highlighting portions of display that have
@@ -35957,8 +36010,12 @@ note_mouse_highlight (struct frame *f, int x, int y)
       }
     else
       cursor = FRAME_OUTPUT_DATA (f)->nontext_cursor;
-  else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
-          || part == ON_VERTICAL_SCROLL_BAR
+  else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE)
+    {
+      cursor = FRAME_OUTPUT_DATA (f)->nontext_cursor;
+      note_fringe_highlight (window, x, y, part);
+    }
+  else if (part == ON_VERTICAL_SCROLL_BAR
           || part == ON_HORIZONTAL_SCROLL_BAR)
     cursor = FRAME_OUTPUT_DATA (f)->nontext_cursor;
   else