Commit c876b227 authored by Stefan Monnier's avatar Stefan Monnier

* 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.
parent 927abf37
......@@ -63,6 +63,7 @@ default toolkit, but you can use --with-x-toolkit=gtk if necessary.
* Changes in Emacs 23.1
** scroll-preserve-screen-position also preserves the column position.
** Completion.
*** `completion-styles' can be customized to choose your favorite completion.
*** The default completion styles include a form of partial-completion.
......
2008-06-05 Stefan Monnier <monnier@iro.umontreal.ca>
* xdisp.c (move_it_in_display_line_to): Improve the type of its args.
(move_it_in_display_line): New wrapper.
* 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.
* dispextern.h (move_it_in_display_line): Declare.
2008-06-05 Juanma Barranquero <lekktu@gmail.com>
* window.c (Fwindow_parameter): Return VALUE, not (PARAMETER . VALUE).
......@@ -113,11 +129,11 @@
(struct named_merge_point): Add `named_merge_point_kind' field.
(push_named_merge_point): Make cycle detection respect different
named-merge-point kinds.
(lface_from_face_name_no_resolve): Renamed from `lface_from_face_name'.
(lface_from_face_name_no_resolve): Rename from `lface_from_face_name'.
Remove face-name alias resolution.
(lface_from_face_name): New definition using
`lface_from_face_name_no_resolve'.
(get_lface_attributes_no_remap): Renamed from `get_lface_attributes'.
(get_lface_attributes_no_remap): Rename from `get_lface_attributes'.
Call lface_from_face_name_no_resolve instead of lface_from_face_name.
(get_lface_attributes): New definition that layers face-remapping on
top of get_lface_attributes_no_remap. New arg `named_merge_points'.
......
......@@ -2685,6 +2685,9 @@ void move_it_vertically P_ ((struct it *, int));
void move_it_vertically_backward P_ ((struct it *, int));
void move_it_by_lines P_ ((struct it *, int, int));
void move_it_past_eol P_ ((struct it *));
void move_it_in_display_line (struct it *it,
EMACS_INT to_charpos, int to_x,
enum move_operation_enum op);
int in_display_vector_p P_ ((struct it *));
int frame_mode_line_height P_ ((struct frame *));
void highlight_trailing_whitespace P_ ((struct frame *, struct glyph_row *));
......
......@@ -1993,6 +1993,10 @@ The optional second argument WINDOW specifies the window to use for
parameters such as width, horizontal scrolling, and so on.
The default is to use the selected window's parameters.
LINES can optionally take the form (COLS . LINES), in which case
the motion will not stop at the start of a screen line but on
its column COLS (if such exists on that line, that is).
`vertical-motion' always uses the current buffer,
regardless of which buffer is displayed in WINDOW.
This is consistent with other cursor motion functions
......@@ -2006,6 +2010,14 @@ whether or not it is currently displayed in some window. */)
struct window *w;
Lisp_Object old_buffer;
struct gcpro gcpro1;
int cols = 0;
/* Allow LINES to be of the form (HPOS . VPOS) aka (COLUMNS . LINES). */
if (CONSP (lines) && (NUMBERP (XCAR (lines))))
{
cols = XINT (XCAR (lines));
lines = XCDR (lines);
}
CHECK_NUMBER (lines);
if (! NILP (window))
......@@ -2094,6 +2106,11 @@ whether or not it is currently displayed in some window. */)
if (XINT (lines) >= 0 || IT_CHARPOS (it) > 0)
move_it_by_lines (&it, XINT (lines), 0);
if (cols)
move_it_in_display_line (&it, ZV,
cols * FRAME_COLUMN_WIDTH (XFRAME (w->frame)),
MOVE_TO_X);
SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
}
......
......@@ -224,8 +224,14 @@ int window_deletion_count;
/* 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 @@ window_scroll_pixel_based (window, n, whole, noerror)
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 @@ window_scroll_pixel_based (window, n, whole, noerror)
{
/* 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 @@ window_scroll_pixel_based (window, n, whole, noerror)
/* 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 @@ window_scroll_line_based (window, n, whole, noerror)
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 @@ window_scroll_line_based (window, n, whole, noerror)
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 @@ window_scroll_line_based (window, n, whole, noerror)
&& (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 @@ window_scroll_line_based (window, n, whole, noerror)
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 @@ window_scroll_line_based (window, n, whole, noerror)
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 @@ syms_of_window ()
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 @@ windows horizontally. A value less than 2 is invalid. */);
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
......
......@@ -939,8 +939,9 @@ static int init_from_display_pos P_ ((struct it *, struct window *,
struct display_pos *));
static void reseat_to_string P_ ((struct it *, unsigned char *,
Lisp_Object, int, int, int, int));
static enum move_it_result move_it_in_display_line_to P_ ((struct it *,
int, int, int));
static enum move_it_result
move_it_in_display_line_to (struct it *, EMACS_INT, int,
enum move_operation_enum);
void move_it_vertically_backward P_ ((struct it *, int));
static void init_to_row_start P_ ((struct it *, struct window *,
struct glyph_row *));
......@@ -6630,9 +6631,9 @@ next_element_from_composition (it)
display is on. */
static enum move_it_result
move_it_in_display_line_to (it, to_charpos, to_x, op)
struct it *it;
int to_charpos, to_x, op;
move_it_in_display_line_to (struct it *it,
EMACS_INT to_charpos, int to_x,
enum move_operation_enum op)
{
enum move_it_result result = MOVE_UNDEFINED;
struct glyph_row *saved_glyph_row;
......@@ -6892,6 +6893,15 @@ move_it_in_display_line_to (it, to_charpos, to_x, op)
return result;
}
/* For external use. */
void
move_it_in_display_line (struct it *it,
EMACS_INT to_charpos, int to_x,
enum move_operation_enum op)
{
move_it_in_display_line_to (it, to_charpos, to_x, op);
}
/* Move IT forward until it satisfies one or more of the criteria in
TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment