diff options
| author | Phillip Lord | 2015-08-06 21:33:58 +0100 |
|---|---|---|
| committer | Phillip Lord | 2015-11-12 21:06:05 +0000 |
| commit | 44dfa86b7d382b84564d68472da1448d08f48129 (patch) | |
| tree | 778e2228ec90a4401b2be6cd7b258ee44a212b26 | |
| parent | 0aec2aaccd8b745fa7214f3edd453c04a04bfba4 (diff) | |
| download | emacs-44dfa86b7d382b84564d68472da1448d08f48129.tar.gz emacs-44dfa86b7d382b84564d68472da1448d08f48129.zip | |
The heuristic that Emacs uses to add an `undo-boundary' has been
reworked, as it interacts poorly with functions on `post-command-hook'
or `after-change-functions'.
* lisp/simple.el: New section added.
* src/cmds.c (remove_excessive_undo_boundaries): Now in lisp.
(self_insert_command): Calls simple.el to amalgamate.
(delete_char): Calls simple.el to amalgamate.
* src/keyboard.c (last_undo_boundary): Removed.
* src/undo.c (run_undoable_change): New function.
| -rw-r--r-- | lisp/simple.el | 137 | ||||
| -rw-r--r-- | src/cmds.c | 41 | ||||
| -rw-r--r-- | src/keyboard.c | 17 | ||||
| -rw-r--r-- | src/lisp.h | 1 | ||||
| -rw-r--r-- | src/undo.c | 51 |
5 files changed, 167 insertions, 80 deletions
diff --git a/lisp/simple.el b/lisp/simple.el index 00c25db07d7..821c7665c6c 100644 --- a/lisp/simple.el +++ b/lisp/simple.el | |||
| @@ -2754,6 +2754,143 @@ with < or <= based on USE-<." | |||
| 2754 | '(0 . 0))) | 2754 | '(0 . 0))) |
| 2755 | '(0 . 0))) | 2755 | '(0 . 0))) |
| 2756 | 2756 | ||
| 2757 | ;;; Default undo-boundary addition | ||
| 2758 | ;; | ||
| 2759 | ;; This section adds a new undo-boundary at either after a command is | ||
| 2760 | ;; called or in some cases on a timer called after a change is made in | ||
| 2761 | ;; any buffer. | ||
| 2762 | (defvar-local undo-auto--last-boundary-cause nil | ||
| 2763 | "Describe the cause of the last undo-boundary. | ||
| 2764 | |||
| 2765 | If `explicit', the last boundary was caused by an explicit call to | ||
| 2766 | `undo-boundary', that is one not called by the code in this | ||
| 2767 | section. | ||
| 2768 | |||
| 2769 | If it is equal to `timer', then the last boundary was inserted | ||
| 2770 | by `undo-auto--boundary-timer'. | ||
| 2771 | |||
| 2772 | If it is equal to `command', then the last boundary was inserted | ||
| 2773 | automatically after a command, that is by the code defined in | ||
| 2774 | this section. | ||
| 2775 | |||
| 2776 | If it is equal to a list, then the last boundary was inserted by | ||
| 2777 | an amalgamating command. The car of the list is the number of | ||
| 2778 | times an amalgamating command has been called, and the cdr are the | ||
| 2779 | buffers that were changed during the last command.") | ||
| 2780 | |||
| 2781 | (defvar undo-auto--current-boundary-timer nil | ||
| 2782 | "Current timer which will run `undo-auto--boundary-timer' or nil. | ||
| 2783 | |||
| 2784 | If set to non-nil, this will effectively disable the timer.") | ||
| 2785 | |||
| 2786 | (defvar undo-auto--this-command-amalgamating nil | ||
| 2787 | "Non-nil if `this-command' should be amalgamated. | ||
| 2788 | This variable is set to nil by `undo-auto--boundaries' and is set | ||
| 2789 | by `undo-auto--amalgamate'." ) | ||
| 2790 | |||
| 2791 | (defun undo-auto--needs-boundary-p () | ||
| 2792 | "Return non-nil if `buffer-undo-list' needs a boundary at the start." | ||
| 2793 | (car-safe buffer-undo-list)) | ||
| 2794 | |||
| 2795 | (defun undo-auto--last-boundary-amalgamating-number () | ||
| 2796 | "Return the number of amalgamating last commands or nil. | ||
| 2797 | Amalgamating commands are, by default, either | ||
| 2798 | `self-insert-command' and `delete-char', but can be any command | ||
| 2799 | that calls `undo-auto--amalgamate'." | ||
| 2800 | (car-safe undo-auto--last-boundary-cause)) | ||
| 2801 | |||
| 2802 | (defun undo-auto--ensure-boundary (cause) | ||
| 2803 | "Add an `undo-boundary' to the current buffer if needed. | ||
| 2804 | REASON describes the reason that the boundary is being added; see | ||
| 2805 | `undo-auto--last-boundary' for more information." | ||
| 2806 | (when (and | ||
| 2807 | (undo-auto--needs-boundary-p)) | ||
| 2808 | (let ((last-amalgamating | ||
| 2809 | (undo-auto--last-boundary-amalgamating-number))) | ||
| 2810 | (undo-boundary) | ||
| 2811 | (setq undo-auto--last-boundary-cause | ||
| 2812 | (if (eq 'amalgamate cause) | ||
| 2813 | (cons | ||
| 2814 | (if last-amalgamating (1+ last-amalgamating) 0) | ||
| 2815 | undo-auto--undoably-changed-buffers) | ||
| 2816 | cause))))) | ||
| 2817 | |||
| 2818 | (defun undo-auto--boundaries (cause) | ||
| 2819 | "Check recently changed buffers and add a boundary if necessary. | ||
| 2820 | REASON describes the reason that the boundary is being added; see | ||
| 2821 | `undo-last-boundary' for more information." | ||
| 2822 | (dolist (b undo-auto--undoably-changed-buffers) | ||
| 2823 | (when (buffer-live-p b) | ||
| 2824 | (with-current-buffer b | ||
| 2825 | (undo-auto--ensure-boundary cause)))) | ||
| 2826 | (setq undo-auto--undoably-changed-buffers nil)) | ||
| 2827 | |||
| 2828 | (defun undo-auto--boundary-timer () | ||
| 2829 | "Timer which will run `undo--auto-boundary-timer'." | ||
| 2830 | (setq undo-auto--current-boundary-timer nil) | ||
| 2831 | (undo-auto--boundaries 'timer)) | ||
| 2832 | |||
| 2833 | (defun undo-auto--boundary-ensure-timer () | ||
| 2834 | "Ensure that the `undo-auto-boundary-timer' is set." | ||
| 2835 | (unless undo-auto--current-boundary-timer | ||
| 2836 | (setq undo-auto--current-boundary-timer | ||
| 2837 | (run-at-time 10 nil #'undo-auto--boundary-timer)))) | ||
| 2838 | |||
| 2839 | (defvar undo-auto--undoably-changed-buffers nil | ||
| 2840 | "List of buffers that have changed recently. | ||
| 2841 | |||
| 2842 | This list is maintained by `undo-auto--undoable-change' and | ||
| 2843 | `undo-auto--boundaries' and can be affected by changes to their | ||
| 2844 | default values. | ||
| 2845 | |||
| 2846 | See also `undo-auto--buffer-undoably-changed'.") | ||
| 2847 | |||
| 2848 | (defun undo-auto--add-boundary () | ||
| 2849 | "Add an `undo-boundary' in appropriate buffers." | ||
| 2850 | (undo-auto--boundaries | ||
| 2851 | (if undo-auto--this-command-amalgamating | ||
| 2852 | 'amalgamate | ||
| 2853 | 'command)) | ||
| 2854 | (setq undo-auto--this-command-amalgamating nil)) | ||
| 2855 | |||
| 2856 | (defun undo-auto--amalgamate () | ||
| 2857 | "Amalgamate undo if necessary. | ||
| 2858 | This function can be called after an amalgamating command. It | ||
| 2859 | removes the previous `undo-boundary' if a series of such calls | ||
| 2860 | have been made. By default `self-insert-command' and | ||
| 2861 | `delete-char' are the only amalgamating commands, although this | ||
| 2862 | function could be called by any command wishing to have this | ||
| 2863 | behaviour." | ||
| 2864 | (let ((last-amalgamating-count | ||
| 2865 | (undo-auto--last-boundary-amalgamating-number))) | ||
| 2866 | (setq undo-auto--this-command-amalgamating t) | ||
| 2867 | (when | ||
| 2868 | last-amalgamating-count | ||
| 2869 | (if | ||
| 2870 | (and | ||
| 2871 | (< last-amalgamating-count 20) | ||
| 2872 | (eq this-command last-command)) | ||
| 2873 | ;; Amalgamate all buffers that have changed. | ||
| 2874 | (dolist (b (cdr undo-auto--last-boundary-cause)) | ||
| 2875 | (when (buffer-live-p b) | ||
| 2876 | (with-current-buffer | ||
| 2877 | b | ||
| 2878 | (when | ||
| 2879 | ;; The head of `buffer-undo-list' is nil. | ||
| 2880 | ;; `car-safe' doesn't work because | ||
| 2881 | ;; `buffer-undo-list' need not be a list! | ||
| 2882 | (and (listp buffer-undo-list) | ||
| 2883 | (not (car buffer-undo-list))) | ||
| 2884 | (setq buffer-undo-list | ||
| 2885 | (cdr buffer-undo-list)))))) | ||
| 2886 | (setq undo-auto--last-boundary-cause 0))))) | ||
| 2887 | |||
| 2888 | (defun undo-auto--undoable-change () | ||
| 2889 | "Called after every undoable buffer change." | ||
| 2890 | (add-to-list 'undo-auto--undoably-changed-buffers (current-buffer)) | ||
| 2891 | (undo-auto--boundary-ensure-timer)) | ||
| 2892 | ;; End auto-boundary section | ||
| 2893 | |||
| 2757 | (defcustom undo-ask-before-discard nil | 2894 | (defcustom undo-ask-before-discard nil |
| 2758 | "If non-nil ask about discarding undo info for the current command. | 2895 | "If non-nil ask about discarding undo info for the current command. |
| 2759 | Normally, Emacs discards the undo info for the current command if | 2896 | Normally, Emacs discards the undo info for the current command if |
diff --git a/src/cmds.c b/src/cmds.c index a975a8ed4e0..6f19a046893 100644 --- a/src/cmds.c +++ b/src/cmds.c | |||
| @@ -220,36 +220,6 @@ to t. */) | |||
| 220 | return Qnil; | 220 | return Qnil; |
| 221 | } | 221 | } |
| 222 | 222 | ||
| 223 | static int nonundocount; | ||
| 224 | |||
| 225 | static void | ||
| 226 | remove_excessive_undo_boundaries (void) | ||
| 227 | { | ||
| 228 | bool remove_boundary = true; | ||
| 229 | |||
| 230 | if (!EQ (Vthis_command, KVAR (current_kboard, Vlast_command))) | ||
| 231 | nonundocount = 0; | ||
| 232 | |||
| 233 | if (NILP (Vexecuting_kbd_macro)) | ||
| 234 | { | ||
| 235 | if (nonundocount <= 0 || nonundocount >= 20) | ||
| 236 | { | ||
| 237 | remove_boundary = false; | ||
| 238 | nonundocount = 0; | ||
| 239 | } | ||
| 240 | nonundocount++; | ||
| 241 | } | ||
| 242 | |||
| 243 | if (remove_boundary | ||
| 244 | && CONSP (BVAR (current_buffer, undo_list)) | ||
| 245 | && NILP (XCAR (BVAR (current_buffer, undo_list))) | ||
| 246 | /* Only remove auto-added boundaries, not boundaries | ||
| 247 | added by explicit calls to undo-boundary. */ | ||
| 248 | && EQ (BVAR (current_buffer, undo_list), last_undo_boundary)) | ||
| 249 | /* Remove the undo_boundary that was just pushed. */ | ||
| 250 | bset_undo_list (current_buffer, XCDR (BVAR (current_buffer, undo_list))); | ||
| 251 | } | ||
| 252 | |||
| 253 | DEFUN ("delete-char", Fdelete_char, Sdelete_char, 1, 2, "p\nP", | 223 | DEFUN ("delete-char", Fdelete_char, Sdelete_char, 1, 2, "p\nP", |
| 254 | doc: /* Delete the following N characters (previous if N is negative). | 224 | doc: /* Delete the following N characters (previous if N is negative). |
| 255 | Optional second arg KILLFLAG non-nil means kill instead (save in kill ring). | 225 | Optional second arg KILLFLAG non-nil means kill instead (save in kill ring). |
| @@ -265,7 +235,7 @@ because it respects values of `delete-active-region' and `overwrite-mode'. */) | |||
| 265 | CHECK_NUMBER (n); | 235 | CHECK_NUMBER (n); |
| 266 | 236 | ||
| 267 | if (abs (XINT (n)) < 2) | 237 | if (abs (XINT (n)) < 2) |
| 268 | remove_excessive_undo_boundaries (); | 238 | call0 (Qundo_auto__amalgamate); |
| 269 | 239 | ||
| 270 | pos = PT + XINT (n); | 240 | pos = PT + XINT (n); |
| 271 | if (NILP (killflag)) | 241 | if (NILP (killflag)) |
| @@ -311,7 +281,7 @@ At the end, it runs `post-self-insert-hook'. */) | |||
| 311 | error ("Negative repetition argument %"pI"d", XFASTINT (n)); | 281 | error ("Negative repetition argument %"pI"d", XFASTINT (n)); |
| 312 | 282 | ||
| 313 | if (XFASTINT (n) < 2) | 283 | if (XFASTINT (n) < 2) |
| 314 | remove_excessive_undo_boundaries (); | 284 | call0 (Qundo_auto__amalgamate); |
| 315 | 285 | ||
| 316 | /* Barf if the key that invoked this was not a character. */ | 286 | /* Barf if the key that invoked this was not a character. */ |
| 317 | if (!CHARACTERP (last_command_event)) | 287 | if (!CHARACTERP (last_command_event)) |
| @@ -321,7 +291,7 @@ At the end, it runs `post-self-insert-hook'. */) | |||
| 321 | XINT (last_command_event)); | 291 | XINT (last_command_event)); |
| 322 | int val = internal_self_insert (character, XFASTINT (n)); | 292 | int val = internal_self_insert (character, XFASTINT (n)); |
| 323 | if (val == 2) | 293 | if (val == 2) |
| 324 | nonundocount = 0; | 294 | Fset (Qundo_auto__this_command_amalgamating, Qnil); |
| 325 | frame_make_pointer_invisible (SELECTED_FRAME ()); | 295 | frame_make_pointer_invisible (SELECTED_FRAME ()); |
| 326 | } | 296 | } |
| 327 | 297 | ||
| @@ -526,6 +496,10 @@ internal_self_insert (int c, EMACS_INT n) | |||
| 526 | void | 496 | void |
| 527 | syms_of_cmds (void) | 497 | syms_of_cmds (void) |
| 528 | { | 498 | { |
| 499 | DEFSYM (Qundo_auto__amalgamate, "undo-auto--amalgamate"); | ||
| 500 | DEFSYM (Qundo_auto__this_command_amalgamating, | ||
| 501 | "undo-auto--this-command-amalgamating"); | ||
| 502 | |||
| 529 | DEFSYM (Qkill_forward_chars, "kill-forward-chars"); | 503 | DEFSYM (Qkill_forward_chars, "kill-forward-chars"); |
| 530 | 504 | ||
| 531 | /* A possible value for a buffer's overwrite-mode variable. */ | 505 | /* A possible value for a buffer's overwrite-mode variable. */ |
| @@ -555,7 +529,6 @@ keys_of_cmds (void) | |||
| 555 | { | 529 | { |
| 556 | int n; | 530 | int n; |
| 557 | 531 | ||
| 558 | nonundocount = 0; | ||
| 559 | initial_define_key (global_map, Ctl ('I'), "self-insert-command"); | 532 | initial_define_key (global_map, Ctl ('I'), "self-insert-command"); |
| 560 | for (n = 040; n < 0177; n++) | 533 | for (n = 040; n < 0177; n++) |
| 561 | initial_define_key (global_map, n, "self-insert-command"); | 534 | initial_define_key (global_map, n, "self-insert-command"); |
diff --git a/src/keyboard.c b/src/keyboard.c index 5f8667586c4..1f08e1f23ed 100644 --- a/src/keyboard.c +++ b/src/keyboard.c | |||
| @@ -1278,9 +1278,6 @@ static int read_key_sequence (Lisp_Object *, int, Lisp_Object, | |||
| 1278 | bool, bool, bool, bool); | 1278 | bool, bool, bool, bool); |
| 1279 | static void adjust_point_for_property (ptrdiff_t, bool); | 1279 | static void adjust_point_for_property (ptrdiff_t, bool); |
| 1280 | 1280 | ||
| 1281 | /* The last boundary auto-added to buffer-undo-list. */ | ||
| 1282 | Lisp_Object last_undo_boundary; | ||
| 1283 | |||
| 1284 | /* FIXME: This is wrong rather than test window-system, we should call | 1281 | /* FIXME: This is wrong rather than test window-system, we should call |
| 1285 | a new set-selection, which will then dispatch to x-set-selection, or | 1282 | a new set-selection, which will then dispatch to x-set-selection, or |
| 1286 | tty-set-selection, or w32-set-selection, ... */ | 1283 | tty-set-selection, or w32-set-selection, ... */ |
| @@ -1505,14 +1502,10 @@ command_loop_1 (void) | |||
| 1505 | } | 1502 | } |
| 1506 | #endif | 1503 | #endif |
| 1507 | 1504 | ||
| 1508 | if (NILP (KVAR (current_kboard, Vprefix_arg))) /* FIXME: Why? --Stef */ | 1505 | /* Ensure that we have added appropriate undo-boundaries as a |
| 1509 | { | 1506 | result of changes from the last command. */ |
| 1510 | Lisp_Object undo = BVAR (current_buffer, undo_list); | 1507 | call0 (Qundo_auto__add_boundary); |
| 1511 | Fundo_boundary (); | 1508 | |
| 1512 | last_undo_boundary | ||
| 1513 | = (EQ (undo, BVAR (current_buffer, undo_list)) | ||
| 1514 | ? Qnil : BVAR (current_buffer, undo_list)); | ||
| 1515 | } | ||
| 1516 | call1 (Qcommand_execute, Vthis_command); | 1509 | call1 (Qcommand_execute, Vthis_command); |
| 1517 | 1510 | ||
| 1518 | #ifdef HAVE_WINDOW_SYSTEM | 1511 | #ifdef HAVE_WINDOW_SYSTEM |
| @@ -11095,6 +11088,8 @@ syms_of_keyboard (void) | |||
| 11095 | DEFSYM (Qpre_command_hook, "pre-command-hook"); | 11088 | DEFSYM (Qpre_command_hook, "pre-command-hook"); |
| 11096 | DEFSYM (Qpost_command_hook, "post-command-hook"); | 11089 | DEFSYM (Qpost_command_hook, "post-command-hook"); |
| 11097 | 11090 | ||
| 11091 | DEFSYM (Qundo_auto__add_boundary, "undo-auto--add-boundary"); | ||
| 11092 | |||
| 11098 | DEFSYM (Qdeferred_action_function, "deferred-action-function"); | 11093 | DEFSYM (Qdeferred_action_function, "deferred-action-function"); |
| 11099 | DEFSYM (Qdelayed_warnings_hook, "delayed-warnings-hook"); | 11094 | DEFSYM (Qdelayed_warnings_hook, "delayed-warnings-hook"); |
| 11100 | DEFSYM (Qfunction_key, "function-key"); | 11095 | DEFSYM (Qfunction_key, "function-key"); |
diff --git a/src/lisp.h b/src/lisp.h index 02109d72174..aaf52bdd1be 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -4174,7 +4174,6 @@ extern void syms_of_casetab (void); | |||
| 4174 | extern Lisp_Object echo_message_buffer; | 4174 | extern Lisp_Object echo_message_buffer; |
| 4175 | extern struct kboard *echo_kboard; | 4175 | extern struct kboard *echo_kboard; |
| 4176 | extern void cancel_echoing (void); | 4176 | extern void cancel_echoing (void); |
| 4177 | extern Lisp_Object last_undo_boundary; | ||
| 4178 | extern bool input_pending; | 4177 | extern bool input_pending; |
| 4179 | #ifdef HAVE_STACK_OVERFLOW_HANDLING | 4178 | #ifdef HAVE_STACK_OVERFLOW_HANDLING |
| 4180 | extern sigjmp_buf return_to_command_loop; | 4179 | extern sigjmp_buf return_to_command_loop; |
diff --git a/src/undo.c b/src/undo.c index 750bc8afff2..364b37eeeb4 100644 --- a/src/undo.c +++ b/src/undo.c | |||
| @@ -26,10 +26,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 26 | #include "commands.h" | 26 | #include "commands.h" |
| 27 | #include "window.h" | 27 | #include "window.h" |
| 28 | 28 | ||
| 29 | /* Last buffer for which undo information was recorded. */ | ||
| 30 | /* BEWARE: This is not traced by the GC, so never dereference it! */ | ||
| 31 | static struct buffer *last_undo_buffer; | ||
| 32 | |||
| 33 | /* Position of point last time we inserted a boundary. */ | 29 | /* Position of point last time we inserted a boundary. */ |
| 34 | static struct buffer *last_boundary_buffer; | 30 | static struct buffer *last_boundary_buffer; |
| 35 | static ptrdiff_t last_boundary_position; | 31 | static ptrdiff_t last_boundary_position; |
| @@ -41,6 +37,12 @@ static ptrdiff_t last_boundary_position; | |||
| 41 | an undo-boundary. */ | 37 | an undo-boundary. */ |
| 42 | static Lisp_Object pending_boundary; | 38 | static Lisp_Object pending_boundary; |
| 43 | 39 | ||
| 40 | void | ||
| 41 | run_undoable_change () | ||
| 42 | { | ||
| 43 | call0 (Qundo_auto__undoable_change); | ||
| 44 | } | ||
| 45 | |||
| 44 | /* Record point as it was at beginning of this command (if necessary) | 46 | /* Record point as it was at beginning of this command (if necessary) |
| 45 | and prepare the undo info for recording a change. | 47 | and prepare the undo info for recording a change. |
| 46 | PT is the position of point that will naturally occur as a result of the | 48 | PT is the position of point that will naturally occur as a result of the |
| @@ -59,15 +61,7 @@ record_point (ptrdiff_t pt) | |||
| 59 | if (NILP (pending_boundary)) | 61 | if (NILP (pending_boundary)) |
| 60 | pending_boundary = Fcons (Qnil, Qnil); | 62 | pending_boundary = Fcons (Qnil, Qnil); |
| 61 | 63 | ||
| 62 | if ((current_buffer != last_undo_buffer) | 64 | run_undoable_change (); |
| 63 | /* Don't call Fundo_boundary for the first change. Otherwise we | ||
| 64 | risk overwriting last_boundary_position in Fundo_boundary with | ||
| 65 | PT of the current buffer and as a consequence not insert an | ||
| 66 | undo boundary because last_boundary_position will equal pt in | ||
| 67 | the test at the end of the present function (Bug#731). */ | ||
| 68 | && (MODIFF > SAVE_MODIFF)) | ||
| 69 | Fundo_boundary (); | ||
| 70 | last_undo_buffer = current_buffer; | ||
| 71 | 65 | ||
| 72 | at_boundary = ! CONSP (BVAR (current_buffer, undo_list)) | 66 | at_boundary = ! CONSP (BVAR (current_buffer, undo_list)) |
| 73 | || NILP (XCAR (BVAR (current_buffer, undo_list))); | 67 | || NILP (XCAR (BVAR (current_buffer, undo_list))); |
| @@ -139,9 +133,7 @@ record_marker_adjustments (ptrdiff_t from, ptrdiff_t to) | |||
| 139 | if (NILP (pending_boundary)) | 133 | if (NILP (pending_boundary)) |
| 140 | pending_boundary = Fcons (Qnil, Qnil); | 134 | pending_boundary = Fcons (Qnil, Qnil); |
| 141 | 135 | ||
| 142 | if (current_buffer != last_undo_buffer) | 136 | run_undoable_change (); |
| 143 | Fundo_boundary (); | ||
| 144 | last_undo_buffer = current_buffer; | ||
| 145 | 137 | ||
| 146 | for (m = BUF_MARKERS (current_buffer); m; m = m->next) | 138 | for (m = BUF_MARKERS (current_buffer); m; m = m->next) |
| 147 | { | 139 | { |
| @@ -228,10 +220,6 @@ record_first_change (void) | |||
| 228 | if (EQ (BVAR (current_buffer, undo_list), Qt)) | 220 | if (EQ (BVAR (current_buffer, undo_list), Qt)) |
| 229 | return; | 221 | return; |
| 230 | 222 | ||
| 231 | if (current_buffer != last_undo_buffer) | ||
| 232 | Fundo_boundary (); | ||
| 233 | last_undo_buffer = current_buffer; | ||
| 234 | |||
| 235 | if (base_buffer->base_buffer) | 223 | if (base_buffer->base_buffer) |
| 236 | base_buffer = base_buffer->base_buffer; | 224 | base_buffer = base_buffer->base_buffer; |
| 237 | 225 | ||
| @@ -259,15 +247,10 @@ record_property_change (ptrdiff_t beg, ptrdiff_t length, | |||
| 259 | if (NILP (pending_boundary)) | 247 | if (NILP (pending_boundary)) |
| 260 | pending_boundary = Fcons (Qnil, Qnil); | 248 | pending_boundary = Fcons (Qnil, Qnil); |
| 261 | 249 | ||
| 262 | if (buf != last_undo_buffer) | ||
| 263 | boundary = true; | ||
| 264 | last_undo_buffer = buf; | ||
| 265 | |||
| 266 | /* Switch temporarily to the buffer that was changed. */ | 250 | /* Switch temporarily to the buffer that was changed. */ |
| 267 | current_buffer = buf; | 251 | set_buffer_internal (buf); |
| 268 | 252 | ||
| 269 | if (boundary) | 253 | run_undoable_change (); |
| 270 | Fundo_boundary (); | ||
| 271 | 254 | ||
| 272 | if (MODIFF <= SAVE_MODIFF) | 255 | if (MODIFF <= SAVE_MODIFF) |
| 273 | record_first_change (); | 256 | record_first_change (); |
| @@ -278,7 +261,8 @@ record_property_change (ptrdiff_t beg, ptrdiff_t length, | |||
| 278 | bset_undo_list (current_buffer, | 261 | bset_undo_list (current_buffer, |
| 279 | Fcons (entry, BVAR (current_buffer, undo_list))); | 262 | Fcons (entry, BVAR (current_buffer, undo_list))); |
| 280 | 263 | ||
| 281 | current_buffer = obuf; | 264 | /* Reset the buffer */ |
| 265 | set_buffer_internal (obuf); | ||
| 282 | } | 266 | } |
| 283 | 267 | ||
| 284 | DEFUN ("undo-boundary", Fundo_boundary, Sundo_boundary, 0, 0, 0, | 268 | DEFUN ("undo-boundary", Fundo_boundary, Sundo_boundary, 0, 0, 0, |
| @@ -308,6 +292,8 @@ but another undo command will undo to the previous boundary. */) | |||
| 308 | } | 292 | } |
| 309 | last_boundary_position = PT; | 293 | last_boundary_position = PT; |
| 310 | last_boundary_buffer = current_buffer; | 294 | last_boundary_buffer = current_buffer; |
| 295 | |||
| 296 | Fset (Qundo_auto__last_boundary_cause, Qexplicit); | ||
| 311 | return Qnil; | 297 | return Qnil; |
| 312 | } | 298 | } |
| 313 | 299 | ||
| @@ -383,7 +369,6 @@ truncate_undo_list (struct buffer *b) | |||
| 383 | && !NILP (Vundo_outer_limit_function)) | 369 | && !NILP (Vundo_outer_limit_function)) |
| 384 | { | 370 | { |
| 385 | Lisp_Object tem; | 371 | Lisp_Object tem; |
| 386 | struct buffer *temp = last_undo_buffer; | ||
| 387 | 372 | ||
| 388 | /* Normally the function this calls is undo-outer-limit-truncate. */ | 373 | /* Normally the function this calls is undo-outer-limit-truncate. */ |
| 389 | tem = call1 (Vundo_outer_limit_function, make_number (size_so_far)); | 374 | tem = call1 (Vundo_outer_limit_function, make_number (size_so_far)); |
| @@ -394,10 +379,6 @@ truncate_undo_list (struct buffer *b) | |||
| 394 | unbind_to (count, Qnil); | 379 | unbind_to (count, Qnil); |
| 395 | return; | 380 | return; |
| 396 | } | 381 | } |
| 397 | /* That function probably used the minibuffer, and if so, that | ||
| 398 | changed last_undo_buffer. Change it back so that we don't | ||
| 399 | force next change to make an undo boundary here. */ | ||
| 400 | last_undo_buffer = temp; | ||
| 401 | } | 382 | } |
| 402 | 383 | ||
| 403 | if (CONSP (next)) | 384 | if (CONSP (next)) |
| @@ -455,6 +436,9 @@ void | |||
| 455 | syms_of_undo (void) | 436 | syms_of_undo (void) |
| 456 | { | 437 | { |
| 457 | DEFSYM (Qinhibit_read_only, "inhibit-read-only"); | 438 | DEFSYM (Qinhibit_read_only, "inhibit-read-only"); |
| 439 | DEFSYM (Qundo_auto__undoable_change, "undo-auto--undoable-change"); | ||
| 440 | DEFSYM (Qundo_auto__last_boundary_cause, "undo-auto--last-boundary-cause"); | ||
| 441 | DEFSYM (Qexplicit, "explicit"); | ||
| 458 | 442 | ||
| 459 | /* Marker for function call undo list elements. */ | 443 | /* Marker for function call undo list elements. */ |
| 460 | DEFSYM (Qapply, "apply"); | 444 | DEFSYM (Qapply, "apply"); |
| @@ -462,7 +446,6 @@ syms_of_undo (void) | |||
| 462 | pending_boundary = Qnil; | 446 | pending_boundary = Qnil; |
| 463 | staticpro (&pending_boundary); | 447 | staticpro (&pending_boundary); |
| 464 | 448 | ||
| 465 | last_undo_buffer = NULL; | ||
| 466 | last_boundary_buffer = NULL; | 449 | last_boundary_buffer = NULL; |
| 467 | 450 | ||
| 468 | defsubr (&Sundo_boundary); | 451 | defsubr (&Sundo_boundary); |