emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 7103192: * src/xdisp.c (syms_of_xdisp) <"scroll-minibuffer-conser


From: Stefan Monnier
Subject: master 7103192: * src/xdisp.c (syms_of_xdisp) <"scroll-minibuffer-conservatively">: New var
Date: Sat, 31 Oct 2020 09:07:58 -0400 (EDT)

branch: master
commit 7103192cd2b0434c7acf712d0b7cf5a2f7b19e75
Author: Stefan Monnier <monnier@iro.umontreal.ca>
Commit: Stefan Monnier <monnier@iro.umontreal.ca>

    * src/xdisp.c (syms_of_xdisp) <"scroll-minibuffer-conservatively">: New var
    
    Fix bug#44070, which causes the minibuffer display to jump upon minor edit
    
    (redisplay_window): Obey it.
    * lisp/simple.el (end-of-buffer): Obey it.
    
    * test/src/xdisp-tests.el (xdisp-tests--in-minibuffer): New macro,
    extracted from `xdisp-tests--minibuffer-resizing`.
    (xdisp-tests--minibuffer-resizing): Use it.
    (xdisp-tests--minibuffer-scroll): New test.
---
 doc/emacs/display.texi  |  4 +++
 etc/NEWS                |  3 +++
 lisp/simple.el          |  6 ++++-
 src/xdisp.c             | 17 +++++++++---
 test/src/xdisp-tests.el | 71 ++++++++++++++++++++++++++++++++-----------------
 5 files changed, 72 insertions(+), 29 deletions(-)

diff --git a/doc/emacs/display.texi b/doc/emacs/display.texi
index 02859d5..7dadb09 100644
--- a/doc/emacs/display.texi
+++ b/doc/emacs/display.texi
@@ -244,6 +244,7 @@ point vertically in the window, but there are several ways 
to alter
 this behavior.
 
 @vindex scroll-conservatively
+@vindex scroll-minibuffer-conservatively
   If you set @code{scroll-conservatively} to a small number @var{n},
 then moving point just a little off the screen (no more than @var{n}
 lines) causes Emacs to scroll just enough to bring point back on
@@ -255,6 +256,9 @@ moves; Emacs always scrolls text just enough to bring point 
into view,
 either at the top or bottom of the window depending on the scroll
 direction.  By default, @code{scroll-conservatively} is@tie{}0, which
 means to always center point in the window.
+This said, in minibuffer windows, scrolling is always conservative by
+default because @code{scroll-minibuffer-conservatively} is non-nil,
+which takes precedence over @code{scroll-conservatively}.
 
 @vindex scroll-step
   Another way to control automatic scrolling is to customize the
diff --git a/etc/NEWS b/etc/NEWS
index 4435d05..a52122b 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -85,6 +85,9 @@ useful on systems such as FreeBSD which ships only with 
"etc/termcap".
 
 * Changes in Emacs 28.1
 
+** Minibuffer scrolling is now conservative by default.
+This is controlled by the new variable 'scroll-minibuffer-conservatively'.
+
 +++
 ** New system for displaying documentation for groups of function.
 This can either be used by saying 'M-x shortdoc-display-group' and
diff --git a/lisp/simple.el b/lisp/simple.el
index a9d79d0..d871be1 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -1134,7 +1134,11 @@ is supplied, or Transient Mark mode is enabled and the 
mark is active."
         ;; If the end of the buffer is not already on the screen,
         ;; then scroll specially to put it near, but not at, the bottom.
         (overlay-recenter (point))
