aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2020-10-31 09:07:53 -0400
committerStefan Monnier2020-10-31 09:07:53 -0400
commit7103192cd2b0434c7acf712d0b7cf5a2f7b19e75 (patch)
tree14333414af14ff4035a27ec26f67ab177394ae01
parentc3a20804a81826ec091a4a096c1987a61e412580 (diff)
downloademacs-7103192cd2b0434c7acf712d0b7cf5a2f7b19e75.tar.gz
emacs-7103192cd2b0434c7acf712d0b7cf5a2f7b19e75.zip
* 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.
-rw-r--r--doc/emacs/display.texi4
-rw-r--r--etc/NEWS3
-rw-r--r--lisp/simple.el6
-rw-r--r--src/xdisp.c17
-rw-r--r--test/src/xdisp-tests.el71
5 files changed, 72 insertions, 29 deletions
diff --git a/doc/emacs/display.texi b/doc/emacs/display.texi
index 02859d522e3..7dadb0966f2 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
244this behavior. 244this behavior.
245 245
246@vindex scroll-conservatively 246@vindex scroll-conservatively
247@vindex scroll-minibuffer-conservatively
247 If you set @code{scroll-conservatively} to a small number @var{n}, 248 If you set @code{scroll-conservatively} to a small number @var{n},
248then moving point just a little off the screen (no more than @var{n} 249then moving point just a little off the screen (no more than @var{n}
249lines) causes Emacs to scroll just enough to bring point back on 250lines) 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,
255either at the top or bottom of the window depending on the scroll 256either at the top or bottom of the window depending on the scroll
256direction. By default, @code{scroll-conservatively} is@tie{}0, which 257direction. By default, @code{scroll-conservatively} is@tie{}0, which
257means to always center point in the window. 258means to always center point in the window.
259This said, in minibuffer windows, scrolling is always conservative by
260default because @code{scroll-minibuffer-conservatively} is non-nil,
261which takes precedence over @code{scroll-conservatively}.
258 262
259@vindex scroll-step 263@vindex scroll-step
260 Another way to control automatic scrolling is to customize the 264 Another way to control automatic scrolling is to customize the
diff --git a/etc/NEWS b/etc/NEWS
index 4435d0563be..a52122bceaf 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -85,6 +85,9 @@ useful on systems such as FreeBSD which ships only with "etc/termcap".
85 85
86* Changes in Emacs 28.1 86* Changes in Emacs 28.1
87 87
88** Minibuffer scrolling is now conservative by default.
89This is controlled by the new variable 'scroll-minibuffer-conservatively'.
90
88+++ 91+++
89** New system for displaying documentation for groups of function. 92** New system for displaying documentation for groups of function.
90This can either be used by saying 'M-x shortdoc-display-group' and 93This can either be used by saying 'M-x shortdoc-display-group' and
diff --git a/lisp/simple.el b/lisp/simple.el
index a9d79d031e8..d871be104cf 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."
1134 ;; If the end of the buffer is not already on the screen, 1134 ;; If the end of the buffer is not already on the screen,
1135 ;; then scroll specially to put it near, but not at, the bottom. 1135 ;; then scroll specially to put it near, but not at, the bottom.
1136 (overlay-recenter (point)) 1136 (overlay-recenter (point))
1137 (recenter -3)))) 1137 ;; FIXME: Arguably if `scroll-conservatively' is set, then
1138 ;; we should pass -1 to `recenter'.
1139 (recenter (if (and scroll-minibuffer-conservatively
1140 (window-minibuffer-p))
1141 -1 -3)))))
1138 1142
1139(defcustom delete-active-region t 1143(defcustom delete-active-region t
1140 "Whether single-char deletion commands delete an active region. 1144 "Whether single-char deletion commands delete an active region.
diff --git a/src/xdisp.c b/src/xdisp.c
index 0e5dffbe007..cc499f33261 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -18820,6 +18820,7 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
18820 18820
18821 /* Try to scroll by specified few lines. */ 18821 /* Try to scroll by specified few lines. */
18822 if ((0 < scroll_conservatively 18822 if ((0 < scroll_conservatively
18823 || (scroll_minibuffer_conservatively && MINI_WINDOW_P (w))
18823 || 0 < emacs_scroll_step 18824 || 0 < emacs_scroll_step
18824 || temp_scroll_step 18825 || temp_scroll_step
18825 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively)) 18826 || NUMBERP (BVAR (current_buffer, scroll_up_aggressively))
@@ -18830,7 +18831,10 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
18830 /* The function returns -1 if new fonts were loaded, 1 if 18831 /* The function returns -1 if new fonts were loaded, 1 if
18831 successful, 0 if not successful. */ 18832 successful, 0 if not successful. */
18832 int ss = try_scrolling (window, just_this_one_p, 18833 int ss = try_scrolling (window, just_this_one_p,
18833 scroll_conservatively, 18834 ((scroll_minibuffer_conservatively
18835 && MINI_WINDOW_P (w))
18836 ? SCROLL_LIMIT + 1
18837 : scroll_conservatively),
18834 emacs_scroll_step, 18838 emacs_scroll_step,
18835 temp_scroll_step, last_line_misfit); 18839 temp_scroll_step, last_line_misfit);
18836 switch (ss) 18840 switch (ss)
@@ -34538,7 +34542,14 @@ syms_of_xdisp (void)
34538 34542
34539 DEFSYM (Qredisplay_internal_xC_functionx, "redisplay_internal (C function)"); 34543 DEFSYM (Qredisplay_internal_xC_functionx, "redisplay_internal (C function)");
34540 34544
34541 DEFVAR_BOOL("inhibit-message", inhibit_message, 34545 DEFVAR_BOOL ("scroll-minibuffer-conservatively",
34546 scroll_minibuffer_conservatively,
34547 doc: /* Non-nil means scroll conservatively in minibuffer windows.
34548When the value is nil, scrolling in minibuffer windows obeys the
34549settings of `scroll-conservatively'. */);
34550 scroll_minibuffer_conservatively = true; /* bug#44070 */
34551
34552 DEFVAR_BOOL ("inhibit-message", inhibit_message,
34542 doc: /* Non-nil means calls to `message' are not displayed. 34553 doc: /* Non-nil means calls to `message' are not displayed.
34543They are still logged to the *Messages* buffer. 34554They are still logged to the *Messages* buffer.
34544 34555
@@ -34546,7 +34557,7 @@ Do NOT set this globally to a non-nil value, as doing that will
34546disable messages everywhere, including in I-search and other 34557disable messages everywhere, including in I-search and other
34547places where they are necessary. This variable is intended to 34558places where they are necessary. This variable is intended to
34548be let-bound around code that needs to disable messages temporarily. */); 34559be let-bound around code that needs to disable messages temporarily. */);
34549 inhibit_message = 0; 34560 inhibit_message = false;
34550 34561
34551 message_dolog_marker1 = Fmake_marker (); 34562 message_dolog_marker1 = Fmake_marker ();
34552 staticpro (&message_dolog_marker1); 34563 staticpro (&message_dolog_marker1);
diff --git a/test/src/xdisp-tests.el b/test/src/xdisp-tests.el
index 95c39dacc3e..fad90fad531 100644
--- a/test/src/xdisp-tests.el
+++ b/test/src/xdisp-tests.el
@@ -21,34 +21,55 @@
21 21
22(require 'ert) 22(require 'ert)
23 23
24(defmacro xdisp-tests--in-minibuffer (&rest body)
25 (declare (debug t) (indent 0))
26 `(catch 'result
27 (minibuffer-with-setup-hook
28 (lambda ()
29 (let ((redisplay-skip-initial-frame nil)
30 (executing-kbd-macro nil)) ;Don't skip redisplay
31 (throw 'result (progn . ,body))))
32 (let ((executing-kbd-macro t)) ;Force real minibuffer in `read-string'.
33 (read-string "toto: ")))))
34
24(ert-deftest xdisp-tests--minibuffer-resizing () ;; bug#43519 35(ert-deftest xdisp-tests--minibuffer-resizing () ;; bug#43519
25 ;; FIXME: This test returns success when run in batch but
26 ;; it's only a lucky accident: it also returned success
27 ;; when bug#43519 was not fixed.
28 (should 36 (should
29 (equal 37 (equal
30 t 38 t
31 (catch 'result 39 (xdisp-tests--in-minibuffer
32 (minibuffer-with-setup-hook 40 (insert "hello")
33 (lambda () 41 (let ((ol (make-overlay (point) (point)))
34 (insert "hello") 42 (max-mini-window-height 1)
35 (let ((ol (make-overlay (point) (point))) 43 (text "askdjfhaklsjdfhlkasjdfhklasdhflkasdhflkajsdhflkashdfkljahsdlfkjahsdlfkjhasldkfhalskdjfhalskdfhlaksdhfklasdhflkasdhflkasdhflkajsdhklajsdgh"))
36 (redisplay-skip-initial-frame nil) 44 ;; (save-excursion (insert text))
37 (max-mini-window-height 1) 45 ;; (sit-for 2)
38 (text "askdjfhaklsjdfhlkasjdfhklasdhflkasdhflkajsdhflkashdfkljahsdlfkjahsdlfkjhasldkfhalskdjfhalskdfhlaksdhfklasdhflkasdhflkasdhflkajsdhklajsdgh")) 46 ;; (delete-region (point) (point-max))
39 ;; (save-excursion (insert text)) 47 (put-text-property 0 1 'cursor t text)
40 ;; (sit-for 2) 48 (overlay-put ol 'after-string text)
41 ;; (delete-region (point) (point-max)) 49 (redisplay 'force)
42 (put-text-property 0 1 'cursor t text) 50 ;; Make sure we do the see "hello" text.
43 (overlay-put ol 'after-string text) 51 (prog1 (equal (window-start) (point-min))
44 (let ((executing-kbd-macro nil)) ;Don't skip redisplay 52 ;; (list (window-start) (window-end) (window-width))
45 (redisplay 'force)) 53 (delete-overlay ol)))))))
46 (throw 'result 54
47 ;; Make sure we do the see "hello" text. 55(ert-deftest xdisp-tests--minibuffer-scroll () ;; bug#44070
48 (prog1 (equal (window-start) (point-min)) 56 (let ((posns
49 ;; (list (window-start) (window-end) (window-width)) 57 (xdisp-tests--in-minibuffer
50 (delete-overlay ol))))) 58 (let ((max-mini-window-height 4))
51 (let ((executing-kbd-macro t)) ;Force real minibuffer in `read-string'. 59 (dotimes (_ 80) (insert "\nhello"))
52 (read-string "toto: "))))))) 60 (beginning-of-buffer)
61 (redisplay 'force)
62 (end-of-buffer)
63 ;; A simple edit like removing the last `o' shouldn't cause
64 ;; the rest of the minibuffer's text to move.
65 (list
66 (progn (redisplay 'force) (window-start))
67 (progn (delete-char -1)
68 (redisplay 'force) (window-start))
69 (progn (goto-char (point-min)) (redisplay 'force)
70 (goto-char (point-max)) (redisplay 'force)
71 (window-start)))))))
72 (should (equal (nth 0 posns) (nth 1 posns)))
73 (should (equal (nth 1 posns) (nth 2 posns)))))
53 74
54;;; xdisp-tests.el ends here 75;;; xdisp-tests.el ends here