From eb6d2fb58da56583490b18f4bfd705844b42180f Mon Sep 17 00:00:00 2001 From: Gregory Heytings Date: Wed, 6 Jul 2022 10:04:38 +0000 Subject: [PATCH] Various improvements to auto-narrow mode. * lisp/files.el (auto-narrow-display-length): Improve docstring. (auto-narrow-widen-automatically): Add 'undo' to the command list. (auto-narrow-hook): New defcustom. (auto-narrow-pre-command-function, auto-narrow-post-command-function): Move initialization code. (auto-narrow-mode): Do not make the 'auto-narrow-mode' permanent local anymore. * lisp/font-lock.el (turn-off-font-lock-mode): New convenience function. * src/xdisp.c (set_vertical_scroll_bar): Fix typo. (redisplay_window): Use the new convenience function. * src/buffer.h (BUFFER_NEEDS_AUTO_NARROWING_P, BUFFER_AUTO_NARROWED_NON_NARROWED_P): Two new convenience functions. * src/window.c (Frecenter): Do not recenter auto-narrowed buffers that are not actually narrowed. * etc/NEWS: Improvement. * doc/emacs/display.texi (Auto-Narrowing): Improvement. --- doc/emacs/display.texi | 20 +++++++++++++++----- etc/NEWS | 13 +++++++++---- lisp/files.el | 27 ++++++++++++++++----------- lisp/font-lock.el | 5 +++++ src/buffer.h | 16 ++++++++++++++++ src/window.c | 5 +++++ src/xdisp.c | 4 ++-- 7 files changed, 68 insertions(+), 22 deletions(-) diff --git a/doc/emacs/display.texi b/doc/emacs/display.texi index 9fe9533e88c..feb4675b32d 100644 --- a/doc/emacs/display.texi +++ b/doc/emacs/display.texi @@ -474,9 +474,10 @@ it. @xref{Disabling}. @vindex auto-narrow-long-line-threshold @vindex auto-narrow-display-length @vindex auto-narrow-widen-automatically +@vindex auto-narrow-hook When a file with extremely long lines is opened or inserted in a -buffer, Emacs automatically enters auto-narrow mode, and the word +buffer, Emacs automatically enters Auto-Narrow mode, and the word @samp{Auto-Narrow} appears in the mode line. This means that Emacs restricts display, but not editing, to a portion of the buffer above and below point. All editing commands, including narrowing commands, @@ -485,12 +486,21 @@ remain available, and they act on the whole buffer. For example, happen with ordinary narrowing, to the end of the portion of the buffer to which display is currently restricted. - The behavior of auto-narrow mode is controlled by three variables: + The behavior of Auto-Narrow mode is controlled by four variables: @code{auto-narrow-long-line-threshold} is the line length above which -auto-narrow move is entered, @code{auto-narrow-display-length} is the -number of characters to which display is restricted, and +Auto-Narrow move is entered, @code{auto-narrow-display-length} is the +number of characters to which display is restricted, @code{auto-narrow-widen-automatically} is a list of commands for which -display is widened before they are executed. +display is widened before they are executed, and +@code{auto-narrow-hook} is a list of functions that are called when +Auto-Narrow mode is entered. By default, Font Lock mode is disabled +in Auto-Narrow mode. + + If you still experience slowdowns while editing a file when +Auto-Narrow mode is enabled, this is not due to Emacs itself, but to +the current major mode or one of the enabled minor modes, and you +should open the file with @kbd{M-x find-file-literally} instead of +@kbd{C-x C-f}. @node View Mode @section View Mode diff --git a/etc/NEWS b/etc/NEWS index 51d31bcf173..3df1fb9c4e7 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -905,10 +905,15 @@ automatically enters auto-narrow mode. This means that Emacs restricts display, but not editing, to a portion of the buffer above and below point. All editing commands, including narrowing commands, remain available, and they act on the whole buffer. The behavior of -that mode is controlled by three variables: -auto-narrow-long-line-threshold, auto-narrow-display-length and -auto-narrow-widen-automatically. To disable that feature, set -auto-narrow-long-line-threshold to nil in your init file. +that mode is controlled by four variables: +auto-narrow-long-line-threshold, auto-narrow-display-length, +auto-narrow-widen-automatically and auto-narrow-hook (which by default +disables font-lock-mode). To disable that feature, set +auto-narrow-long-line-threshold to nil in your init file. If you +still experience slowdowns while editing a file in auto-narrow mode, +this is due to the current major mode or one of the enabled minor +modes: you should open the file with M-x find-file-literally instead +of C-x C-f. --- ** 'zap-to-char' and 'zap-up-to-char' are case-sensitive for upper-case chars. diff --git a/lisp/files.el b/lisp/files.el index 0e6f1a935db..8d6ecb66bc6 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -2692,9 +2692,9 @@ the file contents into it using `insert-file-contents-literally'." "Number of characters to which display is restricted in `auto-narrow-mode'. When `auto-narrow-mode' is in effect, the number of characters -displayed above and below point is one third of -`auto-narrow-display-line-length', except at the beginning and -end of the buffer." +displayed above and below point is at least one third and at most +two thirds of `auto-narrow-display-line-length', except at the +beginning and end of the buffer." :group 'files :group 'find-file :version "29.1" @@ -2706,13 +2706,20 @@ end of the buffer." 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) + bookmark-jump undo) "Commands for which display is automatically widened in `auto-narrow-mode'." :group 'files :group 'find-file :version "29.1" :type '(repeat function)) +(defcustom auto-narrow-hook '(turn-off-font-lock-mode) + "List of functions to be called when `auto-narrow-mode' is entered." + :group 'find-file + :type 'hook + :version "29.1" + :type '(repeat function)) + (defvar-local auto-narrow--widen-automatically nil "Internal variable used by `auto-narrow-mode'.") @@ -2725,11 +2732,6 @@ end of the buffer." (defun auto-narrow-pre-command-function () "Conditionally widen display when `auto-narrow-mode' is in effect." (when auto-narrow-mode - (unless auto-narrow--initialized - (setq auto-narrow--widen-automatically widen-automatically - auto-narrow--isearch-widen-automatically isearch-widen-automatically - auto-narrow--narrowing-state 'auto - auto-narrow--initialized t)) (setq-local widen-automatically t isearch-widen-automatically t) (if (memq this-command '(narrow-to-region narrow-to-defun narrow-to-page)) @@ -2747,7 +2749,11 @@ end of the buffer." (when (and auto-narrow-mode (not (eq auto-narrow--narrowing-state 'explicit))) (unless auto-narrow--initialized - (setq auto-narrow--narrowing-state 'auto)) + (run-hooks 'auto-narrow-hook) + (setq auto-narrow--widen-automatically widen-automatically + auto-narrow--isearch-widen-automatically isearch-widen-automatically + auto-narrow--narrowing-state 'auto + auto-narrow--initialized t)) (let (point cur-point-min buf-point-min buf-point-max size) (setq point (point) cur-point-min (point-min) size (/ auto-narrow-display-length 3)) @@ -2777,7 +2783,6 @@ in a buffer. It restricts display, but not editing, to executing any of the commands listed in `auto-narrow-widen-automatically'." :group 'files :version "29.1" - :after-hook (progn (put 'auto-narrow-mode 'permanent-local t)) (if auto-narrow-mode (auto-narrow-post-command-function) (when (not (eq auto-narrow--narrowing-state 'explicit)) diff --git a/lisp/font-lock.el b/lisp/font-lock.el index 206879b1694..0c30173d9ae 100644 --- a/lisp/font-lock.el +++ b/lisp/font-lock.el @@ -2045,6 +2045,11 @@ Sets various variables using `font-lock-defaults' and (setq font-lock-keywords (font-lock-compile-keywords font-lock-keywords)))) (font-lock-flush))) + +(defun turn-off-font-lock-mode () + "Unconditionally turn off `font-lock-mode'." + (interactive) + (font-lock-mode -1)) ;;; Color etc. support. diff --git a/src/buffer.h b/src/buffer.h index 19faa844e02..84492737b0e 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -1120,12 +1120,28 @@ BUFFER_CHECK_INDIRECTION (struct buffer *b) } } +/* Check the state of auto-narrowed buffers. */ + +INLINE bool +BUFFER_NEEDS_AUTO_NARROWING_P (struct buffer *b) +{ + return EQ (BVAR (b, auto_narrow__narrowing_state), Qneeded); +} + INLINE bool BUFFER_AUTO_NARROWED_P (struct buffer *b) { return EQ (BVAR (b, auto_narrow__narrowing_state), Qauto); } +INLINE bool +BUFFER_AUTO_NARROWED_NON_NARROWED_P (struct buffer *b) +{ + return BUFFER_AUTO_NARROWED_P (b) + && BUF_BEG (b) == BUF_BEGV (b) + && BUF_Z (b) == BUF_ZV (b); +} + /* This structure holds the default values of the buffer-local variables that have special slots in each buffer. The default value occupies the same slot in this structure diff --git a/src/window.c b/src/window.c index af463b90ce6..218b3e6a4f8 100644 --- a/src/window.c +++ b/src/window.c @@ -6557,6 +6557,11 @@ and redisplay normally--don't erase and redraw the frame. */) if (buf != current_buffer) error ("`recenter'ing a window that does not display current-buffer."); + /* Refuse to recenter auto-narrowed buffers that are not actually narrowed, + as this can be very slow. */ + if (BUFFER_AUTO_NARROWED_NON_NARROWED_P (buf)) + return Qnil; + /* If redisplay is suppressed due to an error, try again. */ buf->display_error_modiff = 0; diff --git a/src/xdisp.c b/src/xdisp.c index be51a0eb136..7821c120ca0 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -18872,7 +18872,7 @@ set_vertical_scroll_bar (struct window *w) && NILP (echo_area_buffer[0]))) { struct buffer *buf = XBUFFER (w->contents); - if (! BUFFER_AUTO_NARROWED_P (current_buffer)) + if (! BUFFER_AUTO_NARROWED_P (buf)) { whole = BUF_ZV (buf) - BUF_BEGV (buf); start = marker_position (w->start) - BUF_BEGV (buf); @@ -19142,7 +19142,7 @@ redisplay_window (Lisp_Object window, bool just_this_one_p) variables. */ set_buffer_internal_1 (XBUFFER (w->contents)); - if (EQ (BVAR (current_buffer, auto_narrow__narrowing_state), Qneeded)) + if (BUFFER_NEEDS_AUTO_NARROWING_P (current_buffer)) { safe_call (1, Qauto_narrow_mode); /* Normally set by auto-narrow-mode, set it here anyway as a safety measure. */ -- 2.39.2