diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/keyboard.c | 7 | ||||
-rw-r--r-- | src/keyboard.h | 13 | ||||
-rw-r--r-- | src/undo.c | 57 |
3 files changed, 52 insertions, 25 deletions
diff --git a/src/keyboard.c b/src/keyboard.c index c9e58e7a086..02bc7d2a0b7 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -202,7 +202,7 @@ uintmax_t num_input_events; static EMACS_INT last_auto_save; -/* The value of point when the last command was started. */ +/* The value of point when the last command was started. */ static ptrdiff_t last_point_position; /* The frame in which the last input event occurred, or Qmacro if the @@ -1449,6 +1449,11 @@ command_loop_1 (void) result of changes from the last command. */ call0 (Qundo_auto__add_boundary); + /* Record point and buffer, so we can put point into the undo + information if necessary. */ + point_before_last_command_or_undo = PT; + buffer_before_last_command_or_undo = current_buffer; + call1 (Qcommand_execute, Vthis_command); #ifdef HAVE_WINDOW_SYSTEM diff --git a/src/keyboard.h b/src/keyboard.h index 98bc86b58ed..6c715a44fba 100644 --- a/src/keyboard.h +++ b/src/keyboard.h @@ -245,6 +245,19 @@ extern KBOARD *current_kboard; /* Total number of times read_char has returned, modulo UINTMAX_MAX + 1. */ extern uintmax_t num_input_events; + +/* The location of point immediately before the last command was + executed, or the last time the undo-boundary command added a + boundary.*/ +ptrdiff_t point_before_last_command_or_undo; + +/* The value of current_buffer immediately before the last command was + executed, or the last time the undo-boundary command added a + boundary.*/ +struct buffer *buffer_before_last_command_or_undo; + +extern struct buffer *prev_buffer; + /* Nonzero means polling for input is temporarily suppressed. */ extern int poll_suppress_count; diff --git a/src/undo.c b/src/undo.c index 060dbfc97b1..68065750b0f 100644 --- a/src/undo.c +++ b/src/undo.c @@ -22,10 +22,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ #include "lisp.h" #include "buffer.h" - -/* Position of point last time we inserted a boundary. */ -static struct buffer *last_boundary_buffer; -static ptrdiff_t last_boundary_position; +#include "keyboard.h" /* The first time a command records something for undo. it also allocates the undo-boundary object @@ -36,36 +33,44 @@ static Lisp_Object pending_boundary; /* Record point as it was at beginning of this command (if necessary) and prepare the undo info for recording a change. +/* Prepare the undo info for recording a change. */ +static void +prepare_record () +{ + /* Allocate a cons cell to be the undo boundary after this command. */ + if (NILP (pending_boundary)) + pending_boundary = Fcons (Qnil, Qnil); + + run_undoable_change (); + + if (MODIFF <= SAVE_MODIFF) + record_first_change (); +} + +/* Record point as it was at beginning of this command. PT is the position of point that will naturally occur as a result of the undo record that will be added just after this command terminates. */ - static void record_point (ptrdiff_t pt) { - bool at_boundary; - /* Don't record position of pt when undo_inhibit_record_point holds. */ if (undo_inhibit_record_point) return; - /* Allocate a cons cell to be the undo boundary after this command. */ - if (NILP (pending_boundary)) - pending_boundary = Fcons (Qnil, Qnil); + bool at_boundary; at_boundary = ! CONSP (BVAR (current_buffer, undo_list)) || NILP (XCAR (BVAR (current_buffer, undo_list))); - if (MODIFF <= SAVE_MODIFF) - record_first_change (); + prepare_record(); /* If we are just after an undo boundary, and point wasn't at start of deleted range, record where it was. */ - if (at_boundary - && current_buffer == last_boundary_buffer - && last_boundary_position != pt) + if (at_boundary){ bset_undo_list (current_buffer, - Fcons (make_number (last_boundary_position), + Fcons (make_number (pt), BVAR (current_buffer, undo_list))); + } } /* Record an insertion that just happened or is about to happen, @@ -81,7 +86,7 @@ record_insert (ptrdiff_t beg, ptrdiff_t length) if (EQ (BVAR (current_buffer, undo_list), Qt)) return; - record_point (beg); + prepare_record (); /* If this is following another insertion and consecutive with it in the buffer, combine the two. */ @@ -153,7 +158,6 @@ record_marker_adjustments (ptrdiff_t from, ptrdiff_t to) /* Record that a deletion is about to take place, of the characters in STRING, at location BEG. Optionally record adjustments for markers in the region STRING occupies in the current buffer. */ - void record_delete (ptrdiff_t beg, Lisp_Object string, bool record_markers) { @@ -162,15 +166,21 @@ record_delete (ptrdiff_t beg, Lisp_Object string, bool record_markers) if (EQ (BVAR (current_buffer, undo_list), Qt)) return; + if (point_before_last_command_or_undo != beg && + buffer_before_last_command_or_undo == current_buffer) + { + record_point (point_before_last_command_or_undo); + } + if (PT == beg + SCHARS (string)) { XSETINT (sbeg, -beg); - record_point (PT); + prepare_record (); } else { XSETFASTINT (sbeg, beg); - record_point (beg); + prepare_record (); } /* primitive-undo assumes marker adjustments are recorded @@ -268,10 +278,11 @@ but another undo command will undo to the previous boundary. */) bset_undo_list (current_buffer, Fcons (Qnil, BVAR (current_buffer, undo_list))); } - last_boundary_position = PT; - last_boundary_buffer = current_buffer; Fset (Qundo_auto__last_boundary_cause, Qexplicit); + point_before_last_command_or_undo = PT; + buffer_before_last_command_or_undo = current_buffer; + return Qnil; } @@ -423,8 +434,6 @@ syms_of_undo (void) pending_boundary = Qnil; staticpro (&pending_boundary); - last_boundary_buffer = NULL; - defsubr (&Sundo_boundary); DEFVAR_INT ("undo-limit", undo_limit, |