diff --git a/src/fileio.c b/src/fileio.c index d979571..c5c295e 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -3513,23 +3513,78 @@ CONTEXT should be a list (USER ROLE TYPE RANGE), where the list static Lisp_Object get_window_points_and_markers (void) { + Lisp_Object buffer = Fcurrent_buffer (); Lisp_Object pt_marker = Fpoint_marker (); - Lisp_Object windows - = call3 (Qget_buffer_window_list, Fcurrent_buffer (), Qnil, Qt); - Lisp_Object window_markers = windows; - /* Window markers (and point) are handled specially: rather than move to - just before or just after the modified text, we try to keep the - markers at the same distance (bug#19161). - In general, this is wrong, but for window-markers, this should be harmless - and is convenient for the end user when most of the file is unmodified, - except for a few minor details near the beginning and near the end. */ + Lisp_Object windows = window_list (); + Lisp_Object window; + Lisp_Object window_markers = Qnil; + /* Window markers (and point) are handled specially: rather than + move to just before or just after the modified text, we try to + keep the markers at the same distance (bug#19161). + + In general, this is wrong, but for window markers, this should be + harmless and is convenient for the end user when most of the file + is unmodified, except for a few minor details near the beginning + and near the end. + + Window point markers now include the window point markers from + the lists of each live window's previous and next buffers. */ for (; CONSP (windows); windows = XCDR (windows)) - if (WINDOWP (XCAR (windows))) + if (WINDOW_LIVE_P (window = XCAR (windows))) { - Lisp_Object window_marker = XWINDOW (XCAR (windows))->pointm; - XSETCAR (windows, - Fcons (window_marker, Fmarker_position (window_marker))); + struct window *w = XWINDOW (window); + Lisp_Object prev_buffers = w->prev_buffers; + Lisp_Object next_buffers = w->next_buffers; + + /* Look at window's buffer first. */ + if (EQ (WINDOW_BUFFER (w), buffer)) + { + Lisp_Object window_marker = XWINDOW (XCAR (windows))->pointm; + + window_markers = + Fcons (Fcons (window_marker, Fmarker_position (window_marker)), + window_markers); + + /* Skip the lists of previous and next buffers. */ + continue; + } + + /* Scan window's previous buffers. */ + for (; CONSP (prev_buffers); prev_buffers = XCDR (prev_buffers)) + if (CONSP (XCAR (prev_buffers))) + { + Lisp_Object triple = XCAR (prev_buffers); + + if (EQ (XCAR (triple), buffer)) + { + Lisp_Object prev_marker = Fnth (make_fixnum (2), triple); + + window_markers = + Fcons (Fcons (prev_marker, Fmarker_position (prev_marker)), + window_markers); + + /* Skip the list of window's next buffers. */ + continue; + } + } + + /* Scan window's next buffers. */ + for (; CONSP (next_buffers); next_buffers = XCDR (next_buffers)) + if (CONSP (XCAR (next_buffers))) + { + Lisp_Object triple = XCAR (next_buffers); + + if (EQ (XCAR (triple), buffer)) + { + Lisp_Object next_marker = Fnth (make_fixnum (2), triple); + + window_markers = + Fcons (Fcons (next_marker, Fmarker_position (next_marker)), + window_markers); + } + } } + return Fcons (Fcons (pt_marker, Fpoint ()), window_markers); } @@ -3543,6 +3598,7 @@ CONTEXT should be a list (USER ROLE TYPE RANGE), where the list Lisp_Object car = XCAR (window_markers); Lisp_Object marker = XCAR (car); Lisp_Object oldpos = XCDR (car); + if (MARKERP (marker) && FIXNUMP (oldpos) && XFIXNUM (oldpos) > same_at_start && XFIXNUM (oldpos) < same_at_end) @@ -3552,6 +3608,7 @@ CONTEXT should be a list (USER ROLE TYPE RANGE), where the list double growth = newsize / (double)oldsize; ptrdiff_t newpos = same_at_start + growth * (XFIXNUM (oldpos) - same_at_start); + Fset_marker (marker, make_fixnum (newpos), Qnil); } } @@ -6285,7 +6342,6 @@ current when building the annotations (i.e., at least once), with that DEFSYM (Qdelete_directory, "delete-directory"); DEFSYM (Qsubstitute_env_in_file_name, "substitute-env-in-file-name"); - DEFSYM (Qget_buffer_window_list, "get-buffer-window-list"); DEFSYM (Qstdin, "stdin"); DEFSYM (Qstdout, "stdout");