From 06ccf155aabc663a92bb6552df74df52c2c6fec5 Mon Sep 17 00:00:00 2001 From: Vladimir Kazanov Date: Sun, 24 Dec 2023 11:13:10 +0000 Subject: [PATCH v3] Tooltips for user-defined fringe indicators --- doc/lispref/display.texi | 7 +++-- etc/NEWS | 6 ++++ etc/TODO | 4 --- src/frame.c | 2 ++ src/xdisp.c | 61 ++++++++++++++++++++++++++++++++++++++-- 5 files changed, 71 insertions(+), 9 deletions(-) diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi index f82c2fad14d..b3b81bd342c 100644 --- a/doc/lispref/display.texi +++ b/doc/lispref/display.texi @@ -5492,14 +5492,15 @@ Other Display Specs but it is done as a special case of marginal display (@pxref{Display Margins}). -@item (left-fringe @var{bitmap} @r{[}@var{face}@r{]}) -@itemx (right-fringe @var{bitmap} @r{[}@var{face}@r{]}) +@item (left-fringe @var{bitmap} @r{[}@var{face}@r{]} @r{[}@var{help-echo}@r{]}) +@itemx (right-fringe @var{bitmap} @r{[}@var{face}@r{]} @r{[}@var{help-echo}@r{]}) This display specification on any character of a line of text causes the specified @var{bitmap} be displayed in the left or right fringes for that line, instead of the characters that have the display specification. The optional @var{face} specifies the face whose colors are to be used for the bitmap display. @xref{Fringe Bitmaps}, -for the details. +for the details. The optional @var{help-echo} string can be used to +display tooltips or help text in the echo area. @item (space-width @var{factor}) This display specification affects all the space characters within the diff --git a/etc/NEWS b/etc/NEWS index 32cec82f970..b1f72cb9bf4 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1815,6 +1815,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 for user fringe indicators. +User fringe indicators defined in text display specifications now +support user-defined tooltips. See the "Other Display Specifications" +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 diff --git a/etc/TODO b/etc/TODO index 52c77ccc28d..21b504ad18b 100644 --- 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. diff --git a/src/frame.c b/src/frame.c index abd6ef00901..ff99b0353af 100644 --- a/src/frame.c +++ b/src/frame.c @@ -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"); diff --git a/src/xdisp.c b/src/xdisp.c index 140d71129f3..b4d57b5b6f2 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -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 -- 2.34.1