From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Anand Tamariya Newsgroups: gmane.emacs.devel Subject: Long line JSON Date: Tue, 18 May 2021 15:16:14 +0530 Message-ID: Mime-Version: 1.0 Content-Type: multipart/alternative; boundary="000000000000618e8505c2979580" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="15161"; mail-complaints-to="usenet@ciao.gmane.io" To: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Tue May 18 12:01:59 2021 Return-path: Envelope-to: ged-emacs-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1liwY2-0003oE-Og for ged-emacs-devel@m.gmane-mx.org; Tue, 18 May 2021 12:01:58 +0200 Original-Received: from localhost ([::1]:52314 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1liwY1-0007wr-GE for ged-emacs-devel@m.gmane-mx.org; Tue, 18 May 2021 06:01:57 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:36964) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1liwJ4-0006zQ-0n for emacs-devel@gnu.org; Tue, 18 May 2021 05:46:30 -0400 Original-Received: from mail-il1-x12a.google.com ([2607:f8b0:4864:20::12a]:37811) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1liwJ1-0002hS-FZ for emacs-devel@gnu.org; Tue, 18 May 2021 05:46:29 -0400 Original-Received: by mail-il1-x12a.google.com with SMTP id k4so4893754ili.4 for ; Tue, 18 May 2021 02:46:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:from:date:message-id:subject:to; bh=wHktN60WcbVSQ0Lk1Zy86ALcVcdvl/bhqcdN7HhYXIU=; b=DcJnOfw139dVEZ9q/+26ORe2bF0PWGYvCH1mkTiTE5N5XfVZAjZ06tM7plIjrKiOCw oTFo6R56Jh3HrUsIo/KsjdkJWLKQy12o5RXw1kHUx5dez+UMNF9J58xsm37RAEjQhz32 tP/0pfEnPg/F8rNi2yZmqX/sxGGO1lOZATgmdy26OBn1jvREBTp5fbZ88u+oFsfo64ux 37yOIOTXjv3KvA04pxFNdBFZvtdqwgZoj9hbVA/ztIhJFhEbntN5mywTXEK4SbnfNtGK sjnZGfZNegpM4/y4vtGlIAA/H6LFzIQ5/YK6Jvc1mMCQw9UOabPbrmzh3ozQ5OA02IgZ 6TTw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=wHktN60WcbVSQ0Lk1Zy86ALcVcdvl/bhqcdN7HhYXIU=; b=Lrk1jLduIF3S0CxJ+Q6ZvU4E515GxNKK/oxEIPhAVNwUljqz3lcw4w21e9v+8gdvNR xCx6RwmQXkaRZQTK5ksdtBAqMhg4sQlcEiQTqQ01H9p1Km2TWBK8bG9HZkZgai+ZT2Sz k9arzScI0tRpz1B6/mfIGQDNn/L7sLkVctLWcpig6c0VNyWAIYZID/wMH2r52gFLnTBe YTElcJCNiasdWupAUIqfAu/CzMq3Dt7umDw0ji4zR2P1Y9BDPX/a+PWl9sIcpfNnyigX gwH08Pn+glFDD5dU07asJyRv8eEbUp31VO+eYnlPqDYRmBcoXKQW6uNO23AXYPa/PUSi bLeQ== X-Gm-Message-State: AOAM530BYKFbLrsF1nhcT/kz8FZSanXLpRgcebuireRV3wS+yvMkm2Xu oMntIpUC8U3Srtm/Haq2Lt16Y0dYHLtz1rRCL1J/hXdYxyI= X-Google-Smtp-Source: ABdhPJxjpik0lTq29DaewLGLqrgKT8VSV2CpTAafV7CtUJsmwPYIcZvtAOhPi0comwhZYrHMHSIc57/HirdMIDXWsY0= X-Received: by 2002:a05:6e02:1649:: with SMTP id v9mr3580229ilu.62.1621331185600; Tue, 18 May 2021 02:46:25 -0700 (PDT) Received-SPF: pass client-ip=2607:f8b0:4864:20::12a; envelope-from=atamariya@gmail.com; helo=mail-il1-x12a.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.io gmane.emacs.devel:269438 Archived-At: --000000000000618e8505c2979580 Content-Type: text/plain; charset="UTF-8" Here's a patch which allows me to use Emacs even for large single line JSON file without slowing it down. The idea is to limit Emacs search for new line to MAX_NEWLINE_DISTANCE. With fundamental mode and word-wrap on, I'm able to browse the file via page scroll, beginning/ end of line, beginning/ end of buffer and parenthesis matching. Only the up-down cursor movement is jarring. Warning: It might or might not work for other scenarios. diff --git a/src/insdel.c b/src/insdel.c index 21acf0e61d..164c78fbda 100644 --- a/src/insdel.c +++ b/src/insdel.c @@ -36,6 +36,7 @@ static void insert_from_buffer_1 (struct buffer *, ptrdiff_t, ptrdiff_t, bool); static void gap_left (ptrdiff_t, ptrdiff_t, bool); static void gap_right (ptrdiff_t, ptrdiff_t); +/* const int MAX_NEWLINE_DISTANCE = 256; */ /* List of elements of the form (BEG-UNCHANGED END-UNCHANGED CHANGE-AMOUNT) describing changes which happened while combine_after_change_calls @@ -2053,7 +2054,7 @@ invalidate_buffer_caches (struct buffer *buf, ptrdiff_t start, ptrdiff_t end) set_buffer_internal (buf); - line_beg = find_newline_no_quit (start, start_byte, -1, + line_beg = find_before_next_newline (start, start - 256, -1, &start_byte); set_buffer_internal (old); } diff --git a/src/search.c b/src/search.c index 7389fbef0e..631f657b19 100644 --- a/src/search.c +++ b/src/search.c @@ -653,7 +653,7 @@ find_newline (ptrdiff_t start, ptrdiff_t start_byte, ptrdiff_t end, struct region_cache *newline_cache; struct buffer *cache_buffer; - if (!end) + if (end <= 0) { if (count > 0) end = ZV, end_byte = ZV_BYTE; diff --git a/src/xdisp.c b/src/xdisp.c index cbdef7ad11..eeebb74321 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -427,6 +427,8 @@ #define IT_DISPLAYING_WHITESPACE(it) \ && (*BYTE_POS_ADDR (IT_BYTEPOS (*it)) == ' ' \ || *BYTE_POS_ADDR (IT_BYTEPOS (*it)) == '\t')))) +const int MAX_NEWLINE_DISTANCE = 256; + /* If all the conditions needed to print the fill column indicator are met, return the (nonnegative) column number, else return a negative value. */ @@ -6575,7 +6577,7 @@ back_to_previous_line_start (struct it *it) ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it); DEC_BOTH (cp, bp); - IT_CHARPOS (*it) = find_newline_no_quit (cp, bp, -1, &IT_BYTEPOS (*it)); + IT_CHARPOS (*it) = find_before_next_newline (cp, cp - MAX_NEWLINE_DISTANCE, -1, &IT_BYTEPOS (*it)); } @@ -6607,7 +6609,6 @@ forward_to_next_line_start (struct it *it, bool *skipped_p, ptrdiff_t old_selective; bool newline_found_p = false; int n; - const int MAX_NEWLINE_DISTANCE = 500; /* If already on a newline, just consume it to avoid unintended skipping over invisible text below. */ @@ -6647,63 +6648,7 @@ forward_to_next_line_start (struct it *it, bool *skipped_p, short-cut. */ if (!newline_found_p) { - ptrdiff_t bytepos, start = IT_CHARPOS (*it); - ptrdiff_t limit = find_newline_no_quit (start, IT_BYTEPOS (*it), - 1, &bytepos); - Lisp_Object pos; - - eassert (!STRINGP (it->string)); - - /* If there isn't any `display' property in sight, and no - overlays, we can just use the position of the newline in - buffer text. */ - if (it->stop_charpos >= limit - || ((pos = Fnext_single_property_change (make_fixnum (start), - Qdisplay, Qnil, - make_fixnum (limit)), - NILP (pos)) - && next_overlay_change (start) == ZV)) - { - if (!it->bidi_p) - { - IT_CHARPOS (*it) = limit; - IT_BYTEPOS (*it) = bytepos; - } - else - { - struct bidi_it bprev; - - /* Help bidi.c avoid expensive searches for display - properties and overlays, by telling it that there are - none up to `limit'. */ - if (it->bidi_it.disp_pos < limit) - { - it->bidi_it.disp_pos = limit; - it->bidi_it.disp_prop = 0; - } - do { - bprev = it->bidi_it; - bidi_move_to_visually_next (&it->bidi_it); - } while (it->bidi_it.charpos != limit); - IT_CHARPOS (*it) = limit; - IT_BYTEPOS (*it) = it->bidi_it.bytepos; - if (bidi_it_prev) - *bidi_it_prev = bprev; - } - *skipped_p = newline_found_p = true; - } - else - { - while (!newline_found_p) - { - if (!get_next_display_element (it)) - break; - newline_found_p = ITERATOR_AT_END_OF_LINE_P (it); - if (newline_found_p && it->bidi_p && bidi_it_prev) - *bidi_it_prev = it->bidi_it; - set_iterator_to_next (it, false); - } - } + *skipped_p = true; } it->selective = old_selective; @@ -8227,8 +8172,9 @@ get_visually_first_element (struct it *it) if (string_p) it->bidi_it.charpos = it->bidi_it.bytepos = 0; else - it->bidi_it.charpos = find_newline_no_quit (IT_CHARPOS (*it), - IT_BYTEPOS (*it), -1, + it->bidi_it.charpos = find_before_next_newline (IT_CHARPOS (*it), + IT_CHARPOS (*it) - MAX_NEWLINE_DISTANCE, + -1, &it->bidi_it.bytepos); bidi_paragraph_init (it->paragraph_embedding, &it->bidi_it, true); do @@ -10057,7 +10003,7 @@ move_it_vertically_backward (struct it *it, int dy) ptrdiff_t cp = IT_CHARPOS (*it), bp = IT_BYTEPOS (*it); DEC_BOTH (cp, bp); - cp = find_newline_no_quit (cp, bp, -1, NULL); + cp = find_before_next_newline (cp, cp - MAX_NEWLINE_DISTANCE, -1, NULL); move_it_to (it, cp, -1, -1, -1, MOVE_TO_POS); } bidi_unshelve_cache (it3data, true); @@ -24069,7 +24015,7 @@ DEFUN ("bidi-find-overridden-directionality", itb.bytepos = from_bpos; } else - itb.charpos = find_newline_no_quit (from_pos, CHAR_TO_BYTE (from_pos), + itb.charpos = find_before_next_newline (from_pos, from_pos - MAX_NEWLINE_DISTANCE, -1, &itb.bytepos); itb.paragraph_dir = NEUTRAL_DIR; itb.string.s = NULL; --000000000000618e8505c2979580 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Here's a patch which allows me to use Emacs even = for large single line JSON file without slowing it down. The idea is to lim= it Emacs search for new line to MAX_NEWLINE_DISTANCE. With fundamental mode= and word-wrap on, I'm able to browse the file via page scroll, beginni= ng/ end of line, beginning/ end of buffer and parenthesis matching. Only th= e up-down cursor movement is jarring.

Warning: It= might or might not work for other scenarios.

= diff --git a/src/insdel.c b/src/insdel.c
index 21acf0e61d..164c78fbda = 100644
--- a/src/insdel.c
+++ b/src/insdel.c
@@ -36,6 +36,7 @@
= =C2=A0static void insert_from_buffer_1 (struct buffer *, ptrdiff_t, ptrdiff= _t, bool);
=C2=A0static void gap_left (ptrdiff_t, ptrdiff_t, bool);
= =C2=A0static void gap_right (ptrdiff_t, ptrdiff_t);
+/* const int MAX_NE= WLINE_DISTANCE =3D 256; */
=C2=A0
=C2=A0/* List of elements of the fo= rm (BEG-UNCHANGED END-UNCHANGED CHANGE-AMOUNT)
=C2=A0 =C2=A0 describing = changes which happened while combine_after_change_calls
@@ -2053,7 +2054= ,7 @@ invalidate_buffer_caches (struct buffer *buf, ptrdiff_t start, ptrdif= f_t end)
=C2=A0
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 set_= buffer_internal (buf);
=C2=A0
- =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 line_beg =3D find_newline_no_quit (start, start_byte, -1,
+ =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 line_beg =3D find_before_next_newlin= e (start, start - 256, -1,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0&start_byte);
=C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 set_buffer_internal (old);
= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 }
diff --git a/src/search.c b/= src/search.c
index 7389fbef0e..631f657b19 100644
--- a/src/search.c+++ b/src/search.c
@@ -653,7 +653,7 @@ find_newline (ptrdiff_t start, = ptrdiff_t start_byte, ptrdiff_t end,
=C2=A0 =C2=A0struct region_cache *n= ewline_cache;
=C2=A0 =C2=A0struct buffer *cache_buffer;
=C2=A0
- = =C2=A0if (!end)
+ =C2=A0if (end <=3D 0)
=C2=A0 =C2=A0 =C2=A0{
= =C2=A0 =C2=A0 =C2=A0 =C2=A0if (count > 0)
=C2=A0 =C2=A0 =C2=A0 =C2=A0= end =3D ZV, end_byte =3D ZV_BYTE;
diff --git a/src/xdisp.c b/src/xdisp.= c
index cbdef7ad11..eeebb74321 100644
--- a/src/xdisp.c
+++ b/src/= xdisp.c
@@ -427,6 +427,8 @@ #define IT_DISPLAYING_WHITESPACE(it) =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0\
=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0&& (*BYTE_POS_ADDR (IT_BYTEPOS (*it)= ) =3D=3D ' ' =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 \
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0|| *BYTE_PO= S_ADDR (IT_BYTEPOS (*it)) =3D=3D '\t'))))
=C2=A0
+const int M= AX_NEWLINE_DISTANCE =3D 256;
+
=C2=A0/* If all the conditions needed = to print the fill column indicator are
=C2=A0 =C2=A0 met, return the (no= nnegative) column number, else return a negative
=C2=A0 =C2=A0 value. = =C2=A0*/
@@ -6575,7 +6577,7 @@ back_to_previous_line_start (struct it *i= t)
=C2=A0 =C2=A0ptrdiff_t cp =3D IT_CHARPOS (*it), bp =3D IT_BYTEPOS (*i= t);
=C2=A0
=C2=A0 =C2=A0DEC_BOTH (cp, bp);
- =C2=A0IT_CHARPOS (*it= ) =3D find_newline_no_quit (cp, bp, -1, &IT_BYTEPOS (*it));
+ =C2=A0= IT_CHARPOS (*it) =3D find_before_next_newline (cp, cp - MAX_NEWLINE_DISTANC= E, -1, &IT_BYTEPOS (*it));
=C2=A0}
=C2=A0
=C2=A0
@@ -6607,7= +6609,6 @@ forward_to_next_line_start (struct it *it, bool *skipped_p,
= =C2=A0 =C2=A0ptrdiff_t old_selective;
=C2=A0 =C2=A0bool newline_found_p = =3D false;
=C2=A0 =C2=A0int n;
- =C2=A0const int MAX_NEWLINE_DISTANCE= =3D 500;
=C2=A0
=C2=A0 =C2=A0/* If already on a newline, just consum= e it to avoid unintended
=C2=A0 =C2=A0 =C2=A0 skipping over invisible te= xt below. =C2=A0*/
@@ -6647,63 +6648,7 @@ forward_to_next_line_start (st= ruct it *it, bool *skipped_p,
=C2=A0 =C2=A0 =C2=A0 short-cut. =C2=A0*/=C2=A0 =C2=A0if (!newline_found_p)
=C2=A0 =C2=A0 =C2=A0{
- =C2=A0 = =C2=A0 =C2=A0ptrdiff_t bytepos, start =3D IT_CHARPOS (*it);
- =C2=A0 =C2= =A0 =C2=A0ptrdiff_t limit =3D find_newline_no_quit (start, IT_BYTEPOS (*it)= ,
- =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 1, &bytepos);
- =C2=A0 =C2=A0 =C2=A0Lisp_Object pos;-
- =C2=A0 =C2=A0 =C2=A0eassert (!STRINGP (it->string));
-
- = =C2=A0 =C2=A0 =C2=A0/* If there isn't any `display' property in sig= ht, and no
- =C2=A0 =C2=A0 =C2=A0 =C2=A0overlays, we can just use the po= sition of the newline in
- =C2=A0 =C2=A0 =C2=A0 =C2=A0buffer text. =C2= =A0*/
- =C2=A0 =C2=A0 =C2=A0if (it->stop_charpos >=3D limit
- = =C2=A0 =C2=A0 =C2=A0 =C2=A0 || ((pos =3D Fnext_single_property_change (make= _fixnum (start),
- =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Qdisplay, Qnil,
- =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0make_fixnum (limit)),
- =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0NILP (pos))
- =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 && next_overlay_change (start) =3D=3D ZV))
- =C2=A0 =C2=A0 = =C2=A0 {
- =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (!it->bidi_p)
- =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 {
- =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 IT_CHARPOS (*it) =3D limit;
- =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 IT_BYTEPOS (*it) =3D bytepos;
- =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 }=
- =C2=A0 =C2=A0 =C2=A0 =C2=A0 else
- =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 {
- =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 struct bidi_it bprev;<= br>-
- =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 /* Help bidi.c avoid ex= pensive searches for display
- =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0properties and overlays, by telling it that there are
- = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0none up to `limit= 9;. =C2=A0*/
- =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (it->bidi= _it.disp_pos < limit)
- =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 {
- =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 it->b= idi_it.disp_pos =3D limit;
- =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 it->bidi_it.disp_prop =3D 0;
- =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 }
- =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 d= o {
- =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 bprev =3D it->= bidi_it;
- =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 bidi_move_to= _visually_next (&it->bidi_it);
- =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 } while (it->bidi_it.charpos !=3D limit);
- =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 IT_CHARPOS (*it) =3D limit;
- =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 IT_BYTEPOS (*it) =3D it->bidi_it.bytepos;- =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (bidi_it_prev)
- =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 *bidi_it_prev =3D bprev;
- =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 }
- =C2=A0 =C2=A0 =C2=A0 =C2=A0 *skipped= _p =3D newline_found_p =3D true;
- =C2=A0 =C2=A0 =C2=A0 }
- =C2=A0 = =C2=A0 =C2=A0else
- =C2=A0 =C2=A0 =C2=A0 {
- =C2=A0 =C2=A0 =C2=A0 =C2= =A0 while (!newline_found_p)
- =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 {
-= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (!get_next_display_element (i= t))
- =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 break;
- =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 newline_found_p =3D ITERATOR_AT_END_= OF_LINE_P (it);
- =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (newline_= found_p && it->bidi_p && bidi_it_prev)
- =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 *bidi_it_prev =3D it->bidi_it;- =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 set_iterator_to_next (it, fals= e);
- =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 }
- =C2=A0 =C2=A0 =C2=A0 }+ =C2=A0 =C2=A0*skipped_p =3D true;
=C2=A0 =C2=A0 =C2=A0}
=C2=A0=C2=A0 =C2=A0it->selective =3D old_selective;
@@ -8227,8 +8172,9 @@ = get_visually_first_element (struct it *it)
=C2=A0 =C2=A0 =C2=A0 =C2=A0if= (string_p)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 it->bidi_it.charpos =3D it-&g= t;bidi_it.bytepos =3D 0;
=C2=A0 =C2=A0 =C2=A0 =C2=A0else
- =C2=A0 =C2= =A0 =C2=A0 it->bidi_it.charpos =3D find_newline_no_quit (IT_CHARPOS (*it= ),
- =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 IT_BYTEPOS (*it), -1,
+ =C2=A0 =C2=A0= =C2=A0 it->bidi_it.charpos =3D find_before_next_newline (IT_CHARPOS (*i= t),
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 IT_CHARPOS (*it) - MAX_NEW= LINE_DISTANCE,
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 -1,
=C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 &it->bidi_it.bytepos);
=C2=A0 =C2=A0 = =C2=A0 =C2=A0bidi_paragraph_init (it->paragraph_embedding, &it->b= idi_it, true);
=C2=A0 =C2=A0 =C2=A0 =C2=A0do
@@ -10057,7 +10003,7 @@ = move_it_vertically_backward (struct it *it, int dy)
=C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 ptrdiff_t cp =3D IT_CHARPOS (*it), bp =3D IT_BYTEPOS (*it);<= br>=C2=A0
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 DEC_BOTH (cp, bp);
- =C2= =A0 =C2=A0 =C2=A0 =C2=A0 cp =3D find_newline_no_quit (cp, bp, -1, NULL);+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 cp =3D find_before_next_newline (cp, cp - MA= X_NEWLINE_DISTANCE, -1, NULL);
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 move_i= t_to (it, cp, -1, -1, -1, MOVE_TO_POS);
=C2=A0 =C2=A0 =C2=A0 =C2=A0 }=C2=A0 =C2=A0 =C2=A0 =C2=A0bidi_unshelve_cache (it3data, true);
@@ -240= 69,7 +24015,7 @@ DEFUN ("bidi-find-overridden-directionality",=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 itb.bytepos =3D from_bpos;
=C2=A0 = =C2=A0 =C2=A0 =C2=A0 }
=C2=A0 =C2=A0 =C2=A0 =C2=A0else
- =C2=A0 =C2= =A0 =C2=A0 itb.charpos =3D find_newline_no_quit (from_pos, CHAR_TO_BYTE (fr= om_pos),
+ =C2=A0 =C2=A0 =C2=A0 itb.charpos =3D find_before_next_newline= (from_pos, from_pos - MAX_NEWLINE_DISTANCE,
=C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 -1, &itb.bytepos);=
=C2=A0 =C2=A0 =C2=A0 =C2=A0itb.paragraph_dir =3D NEUTRAL_DIR;
=C2=A0= =C2=A0 =C2=A0 =C2=A0itb.string.s =3D NULL;
--000000000000618e8505c2979580--