Mercurial > emacs
diff src/window.c @ 95566:b3c0438c570b
* window.c (window_scroll_pixel_based_preserve_x)
(window_scroll_preserve_hpos, window_scroll_preserve_vpos): New vars.
(window_scroll_pixel_based, window_scroll_line_based):
Use them to preserve column positions.
(syms_of_window): Initialize them.
* indent.c (Fvertical_motion): Extend first arg to allow passing an
(HPOS . VPOS) pair.
* xdisp.c (move_it_in_display_line_to): Improve the type of its args.
(move_it_in_display_line): New wrapper.
* dispextern.h (move_it_in_display_line): Declare.
author | Stefan Monnier <monnier@iro.umontreal.ca> |
---|---|
date | Thu, 05 Jun 2008 03:57:09 +0000 |
parents | 823072be49ad |
children | 9a4b27c8feec |
line wrap: on
line diff
--- a/src/window.c Thu Jun 05 03:23:31 2008 +0000 +++ b/src/window.c Thu Jun 05 03:57:09 2008 +0000 @@ -224,8 +224,14 @@ /* Used by the function window_scroll_pixel_based */ +static int window_scroll_pixel_based_preserve_x; static int window_scroll_pixel_based_preserve_y; +/* Same for window_scroll_line_based. */ + +static int window_scroll_preserve_hpos; +static int window_scroll_preserve_vpos; + #if 0 /* This isn't used anywhere. */ /* Nonzero means we can split a frame even if it is "unsplittable". */ static int inhibit_frame_unsplittable; @@ -5216,10 +5222,12 @@ start_display (&it, w, start); move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS); window_scroll_pixel_based_preserve_y = it.current_y; + window_scroll_pixel_based_preserve_x = it.current_x; } } else - window_scroll_pixel_based_preserve_y = -1; + window_scroll_pixel_based_preserve_y + = window_scroll_pixel_based_preserve_x = -1; /* Move iterator it from start the specified distance forward or backward. The result is the new window start. */ @@ -5355,10 +5363,11 @@ { /* If we have a header line, take account of it. This is necessary because we set it.current_y to 0, above. */ - move_it_to (&it, -1, -1, + move_it_to (&it, -1, + window_scroll_pixel_based_preserve_x, window_scroll_pixel_based_preserve_y - (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0 ), - -1, MOVE_TO_Y); + -1, MOVE_TO_Y | MOVE_TO_X); SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it)); } else @@ -5416,8 +5425,9 @@ /* It would be wrong to subtract CURRENT_HEADER_LINE_HEIGHT here because we called start_display again and did not alter it.current_y this time. */ - move_it_to (&it, -1, -1, window_scroll_pixel_based_preserve_y, -1, - MOVE_TO_Y); + move_it_to (&it, -1, window_scroll_pixel_based_preserve_x, + window_scroll_pixel_based_preserve_y, -1, + MOVE_TO_Y | MOVE_TO_X); SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it)); } else @@ -5455,8 +5465,7 @@ int lose; Lisp_Object bolp; int startpos; - struct position posit; - int original_vpos; + Lisp_Object original_pos = Qnil; /* If scrolling screen-fulls, compute the number of lines to scroll from the window's height. */ @@ -5465,11 +5474,24 @@ startpos = marker_position (w->start); - posit = *compute_motion (startpos, 0, 0, 0, - PT, ht, 0, - -1, XINT (w->hscroll), - 0, w); - original_vpos = posit.vpos; + if (!NILP (Vscroll_preserve_screen_position)) + { + if (window_scroll_preserve_vpos <= 0 + || (!EQ (current_kboard->Vlast_command, Qscroll_up) + && !EQ (current_kboard->Vlast_command, Qscroll_down))) + { + struct position posit + = *compute_motion (startpos, 0, 0, 0, + PT, ht, 0, + -1, XINT (w->hscroll), + 0, w); + window_scroll_preserve_vpos = posit.vpos; + window_scroll_preserve_hpos = posit.hpos + XINT (w->hscroll); + } + + original_pos = Fcons (make_number (window_scroll_preserve_hpos), + make_number (window_scroll_preserve_vpos)); + } XSETFASTINT (tem, PT); tem = Fpos_visible_in_window_p (tem, window, Qnil); @@ -5520,7 +5542,7 @@ && (whole || !EQ (Vscroll_preserve_screen_position, Qt))) { SET_PT_BOTH (pos, pos_byte); - Fvertical_motion (make_number (original_vpos), window); + Fvertical_motion (original_pos, window); } /* If we scrolled forward, put point enough lines down that it is outside the scroll margin. */ @@ -5542,7 +5564,7 @@ else if (!NILP (Vscroll_preserve_screen_position)) { SET_PT_BOTH (pos, pos_byte); - Fvertical_motion (make_number (original_vpos), window); + Fvertical_motion (original_pos, window); } else SET_PT (top_margin); @@ -5567,7 +5589,7 @@ if (!NILP (Vscroll_preserve_screen_position)) { SET_PT_BOTH (pos, pos_byte); - Fvertical_motion (make_number (original_vpos), window); + Fvertical_motion (original_pos, window); } else Fvertical_motion (make_number (-1), window); @@ -7439,7 +7461,10 @@ minibuf_selected_window = Qnil; staticpro (&minibuf_selected_window); + window_scroll_pixel_based_preserve_x = -1; window_scroll_pixel_based_preserve_y = -1; + window_scroll_preserve_hpos = -1; + window_scroll_preserve_vpos = -1; DEFVAR_LISP ("temp-buffer-show-function", &Vtemp_buffer_show_function, doc: /* Non-nil means call as function to display a help buffer. @@ -7640,7 +7665,7 @@ DEFVAR_LISP ("scroll-preserve-screen-position", &Vscroll_preserve_screen_position, - doc: /* *Controls if scroll commands move point to keep its screen line unchanged. + doc: /* *Controls if scroll commands move point to keep its screen position unchanged. A value of nil means point does not keep its screen position except at the scroll margin or window boundary respectively. A value of t means point keeps its screen position if the scroll