From 1df7e8f069e2e7a3b9b321ff8c42e59b314021d2 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Sat, 16 Feb 2002 12:40:51 +0000 Subject: [PATCH] (automatic_hscroll_margin, Vautomatic_hscroll_step): New variables. (syms_of_xdisp): DEVFAR them. (hscroll_window_tree): Use automatic_hscroll_margin and Vautomatic_hscroll_step to compute the amount of window scrolling. --- src/xdisp.c | 98 +++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 87 insertions(+), 11 deletions(-) diff --git a/src/xdisp.c b/src/xdisp.c index aec0e9e0f06..3766f0b5219 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -582,6 +582,13 @@ int trace_move; int automatic_hscrolling_p; +/* How close to the margin can point get before the window is scrolled + horizontally. */ +int automatic_hscroll_margin; + +/* How much to scroll horizontally when point is inside the above margin. */ +Lisp_Object Vautomatic_hscroll_step; + /* A list of symbols, one for each supported image type. */ Lisp_Object Vimage_types; @@ -8017,11 +8024,32 @@ hscroll_window_tree (window) Lisp_Object window; { int hscrolled_p = 0; - + int hscroll_relative_p = FLOATP (Vautomatic_hscroll_step); + int hscroll_step_abs = 0; + double hscroll_step_rel = 0; + + if (hscroll_relative_p) + { + hscroll_step_rel = XFLOAT_DATA (Vautomatic_hscroll_step); + if (hscroll_step_rel < 0) + { + hscroll_relative_p = 0; + hscroll_step_abs = 0; + } + } + else if (INTEGERP (Vautomatic_hscroll_step)) + { + hscroll_step_abs = XINT (Vautomatic_hscroll_step); + if (hscroll_step_abs < 0) + hscroll_step_abs = 0; + } + else + hscroll_step_abs = 0; + while (WINDOWP (window)) { struct window *w = XWINDOW (window); - + if (WINDOWP (w->hchild)) hscrolled_p |= hscroll_window_tree (w->hchild); else if (WINDOWP (w->vchild)) @@ -8043,24 +8071,25 @@ hscroll_window_tree (window) &text_area_width, &text_area_height); /* Scroll when cursor is inside this scroll margin. */ - /* Shouldn't we export this `5' for customization ? -stef */ - hscroll_margin = 5 * CANON_X_UNIT (XFRAME (w->frame)); - + hscroll_margin + = automatic_hscroll_margin * CANON_X_UNIT (XFRAME (w->frame)); + if ((XFASTINT (w->hscroll) - && w->cursor.x < hscroll_margin) + && w->cursor.x <= hscroll_margin) || (cursor_row->enabled_p && cursor_row->truncated_on_right_p - && (w->cursor.x > text_area_width - hscroll_margin))) + && (w->cursor.x >= text_area_width - hscroll_margin))) { struct it it; int hscroll; struct buffer *saved_current_buffer; int pt; + int wanted_x; /* Find point in a display of infinite width. */ saved_current_buffer = current_buffer; current_buffer = XBUFFER (w->buffer); - + if (w == XWINDOW (selected_window)) pt = BUF_PT (current_buffer); else @@ -8077,9 +8106,33 @@ hscroll_window_tree (window) move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS); current_buffer = saved_current_buffer; - /* Center cursor in window. */ - hscroll = (max (0, it.current_x - text_area_width / 2) - / CANON_X_UNIT (it.f)); + /* Position cursor in window. */ + if (!hscroll_relative_p && hscroll_step_abs == 0) + hscroll = max (0, it.current_x - text_area_width / 2) + / CANON_X_UNIT (it.f); + else if (w->cursor.x >= text_area_width - hscroll_margin) + { + if (hscroll_relative_p) + wanted_x = text_area_width * (1 - hscroll_step_rel) + - hscroll_margin; + else + wanted_x = text_area_width + - hscroll_step_abs * CANON_X_UNIT (it.f) + - hscroll_margin; + hscroll + = max (0, it.current_x - wanted_x) / CANON_X_UNIT (it.f); + } + else + { + if (hscroll_relative_p) + wanted_x = text_area_width * hscroll_step_rel + + hscroll_margin; + else + wanted_x = hscroll_step_abs * CANON_X_UNIT (it.f) + + hscroll_margin; + hscroll + = max (0, it.current_x - wanted_x) / CANON_X_UNIT (it.f); + } hscroll = max (hscroll, XFASTINT (w->min_hscroll)); /* Don't call Fset_window_hscroll if value hasn't @@ -15010,6 +15063,29 @@ nil means don't display a cursor there. */); DEFVAR_BOOL ("automatic-hscrolling", &automatic_hscrolling_p, doc: /* *Non-nil means scroll the display automatically to make point visible. */); automatic_hscrolling_p = 1; + + DEFVAR_INT ("automatic-hscroll-margin", &automatic_hscroll_margin, + doc: /* *How many columns away from the window edge point is allowed to get +before automatic hscrolling will horizontally scroll the window. */); + automatic_hscroll_margin = 5; + + DEFVAR_LISP ("automatic-hscroll-step", &Vautomatic_hscroll_step, + doc: /* *How many columns to scroll the window when point gets too close to the edge. +When point is less than `automatic-hscroll-margin' columns from the window +edge, automatic hscrolling will scroll the window by the amount of columns +determined by this variable. If its value is a positive integer, scroll that +many columns. If it's a positive floating-point number, it specifies the +fraction of the window's width to scroll. If it's nil or zero, point will be +centered horizontally after the scroll. Any other value, including negative +numbers, are treated as if the value were zero. + +Automatic hscrolling always moves point outside the scroll margin, so if +point was more than scroll step columns inside the margin, the window will +scroll more than the value given by the scroll step. + +Note that the lower bound for automatic hscrolling specified by `scroll-left' +and `scroll-right' overrides this variable's effect. */); + Vautomatic_hscroll_step = make_number (0); DEFVAR_LISP ("image-types", &Vimage_types, doc: /* List of supported image types. -- 2.39.2