Optional display of overlay-arrow in margin (bug#81109)

* lisp/emacs-lisp/edebug.el (edebug-prepare-margin): New
function to set up left margin for Edebug.
(edebug--display-1): Use it.
* src/xdisp.c (display_line): Try to use left margin to display
overlay arrow and fallback to the text area otherwise.
* doc/lispref/display.texi (Overlay Arrow):
* doc/lispref/edebug.texi (Using Edebug):
* doc/emacs/building.texi (Debugger Operation): Document the
change.
* etc/NEWS: Announce the change.
This commit is contained in:
Manuel Giraud 2026-05-28 10:01:58 +02:00 committed by Eli Zaretskii
parent 90de836831
commit 15e5f404f0
6 changed files with 57 additions and 19 deletions

View file

@ -746,13 +746,13 @@ for special commands that can be used in the GUD interaction buffer.
As you debug a program, Emacs displays the relevant source files by As you debug a program, Emacs displays the relevant source files by
visiting them in Emacs buffers, with an arrow in the left fringe visiting them in Emacs buffers, with an arrow in the left fringe
indicating the current execution line. (On a text terminal, the arrow indicating the current execution line. (On a text terminal, the arrow
appears as @samp{=>}, overlaid on the first two text columns.) Moving appears as @samp{=>}, in the left margin.) Moving point in such a
point in such a buffer does not move the arrow. You are free to edit buffer does not move the arrow. You are free to edit these source
these source files, but note that inserting or deleting lines will files, but note that inserting or deleting lines will throw off the
throw off the arrow's positioning, as Emacs has no way to figure out arrow's positioning, as Emacs has no way to figure out which edited
which edited source line corresponds to the line reported by the source line corresponds to the line reported by the debugger subprocess.
debugger subprocess. To update this information, you typically have To update this information, you typically have to recompile and restart
to recompile and restart the program. the program.
@cindex GUD and hl-line-mode @cindex GUD and hl-line-mode
@cindex highlighting execution lines in GUD @cindex highlighting execution lines in GUD

View file

@ -5065,11 +5065,12 @@ to the left of the display area.
@defvar overlay-arrow-position @defvar overlay-arrow-position
This variable holds a marker that indicates where to display the overlay This variable holds a marker that indicates where to display the overlay
arrow. It should point at the beginning of a line. On a non-graphical arrow. It should point at the beginning of a line. On a non-graphical
display, or when the left fringe is not shown, the arrow text display, or when the left fringe is not shown, the arrow text appears at
appears at the beginning of that line, overlaying any text that would the beginning of that line, overlaying any text that would otherwise
otherwise appear. Since the arrow is usually short, and the line appear. Since the arrow is usually short, and the line usually begins
usually begins with indentation, normally nothing significant is with indentation, normally nothing significant is overwritten. If the
overwritten. window has a left margin with enough space, Emacs displays the arrow
there instead and the text area is not overwritten.
The overlay-arrow string is displayed in any given buffer if the value The overlay-arrow string is displayed in any given buffer if the value
of @code{overlay-arrow-position} in that buffer points into that of @code{overlay-arrow-position} in that buffer points into that

View file

@ -105,8 +105,10 @@ the Lisp code you are debugging. This is referred to as the @dfn{source
code buffer}, and it is temporarily read-only. code buffer}, and it is temporarily read-only.
An arrow in the left fringe indicates the line where the function is An arrow in the left fringe indicates the line where the function is
executing. Point initially shows where within the line the function is executing. On a non-graphical display (or when the left fringe is not
executing, but this ceases to be true if you move point yourself. shown), this arrow is displayed in the left margin instead. Point
initially shows where within the line the function is executing, but
this ceases to be true if you move point yourself.
If you instrument the definition of @code{fac} (shown below) and then If you instrument the definition of @code{fac} (shown below) and then
execute @code{(fac 3)}, here is what you would normally see. Point is execute @code{(fac 3)}, here is what you would normally see. Point is

View file

