summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Heytings <gregory@heytings.org>2023-03-28 23:06:56 +0000
committerGregory Heytings <gregory@heytings.org>2023-03-29 01:12:39 +0200
commitafc2c6c13cb2ebb50a6c31fca5552f9b98b4af95 (patch)
tree762b7f83fd30c7a60355f8bacf890bf8c1674148
parent7e26a5c774e7c71782d89abe1d4be125d8422a4b (diff)
downloademacs-afc2c6c13cb2ebb50a6c31fca5552f9b98b4af95.tar.gz
Improve accuracy of cursor motion commands in long lines
* src/xdisp.c (get_nearby_bol_pos): New function. (get_small_narrowing_begv): Use it. This makes cursor motion commands much more accurate in the first 500K characters of each long line.
-rw-r--r--src/xdisp.c23
1 files changed, 21 insertions, 2 deletions
diff --git a/src/xdisp.c b/src/xdisp.c
index c752f6712ab..454cbbbf6d5 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -3608,11 +3608,30 @@ get_medium_narrowing_zv (struct window *w, ptrdiff_t pos)
return min ((pos / len + 1) * len, ZV);
}
+static ptrdiff_t
+get_nearby_bol_pos (ptrdiff_t pos)
+{
+ ptrdiff_t start, pos_bytepos, cur, next, found, bol = 0;
+ start = pos - 500000 < BEGV ? BEGV : pos - 500000;
+ pos_bytepos = CHAR_TO_BYTE (pos);
+ for (cur = start; cur < pos; cur = next)
+ {
+ next = find_newline1 (cur, CHAR_TO_BYTE (cur), pos, pos_bytepos,
+ 1, &found, NULL, false);
+ if (found)
+ bol = next;
+ else
+ break;
+ }
+ return bol;
+}
+
ptrdiff_t
get_small_narrowing_begv (struct window *w, ptrdiff_t pos)
{
int len = get_narrowed_width (w);
- return max ((pos / len - 1) * len, BEGV);
+ int bol_pos = get_nearby_bol_pos (pos);
+ return max (bol_pos + ((pos - bol_pos) / len - 1) * len, BEGV);
}
ptrdiff_t
@@ -3653,7 +3672,7 @@ unwind_narrowed_begv (Lisp_Object point_min)
#define SET_WITH_NARROWED_BEGV(IT,DST,EXPR,BV) \
do { \
- if (IT->medium_narrowing_begv) \
+ if (IT->medium_narrowing_begv) \
{ \
specpdl_ref count = SPECPDL_INDEX (); \
record_unwind_protect (unwind_narrowed_begv, Fpoint_min ()); \