master 15e5f404f05: Optional display of overlay-arrow in margin (bug#81109)

Eli Zaretskii <[email protected]>
Newsgroups gmane.emacs.diffs
Message-ID <[email protected]>
branch: master
commit 15e5f404f05f7a1ca5bdd8eb6a7579e0546472da
Author: Manuel Giraud <[email protected]>
Commit: Eli Zaretskii <[email protected]>

    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.
---
 doc/emacs/building.texi   | 14 +++++++-------
 doc/lispref/display.texi  | 11 ++++++-----
 doc/lispref/edebug.texi   |  6 ++++--
 etc/NEWS                  |  7 +++++++
 lisp/emacs-lisp/edebug.el | 15 ++++++++++++++-
 src/xdisp.c               | 23 +++++++++++++++++++----
 6 files changed, 57 insertions(+), 19 deletions(-)

diff --git a/doc/emacs/building.texi b/doc/emacs/building.texi
index 2af98997480..78c13903edf 100644
--- a/doc/emacs/building.texi
+++ b/doc/emacs/building.texi
@@ -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
 visiting them in Emacs buffers, with an arrow in the left fringe
 indicating the current execution line.  (On a text terminal, the arrow
-appears as @samp{=>}, overlaid on the first two text columns.)  Moving
-point in such a buffer does not move the arrow.  You are free to edit
-these source files, but note that inserting or deleting lines will
-throw off the arrow's positioning, as Emacs has no way to figure out
-which edited source line corresponds to the line reported by the
-debugger subprocess.  To update this information, you typically have
-to recompile and restart the program.
+appears as @samp{=>}, in the left margin.)  Moving point in such a
+buffer does not move the arrow.  You are free to edit these source
+files, but note that inserting or deleting lines will throw off the
+arrow's positioning, as Emacs has no way to figure out which edited
+source line corresponds to the line reported by the debugger subprocess.
+To update this information, you typically have to recompile and restart
+the program.
 
 @cindex GUD and hl-line-mode
 @cindex highlighting execution lines in GUD
diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi
index 49b09f6583d..ae7d314c795 100644
--- a/doc/lispref/display.texi
+++ b/doc/lispref/display.texi
@@ -5065,11 +5065,12 @@ to the left of the display area.
 @defvar overlay-arrow-position
 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
-display, or when the left fringe is not shown, the arrow text
-appears at the beginning of that line, overlaying any text that would
-otherwise appear.  Since the arrow is usually short, and the line
-usually begins with indentation, normally nothing significant is
-overwritten.
+display, or when the left fringe is not shown, the arrow text appears at
+the beginning of that line, overlaying any text that would otherwise
+appear.  Since the arrow is usually short, and the line usually begins
+with indentation, normally nothing significant is overwritten.  If the
+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
 of @code{overlay-arrow-position} in that buffer points into that
diff --git a/doc/lispref/edebug.texi b/doc/lispref/edebug.texi
index 8aec8abf7c0..e729cb7aef3 100644
--- a/doc/lispref/edebug.texi
+++ b/doc/lispref/edebug.texi
@@ -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.
 
   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, but this ceases to be true if you move point yourself.
+executing.  On a non-graphical display (or when the left fringe is not
+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
 execute @code{(fac 3)}, here is what you would normally see.  Point is
diff --git a/etc/NEWS b/etc/NEWS
index 70bb5a8ac0b..1efc9a86b86 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -72,6 +72,13 @@ accept or ignore the value.
 unconditionally.  The previous behavior, toggling the mode, was
 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
 
diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el
index 3bb12e18842..d938e39b30b 100644
--- a/lisp/emacs-lisp/edebug.el
+++ b/lisp/emacs-lisp/edebug.el
@@ -2721,6 +2721,9 @@ when edebug becomes active."
                               edebug-function)
                 ))
 
+          ;; Margin setup for overlay arrow.
+          (edebug-prepare-margin)
+
           ;; Make sure we bind those in the right buffer (bug#16410).
           (let ((overlay-arrow-position overlay-arrow-position)
                 (overlay-arrow-string overlay-arrow-string))
@@ -3001,6 +3004,17 @@ when edebug becomes active."
     )
   "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 ()
   ;; Set up the overlay arrow at beginning-of-line in current buffer.
   ;; The arrow string is derived from edebug-arrow-alist and
@@ -3011,7 +3025,6 @@ when edebug becomes active."
     (setq overlay-arrow-position (make-marker))
     (set-marker overlay-arrow-position pos (current-buffer))))
 
-
 (defun edebug-toggle-save-all-windows ()
   "Toggle the saving and restoring of all windows.
 Also, each time you toggle it on, the inside and outside window
diff --git a/src/xdisp.c b/src/xdisp.c
index 67fe2295dc2..e2321762699 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -26753,8 +26753,23 @@ display_line (struct it *it, int cursor_vpos)
 	    = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
 	  struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
 	  struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
-	  struct glyph *p = row->glyphs[TEXT_AREA];
-	  struct glyph *p2, *end;
+	  struct glyph *p, *p2, *end, *where;
+	  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.  */
 	  while (glyph < arrow_end)
@@ -26762,14 +26777,14 @@ display_line (struct it *it, int cursor_vpos)
 
 	  /* Throw away padding glyphs.  */
 	  p2 = p;
-	  end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
+	  end = where + *p_used;
 	  while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
 	    ++p2;
 	  if (p2 > p)
 	    {
 	      while (p2 < end)
 		*p++ = *p2++;
-	      row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
+	      *p_used = p2 - where;
 	    }
 	}
       else
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.