all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Keith David Bershatsky <esq@lawlist.com>
To: 28936@debbugs.gnu.org
Subject: bug#28936: move_it_in_display_line_to returns MOVE_POS_MATCH_OR_ZV before ZV
Date: Sat, 21 Oct 2017 20:02:58 -0700	[thread overview]
Message-ID: <m260b73mvx.wl%esq@lawlist.com> (raw)

A couple of observations:

1.  `move_it_in_display_line' could use an additional comment at the outset to let readers know that it is not compatible with moving to X in a horizontal scrolling and/or truncate lines situation.  The existing commentary that it was intended for external use was insufficient to deter me, and it required a learning curve on my part to better understand its limited potential use.

2.  When IT is on the last line in the buffer containing a few or more characters, `move_it_in_display_line_to' stops short of the target X and erroneously returns MOVE_POS_MATCH_OR_ZV when used as follows.  I have display-line-numbers set to a non-nil value in the event that makes a difference.  There is nothing special in terms of text-properties or overlays present in the buffer.

    int target_x = [Some arbitrary X that is a few characters before ZV.];

    move_it_in_display_line_to (it, ZV, target_x, MOVE_TO_POS | MOVE_TO_X);

The workaround is to compare the result of MOVE_POS_MATCH_OR_ZV with IT_CHARPOS to ensure that we are really at a ZV situation.

Here is a working draft of what I am using for my crosshairs (#17684).

int
move_it_in_display_line_to_x (struct it *it, int target_x)
{
  struct it saved_it;
  void *saved_data = bidi_shelve_cache ();
  enum move_it_result rc = MOVE_X_REACHED;
  int new_x, prev_x;
  /* Advance straight to `it->first_visible_x` if IT is prior thereto. */
  if (it->current_x < it->first_visible_x)
    move_it_in_display_line_to (it, ZV, it->first_visible_x, MOVE_TO_POS | MOVE_TO_X);
  while (it->current_x + it->pixel_width <= target_x)
    {
      SAVE_IT (saved_it, *it, saved_data);
      new_x = it->current_x + it->pixel_width;
      if (new_x == it->current_x)
        new_x++;
      rc = move_it_in_display_line_to (it, ZV, new_x, MOVE_TO_POS | MOVE_TO_X);
      if (ITERATOR_AT_END_OF_LINE_P (it)
          || FETCH_BYTE (IT_BYTEPOS (it)) == '\n'
          /* There is a bug in `move_it_in_display_line_to' such that it returns
          MOVE_POS_MATCH_OR_ZV before reaching ZV when the latter is at the end
          of the line:  abcdefg[EOB].  The workaround is to add an extra check
          using IT_CHARPOS and comparing it to ZV. */
          || (rc == MOVE_POS_MATCH_OR_ZV
              && IT_CHARPOS (*it) == ZV))
        break;
    }
  /* When word-wrap is on, TO_X may lie past the end of a wrapped line.
  Then it->current is the character on the next line, so backtrack to the
  space before the wrap point.  */
  if (it->line_wrap == WORD_WRAP
      && rc == MOVE_LINE_CONTINUED)
    {
      prev_x = max (it->current_x - 1, 0);
      RESTORE_IT (it, &saved_it, saved_data);
      move_it_in_display_line_to (it, -1, prev_x, MOVE_TO_X);
    }
  bidi_unshelve_cache (saved_data, true);
  return rc;
}

Thanks,

Keith





             reply	other threads:[~2017-10-22  3:02 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-10-22  3:02 Keith David Bershatsky [this message]
2017-10-22  5:14 ` bug#28936: move_it_in_display_line_to returns MOVE_POS_MATCH_OR_ZV before ZV Keith David Bershatsky
2017-10-22 14:12   ` Eli Zaretskii
2017-10-22 14:10 ` Eli Zaretskii
2017-10-22 18:05 ` Keith David Bershatsky
2017-10-22 18:30   ` Eli Zaretskii
2017-10-22 19:53   ` Eli Zaretskii
2017-10-22 19:22 ` bug#28936: nRe: " Keith David Bershatsky
2017-10-22 19:41   ` Eli Zaretskii
2017-10-23  5:20 ` Keith David Bershatsky
2017-10-23 13:55   ` Eli Zaretskii
2017-10-25  3:46 ` bug#28936: enhancement request: remove vertical scroll bar automatically when not needed Keith David Bershatsky
2017-10-25  5:30 ` Keith David Bershatsky

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=m260b73mvx.wl%esq@lawlist.com \
    --to=esq@lawlist.com \
    --cc=28936@debbugs.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.