summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Monnier <monnier@iro.umontreal.ca>2008-06-05 03:57:09 +0000
committerStefan Monnier <monnier@iro.umontreal.ca>2008-06-05 03:57:09 +0000
commitc876b227d9b0cbd09bbb8c07db0a3cb0d85fae78 (patch)
tree36b9cdbe3c2af0181b8e074c80a98e1119597f03
parent927abf37e2793fae653540cca8b4c324c65e448f (diff)
downloademacs-c876b227d9b0cbd09bbb8c07db0a3cb0d85fae78.tar.gz
* 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.
-rw-r--r--etc/NEWS1
-rw-r--r--src/ChangeLog20
-rw-r--r--src/dispextern.h3
-rw-r--r--src/indent.c17
-rw-r--r--src/window.c57
-rw-r--r--src/xdisp.c20
6 files changed, 95 insertions, 23 deletions
diff --git a/etc/NEWS b/etc/NEWS
index 2346b068fc4..f5211acaff0 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -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.
diff --git a/src/ChangeLog b/src/ChangeLog
index 48f80bf1583..9abd806ce63 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,19 @@
+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'.
diff --git a/src/dispextern.h b/src/dispextern.h
index 4a4c731748b..969f1c55021 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -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 *));
diff --git a/src/indent.c b/src/indent.c
index 9d69936d440..fdc042bc9e4 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -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));
}
diff --git a/src/window.c b/src/window.c
index 095e8412aa8..9385b307b9e 100644
--- a/src/window.c
+++ b/src/window.c
@@ -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
diff --git a/src/xdisp.c b/src/xdisp.c
index 8d87123934b..56db272dcb0 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -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.