emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Problems with move_it_in_display_line_to X when tabs exist.


From: Keith David Bershatsky
Subject: Re: Problems with move_it_in_display_line_to X when tabs exist.
Date: Sun, 21 Jan 2018 12:32:34 -0800

I was able to obtain the correct width of the tab STRETCH (in this example) by 
adding the following snippet to x_produce_glyphs.  However, it.current_x is 
wrong for the glyphs that _follow_ the tab STRETCH -- the difference is an 
extra font->space_width.  It is impossible for IT to land on the first 
character following the tab STRETCH using move_it_in_display_line_to -- i.e., 
IT stops one (1) character to the right of where it should be.

I have revised the function debug-tab-pixel-width to include the output of 
dump_glyph_row so that we can see the values for it->pixel_width are wrong as 
to the tab STRETCH width.  [We force a redisplay _before_ calling 
dump_glyph_row so that the values reflect what we actually see on the screen.]  
There are seven (7) new screen-shots that include the STDERR output to the 
terminal as we increase the value of w->hscroll by a factor of 1 in each 
subsequent image; i.e., as we call (scroll-left 1) again and again.  Attached 
is a revised patch.diff to run similar tests as we did before, but now using 
the new method of calculating the tab STRETCH width.

Any ideas regarding how to fix the erroneous it.current_x as to glyphs that 
_follow_ the tab STRETCH would be greatly appreciated.  [Other IT values may be 
incorrect as well, but I've only noticed problems with the pixel_width and 
current_x.]

Also, there may be a better way to properly calculate the correct value of the 
tab STRETCH in this example?  I used a new pointer of it->my_pixel_width so as 
not to break anything in the process while working on this issue.

dispextern.h (new snippet added):  int my_pixel_width;

xdisp.c (new snippet added):

  if (it->char_to_display == '\t'
      && !NILP (Vdisplay_line_numbers)
      && it->w->hscroll > 0
      && it->current_x < it->lnum_pixel_width)
    {
      int my_tab_width = it->tab_width * font->space_width;
      int my_x = it->current_x + it->continuation_lines_width;
      int my_next_tab_x = ((1 + my_x + my_tab_width - 1) / my_tab_width)
                          * my_tab_width;
      if (my_next_tab_x - my_x < font->space_width)
        my_next_tab_x += my_tab_width;
      if (!NILP (Vdisplay_line_numbers))
        my_next_tab_x += it->lnum_pixel_width
                         - ((it->w->hscroll * font->space_width)
                            % my_tab_width);
      /* FIXME:  Should we use font->space_width instead of it->current_x? */
      it->my_pixel_width = my_next_tab_x - it->lnum_pixel_width - it->current_x;
    }
    else
      it->my_pixel_width = 0;

GOAL:  The goal is to interactively call (scroll-left 1) -- one or more times 
in a row -- and obtain the beginning _visible_ X and HPOS of the tab STRETCH; 
and, also obtain its _visible_ pixel-width.


00.  Opening screen-shot -- just setting up the test buffer.

  https://www.lawlist.com/images/debug_tab_width_00.png


01.  Place the cursor at the end of the line containing "       @" and press 
the f5 key one time.

  https://www.lawlist.com/images/debug_tab_width_01.png

  OBSERVATIONS (w->hscroll == 1):  There is a hiccup on loops 3 and 4 (see 
screen-shot) -- perhaps this is due to the wrong value of it.pixel_width when 
calling:

  move_it_in_display_line_to (&it, ZV, it.current_x + it.pixel_width,
                              MOVE_TO_POS | MOVE_TO_X);

The expected result is that the tab STRETCH will have an it.pixel_width of 42.  
The third (3rd) iteration/loop has the wrong value; i.e., 49.  The fourth (4th) 
iteration/loop has the correct value (i.e., 42) -- this is the _only_ occasion 
where we see the correct value of it.pixel_width (in this example).  When 
w->hscroll > 1, it.pixel_width is _never_ correct as to the tab STRETCH (in 
this example).


02.  With the cursor at the end of the line containing "        @", press the 
f5 key one time.

  https://www.lawlist.com/images/debug_tab_width_02.png

  OBSERVATIONS (w->hscroll == 2):  The expected result is that the tab STRETCH 
will have an it.pixel_width of 35; however, it has a value of 49 instead.


03. With the cursor at the end of the line containing " @", press the f5 key 
one time.

  https://www.lawlist.com/images/debug_tab_width_03.png

  OBSERVATIONS (w->hscroll == 3):  The expected result is that the tab STRETCH 
will have an it.pixel_width of 28; however, it has a value of 49 instead.


04. With the cursor at the end of the line containing " @", press the f5 key 
one time.

  https://www.lawlist.com/images/debug_tab_width_04.png

  OBSERVATIONS (w->hscroll == 4):  The expected result is that the tab STRETCH 
will have an it.pixel_width of 21; however, it has a value of 49 instead.


05. With the cursor at the end of the line containing " @", press the f5 key 
one time.

  https://www.lawlist.com/images/debug_tab_width_05.png

  OBSERVATIONS (w->hscroll == 5):  The expected result is that the tab STRETCH 
will have an it.pixel_width of 14; however, it has a value of 49 instead.


06. With the cursor at the end of the line containing " @", press the f5 key 
one time.

  https://www.lawlist.com/images/debug_tab_width_06.png

  OBSERVATIONS (w->hscroll == 6):  The expected result is that the tab STRETCH 
will have an it.pixel_width of 7; however, it has a value of 49 instead.


LISP CODE (buffer-local):

(setq display-line-numbers t)
(setq buffer-display-table (make-display-table))
(aset buffer-display-table
      ?\t
      (vector (make-glyph-code ?\u00BB 'font-lock-warning-face)
              (make-glyph-code ?\t 'highlight)))
(setq tab-width 8)
(global-set-key [f5] (lambda () (interactive) (debug-tab-pixel-width)))


TEST TEXT (a tab, followed by the "@" symbol) -- the text begins on line 13:

        @


C CODE:  Apply the attached patch.diff to Emacs 26 as of 01/21/2018 bearing 
last commit c965e5a641d9478d23a233b48977503506b1b603.

Attachment: patch.diff
Description: application/diff


reply via email to

[Prev in Thread] Current Thread [Next in Thread]