* bug#37641: major/minor tick faces bleed into empty lines at the end of buffer @ 2019-10-07 1:04 Juanma Barranquero 2019-10-07 3:42 ` Juanma Barranquero 0 siblings, 1 reply; 11+ messages in thread From: Juanma Barranquero @ 2019-10-07 1:04 UTC (permalink / raw) To: 37641 [-- Attachment #1.1: Type: text/plain, Size: 258 bytes --] Quite easy to see with: (setq display-line-numbers-major-tick 5) (set-face-attribute 'line-number-major-tick nil :foreground "white" :background "black") and then just enable line numbers in *Scratch* and insert a few lines at the end. [image: image.png] [-- Attachment #1.2: Type: text/html, Size: 452 bytes --] [-- Attachment #2: image.png --] [-- Type: image/png, Size: 5658 bytes --] ^ permalink raw reply [flat|nested] 11+ messages in thread
* bug#37641: major/minor tick faces bleed into empty lines at the end of buffer 2019-10-07 1:04 bug#37641: major/minor tick faces bleed into empty lines at the end of buffer Juanma Barranquero @ 2019-10-07 3:42 ` Juanma Barranquero 2019-10-07 16:17 ` Eli Zaretskii 0 siblings, 1 reply; 11+ messages in thread From: Juanma Barranquero @ 2019-10-07 3:42 UTC (permalink / raw) To: 37641 [-- Attachment #1: Type: text/plain, Size: 829 bytes --] This patch seems to fix the problem. diff --git i/src/xdisp.c w/src/xdisp.c index 563cf473cf..a2d605f3ea 100644 --- i/src/xdisp.c +++ w/src/xdisp.c @@ -22679,9 +22679,11 @@ maybe_produce_line_number (struct it *it) && it->what != IT_EOB) tem_it.face_id = current_lnum_face_id; - else if (display_line_numbers_major_tick > 0 + else if (!beyond_zv + && display_line_numbers_major_tick > 0 && (lnum_to_display % display_line_numbers_major_tick == 0)) tem_it.face_id = merge_faces (it->w, Qline_number_major_tick, 0, DEFAULT_FACE_ID); - else if (display_line_numbers_minor_tick > 0 + else if (!beyond_zv + && display_line_numbers_minor_tick > 0 && (lnum_to_display % display_line_numbers_minor_tick == 0)) tem_it.face_id = merge_faces (it->w, Qline_number_minor_tick, [-- Attachment #2: Type: text/html, Size: 1039 bytes --] ^ permalink raw reply related [flat|nested] 11+ messages in thread
* bug#37641: major/minor tick faces bleed into empty lines at the end of buffer 2019-10-07 3:42 ` Juanma Barranquero @ 2019-10-07 16:17 ` Eli Zaretskii 2019-10-08 2:38 ` Juanma Barranquero 0 siblings, 1 reply; 11+ messages in thread From: Eli Zaretskii @ 2019-10-07 16:17 UTC (permalink / raw) To: Juanma Barranquero; +Cc: 37641 > From: Juanma Barranquero <lekktu@gmail.com> > Date: Mon, 7 Oct 2019 05:42:46 +0200 > > This patch seems to fix the problem. Looks good, but please simplify by having 2-level if, the outer one checking when to display a number, the inner which face to use for that. There's no need to test beyond_zv more than once, and AFAIR beyond_zv and it->what == IT_EOB are equivalent. Thanks. ^ permalink raw reply [flat|nested] 11+ messages in thread
* bug#37641: major/minor tick faces bleed into empty lines at the end of buffer 2019-10-07 16:17 ` Eli Zaretskii @ 2019-10-08 2:38 ` Juanma Barranquero 2019-10-08 4:23 ` Juanma Barranquero 2019-10-08 8:49 ` Eli Zaretskii 0 siblings, 2 replies; 11+ messages in thread From: Juanma Barranquero @ 2019-10-08 2:38 UTC (permalink / raw) To: Eli Zaretskii; +Cc: 37641 [-- Attachment #1.1: Type: text/plain, Size: 2975 bytes --] On Mon, Oct 7, 2019 at 6:17 PM Eli Zaretskii <eliz@gnu.org> wrote: > Looks good, but please simplify by having 2-level if, the outer one > checking when to display a number, the inner which face to use for > that. There's no need to test beyond_zv more than once, and AFAIR > beyond_zv and it->what == IT_EOB are equivalent. beyond_zv and it->what == IT_EOB are similar, but not equivalent. I see the difference when deleting empty lines at the end of the buffer (specifically, when deleting from the last line, and not past the last line). With the `what' check, the face still bleed info the first post-EOB line. Checking beyond_zv it works (see attached images). As for simplifying the check, it is possible to check beyond_zv only once, with the minor downside of having two paths to set lnum_face (which works as the default face, and the face post-EOB). if (check for current line) // checks also it->what != IT_EOB set face to current_lnum_face; else if (beyond_zv) set face to lnum_face; // 1 else if (check for major tick) set face to major_tick; else if (check for minor tick) set face to minor_tick; else set face to lnum_face; // 2 BTW, if the "it->what != IT_EOB" comparison in the current line check can indeed be changed to !beyond_zv (which seems to work, at least on my tests), then you can go to if (beyond_zv) set face to lnum_face; // 1 else if (check for current line) // does not check it->what != IT_EOB set face to current_lnum_face; else if (check for major tick) set face to major_tick; else if (check for minor tick) set face to minor_tick; else set face to lnum_face; // 2 which is equally clean and saves another comparison. And the nicest thing is that the patch is very clean (attached also because Gmail as usual is screwing with it). diff --git a/src/xdisp.c b/src/xdisp.c index 29d49d57df..ad73981c1d 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -22662,13 +22662,14 @@ maybe_produce_line_number (struct it *it) { /* For continuation lines and lines after ZV, instead of a line number, produce a blank prefix of the same width. */ - if (lnum_face_id != current_lnum_face_id - && (EQ (Vdisplay_line_numbers, Qvisual) - ? this_line == 0 - : this_line == it->pt_lnum) - /* Avoid displaying the line-number-current-line face on - empty lines beyond EOB. */ - && it->what != IT_EOB) + if (beyond_zv) + /* Avoid displaying any face other than line-number on + empty lines beyond EOB. */ + tem_it.face_id = lnum_face_id; + else if (lnum_face_id != current_lnum_face_id + && (EQ (Vdisplay_line_numbers, Qvisual) + ? this_line == 0 + : this_line == it->pt_lnum)) tem_it.face_id = current_lnum_face_id; else if (display_line_numbers_major_tick > 0 && (lnum_to_display % display_line_numbers_major_tick == 0)) [-- Attachment #1.2: Type: text/html, Size: 3644 bytes --] [-- Attachment #2: it_eob.png --] [-- Type: image/png, Size: 4796 bytes --] [-- Attachment #3: beyond_zv.png --] [-- Type: image/png, Size: 5327 bytes --] [-- Attachment #4: beyond.patch --] [-- Type: application/octet-stream, Size: 1058 bytes --] diff --git a/src/xdisp.c b/src/xdisp.c index 29d49d57df..ad73981c1d 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -22662,13 +22662,14 @@ maybe_produce_line_number (struct it *it) { /* For continuation lines and lines after ZV, instead of a line number, produce a blank prefix of the same width. */ - if (lnum_face_id != current_lnum_face_id - && (EQ (Vdisplay_line_numbers, Qvisual) - ? this_line == 0 - : this_line == it->pt_lnum) - /* Avoid displaying the line-number-current-line face on - empty lines beyond EOB. */ - && it->what != IT_EOB) + if (beyond_zv) + /* Avoid displaying any face other than line-number on + empty lines beyond EOB. */ + tem_it.face_id = lnum_face_id; + else if (lnum_face_id != current_lnum_face_id + && (EQ (Vdisplay_line_numbers, Qvisual) + ? this_line == 0 + : this_line == it->pt_lnum)) tem_it.face_id = current_lnum_face_id; else if (display_line_numbers_major_tick > 0 && (lnum_to_display % display_line_numbers_major_tick == 0)) ^ permalink raw reply related [flat|nested] 11+ messages in thread
* bug#37641: major/minor tick faces bleed into empty lines at the end of buffer 2019-10-08 2:38 ` Juanma Barranquero @ 2019-10-08 4:23 ` Juanma Barranquero 2019-10-08 8:51 ` Eli Zaretskii 2019-10-08 8:49 ` Eli Zaretskii 1 sibling, 1 reply; 11+ messages in thread From: Juanma Barranquero @ 2019-10-08 4:23 UTC (permalink / raw) To: Eli Zaretskii; +Cc: 37641 [-- Attachment #1: Type: text/plain, Size: 2036 bytes --] As an aside, if it is safe to assume that the faces are not going to change between digits of the line number, perhaps this change would be a gain. It moves merging the tick faces outside the lnum_buf loop, and it is done only for the right line numbers and when not beyond_zv. diff --git i/src/xdisp.c w/src/xdisp.c index ad73981c1d..2d79a42270 100644 --- i/src/xdisp.c +++ w/src/xdisp.c @@ -22657,6 +22657,21 @@ maybe_produce_line_number (struct it *it) int width_limit = tem_it.last_visible_x - tem_it.first_visible_x - 3 * FRAME_COLUMN_WIDTH (it->f); + + /* Select face for tick line numbers, if needed */ + int tick_face_id = -1; + if (!beyond_zv) + { + if (display_line_numbers_major_tick > 0 + && (lnum_to_display % display_line_numbers_major_tick == 0)) + tick_face_id = merge_faces (it->w, Qline_number_major_tick, + 0, DEFAULT_FACE_ID); + else if (display_line_numbers_minor_tick > 0 + && (lnum_to_display % display_line_numbers_minor_tick == 0)) + tick_face_id = merge_faces (it->w, Qline_number_minor_tick, + 0, DEFAULT_FACE_ID); + } + /* Produce glyphs for the line number in a scratch glyph_row. */ for (const char *p = lnum_buf; *p; p++) { @@ -22671,14 +22686,8 @@ maybe_produce_line_number (struct it *it) ? this_line == 0 : this_line == it->pt_lnum)) tem_it.face_id = current_lnum_face_id; - else if (display_line_numbers_major_tick > 0 - && (lnum_to_display % display_line_numbers_major_tick == 0)) - tem_it.face_id = merge_faces (it->w, Qline_number_major_tick, - 0, DEFAULT_FACE_ID); - else if (display_line_numbers_minor_tick > 0 - && (lnum_to_display % display_line_numbers_minor_tick == 0)) - tem_it.face_id = merge_faces (it->w, Qline_number_minor_tick, - 0, DEFAULT_FACE_ID); + else if (tick_face_id >= 0) + tem_it.face_id = tick_face_id; else tem_it.face_id = lnum_face_id; if (beyond_zv [-- Attachment #2: Type: text/html, Size: 2424 bytes --] ^ permalink raw reply related [flat|nested] 11+ messages in thread
* bug#37641: major/minor tick faces bleed into empty lines at the end of buffer 2019-10-08 4:23 ` Juanma Barranquero @ 2019-10-08 8:51 ` Eli Zaretskii 0 siblings, 0 replies; 11+ messages in thread From: Eli Zaretskii @ 2019-10-08 8:51 UTC (permalink / raw) To: Juanma Barranquero; +Cc: 37641 > From: Juanma Barranquero <lekktu@gmail.com> > Date: Tue, 8 Oct 2019 06:23:36 +0200 > Cc: 37641@debbugs.gnu.org > > As an aside, if it is safe to assume that the faces are not going to change between digits of the line number, > perhaps this change would be a gain. What does "between digits" mean? While producing the glyphs for the digits of a single line number, no faces can change, because no Lisp is invoked. Is that what you meant? > It moves merging the tick faces outside the lnum_buf loop, and it is done only for the right line numbers and > when not beyond_zv. Yes, moving code out of the loop is a good idea. ^ permalink raw reply [flat|nested] 11+ messages in thread
* bug#37641: major/minor tick faces bleed into empty lines at the end of buffer 2019-10-08 2:38 ` Juanma Barranquero 2019-10-08 4:23 ` Juanma Barranquero @ 2019-10-08 8:49 ` Eli Zaretskii 2019-10-08 9:37 ` Juanma Barranquero 1 sibling, 1 reply; 11+ messages in thread From: Eli Zaretskii @ 2019-10-08 8:49 UTC (permalink / raw) To: Juanma Barranquero; +Cc: 37641 > From: Juanma Barranquero <lekktu@gmail.com> > Date: Tue, 8 Oct 2019 04:38:18 +0200 > Cc: 37641@debbugs.gnu.org > > > Looks good, but please simplify by having 2-level if, the outer one > > checking when to display a number, the inner which face to use for > > that. There's no need to test beyond_zv more than once, and AFAIR > > beyond_zv and it->what == IT_EOB are equivalent. > > beyond_zv and it->what == IT_EOB are similar, but not equivalent. I see the difference when deleting empty > lines at the end of the buffer (specifically, when deleting from the last line, and not past the last line). > > With the `what' check, the face still bleed info the first post-EOB line. Checking beyond_zv it works (see > attached images). Sorry, I don't think I understand what the images show me. They seem identical. Which face bleeds and where? Please point out what should I be looking at to understand the difference. Did you try to arrange for the last line to be a multiple of one of the ticks as well? Also, what happens if you use the beyond_zv test in all the conditions, or use the it->what test in all the conditions? IOW, I don't understand why we need two different conditions regarding EOB for displaying a number with different faces. What am I missing? > As for simplifying the check, it is possible to check beyond_zv only once, with the minor downside of having > two paths to set lnum_face (which works as the default face, and the face post-EOB). You could simply start with tem_it.face_id = lnum_face_id; and then have a series of tests for replacing that with another face ID; it would at least save you the 'else' clause. Thanks. ^ permalink raw reply [flat|nested] 11+ messages in thread
* bug#37641: major/minor tick faces bleed into empty lines at the end of buffer 2019-10-08 8:49 ` Eli Zaretskii @ 2019-10-08 9:37 ` Juanma Barranquero 2019-10-08 10:47 ` Juanma Barranquero 0 siblings, 1 reply; 11+ messages in thread From: Juanma Barranquero @ 2019-10-08 9:37 UTC (permalink / raw) To: Eli Zaretskii; +Cc: 37641 [-- Attachment #1: Type: text/plain, Size: 2752 bytes --] On Tue, Oct 8, 2019 at 10:50 AM Eli Zaretskii <eliz@gnu.org> wrote: > Sorry, I don't think I understand what the images show me. They seem > identical. Which face bleeds and where? Please point out what should > I be looking at to understand the difference. In both images, the line numbered 19 is the last line in the buffer. In the it_eob image, the "line" past the end of the buffer has an empty number, drawn with the major-tick face (but obviously without number). The rest of non-lines, until the end of the buffer, have their empty number drawn in the line-number face. In the beyond_zv image, the empty line after the end of the buffer is in the line-number face, as all the other past that point. I think that's the right behavior. There's no reason for the line after the end of the buffer to be drawn with the major-tick face, even if it would be a major-tick line if it existed. It's ugly. > Did you try to arrange for the last line to be a multiple of one of > the ticks as well? In my examples? Yes, that's the whole point of the test: knowing what happens when the line after EOB would match a tick line number. > Also, what happens if you use the beyond_zv test > in all the conditions That's what I've done in the second patch I sent (applied after the first one, not alone). In my simple tests, everything works as expected. > or use the it->what test in all the conditions? I didn't try that, but as the first check (that uses it->what) is trying to decide whether to draw with the current-line-number, I don't think it is relevant to the problem I was trying to fix. It is relevant for consistency, of course. > IOW, I don't understand why we need two different conditions regarding > EOB for displaying a number with different faces. What am I missing? I don't know why (or if) the it->what check is necessary, instead of beyond_zv. I *know* that the other conditions (the ones affecting the choosing of tick faces) need beyond_zv, at least to get what I think is the right behavior (the one in the beyond_zv image). As said, I think that in fact it the first check can be safely replaced by !beyond_zv. > You could simply start with > > tem_it.face_id = lnum_face_id; > > and then have a series of tests for replacing that with another face > ID; it would at least save you the 'else' clause. Yes, good idea. Thanks. > What does "between digits" mean? While producing the glyphs for the > digits of a single line number, no faces can change, because no Lisp > is invoked. Is that what you meant? Yes, thanks. I expected as much, but the way the original code was written, and redisplay being notoriously tricky and an arcane art best left to wizards, I though I was missing something (I'm not joking). [-- Attachment #2: Type: text/html, Size: 3159 bytes --] ^ permalink raw reply [flat|nested] 11+ messages in thread
* bug#37641: major/minor tick faces bleed into empty lines at the end of buffer 2019-10-08 9:37 ` Juanma Barranquero @ 2019-10-08 10:47 ` Juanma Barranquero 2019-10-09 10:22 ` Eli Zaretskii 0 siblings, 1 reply; 11+ messages in thread From: Juanma Barranquero @ 2019-10-08 10:47 UTC (permalink / raw) To: Eli Zaretskii; +Cc: 37641 [-- Attachment #1.1: Type: text/plain, Size: 789 bytes --] Turns out there's a difference after all. See the attached images. If you move the cursor past the EOB, with the beyond_zv check the line is drawn with the line-number face, not the line-number-current-line face. If we check with it->what != IT_EOB, then the line-number-current-line face is used. I think the right thing to do, when dealing with the "phantom line" just past the EOB, is to: - Use line-number-current-line, if the cursor is there. - Use the line-number face, and not the tick faces, if the cursor is not, regardless of whether this phantom line would be a tick line or not if it were used. So there's a patch that checks for tick faces with beyond_zv, for the current line face with it->what, and that moves all face setting for line numbers entirely out of the loop. [-- Attachment #1.2: Type: text/html, Size: 924 bytes --] [-- Attachment #2: bug-37641.patch --] [-- Type: application/x-patch, Size: 2277 bytes --] [-- Attachment #3: it_eob.png --] [-- Type: image/png, Size: 4796 bytes --] [-- Attachment #4: beyond_zv.png --] [-- Type: image/png, Size: 5327 bytes --] ^ permalink raw reply [flat|nested] 11+ messages in thread
* bug#37641: major/minor tick faces bleed into empty lines at the end of buffer 2019-10-08 10:47 ` Juanma Barranquero @ 2019-10-09 10:22 ` Eli Zaretskii 2019-10-09 10:39 ` Juanma Barranquero 0 siblings, 1 reply; 11+ messages in thread From: Eli Zaretskii @ 2019-10-09 10:22 UTC (permalink / raw) To: Juanma Barranquero; +Cc: 37641 > From: Juanma Barranquero <lekktu@gmail.com> > Date: Tue, 8 Oct 2019 12:47:22 +0200 > Cc: 37641@debbugs.gnu.org > > Turns out there's a difference after all. See the attached images. If you move the > cursor past the EOB, with the beyond_zv check the line is drawn with the line-number > face, not the line-number-current-line face. If we check with it->what != IT_EOB, > then the line-number-current-line face is used. > > I think the right thing to do, when dealing with the "phantom line" just past the EOB, > is to: > - Use line-number-current-line, if the cursor is there. > - Use the line-number face, and not the tick faces, if the cursor is not, regardless > of whether this phantom line would be a tick line or not if it were used. Agreed. > So there's a patch that checks for tick faces with beyond_zv, for the current line > face with it->what, and that moves all face setting for line numbers entirely out of > the loop. LGTM, thanks. ^ permalink raw reply [flat|nested] 11+ messages in thread
* bug#37641: major/minor tick faces bleed into empty lines at the end of buffer 2019-10-09 10:22 ` Eli Zaretskii @ 2019-10-09 10:39 ` Juanma Barranquero 0 siblings, 0 replies; 11+ messages in thread From: Juanma Barranquero @ 2019-10-09 10:39 UTC (permalink / raw) To: Eli Zaretskii; +Cc: 37641-done [-- Attachment #1: Type: text/plain, Size: 408 bytes --] Closing. Fixed by this commit: commit 4b06250ef1fe98a766938862912383d2ee051dfb Author: Juanma Barranquero <lekktu@gmail.com> Date: 2019-10-09 12:36:57 +0200 Do not use tick faces beyond ZV (bug#37641) * src/xdisp.c (maybe_produce_line_number): Check beyond_zv before using a tick face for the line number. Move all face selection code outside the loop that draws the line number. [-- Attachment #2: Type: text/html, Size: 546 bytes --] ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2019-10-09 10:39 UTC | newest] Thread overview: 11+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2019-10-07 1:04 bug#37641: major/minor tick faces bleed into empty lines at the end of buffer Juanma Barranquero 2019-10-07 3:42 ` Juanma Barranquero 2019-10-07 16:17 ` Eli Zaretskii 2019-10-08 2:38 ` Juanma Barranquero 2019-10-08 4:23 ` Juanma Barranquero 2019-10-08 8:51 ` Eli Zaretskii 2019-10-08 8:49 ` Eli Zaretskii 2019-10-08 9:37 ` Juanma Barranquero 2019-10-08 10:47 ` Juanma Barranquero 2019-10-09 10:22 ` Eli Zaretskii 2019-10-09 10:39 ` Juanma Barranquero
Code repositories for project(s) associated with this public inbox https://git.savannah.gnu.org/cgit/emacs.git This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).