GNU bug report logs - #80025
Margin columns

Previous Next

Package: emacs;

Reported by: Juri Linkov <juri <at> linkov.net>

Date: Wed, 17 Dec 2025 18:31:03 UTC

Severity: normal

To reply to this bug, email your comments to 80025 AT debbugs.gnu.org.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to eliz <at> gnu.org, bug-gnu-emacs <at> gnu.org:
bug#80025; Package emacs. (Wed, 17 Dec 2025 18:31:04 GMT) Full text and rfc822 format available.

Acknowledgement sent to Juri Linkov <juri <at> linkov.net>:
New bug report received and forwarded. Copy sent to eliz <at> gnu.org, bug-gnu-emacs <at> gnu.org. (Wed, 17 Dec 2025 18:31:05 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Juri Linkov <juri <at> linkov.net>
To: bug-gnu-emacs <at> gnu.org
Subject: Margin columns
Date: Wed, 17 Dec 2025 20:28:17 +0200
[Message part 1 (text/plain, inline)]
[moved from emacs-devel]

>> I see that PRODUCE_GLYPHS calls either 'produce_glyphs' directly or
>> 'FRAME_RIF->produce_glyphs' ('gui_produce_glyphs').  Then both versions
>> have several calls to 'append_glyph'.  This means that the most suitable
>> place for filling with the SPC character glyph in the margins is
>> 'append_glyph'?
>
> Yes.  You need to modify this line:
>
>   glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
>
> It currently makes 'glyph' point to the next glyph-row slot, and then
> fills that slot with the information about the character.  Instead,
> the new code should (in case of margins only) find the slot whose
> index is the column number you want to use, and, if that slot is
> beyond the one identified by used[are] as above, fill the preceding
> columns with a space glyph.

Thanks for pointing to the right place.

So I tried to do exactly this, filling the columns with the space glyph,
and it works.

Currently the margin column is hard-coded for testing.
But since now the hardest part is done, it's trivial
to get the margin column from the display spec.

I see two ways of sending the value of the margin column
from 'handle_single_display_spec' to 'append_glyph':

1. using a static variable;
2. adding a new field to the struct 'it'.

What variant would be more preferable?

Here is the current state:

[margin_column.patch (text/x-diff, inline)]
diff --git a/src/xdisp.c b/src/xdisp.c
index 06d5481acd3..13f580e0e9d 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -31863,7 +31863,38 @@ append_glyph (struct it *it)
   eassert (it->glyph_row);
   eassert (it->char_to_display != '\n' && it->char_to_display != '\t');
 
-  glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
+  if (area == LEFT_MARGIN_AREA || area == RIGHT_MARGIN_AREA)
+    {
+      int margin_column = 2;
+      if (margin_column < (area == LEFT_MARGIN_AREA
+			   ? WINDOW_LEFT_MARGIN_WIDTH (it->w)
+			   : WINDOW_RIGHT_MARGIN_WIDTH (it->w)))
+	{
+	  int face_id = lookup_basic_face (it->w, it->f, DEFAULT_FACE_ID);
+	  while (it->glyph_row->used[area] < margin_column
+		 && it->glyph_row->glyphs[area] + it->glyph_row->used[area]
+		 < it->glyph_row->glyphs[area + 1])
+	    {
+	      struct glyph *fill_glyph =
+		it->glyph_row->glyphs[area] + it->glyph_row->used[area];
+	      *fill_glyph = space_glyph;
+	      fill_glyph->pixel_width = FRAME_COLUMN_WIDTH (it->f);
+	      fill_glyph->face_id = face_id;
+	      fill_glyph->frame = it->f;
+	      ++it->glyph_row->used[area];
+	    }
+
+	  glyph = it->glyph_row->glyphs[area] + margin_column;
+
+	  if (margin_column >= it->glyph_row->used[area])
+	    it->glyph_row->used[area] = margin_column + 1;
+	}
+      else
+	glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
+    }
+  else
+    glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
+
   if (glyph < it->glyph_row->glyphs[area + 1])
     {
       /* If the glyph row is reversed, we need to prepend the glyph
@@ -31928,7 +31959,8 @@ append_glyph (struct it *it)
 	  glyph->resolved_level = 0;
 	  glyph->bidi_type = UNKNOWN_BT;
 	}
-      ++it->glyph_row->used[area];
+      if (!(area == LEFT_MARGIN_AREA || area == RIGHT_MARGIN_AREA))
+	++it->glyph_row->used[area];
     }
   else
     IT_EXPAND_MATRIX_WIDTH (it, area);

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#80025; Package emacs. (Wed, 17 Dec 2025 18:43:02 GMT) Full text and rfc822 format available.

Message #8 received at 80025 <at> debbugs.gnu.org (full text, mbox):

From: Eli Zaretskii <eliz <at> gnu.org>
To: Juri Linkov <juri <at> linkov.net>
Cc: 80025 <at> debbugs.gnu.org
Subject: Re: bug#80025: Margin columns
Date: Wed, 17 Dec 2025 20:41:53 +0200
> Cc: Eli Zaretskii <eliz <at> gnu.org>
> From: Juri Linkov <juri <at> linkov.net>
> Date: Wed, 17 Dec 2025 20:28:17 +0200
> 
> >> I see that PRODUCE_GLYPHS calls either 'produce_glyphs' directly or
> >> 'FRAME_RIF->produce_glyphs' ('gui_produce_glyphs').  Then both versions
> >> have several calls to 'append_glyph'.  This means that the most suitable
> >> place for filling with the SPC character glyph in the margins is
> >> 'append_glyph'?
> >
> > Yes.  You need to modify this line:
> >
> >   glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
> >
> > It currently makes 'glyph' point to the next glyph-row slot, and then
> > fills that slot with the information about the character.  Instead,
> > the new code should (in case of margins only) find the slot whose
> > index is the column number you want to use, and, if that slot is
> > beyond the one identified by used[are] as above, fill the preceding
> > columns with a space glyph.
> 
> Thanks for pointing to the right place.
> 
> So I tried to do exactly this, filling the columns with the space glyph,
> and it works.
> 
> Currently the margin column is hard-coded for testing.
> But since now the hardest part is done, it's trivial
> to get the margin column from the display spec.
> 
> I see two ways of sending the value of the margin column
> from 'handle_single_display_spec' to 'append_glyph':
> 
> 1. using a static variable;
> 2. adding a new field to the struct 'it'.
> 
> What variant would be more preferable?

The second one is cleaner.

> +	  glyph = it->glyph_row->glyphs[area] + margin_column;
> +
> +	  if (margin_column >= it->glyph_row->used[area])
> +	    it->glyph_row->used[area] = margin_column + 1;

I would omit the "+ 1" part in the last line, and then this:

> -      ++it->glyph_row->used[area];
> +      if (!(area == LEFT_MARGIN_AREA || area == RIGHT_MARGIN_AREA))
> +	++it->glyph_row->used[area];

could be left unchanged, AFAICT.

Thanks.




This bug report was last modified 2 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.