aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndreas Schwab2016-12-19 23:07:42 +0100
committerAndreas Schwab2016-12-19 23:17:36 +0100
commit85aebc12de28667cdccde5b080972453544d015e (patch)
treecf7810bfb5228fe6f5ef39dc5bc6faf1ac45d060 /src
parent504e3846041e4fcd1707a9ad6176ddaf3fec3d02 (diff)
downloademacs-85aebc12de28667cdccde5b080972453544d015e.tar.gz
emacs-85aebc12de28667cdccde5b080972453544d015e.zip
Protect change of window's buffer in vertical-motion against unwinds (bug#25209)
* indent.c (restore_window_buffer): New function. (Fvertical_motion): Use it to restore window's buffer.
Diffstat (limited to 'src')
-rw-r--r--src/indent.c32
1 files changed, 20 insertions, 12 deletions
diff --git a/src/indent.c b/src/indent.c
index b68b60297fd..29c9ffd90cc 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -1958,6 +1958,20 @@ window_column_x (struct window *w, Lisp_Object window,
1958 return x; 1958 return x;
1959} 1959}
1960 1960
1961/* Restore window's buffer and point. */
1962
1963static void
1964restore_window_buffer (Lisp_Object list)
1965{
1966 struct window *w = decode_live_window (XCAR (list));
1967 list = XCDR (list);
1968 wset_buffer (w, XCAR (list));
1969 list = XCDR (list);
1970 set_marker_both (w->pointm, w->contents,
1971 XFASTINT (XCAR (list)),
1972 XFASTINT (XCAR (XCDR (list))));
1973}
1974
1961DEFUN ("vertical-motion", Fvertical_motion, Svertical_motion, 1, 3, 0, 1975DEFUN ("vertical-motion", Fvertical_motion, Svertical_motion, 1, 3, 0,
1962 doc: /* Move point to start of the screen line LINES lines down. 1976 doc: /* Move point to start of the screen line LINES lines down.
1963If LINES is negative, this means moving up. 1977If LINES is negative, this means moving up.
@@ -1997,10 +2011,9 @@ whether or not it is currently displayed in some window. */)
1997 struct it it; 2011 struct it it;
1998 struct text_pos pt; 2012 struct text_pos pt;
1999 struct window *w; 2013 struct window *w;
2000 Lisp_Object old_buffer;
2001 EMACS_INT old_charpos UNINIT, old_bytepos UNINIT;
2002 Lisp_Object lcols; 2014 Lisp_Object lcols;
2003 void *itdata = NULL; 2015 void *itdata = NULL;
2016 ptrdiff_t count = SPECPDL_INDEX ();
2004 2017
2005 /* Allow LINES to be of the form (HPOS . VPOS) aka (COLUMNS . LINES). */ 2018 /* Allow LINES to be of the form (HPOS . VPOS) aka (COLUMNS . LINES). */
2006 bool lcols_given = CONSP (lines); 2019 bool lcols_given = CONSP (lines);
@@ -2013,13 +2026,13 @@ whether or not it is currently displayed in some window. */)
2013 CHECK_NUMBER (lines); 2026 CHECK_NUMBER (lines);
2014 w = decode_live_window (window); 2027 w = decode_live_window (window);
2015 2028
2016 old_buffer = Qnil;
2017 if (XBUFFER (w->contents) != current_buffer) 2029 if (XBUFFER (w->contents) != current_buffer)
2018 { 2030 {
2019 /* Set the window's buffer temporarily to the current buffer. */ 2031 /* Set the window's buffer temporarily to the current buffer. */
2020 old_buffer = w->contents; 2032 Lisp_Object old = list4 (window, w->contents,
2021 old_charpos = marker_position (w->pointm); 2033 make_number (marker_position (w->pointm)),
2022 old_bytepos = marker_byte_position (w->pointm); 2034 make_number (marker_byte_position (w->pointm)));
2035 record_unwind_protect (restore_window_buffer, old);
2023 wset_buffer (w, Fcurrent_buffer ()); 2036 wset_buffer (w, Fcurrent_buffer ());
2024 set_marker_both (w->pointm, w->contents, 2037 set_marker_both (w->pointm, w->contents,
2025 BUF_PT (current_buffer), BUF_PT_BYTE (current_buffer)); 2038 BUF_PT (current_buffer), BUF_PT_BYTE (current_buffer));
@@ -2255,12 +2268,7 @@ whether or not it is currently displayed in some window. */)
2255 bidi_unshelve_cache (itdata, 0); 2268 bidi_unshelve_cache (itdata, 0);
2256 } 2269 }
2257 2270
2258 if (BUFFERP (old_buffer)) 2271 unbind_to (count, Qnil);
2259 {
2260 wset_buffer (w, old_buffer);
2261 set_marker_both (w->pointm, w->contents,
2262 old_charpos, old_bytepos);
2263 }
2264 2272
2265 return make_number (it.vpos); 2273 return make_number (it.vpos);
2266} 2274}