-        (recenter -3))))
+        ;; FIXME: Arguably if `scroll-conservatively' is set, then
+         ;; we should pass -1 to `recenter'.
+        (recenter (if (and scroll-minibuffer-conservatively
+                           (window-minibuffer-p))
+                      -1 -3)))))
 
 (defcustom delete-active-region t
   "Whether single-char deletion commands delete an active region.
diff --git a/src/xdisp.c b/src/xdisp.c
index 0e5dffb..cc499f3 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -18820,6 +18820,7 @@ redisplay_window (Lisp_Object window, bool 
just_this_one_p)
 
   /* Try to scroll by specified few lines.  */
   if ((0 < scroll_conservatively
+       || (scroll_minibuffer_conservatively && MINI_WINDOW_P (w))
        || 0 < emacs_scroll_step
        || temp_scroll_step
        || NUMBERP (BVAR (current_buffer, scroll_up_aggressively))
@@ -18830,7 +18831,10 @@ redisplay_window (Lisp_Object window, bool 
just_this_one_p)
       /* The function returns -1 if new fonts were loaded, 1 if
         successful, 0 if not successful.  */
       int ss = try_scrolling (window, just_this_one_p,
-                             scroll_conservatively,
+                             ((scroll_minibuffer_conservatively
+                               && MINI_WINDOW_P (w))
+                              ? SCROLL_LIMIT + 1
+                              : scroll_conservatively),
                              emacs_scroll_step,
                              temp_scroll_step, last_line_misfit);
       switch (ss)
@@ -34538,7 +34542,14 @@ syms_of_xdisp (void)
 
   DEFSYM (Qredisplay_internal_xC_functionx, "redisplay_internal (C function)");
 
-  DEFVAR_BOOL("inhibit-message", inhibit_message,
+  DEFVAR_BOOL ("scroll-minibuffer-conservatively",
+               scroll_minibuffer_conservatively,
+               doc: /* Non-nil means scroll conservatively in minibuffer 
windows.
+When the value is nil, scrolling in minibuffer windows obeys the
+settings of `scroll-conservatively'.  */);
+  scroll_minibuffer_conservatively = true; /* bug#44070 */
+
+  DEFVAR_BOOL ("inhibit-message", inhibit_message,
               doc:  /* Non-nil means calls to `message' are not displayed.
 They are still logged to the *Messages* buffer.
 
@@ -34546,7 +34557,7 @@ Do NOT set this globally to a non-nil value, as doing 
that will
 disable messages everywhere, including in I-search and other
 places where they are necessary.  This variable is intended to
 be let-bound around code that needs to disable messages temporarily. */);
-  inhibit_message = 0;
+  inhibit_message = false;
 
   message_dolog_marker1 = Fmake_marker ();
   staticpro (&message_dolog_marker1);
diff --git a/test/src/xdisp-tests.el b/test/src/xdisp-tests.el
index 95c39da..fad90fa 100644
--- a/test/src/xdisp-tests.el
+++ b/test/src/xdisp-tests.el
@@ -21,34 +21,55 @@
 
 (require 'ert)
 
+(defmacro xdisp-tests--in-minibuffer (&rest body)
+  (declare (debug t) (indent 0))
+  `(catch 'result
+     (minibuffer-with-setup-hook
+         (lambda ()
+           (let ((redisplay-skip-initial-frame nil)
+                 (executing-kbd-macro nil)) ;Don't skip redisplay
+             (throw 'result (progn . ,body))))
+       (let ((executing-kbd-macro t)) ;Force real minibuffer in `read-string'.
+         (read-string "toto: ")))))
+
 (ert-deftest xdisp-tests--minibuffer-resizing () ;; bug#43519
-  ;; FIXME: This test returns success when run in batch but
-  ;; it's only a lucky accident: it also returned success
-  ;; when bug#43519 was not fixed.
   (should
    (equal
     t
-    (catch 'result
-      (minibuffer-with-setup-hook
-          (lambda ()
-            (insert "hello")
-            (let ((ol (make-overlay (point) (point)))
-                  (redisplay-skip-initial-frame nil)
-                  (max-mini-window-height 1)
-                  (text 
"askdjfhaklsjdfhlkasjdfhklasdhflkasdhflkajsdhflkashdfkljahsdlfkjahsdlfkjhasldkfhalskdjfhalskdfhlaksdhfklasdhflkasdhflkasdhflkajsdhklajsdgh"))
-              ;; (save-excursion (insert text))
-              ;; (sit-for 2)
-              ;; (delete-region (point) (point-max))
-              (put-text-property 0 1 'cursor t text)
-              (overlay-put ol 'after-string text)
-              (let ((executing-kbd-macro nil)) ;Don't skip redisplay
-                (redisplay 'force))
-              (throw 'result
-                     ;; Make sure we do the see "hello" text.
-                     (prog1 (equal (window-start) (point-min))
-                       ;; (list (window-start) (window-end) (window-width))
-                       (delete-overlay ol)))))
-        (let ((executing-kbd-macro t)) ;Force real minibuffer in `read-string'.
-          (read-string "toto: ")))))))
+    (xdisp-tests--in-minibuffer
+      (insert "hello")
+      (let ((ol (make-overlay (point) (point)))
+            (max-mini-window-height 1)
+            (text 
"askdjfhaklsjdfhlkasjdfhklasdhflkasdhflkajsdhflkashdfkljahsdlfkjahsdlfkjhasldkfhalskdjfhalskdfhlaksdhfklasdhflkasdhflkasdhflkajsdhklajsdgh"))
+        ;; (save-excursion (insert text))
+        ;; (sit-for 2)
+        ;; (delete-region (point) (point-max))
+        (put-text-property 0 1 'cursor t text)
+        (overlay-put ol 'after-string text)
+        (redisplay 'force)
+        ;; Make sure we do the see "hello" text.
+        (prog1 (equal (window-start) (point-min))
+          ;; (list (window-start) (window-end) (window-width))
+          (delete-overlay ol)))))))
+
+(ert-deftest xdisp-tests--minibuffer-scroll () ;; bug#44070
+  (let ((posns
+         (xdisp-tests--in-minibuffer
+           (let ((max-mini-window-height 4))
+             (dotimes (_ 80) (insert "\nhello"))
+             (beginning-of-buffer)
+             (redisplay 'force)
+             (end-of-buffer)
+             ;; A simple edit like removing the last `o' shouldn't cause
+             ;; the rest of the minibuffer's text to move.
+             (list
+              (progn (redisplay 'force) (window-start))
+              (progn (delete-char -1)
+                     (redisplay 'force) (window-start))
+              (progn (goto-char (point-min)) (redisplay 'force)
+                     (goto-char (point-max)) (redisplay 'force)
+                     (window-start)))))))
+    (should (equal (nth 0 posns) (nth 1 posns)))
+    (should (equal (nth 1 posns) (nth 2 posns)))))
 
 ;;; xdisp-tests.el ends here



reply via email to

[Prev in Thread] Current Thread [Next in Thread]