From: Eli Zaretskii <eliz@gnu.org>
To: Alan Mackenzie <acm@muc.de>
Cc: emacs-devel@gnu.org
Subject: Re: "... the window start at a meaningless point within a line."
Date: Thu, 15 Oct 2015 23:14:39 +0300 [thread overview]
Message-ID: <834mhr99e8.fsf@gnu.org> (raw)
In-Reply-To: <20151015181642.GA6467@acm.fritz.box>
> Date: Thu, 15 Oct 2015 18:16:43 +0000
> Cc: emacs-devel@gnu.org
> From: Alan Mackenzie <acm@muc.de>
>
> As expected, it has been more difficult than expected.
It always is.
> I suspect I still have to modify one or two other primitives, such
> as `compute-motion'.
Why do you need to touch compute-motion? I don't think it's used in
your scenarios.
> I have a working proof of concept in a patch below. It is not ready for
> committing for several reasons. One is that I haven't fully grasped what
> SAVE_IT and RESTORE_IT do with the third parameter (bidi data, I think),
> so I've just used SAVE_IT everywhere without much thought.
That argument is where the data is saved and restored.
> --- a/src/dispextern.h
> +++ b/src/dispextern.h
> @@ -2679,6 +2679,29 @@ struct it
> inhibit_free_realized_faces = true; \
> } while (false)
>
> +/* SAVE_IT and RESTORE_IT are called when we save a snapshot of the
> + iterator state and later restore it. This is needed because the
> + bidi iterator on bidi.c keeps a stacked cache of its states, which
> + is really a singleton. When we use scratch iterator objects to
> + move around the buffer, we can cause the bidi cache to be pushed or
> + popped, and therefore we need to restore the cache state when we
> + return to the original iterator. */
> +#define SAVE_IT(ITCOPY, ITORIG, CACHE) \
> + do { \
> + if (CACHE) \
> + bidi_unshelve_cache (CACHE, true); \
> + ITCOPY = ITORIG; \
> + CACHE = bidi_shelve_cache (); \
> + } while (false)
> +
> +#define RESTORE_IT(pITORIG, pITCOPY, CACHE) \
> + do { \
> + if (pITORIG != pITCOPY) \
> + *(pITORIG) = *(pITCOPY); \
> + bidi_unshelve_cache (CACHE, false); \
> + CACHE = NULL; \
> + } while (false)
> +
I'd prefer these to stay private to xdisp.c. If you really need them
elsewhere (I don't think so), there are alternative solutions.
> +/* Get the end of the text line on which POS is. */
> +static ptrdiff_t
> +pos_line_end_position (struct text_pos *pos)
> +{
> + ptrdiff_t pt = PT, pt_byte = PT_BYTE;
> + Lisp_Object eol;
> +
> + SET_PT_BOTH (pos->charpos, pos->bytepos);
> + eol = Fline_end_position (Qnil);
> + SET_PT_BOTH (pt, pt_byte);
> + return XINT (eol);
> +}
There are much easier ways to get the end of the line: e.g., scan from
POS for a newline.
> + if (beginning < L0_phys_EOL
> + && end >= ws)
Sorry, but this is a non-starter: you cannot compare character
positions with < and >, assuming characters are displayed on a line in
strict logical order. These comparisons will completely break in
bidirectional text, where character positions change non-linearly with
screen coordinates.
> + if (IT_CHARPOS (*it) < ws)
> + {
> + below = false; /* exact_it is already past `it'. */
> + SAVE_IT (post_exact_it, exact_it, cache);
> + }
Same here.
> + while (1)
> + {
> + if (IT_CHARPOS (exact_it) < IT_CHARPOS (*it))
> + SAVE_IT (pre_exact_it, exact_it, cache);
> + if (!forward_to_next_display_line_start (&exact_it))
> + break; /* protection against infinite looping. */
> + if (below
> + && IT_CHARPOS (exact_it) >= IT_CHARPOS (*it))
> + {
> + below = false;
> + SAVE_IT (post_exact_it, exact_it, cache);
> + }
> + if (IT_CHARPOS (exact_it) > end)
> + break;
And here. And everywhere else.
> + if (IT_CHARPOS (exact_it) == IT_CHARPOS (xdisp_it))
Comparisons with == are OK.
I also suspect you don't need all those calls to SAVE_IT all over the
place. In any case, you are leaking memory here, because there's not
a single RESTORE_IT to free the memory that SAVE_IT allocates.
Can you describe the algorithm of this function in English? Then
perhaps I could help you rewrite it in bidi-aware way.
next prev parent reply other threads:[~2015-10-15 20:14 UTC|newest]
Thread overview: 57+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-09-30 20:45 "... the window start at a meaningless point within a line." Alan Mackenzie
2015-10-01 8:48 ` Eli Zaretskii
2015-10-01 9:41 ` Alan Mackenzie
2015-10-01 10:16 ` Eli Zaretskii
2015-10-01 11:02 ` Alan Mackenzie
2015-10-01 12:03 ` Eli Zaretskii
2015-10-01 16:35 ` Alan Mackenzie
2015-10-15 18:16 ` Alan Mackenzie
2015-10-15 20:14 ` Eli Zaretskii [this message]
2015-10-16 9:55 ` Alan Mackenzie
2015-10-16 10:19 ` Eli Zaretskii
2015-10-16 15:19 ` Alan Mackenzie
2015-10-16 17:26 ` Eli Zaretskii
2015-10-16 20:46 ` David Kastrup
2015-10-17 7:15 ` Eli Zaretskii
2015-10-17 7:56 ` David Kastrup
2015-10-16 21:14 ` Alan Mackenzie
2015-10-16 17:35 ` Eli Zaretskii
2015-10-16 18:12 ` Alan Mackenzie
2015-10-16 18:23 ` Eli Zaretskii
2015-10-16 18:36 ` Eli Zaretskii
2015-10-16 20:12 ` Alan Mackenzie
2015-10-17 8:33 ` Eli Zaretskii
2015-10-17 11:57 ` Alan Mackenzie
2015-10-17 12:34 ` Eli Zaretskii
2015-10-17 13:31 ` Eli Zaretskii
2015-10-17 14:22 ` Eli Zaretskii
2015-10-18 15:00 ` Alan Mackenzie
2015-10-18 17:44 ` Eli Zaretskii
2015-10-19 10:27 ` Alan Mackenzie
2015-10-27 13:40 ` Alan Mackenzie
2015-10-27 17:35 ` Alan Mackenzie
2015-10-27 18:33 ` Eli Zaretskii
2015-10-27 18:23 ` Eli Zaretskii
2015-10-28 8:58 ` Alan Mackenzie
2015-10-28 13:15 ` Alan Mackenzie
2015-10-31 13:21 ` Eli Zaretskii
2015-10-31 21:17 ` Alan Mackenzie
2015-11-01 3:40 ` Eli Zaretskii
2015-11-01 14:45 ` Alan Mackenzie
2015-11-01 15:23 ` Alan Mackenzie
2015-11-01 17:45 ` Eli Zaretskii
2015-11-01 18:07 ` Eli Zaretskii
2015-11-01 18:46 ` Alan Mackenzie
2015-10-18 14:53 ` Alan Mackenzie
2015-10-18 17:46 ` Eli Zaretskii
2015-10-19 10:45 ` Alan Mackenzie
2015-10-19 10:56 ` Eli Zaretskii
2015-10-19 11:24 ` Alan Mackenzie
2015-10-19 11:28 ` Eli Zaretskii
2015-10-19 12:02 ` Alan Mackenzie
2015-10-19 12:33 ` Eli Zaretskii
2015-10-19 13:11 ` Alan Mackenzie
2015-10-19 13:27 ` Eli Zaretskii
2015-10-19 19:15 ` Alan Mackenzie
2015-10-27 13:46 ` Alan Mackenzie
2015-10-17 15:30 ` Alan Mackenzie
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=834mhr99e8.fsf@gnu.org \
--to=eliz@gnu.org \
--cc=acm@muc.de \
--cc=emacs-devel@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.