@ -72,6 +72,13 @@ accept or ignore the value.
unconditionally. The previous behavior, toggling the mode, was unconditionally. The previous behavior, toggling the mode, was
neither reliable nor generally desirable. neither reliable nor generally desirable.
+++
** Emacs tries to display overlay arrow in the left margin.
On a non-graphical display (or when the left fringe is not shown), if a
left margin is present, Emacs will now display the overlay arrow into
this margin. Edebug is now using this feature by explicitly setting up
a left margin for it.
* Editing Changes in Emacs 32.1 * Editing Changes in Emacs 32.1

View file

@ -2721,6 +2721,9 @@ when edebug becomes active."
edebug-function) edebug-function)
)) ))
;; Margin setup for overlay arrow.
(edebug-prepare-margin)
;; Make sure we bind those in the right buffer (bug#16410). ;; Make sure we bind those in the right buffer (bug#16410).
(let ((overlay-arrow-position overlay-arrow-position) (let ((overlay-arrow-position overlay-arrow-position)
(overlay-arrow-string overlay-arrow-string)) (overlay-arrow-string overlay-arrow-string))
@ -3001,6 +3004,17 @@ when edebug becomes active."
) )
"Association list of arrows for each edebug mode.") "Association list of arrows for each edebug mode.")
(defun edebug-prepare-margin ()
"Increase (or set) left margin with the size of the longest arrow string."
(let ((arrow-len (apply #'max (mapcar (lambda (x)
(string-width (cdr x)))
edebug-arrow-alist)))
(margins (window-margins)))
;; Set or increase left margin.
(if (numberp (car margins))
(set-window-margins nil (+ (car margins) arrow-len))
(set-window-margins nil arrow-len))))
(defun edebug-overlay-arrow () (defun edebug-overlay-arrow ()
;; Set up the overlay arrow at beginning-of-line in current buffer. ;; Set up the overlay arrow at beginning-of-line in current buffer.
;; The arrow string is derived from edebug-arrow-alist and ;; The arrow string is derived from edebug-arrow-alist and
@ -3011,7 +3025,6 @@ when edebug becomes active."
(setq overlay-arrow-position (make-marker)) (setq overlay-arrow-position (make-marker))
(set-marker overlay-arrow-position pos (current-buffer)))) (set-marker overlay-arrow-position pos (current-buffer))))
(defun edebug-toggle-save-all-windows () (defun edebug-toggle-save-all-windows ()
"Toggle the saving and restoring of all windows. "Toggle the saving and restoring of all windows.
Also, each time you toggle it on, the inside and outside window Also, each time you toggle it on, the inside and outside window

View file

@ -26753,8 +26753,23 @@ display_line (struct it *it, int cursor_vpos)
= get_overlay_arrow_glyph_row (it->w, overlay_arrow_string); = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
struct glyph *glyph = arrow_row->glyphs[TEXT_AREA]; struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA]; struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
struct glyph *p = row->glyphs[TEXT_AREA]; struct glyph *p, *p2, *end, *where;
struct glyph *p2, *end; short *p_used;
/* When possible, put the arrow glyphs at the start of the
left margin. Otherwise put them at the start of the text
area. */
if (WINDOW_LEFT_MARGIN_WIDTH (it->w) >= arrow_row->used[TEXT_AREA])
{
p = where = row->glyphs[LEFT_MARGIN_AREA];
p_used = &(row->used[LEFT_MARGIN_AREA]);
row->used[LEFT_MARGIN_AREA] += arrow_row->used[TEXT_AREA];
}
else
{
p = where = row->glyphs[TEXT_AREA];
p_used = &(row->used[TEXT_AREA]);
}
/* Copy the arrow glyphs. */ /* Copy the arrow glyphs. */
while (glyph < arrow_end) while (glyph < arrow_end)
@ -26762,14 +26777,14 @@ display_line (struct it *it, int cursor_vpos)
/* Throw away padding glyphs. */ /* Throw away padding glyphs. */
p2 = p; p2 = p;
end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]; end = where + *p_used;
while (p2 < end && CHAR_GLYPH_PADDING_P (*p2)) while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
++p2; ++p2;
if (p2 > p) if (p2 > p)
{ {
while (p2 < end) while (p2 < end)
*p++ = *p2++; *p++ = *p2++;
row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA]; *p_used = p2 - where;
} }
} }
else else