diff options
| author | Stefan Monnier | 2002-04-04 20:42:56 +0000 |
|---|---|---|
| committer | Stefan Monnier | 2002-04-04 20:42:56 +0000 |
| commit | 6396140ae1bc3a3cec38a7035a31ca9a5436cca1 (patch) | |
| tree | 94ab1d0dc57136e63b7d89e5547e9b1b0f3900e6 /src | |
| parent | b3bbfb96761cf5bea428ee08bf41c04cc3b9df06 (diff) | |
| download | emacs-6396140ae1bc3a3cec38a7035a31ca9a5436cca1.tar.gz emacs-6396140ae1bc3a3cec38a7035a31ca9a5436cca1.zip | |
(record_point): New fun.
(record_delete, record_insert): Use it.
Diffstat (limited to 'src')
| -rw-r--r-- | src/undo.c | 120 |
1 files changed, 63 insertions, 57 deletions
diff --git a/src/undo.c b/src/undo.c index ec6f9d6b1db..bf0c9f5b669 100644 --- a/src/undo.c +++ b/src/undo.c | |||
| @@ -36,19 +36,15 @@ Lisp_Object Qinhibit_read_only; | |||
| 36 | an undo-boundary. */ | 36 | an undo-boundary. */ |
| 37 | Lisp_Object pending_boundary; | 37 | Lisp_Object pending_boundary; |
| 38 | 38 | ||
| 39 | /* Record an insertion that just happened or is about to happen, | 39 | /* Record point as it was at beginning of this command (if necessary) |
| 40 | for LENGTH characters at position BEG. | 40 | And prepare the undo info for recording a change. |
| 41 | (It is possible to record an insertion before or after the fact | 41 | PT is the position of point that will naturally occur as a result of the |
| 42 | because we don't need to record the contents.) */ | 42 | undo record that will be added just after this command terminates. */ |
| 43 | 43 | ||
| 44 | void | 44 | static void |
| 45 | record_insert (beg, length) | 45 | record_point (pt) |
| 46 | int beg, length; | ||
| 47 | { | 46 | { |
| 48 | Lisp_Object lbeg, lend; | 47 | int at_boundary; |
| 49 | |||
| 50 | if (EQ (current_buffer->undo_list, Qt)) | ||
| 51 | return; | ||
| 52 | 48 | ||
| 53 | /* Allocate a cons cell to be the undo boundary after this command. */ | 49 | /* Allocate a cons cell to be the undo boundary after this command. */ |
| 54 | if (NILP (pending_boundary)) | 50 | if (NILP (pending_boundary)) |
| @@ -59,9 +55,58 @@ record_insert (beg, length) | |||
| 59 | Fundo_boundary (); | 55 | Fundo_boundary (); |
| 60 | XSETBUFFER (last_undo_buffer, current_buffer); | 56 | XSETBUFFER (last_undo_buffer, current_buffer); |
| 61 | 57 | ||
| 58 | if (CONSP (current_buffer->undo_list)) | ||
| 59 | { | ||
| 60 | /* Set AT_BOUNDARY to 1 only when we have nothing other than | ||
| 61 | marker adjustment before undo boundary. */ | ||
| 62 | |||
| 63 | Lisp_Object tail = current_buffer->undo_list, elt; | ||
| 64 | |||
| 65 | while (1) | ||
| 66 | { | ||
| 67 | if (NILP (tail)) | ||
| 68 | elt = Qnil; | ||
| 69 | else | ||
| 70 | elt = XCAR (tail); | ||
| 71 | if (NILP (elt) || ! (CONSP (elt) && MARKERP (XCAR (elt)))) | ||
| 72 | break; | ||
| 73 | tail = XCDR (tail); | ||
| 74 | } | ||
| 75 | at_boundary = NILP (elt); | ||
| 76 | } | ||
| 77 | else | ||
| 78 | at_boundary = 1; | ||
| 79 | |||
| 62 | if (MODIFF <= SAVE_MODIFF) | 80 | if (MODIFF <= SAVE_MODIFF) |
| 63 | record_first_change (); | 81 | record_first_change (); |
| 64 | 82 | ||
| 83 | /* If we are just after an undo boundary, and | ||
| 84 | point wasn't at start of deleted range, record where it was. */ | ||
| 85 | if (at_boundary | ||
| 86 | && last_point_position != pt | ||
| 87 | /* If we're called from batch mode, this could be nil. */ | ||
| 88 | && BUFFERP (last_point_position_buffer) | ||
| 89 | && current_buffer == XBUFFER (last_point_position_buffer)) | ||
| 90 | current_buffer->undo_list | ||
| 91 | = Fcons (make_number (last_point_position), current_buffer->undo_list); | ||
| 92 | } | ||
| 93 | |||
| 94 | /* Record an insertion that just happened or is about to happen, | ||
| 95 | for LENGTH characters at position BEG. | ||
| 96 | (It is possible to record an insertion before or after the fact | ||
| 97 | because we don't need to record the contents.) */ | ||
| 98 | |||
| 99 | void | ||
| 100 | record_insert (beg, length) | ||
| 101 | int beg, length; | ||
| 102 | { | ||
| 103 | Lisp_Object lbeg, lend; | ||
| 104 | |||
| 105 | if (EQ (current_buffer->undo_list, Qt)) | ||
| 106 | return; | ||
| 107 | |||
| 108 | record_point (beg); | ||
| 109 | |||
| 65 | /* If this is following another insertion and consecutive with it | 110 | /* If this is following another insertion and consecutive with it |
| 66 | in the buffer, combine the two. */ | 111 | in the buffer, combine the two. */ |
| 67 | if (CONSP (current_buffer->undo_list)) | 112 | if (CONSP (current_buffer->undo_list)) |
| @@ -93,59 +138,20 @@ record_delete (beg, string) | |||
| 93 | Lisp_Object string; | 138 | Lisp_Object string; |
| 94 | { | 139 | { |
| 95 | Lisp_Object sbeg; | 140 | Lisp_Object sbeg; |
| 96 | int at_boundary; | ||
| 97 | 141 | ||
| 98 | if (EQ (current_buffer->undo_list, Qt)) | 142 | if (EQ (current_buffer->undo_list, Qt)) |
| 99 | return; | 143 | return; |
| 100 | 144 | ||
| 101 | /* Allocate a cons cell to be the undo boundary after this command. */ | 145 | if (PT == beg + XSTRING (string)->size) |
| 102 | if (NILP (pending_boundary)) | ||
| 103 | pending_boundary = Fcons (Qnil, Qnil); | ||
| 104 | |||
| 105 | if (BUFFERP (last_undo_buffer) | ||
| 106 | && current_buffer != XBUFFER (last_undo_buffer)) | ||
| 107 | Fundo_boundary (); | ||
| 108 | XSETBUFFER (last_undo_buffer, current_buffer); | ||
| 109 | |||
| 110 | if (CONSP (current_buffer->undo_list)) | ||
| 111 | { | 146 | { |
| 112 | /* Set AT_BOUNDARY to 1 only when we have nothing other than | 147 | XSETINT (sbeg, -beg); |
| 113 | marker adjustment before undo boundary. */ | 148 | record_point (PT); |
| 114 | |||
| 115 | Lisp_Object tail = current_buffer->undo_list, elt; | ||
| 116 | |||
| 117 | while (1) | ||
| 118 | { | ||
| 119 | if (NILP (tail)) | ||
| 120 | elt = Qnil; | ||
| 121 | else | ||
| 122 | elt = XCAR (tail); | ||
| 123 | if (NILP (elt) || ! (CONSP (elt) && MARKERP (XCAR (elt)))) | ||
| 124 | break; | ||
| 125 | tail = XCDR (tail); | ||
| 126 | } | ||
| 127 | at_boundary = NILP (elt); | ||
| 128 | } | 149 | } |
| 129 | else | 150 | else |
| 130 | at_boundary = 0; | 151 | { |
| 131 | 152 | XSETFASTINT (sbeg, beg); | |
| 132 | if (MODIFF <= SAVE_MODIFF) | 153 | record_point (beg); |
| 133 | record_first_change (); | 154 | } |
| 134 | |||
| 135 | if (PT == beg + XSTRING (string)->size) | ||
| 136 | XSETINT (sbeg, -beg); | ||
| 137 | else | ||
| 138 | XSETFASTINT (sbeg, beg); | ||
| 139 | |||
| 140 | /* If we are just after an undo boundary, and | ||
| 141 | point wasn't at start of deleted range, record where it was. */ | ||
| 142 | if (at_boundary | ||
| 143 | && last_point_position != XFASTINT (sbeg) | ||
| 144 | /* If we're called from batch mode, this could be nil. */ | ||
| 145 | && BUFFERP (last_point_position_buffer) | ||
| 146 | && current_buffer == XBUFFER (last_point_position_buffer)) | ||
| 147 | current_buffer->undo_list | ||
| 148 | = Fcons (make_number (last_point_position), current_buffer->undo_list); | ||
| 149 | 155 | ||
| 150 | current_buffer->undo_list | 156 | current_buffer->undo_list |
| 151 | = Fcons (Fcons (string, sbeg), current_buffer->undo_list); | 157 | = Fcons (Fcons (string, sbeg), current_buffer->undo_list); |