Package: emacs;
Reported by: Gregory Heytings <gregory <at> heytings.org>
Date: Tue, 5 Jul 2022 08:50:02 UTC
Severity: normal
Done: Gregory Heytings <gregory <at> heytings.org>
Bug is archived. No further changes may be made.
View this message in rfc822 format
From: Eli Zaretskii <eliz <at> gnu.org> To: Gregory Heytings <gregory <at> heytings.org> Cc: 56393 <at> debbugs.gnu.org Subject: bug#56393: Actually fix the long lines display bug Date: Tue, 05 Jul 2022 15:54:59 +0300
> Date: Tue, 05 Jul 2022 10:17:37 +0000 > From: Gregory Heytings <gregory <at> heytings.org> > > Gosh! After including too little, I included too much. The attached one > is correct (I hope). Thanks! It's a good idea, but I wonder how far we can safely take it; see below. > diff --git a/doc/emacs/trouble.texi b/doc/emacs/trouble.texi > index f06b93759d..887e5c6170 100644 > --- a/doc/emacs/trouble.texi > +++ b/doc/emacs/trouble.texi > @@ -158,7 +158,6 @@ Lossage > * Crashing:: What Emacs does when it crashes. > * After a Crash:: Recovering editing in an Emacs session that crashed. > * Emergency Escape:: What to do if Emacs stops responding. > -* Long Lines:: Mitigating slowness due to extremely long lines. > * DEL Does Not Delete:: What to do if @key{DEL} doesn't delete. > @end menu > > @@ -433,64 +432,6 @@ Emergency Escape > emergency escape---but there are cases where it won't work, when a > system call hangs or when Emacs is stuck in a tight loop in C code. > > -@node Long Lines > -@subsection Long Lines > -@cindex long lines This removal is premature, IMO. We should first establish that this feature can indeed cope well enough with the important use cases, and I'm not sure we are there yet. It is possible that this feature will be one of several available features that attempt to solve the same problem in different ways, each way with its own advantages and disadvantages. > --- a/etc/NEWS > +++ b/etc/NEWS > @@ -324,9 +324,6 @@ startup. Previously, these functions ignored > > * Changes in Emacs 29.1 > > ---- > -** 'longlines-mode' is no longer obsolete. > - Likewise here. > +** Emacs is now capable of editing files with arbitarily long lines. I'd suggest saying something like Emacs now copes better with editing files with extremely long lines. > +(defcustom auto-narrow-display-length 30000 > + "Number of characters to which display is restricted in `auto-narrow-mode'." This should tell how the narrowed region is positioned relative to point, I think, because without it the doc string tells too little. > +(defcustom auto-narrow-widen-automatically > + '( move-beginning-of-line move-end-of-line backward-sentence forward-sentence > + backward-sexp forward-sexp beginning-of-defun end-of-defun > + beginning-of-buffer end-of-buffer goto-char goto-line > + mark-sexp mark-defun mark-paragraph mark-whole-buffer mark-page > + exchange-point-and-mark pop-global-mark set-mark-command jump-to-register > + bookmark-jump) > + "Commands for which display is automatically widened in `auto-narrow-mode'." What are the criteria for this default? (I'm surprised the list is so short, for the reasons I explain below.) > +(setq auto-narrow-long-line-threshold 30000 > + auto-narrow-pre-command-function #'auto-narrow-pre-command-function > + auto-narrow-post-command-function #'auto-narrow-post-command-function) We might eventually decide to have this turned off by default. > --- a/src/fileio.c > +++ b/src/fileio.c > @@ -4997,6 +4997,20 @@ because (1) it preserves some marker positions (in unchanged portions > Otherwise start with an empty undo_list. */ > bset_undo_list (current_buffer, EQ (old_undo, Qt) ? Qt : Qnil); > > + if (!noninteractive && !NILP (Vauto_narrow_long_line_threshold)) > + { > + ptrdiff_t cur, next, found, max = 0; > + for (cur = PT; cur < PT + inserted; cur = next) > + { > + next = find_newline1 (cur, CHAR_TO_BYTE (cur), 0, -1, 1, > + &found, NULL, true); > + if (next - cur > max) max = next - cur; > + if (!found) break; > + } > + if (max > XFIXNUM (Vauto_narrow_long_line_threshold)) > + safe_call (1, Qauto_narrow_mode); > + } > + This will invoke auto-narrow-mode for any file that is for some reason inserted by Emacs into some buffer. Many Emacs commands insert files into temporary buffers or buffers that are never meant for display, and AFAIU the above will narrow such a buffer if a file inserted happens to have long lines, is that correct? If so, a Lisp program that inserts such a file, and then processes it, might fail to do its job because it will bump into the auto-narrowed restriction. I think this is a symptom of a larger problem with this approach; more about it below. > + DEFVAR_LISP ("auto-narrow-long-line-threshold", > + Vauto_narrow_long_line_threshold, > + doc: /* Line length above which `auto-narrow-mode' is entered. > +When non-nil, and when a file with one or more lines longer than > +`auto-narrow-long-line-threshold' is opened or inserted in a buffer, > +`auto-narrow-mode' is automatically enabled. > +When nil, `auto-narrow-mode' is not entered automatically. */); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ "When nil, `auto-narrow-mode' is disabled." > --- a/src/keyboard.c > +++ b/src/keyboard.c > @@ -1290,6 +1290,9 @@ command_loop_1 (void) > > if (NILP (Vmemory_full)) > { > + if (!NILP (Vauto_narrow_post_command_function) && !NILP (Vrun_hooks)) > + safe_run_hooks (Qauto_narrow_post_command_function); > + > /* Make sure this hook runs after commands that get errors and > throw to top level. */ > [...] > @@ -1522,6 +1527,8 @@ command_loop_1 (void) > } > kset_last_prefix_arg (current_kboard, Vcurrent_prefix_arg); > > + safe_run_hooks (Qauto_narrow_post_command_function); > + > safe_run_hooks (Qpost_command_hook); AFAIU, this means post-command-hook functions will run with the current buffer narrowed, right? That could cause them to fail, if they for some reason want to access the buffer portions outside the restriction. > @@ -1472,6 +1475,8 @@ command_loop_1 (void) > Vreal_this_command = cmd; > safe_run_hooks (Qpre_command_hook); > > + safe_run_hooks (Qauto_narrow_pre_command_function); > + And here's a similar problem with pre-command-hook functions. A similar problem will happen with any Lisp that is run from the redisplay code: it will only see the narrowed region. I don't quite see clearly what these general issues could mean, but they are at least worrisome, I think, because they could potentially mean significant breakage in many places. The simple measure of having a list of commands that automatically widen the buffer is insufficient, I'm afraid, because the real problem is not on the command level, it is on the level of Lisp programs which say save-excursion and then go far away for whatever purposes. Also for commands written by users: for example, if someone writes a command that is a trivial wrapper around goto-line, that command will no longer automatically widen as goto-line does, right? Can we come up with a better solution for these potential problems? Alternatively, maybe you will explain that I'm bothered by a non-existent problem? Other observations: Since the narrowing is basically in effect only during redisplay, it doesn't help with commands that use display code outside of redisplay proper. For example, C-n, C-v, C-l, and other commands are still extremely sluggish in files with long lines. E.g., try the file long-line.xml mentioned here: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=45898#80 Or try dragging the mode line of a window showing that file. Also, the automatic restriction is very visible and causes surprising effects: (point-min) and (point-max) evaluate to the narrowed region (so it's basically very hard to know the real size of the buffer), and scrolling through the buffer causes the scroll-bar thumb move in a non-monotonic manner: I scroll towards the end of the buffer, but the thumb sometimes jumps back up, as if I moved towards the beginning. And sometimes I see that C-n moves point horizontally, i.e. point stays on the same screen line, instead of the expected vertical movement. I guess this is because the restriction violates some assumptions that Emacs makes regarding horizontal coordinates of some reference position. I think at this point it is best to have this feature on a feature branch, so that people could try it, and so that improving it won't need to post the entire patch each time anew. Thanks.
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.