diff options
| author | Stefan Monnier | 2008-02-25 19:09:22 +0000 |
|---|---|---|
| committer | Stefan Monnier | 2008-02-25 19:09:22 +0000 |
| commit | 13cda5f9e546fa6e8fcd5bd76fff43506da95863 (patch) | |
| tree | 3a384cbd6a71dcbb9c5a53c96930a28362a2c58b | |
| parent | d6d61574551949db41692244863d457482d3dc61 (diff) | |
| download | emacs-13cda5f9e546fa6e8fcd5bd76fff43506da95863.tar.gz emacs-13cda5f9e546fa6e8fcd5bd76fff43506da95863.zip | |
(Fbuffer_swap_text): New function.
(syms_of_buffer): Defsubr it.
| -rw-r--r-- | etc/NEWS | 3 | ||||
| -rw-r--r-- | src/ChangeLog | 5 | ||||
| -rw-r--r-- | src/buffer.c | 96 |
3 files changed, 104 insertions, 0 deletions
| @@ -597,6 +597,9 @@ functions and variables (formerly used for Tamil script). | |||
| 597 | 597 | ||
| 598 | * Lisp Changes in Emacs 23.1 | 598 | * Lisp Changes in Emacs 23.1 |
| 599 | 599 | ||
| 600 | ** The new `buffer-swap-text' function can swap the text between two buffers. | ||
| 601 | This can be useful for modes such as tar-mode, archive-mode, RMAIL. | ||
| 602 | |||
| 600 | ** `clear-image-cache' can be told to flush only images of a specific file. | 603 | ** `clear-image-cache' can be told to flush only images of a specific file. |
| 601 | 604 | ||
| 602 | ** clone-indirect-buffer now runs the clone-indirect-buffer-hook. | 605 | ** clone-indirect-buffer now runs the clone-indirect-buffer-hook. |
diff --git a/src/ChangeLog b/src/ChangeLog index 9d996e1d22f..5b8efde3351 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,8 @@ | |||
| 1 | 2008-02-25 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 2 | |||
| 3 | * buffer.c (Fbuffer_swap_text): New function. | ||
| 4 | (syms_of_buffer): Defsubr it. | ||
| 5 | |||
| 1 | 2008-02-25 Chong Yidong <cyd@stupidchicken.com> | 6 | 2008-02-25 Chong Yidong <cyd@stupidchicken.com> |
| 2 | 7 | ||
| 3 | * keyboard.c (command_loop_1): Revert 2006-10-09 change. | 8 | * keyboard.c (command_loop_1): Revert 2006-10-09 change. |
diff --git a/src/buffer.c b/src/buffer.c index c0162841c62..efcaafb9507 100644 --- a/src/buffer.c +++ b/src/buffer.c | |||
| @@ -2212,6 +2212,101 @@ advance_to_char_boundary (byte_pos) | |||
| 2212 | return byte_pos; | 2212 | return byte_pos; |
| 2213 | } | 2213 | } |
| 2214 | 2214 | ||
| 2215 | DEFUN ("buffer-swap-text", Fbuffer_swap_text, Sbuffer_swap_text, | ||
| 2216 | 1, 1, 0, | ||
| 2217 | doc: /* Swap the text between current buffer and BUFFER. */) | ||
| 2218 | (buffer) | ||
| 2219 | Lisp_Object buffer; | ||
| 2220 | { | ||
| 2221 | struct buffer *other_buffer; | ||
| 2222 | CHECK_BUFFER (buffer); | ||
| 2223 | other_buffer = XBUFFER (buffer); | ||
| 2224 | |||
| 2225 | /* Actually, it probably works just fine. | ||
| 2226 | * if (other_buffer == current_buffer) | ||
| 2227 | * error ("Cannot swap a buffer's text with itself"); */ | ||
| 2228 | |||
| 2229 | /* Actually, this may be workable as well, tho probably only if they're | ||
| 2230 | *both* indirect. */ | ||
| 2231 | if (other_buffer->base_buffer | ||
| 2232 | || current_buffer->base_buffer) | ||
| 2233 | error ("Cannot swap indirect buffers's text"); | ||
| 2234 | |||
| 2235 | { /* This is probably harder to make work. */ | ||
| 2236 | struct buffer *other; | ||
| 2237 | for (other = all_buffers; other; other = other->next) | ||
| 2238 | if (other->base_buffer == other_buffer | ||
| 2239 | || other->base_buffer == current_buffer) | ||
| 2240 | error ("One of the buffers to swap has indirect buffers"); | ||
| 2241 | } | ||
| 2242 | |||
| 2243 | #define swapfield(field, type) \ | ||
| 2244 | do { \ | ||
| 2245 | type tmp##field = other_buffer->field; \ | ||
| 2246 | other_buffer->field = current_buffer->field; \ | ||
| 2247 | current_buffer->field = tmp##field; \ | ||
| 2248 | } while (0) | ||
| 2249 | |||
| 2250 | swapfield (own_text, struct buffer_text); | ||
| 2251 | eassert (current_buffer->text == ¤t_buffer->own_text); | ||
| 2252 | eassert (other_buffer->text == &other_buffer->own_text); | ||
| 2253 | swapfield (pt, EMACS_INT); | ||
| 2254 | swapfield (pt_byte, EMACS_INT); | ||
| 2255 | swapfield (begv, EMACS_INT); | ||
| 2256 | swapfield (begv_byte, EMACS_INT); | ||
| 2257 | swapfield (zv, EMACS_INT); | ||
| 2258 | swapfield (zv_byte, EMACS_INT); | ||
| 2259 | eassert (!current_buffer->base_buffer); | ||
| 2260 | eassert (!other_buffer->base_buffer); | ||
| 2261 | current_buffer->clip_changed = 1; other_buffer->clip_changed = 1; | ||
| 2262 | swapfield (newline_cache, struct region_cache *); | ||
| 2263 | swapfield (width_run_cache, struct region_cache *); | ||
| 2264 | current_buffer->prevent_redisplay_optimizations_p = 1; | ||
| 2265 | other_buffer->prevent_redisplay_optimizations_p = 1; | ||
| 2266 | swapfield (overlays_before, struct Lisp_Overlay *); | ||
| 2267 | swapfield (overlays_after, struct Lisp_Overlay *); | ||
| 2268 | swapfield (overlay_center, EMACS_INT); | ||
| 2269 | swapfield (undo_list, Lisp_Object); | ||
| 2270 | swapfield (mark, Lisp_Object); | ||
| 2271 | if (MARKERP (current_buffer->mark) && XMARKER (current_buffer->mark)->buffer) | ||
| 2272 | XMARKER (current_buffer->mark)->buffer = current_buffer; | ||
| 2273 | if (MARKERP (other_buffer->mark) && XMARKER (other_buffer->mark)->buffer) | ||
| 2274 | XMARKER (other_buffer->mark)->buffer = other_buffer; | ||
| 2275 | swapfield (enable_multibyte_characters, Lisp_Object); | ||
| 2276 | /* FIXME: Not sure what we should do with these *_marker fields. | ||
| 2277 | Hopefully they're just nil anyway. */ | ||
| 2278 | swapfield (pt_marker, Lisp_Object); | ||
| 2279 | swapfield (begv_marker, Lisp_Object); | ||
| 2280 | swapfield (zv_marker, Lisp_Object); | ||
| 2281 | current_buffer->point_before_scroll = Qnil; | ||
| 2282 | other_buffer->point_before_scroll = Qnil; | ||
| 2283 | |||
| 2284 | current_buffer->text->modiff++; other_buffer->text->modiff++; | ||
| 2285 | current_buffer->text->chars_modiff++; other_buffer->text->chars_modiff++; | ||
| 2286 | current_buffer->text->overlay_modiff++; other_buffer->text->overlay_modiff++; | ||
| 2287 | current_buffer->text->beg_unchanged = current_buffer->text->gpt; | ||
| 2288 | current_buffer->text->end_unchanged = current_buffer->text->gpt; | ||
| 2289 | other_buffer->text->beg_unchanged = current_buffer->text->gpt; | ||
| 2290 | other_buffer->text->end_unchanged = current_buffer->text->gpt; | ||
| 2291 | { | ||
| 2292 | struct Lisp_Marker *m; | ||
| 2293 | for (m = BUF_MARKERS (current_buffer); m; m = m->next) | ||
| 2294 | if (m->buffer == other_buffer) | ||
| 2295 | m->buffer = current_buffer; | ||
| 2296 | for (m = BUF_MARKERS (other_buffer); m; m = m->next) | ||
| 2297 | if (m->buffer == current_buffer) | ||
| 2298 | m->buffer = other_buffer; | ||
| 2299 | } | ||
| 2300 | if (current_buffer->text->intervals) | ||
| 2301 | (eassert (EQ (current_buffer->text->intervals->up.obj, buffer)), | ||
| 2302 | XSETBUFFER (current_buffer->text->intervals->up.obj, current_buffer)); | ||
| 2303 | if (other_buffer->text->intervals) | ||
| 2304 | (eassert (EQ (other_buffer->text->intervals->up.obj, Fcurrent_buffer ())), | ||
| 2305 | XSETBUFFER (other_buffer->text->intervals->up.obj, other_buffer)); | ||
| 2306 | |||
| 2307 | return Qnil; | ||
| 2308 | } | ||
| 2309 | |||
| 2215 | DEFUN ("set-buffer-multibyte", Fset_buffer_multibyte, Sset_buffer_multibyte, | 2310 | DEFUN ("set-buffer-multibyte", Fset_buffer_multibyte, Sset_buffer_multibyte, |
| 2216 | 1, 1, 0, | 2311 | 1, 1, 0, |
| 2217 | doc: /* Set the multibyte flag of the current buffer to FLAG. | 2312 | doc: /* Set the multibyte flag of the current buffer to FLAG. |
| @@ -6189,6 +6284,7 @@ The function `kill-all-local-variables' runs this before doing anything else. * | |||
| 6189 | defsubr (&Sbarf_if_buffer_read_only); | 6284 | defsubr (&Sbarf_if_buffer_read_only); |
| 6190 | defsubr (&Sbury_buffer); | 6285 | defsubr (&Sbury_buffer); |
| 6191 | defsubr (&Serase_buffer); | 6286 | defsubr (&Serase_buffer); |
| 6287 | defsubr (&Sbuffer_swap_text); | ||
| 6192 | defsubr (&Sset_buffer_multibyte); | 6288 | defsubr (&Sset_buffer_multibyte); |
| 6193 | defsubr (&Skill_all_local_variables); | 6289 | defsubr (&Skill_all_local_variables); |
| 6194 | 6290 | ||