all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Stefan Monnier <monnier@iro.umontreal.ca>
To: Adrian Robert <arobert@interstitiality.net>
Cc: emacs- devel <emacs-devel@gnu.org>
Subject: Re: "Pager" page-up and -down, why not merge?
Date: Wed, 04 Jun 2008 12:14:24 -0400	[thread overview]
Message-ID: <jwvod6hw7mh.fsf-monnier+emacs@gnu.org> (raw)
In-Reply-To: <5896C8E2-D065-4B8E-927F-8784062241EF@interstitiality.net> (Adrian Robert's message of "Tue, 3 Jun 2008 16:57:38 -0400")

> scroll-up in emacs.  In particular, hitting sequences like [next]  or Ctrl-v
> followed by [previous] or M-v leaves point in the same  place, which is very
> calming.  ;-)

In what way is it different from setting scroll-preserve-screen-position?

> Is there any reason these could not be incorporated into
> emacs to replace scroll-up and scroll-down in these bindings?

The devil is in the details, see comment below.

> (defvar pager-temporary-goal-column 0
>   "Similar to temporary-goal-column but used by the pager.el functions")
> ;(make-variable-buffer-local 'pager-temporary-goal-column)

I suggest we reuse temporary-goal-column instead.

> (defconst pager-keep-column-commands
>   '(pager-row-down pager-row-up row-dn row-up
> 		   pager-page-down pager-page-up pg-dn pg-up)
>   "Commands which when called without any other intervening command should
> keep the `pager-temporary-goal-column'")

What are those extra commands?

> (defun pager-scroll-screen (lines)
>   "Scroll screen LINES, but keep the cursors position on screen."
>   (if (not (memq last-command pager-keep-column-commands))
>       (setq pager-temporary-goal-column (current-column)))
>   (save-excursion
>     (goto-char (window-start))
>     (vertical-motion lines)
>     (set-window-start (selected-window) (point)))
>   (vertical-motion lines)
>   (move-to-column pager-temporary-goal-column))

Since this doesn't doesn't use scroll-up or scroll-down, it's very much
unclear whether it's going to behave sufficiently well in all cases.

I'm especially uncomfortable with the use of vertical-motion, which
doesn't actually use the redisplay's code, but some approximation of its
behavior, (so it doesn't pay attention to images and other things like
that, for example).

I'd suggest a different approach: use scroll-up/scroll-down as before, but
wrap them within code that uses compute-motion first to determine the
original screen position, and then vertical-motion afterwards to set
the cursor back to its position (but double-checking that this new
computed position is indeed visible on screen, to avoid pathological
behavior when compute-motion of vertical-motion get it wrong).

This way, you can guarantee that the scrolling behavior is 100%
preserved, and the new code only moves point around within the displayed
part of the buffer presumably to the position it had before.

Instead of compute-motion/vertical-motion, you could try to use
posn-at-point and posn-at-x-y.


        Stefan


PS: Here's a patch to window.c which makes
scroll-preserve-screen-position preserve the column position as well as
the line position, tho it only applies to GUI frames, not to tty frames
(which use another piece of code which I haven't bothered to adjust
accordingly).


=== modified file 'src/window.c'
--- src/window.c	2008-06-03 06:20:49 +0000
+++ src/window.c	2008-06-04 16:10:40 +0000
@@ -229,6 +229,7 @@
 /* Used by the function window_scroll_pixel_based */
 
 static int window_scroll_pixel_based_preserve_y;
+static int window_scroll_pixel_based_preserve_x;
 
 #if 0 /* This isn't used anywhere.  */
 /* Nonzero means we can split a frame even if it is "unsplittable".  */
@@ -5221,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.  */
@@ -5360,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
@@ -5421,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
@@ -7445,6 +7450,7 @@
   staticpro (&minibuf_selected_window);
 
   window_scroll_pixel_based_preserve_y = -1;
+  window_scroll_pixel_based_preserve_x = -1;
 
   DEFVAR_LISP ("temp-buffer-show-function", &Vtemp_buffer_show_function,
 	       doc: /* Non-nil means call as function to display a help buffer.





  parent reply	other threads:[~2008-06-04 16:14 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-06-03 20:57 "Pager" page-up and -down, why not merge? Adrian Robert
2008-06-04 11:13 ` Richard M Stallman
2008-06-04 12:29   ` Adrian Robert
2008-06-04 13:46   ` Juanma Barranquero
2008-06-05 12:36     ` Richard M Stallman
2008-06-05 13:09       ` Juanma Barranquero
2008-06-04 16:14 ` Stefan Monnier [this message]
2008-06-04 22:09   ` Juanma Barranquero
2008-06-04 23:55     ` Adrian Robert
2008-06-05  3:58     ` Stefan Monnier
2008-06-06 13:24   ` Adrian Robert

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=jwvod6hw7mh.fsf-monnier+emacs@gnu.org \
    --to=monnier@iro.umontreal.ca \
    --cc=arobert@interstitiality.net \
    --cc=emacs-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.