Avoid weird behavior with large horizontal scrolls.
Without this change, for example, large hscroll values would mess up Emacs's display on Fedora 15 x86, presumably due to overflows in int calculations in the display code. Also, if buffers had long lines, Emacs would freeze. * window.c (HSCROLL_MAX): Reduce to 100000, and make it visible to GDB. (set_window_hscroll): New function, containing the old guts of Fset_window_hscroll. Return the clipped value. (Fset_window_hscroll, Fscroll_left, Fscroll_right): Use it. This avoids the need to check against PTRDIFF_MAX.
This commit is contained in:
parent
dea7f1e5a4
commit
24a212eb23
2 changed files with 36 additions and 25 deletions
|
@ -1,5 +1,16 @@
|
|||
2012-07-04 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
Avoid weird behavior with large horizontal scrolls.
|
||||
Without this change, for example, large hscroll values would
|
||||
mess up Emacs's display on Fedora 15 x86, presumably due to
|
||||
overflows in int calculations in the display code.
|
||||
Also, if buffers had long lines, Emacs would freeze.
|
||||
* window.c (HSCROLL_MAX): Reduce to 100000, and make it visible to GDB.
|
||||
(set_window_hscroll): New function, containing the old guts of
|
||||
Fset_window_hscroll. Return the clipped value.
|
||||
(Fset_window_hscroll, Fscroll_left, Fscroll_right): Use it.
|
||||
This avoids the need to check against PTRDIFF_MAX.
|
||||
|
||||
* buffer.c (Fgenerate_new_buffer_name): Fix sprintf format mismatch.
|
||||
|
||||
2012-07-04 Dmitry Antipov <dmantipov@yandex.ru>
|
||||
|
|
50
src/window.c
50
src/window.c
|
@ -51,6 +51,11 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
|||
#include "nsterm.h"
|
||||
#endif
|
||||
|
||||
/* Horizontal scrolling has problems with large scroll amounts.
|
||||
It's too slow with long lines, and even with small lines the
|
||||
display can be messed up. Impose a reasonable maximum. */
|
||||
enum { HSCROLL_MAX = 100000 };
|
||||
|
||||
Lisp_Object Qwindowp, Qwindow_live_p;
|
||||
static Lisp_Object Qwindow_configuration_p, Qrecord_window_buffer;
|
||||
static Lisp_Object Qwindow_deletable_p, Qdelete_window, Qdisplay_buffer;
|
||||
|
@ -670,27 +675,35 @@ WINDOW must be a live window and defaults to the selected one. */)
|
|||
return make_number (decode_window (window)->hscroll);
|
||||
}
|
||||
|
||||
/* Set W's horizontal scroll amount to HSCROLL clipped to a reasonable
|
||||
range, returning the new amount as a fixnum. */
|
||||
static Lisp_Object
|
||||
set_window_hscroll (struct window *w, EMACS_INT hscroll)
|
||||
{
|
||||
int new_hscroll = clip_to_bounds (0, hscroll, HSCROLL_MAX);
|
||||
|
||||
/* Prevent redisplay shortcuts when changing the hscroll. */
|
||||
if (w->hscroll != new_hscroll)
|
||||
XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
|
||||
|
||||
w->hscroll = new_hscroll;
|
||||
return make_number (new_hscroll);
|
||||
}
|
||||
|
||||
DEFUN ("set-window-hscroll", Fset_window_hscroll, Sset_window_hscroll, 2, 2, 0,
|
||||
doc: /* Set number of columns WINDOW is scrolled from left margin to NCOL.
|
||||
If WINDOW is nil, the selected window is used.
|
||||
Return NCOL. NCOL should be zero or positive.
|
||||
Clip the number to a reasonable value if out of range.
|
||||
Return the new number. NCOL should be zero or positive.
|
||||
|
||||
Note that if `automatic-hscrolling' is non-nil, you cannot scroll the
|
||||
window so that the location of point moves off-window. */)
|
||||
(Lisp_Object window, Lisp_Object ncol)
|
||||
{
|
||||
struct window *w = decode_window (window);
|
||||
ptrdiff_t hscroll;
|
||||
|
||||
CHECK_NUMBER (ncol);
|
||||
hscroll = clip_to_bounds (0, XINT (ncol), PTRDIFF_MAX);
|
||||
|
||||
/* Prevent redisplay shortcuts when changing the hscroll. */
|
||||
if (w->hscroll != hscroll)
|
||||
XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
|
||||
|
||||
w->hscroll = hscroll;
|
||||
return ncol;
|
||||
return set_window_hscroll (w, XINT (ncol));
|
||||
}
|
||||
|
||||
DEFUN ("window-redisplay-end-trigger", Fwindow_redisplay_end_trigger,
|
||||
|
@ -4850,9 +4863,6 @@ specifies the window to scroll. This takes precedence over
|
|||
return Qnil;
|
||||
}
|
||||
|
||||
/* Scrolling amount must fit in both ptrdiff_t and Emacs fixnum. */
|
||||
#define HSCROLL_MAX min (PTRDIFF_MAX, MOST_POSITIVE_FIXNUM)
|
||||
|
||||
DEFUN ("scroll-left", Fscroll_left, Sscroll_left, 0, 2, "^P\np",
|
||||
doc: /* Scroll selected window display ARG columns left.
|
||||
Default for ARG is window width minus 2.
|
||||
|
@ -4864,16 +4874,11 @@ will not scroll a window to a column less than the value returned
|
|||
by this function. This happens in an interactive call. */)
|
||||
(register Lisp_Object arg, Lisp_Object set_minimum)
|
||||
{
|
||||
Lisp_Object result;
|
||||
ptrdiff_t hscroll;
|
||||
struct window *w = XWINDOW (selected_window);
|
||||
EMACS_INT requested_arg = (NILP (arg)
|
||||
? window_body_cols (w) - 2
|
||||
: XINT (Fprefix_numeric_value (arg)));
|
||||
ptrdiff_t clipped_arg =
|
||||
clip_to_bounds (- w->hscroll, requested_arg, HSCROLL_MAX - w->hscroll);
|
||||
hscroll = w->hscroll + clipped_arg;
|
||||
result = Fset_window_hscroll (selected_window, make_number (hscroll));
|
||||
Lisp_Object result = set_window_hscroll (w, w->hscroll + requested_arg);
|
||||
|
||||
if (!NILP (set_minimum))
|
||||
w->min_hscroll = w->hscroll;
|
||||
|
@ -4892,16 +4897,11 @@ will not scroll a window to a column less than the value returned
|
|||
by this function. This happens in an interactive call. */)
|
||||
(register Lisp_Object arg, Lisp_Object set_minimum)
|
||||
{
|
||||
Lisp_Object result;
|
||||
ptrdiff_t hscroll;
|
||||
struct window *w = XWINDOW (selected_window);
|
||||
EMACS_INT requested_arg = (NILP (arg)
|
||||
? window_body_cols (w) - 2
|
||||
: XINT (Fprefix_numeric_value (arg)));
|
||||
ptrdiff_t clipped_arg =
|
||||
clip_to_bounds (w->hscroll - HSCROLL_MAX, requested_arg, w->hscroll);
|
||||
hscroll = w->hscroll - clipped_arg;
|
||||
result = Fset_window_hscroll (selected_window, make_number (hscroll));
|
||||
Lisp_Object result = set_window_hscroll (w, w->hscroll - requested_arg);
|
||||
|
||||
if (!NILP (set_minimum))
|
||||
w->min_hscroll = w->hscroll;
|
||||
|
|
Loading…
Add table
Reference in a new issue