unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Long line JSON
@ 2021-05-18  9:46 Anand Tamariya
  2021-05-18 12:08 ` Eli Zaretskii
  0 siblings, 1 reply; 2+ messages in thread
From: Anand Tamariya @ 2021-05-18  9:46 UTC (permalink / raw)
  To: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 6735 bytes --]

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;

[-- Attachment #2: Type: text/html, Size: 8234 bytes --]

^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: Long line JSON
  2021-05-18  9:46 Long line JSON Anand Tamariya
@ 2021-05-18 12:08 ` Eli Zaretskii
  0 siblings, 0 replies; 2+ messages in thread
From: Eli Zaretskii @ 2021-05-18 12:08 UTC (permalink / raw)
  To: Anand Tamariya; +Cc: emacs-devel

> From: Anand Tamariya <atamariya@gmail.com>
> Date: Tue, 18 May 2021 15:16:14 +0530
> 
> 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.

Thanks, but this cannot be used in Emacs as-is, as it unconditionally
removes or disables code that is important in some situations.



^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2021-05-18 12:08 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-18  9:46 Long line JSON Anand Tamariya
2021-05-18 12:08 ` Eli Zaretskii

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).