]> git.eshelyaron.com Git - emacs.git/commitdiff
* window.c (window_scroll_pixel_based_preserve_x)
authorStefan Monnier <monnier@iro.umontreal.ca>
Thu, 5 Jun 2008 03:57:09 +0000 (03:57 +0000)
committerStefan Monnier <monnier@iro.umontreal.ca>
Thu, 5 Jun 2008 03:57:09 +0000 (03:57 +0000)
(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.

etc/NEWS
src/ChangeLog
src/dispextern.h
src/indent.c
src/window.c
src/xdisp.c

index 2346b068fc404e7e6a835710d4de07bf7d47fa26..f5211acaff00dc4e75e14779c37760396d233443 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -63,6 +63,7 @@ default toolkit, but you can use --with-x-toolkit=gtk if necessary.
 \f
 * 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.
index 48f80bf15834e1307d0a70f422d5d21055f69c7b..9abd806ce63f7dc45abc3f3226cf3da5cb55602c 100644 (file)
@@ -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).
        (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'.
index 4a4c731748b081bd20d44c5629a518c2a31b33f4..969f1c550210efababec9e092a2be349fe48de94 100644 (file)
@@ -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 *));
index 9d69936d4405e588a09cbf2f493db6c5024eb3c1..fdc042bc9e4c8c4d042810698fb14ad234321d88 100644 (file)
@@ -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));
     }
 
index 095e8412aa8bf2199f65d88b517705cc118c8bc8..9385b307b9e893ef126ccec7181cba56f5845653 100644 (file)
@@ -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
index 8d87123934b8e7b087b6bffa7233b8a14f5bd271..56db272dcb046de4fe013c927f575e84a8327afa 100644 (file)
@@ -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.