[gnu.emacs.bug] Suspected bug in set-window-point

drw@BOURBAKI.MIT.EDU (01/23/90)

I believe there is a bug in the code for set-window-point.  To
re-create the symptoms, create two large buffers, *a* and *b* and
two windows, each showing one buffer.  Move the points to the ends of
the buffers, and put the cursor in *a*.  Now execute the code:

    (defun test ()
      (interactive)
      (let* ((a-buffer (get-buffer "*a*"))
	     (b-buffer (get-buffer "*b*"))
	     (a-window (get-buffer-window a-buffer)))
	(select-window a-window)
	(set-buffer b-buffer)
	(set-window-point a-window 1)))

Despite doing a set-window-point of the window showing *a* to 1, the
point of the window remains at the end of the buffer.  However, if the
line (set-buffer b-buffer) is removed, the code works as expected,
moving the point in *a* to the beginning.

Although the exact operations of the window points are not well
documented in the Emacs Lisp manual, it seems to be a bug to me.

The apparent cause is that the code of set-window-point is:

	if WINDOW == selected-window()
	then goto-char(POS)
	else set-marker(WINDOW->pointm, POS, WINDOW->buffer)

This appears to omit a check that the current buffer is the buffer of
WINDOW, as is done in window-point:

	if WINDOW == selected-window() && current-buffer() == WINDOW->buffer
	then return point()
	else return marker-position(WINDOW->pointm)

This behavior is seen in both 18.53 and 18.54.  There don't appear
to be any changes to window.c in the 18.55.

Thanks,

Dale
drw@math.mit.edu

kjones@talos.uu.net (Kyle Jones) (01/23/90)

drw@BOURBAKI.MIT.EDU writes about:
 > I believe there is a bug in the code for set-window-point.  [...]
 > The apparent cause is that the code of set-window-point is:
 > 
 > 	if WINDOW == selected-window()
 > 	then goto-char(POS)
 > 	else set-marker(WINDOW->pointm, POS, WINDOW->buffer)
 > 
 > This appears to omit a check that the current buffer is the buffer of
 > WINDOW, as is done in window-point:
 > 
 > 	if WINDOW == selected-window() && current-buffer() == WINDOW->buffer
 > 	then return point()
 > 	else return marker-position(WINDOW->pointm)

Correct.  I reported this bug and received this new definition of
Fset_window_point from RMS to test; it fixes the problem.  Since it
hasn't made it into the distribution yet, here it is.

DEFUN ("set-window-point", Fset_window_point, Sset_window_point, 2, 2, 0,
  "Make point value in WINDOW be at position POS in WINDOW's buffer.")
  (window, pos)
     Lisp_Object window, pos;
{
  register struct window *w = decode_window (window);

  CHECK_NUMBER_COERCE_MARKER (pos, 1);
  if (w == XWINDOW (selected_window))
    {
      struct buffer *obuf = bf_cur;
      Fset_buffer (w->buffer);
      Fgoto_char (pos);
      SetBfp (obuf);
    }
  else
    Fset_marker (w->pointm, pos, w->buffer);
  return pos;
}