diff options
| author | Richard M. Stallman | 1995-01-02 21:50:28 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1995-01-02 21:50:28 +0000 |
| commit | 336cd056699a1270aae0eb1e5709e374a188900b (patch) | |
| tree | bcd5e4022528a74255fa758d9fb9e570ae06b482 /src/buffer.c | |
| parent | e5d967c90e1f6c9349294faedcee9c40595b809b (diff) | |
| download | emacs-336cd056699a1270aae0eb1e5709e374a188900b.tar.gz emacs-336cd056699a1270aae0eb1e5709e374a188900b.zip | |
(Fmake_indirect_buffer): New function.
(Fbuffer_base_buffer): New function.
(syms_of_buffer): defsubr them.
(reset_buffer): Don't alter intervals here.
(Fget_buffer_create): Use BUF_MARKERS. Init BUF_INTERVALS here.
(Fkill_buffer): Use BUF_MARKERS; but don't touch it in indir buf.
Likewise BUF_INTERVALS.
(init_buffer_once): Set up .text and BUF_INTERVALS
in buffer_local_symbols and buffer_defaults.
(Fkill_buffer): Don't free the text in indirect buffer.
When killing a base buffer, kill its indirect buffers first.
(set_buffer_temp): New function.
(reset_buffer_local_variables): Initialize buffer_file_type field.
(Fget_buffer_create): Initialize pt_marker, begv/zv_marker.
(set_buffer_internal): Use and update these markers.
Copy undo_list in and out of the base buffer.
(Fget_buffer_create): Init save_modiff field here.
(reset_buffer): Not here.
(Fbuffer_modified_p): Use BUF_SAVE_MODIFF.
(Fset_buffer_modified_p): Use SAVE_MODIFF.
(Fkill_buffer, list_buffers_1): Use BUF_SAVE_MODIFF.
(Fget_buffer_create): Initialize the size and text fields.
Diffstat (limited to 'src/buffer.c')
| -rw-r--r-- | src/buffer.c | 300 |
1 files changed, 275 insertions, 25 deletions
diff --git a/src/buffer.c b/src/buffer.c index 34558e236f4..8ab052b5fae 100644 --- a/src/buffer.c +++ b/src/buffer.c | |||
| @@ -255,6 +255,12 @@ The value is never nil.") | |||
| 255 | 255 | ||
| 256 | b = (struct buffer *) xmalloc (sizeof (struct buffer)); | 256 | b = (struct buffer *) xmalloc (sizeof (struct buffer)); |
| 257 | 257 | ||
| 258 | b->size = sizeof (struct buffer) / sizeof (EMACS_INT); | ||
| 259 | |||
| 260 | /* An ordinary buffer uses its own struct buffer_text. */ | ||
| 261 | b->text = &b->own_text; | ||
| 262 | b->base_buffer = 0; | ||
| 263 | |||
| 258 | BUF_GAP_SIZE (b) = 20; | 264 | BUF_GAP_SIZE (b) = 20; |
| 259 | BLOCK_INPUT; | 265 | BLOCK_INPUT; |
| 260 | BUFFER_ALLOC (BUF_BEG_ADDR (b), BUF_GAP_SIZE (b)); | 266 | BUFFER_ALLOC (BUF_BEG_ADDR (b), BUF_GAP_SIZE (b)); |
| @@ -268,6 +274,8 @@ The value is never nil.") | |||
| 268 | BUF_ZV (b) = 1; | 274 | BUF_ZV (b) = 1; |
| 269 | BUF_Z (b) = 1; | 275 | BUF_Z (b) = 1; |
| 270 | BUF_MODIFF (b) = 1; | 276 | BUF_MODIFF (b) = 1; |
| 277 | BUF_SAVE_MODIFF (b) = 1; | ||
| 278 | BUF_INTERVALS (b) = 0; | ||
| 271 | 279 | ||
| 272 | b->newline_cache = 0; | 280 | b->newline_cache = 0; |
| 273 | b->width_run_cache = 0; | 281 | b->width_run_cache = 0; |
| @@ -277,8 +285,11 @@ The value is never nil.") | |||
| 277 | b->next = all_buffers; | 285 | b->next = all_buffers; |
| 278 | all_buffers = b; | 286 | all_buffers = b; |
| 279 | 287 | ||
| 280 | b->mark = Fmake_marker (); | 288 | /* An ordinary buffer normally doesn't need markers |
| 281 | /*b->number = make_number (++buffer_count);*/ | 289 | to handle BEGV and ZV. */ |
| 290 | b->pt_marker = Qnil; | ||
| 291 | b->begv_marker = Qnil; | ||
| 292 | b->zv_marker = Qnil; | ||
| 282 | 293 | ||
| 283 | name = Fcopy_sequence (name); | 294 | name = Fcopy_sequence (name); |
| 284 | INITIALIZE_INTERVAL (XSTRING (name), NULL_INTERVAL); | 295 | INITIALIZE_INTERVAL (XSTRING (name), NULL_INTERVAL); |
| @@ -297,8 +308,97 @@ The value is never nil.") | |||
| 297 | Vbuffer_alist = nconc2 (Vbuffer_alist, Fcons (Fcons (name, buf), Qnil)); | 308 | Vbuffer_alist = nconc2 (Vbuffer_alist, Fcons (Fcons (name, buf), Qnil)); |
| 298 | 309 | ||
| 299 | b->mark = Fmake_marker (); | 310 | b->mark = Fmake_marker (); |
| 300 | b->markers = Qnil; | 311 | BUF_MARKERS (b) = Qnil; |
| 312 | b->name = name; | ||
| 313 | return buf; | ||
| 314 | } | ||
| 315 | |||
| 316 | DEFUN ("make-indirect-buffer", | ||
| 317 | Fmake_indirect_buffer, Smake_indirect_buffer, 2, 2, | ||
| 318 | "BMake indirect buffer: \nbIndirect to base buffer: ", | ||
| 319 | "Create and return an indirect buffer named NAME, with base buffer BASE.\n\ | ||
| 320 | BASE should be an existing buffer (or buffer name).") | ||
| 321 | (name, base_buffer) | ||
| 322 | register Lisp_Object name, base_buffer; | ||
| 323 | { | ||
| 324 | register Lisp_Object buf; | ||
| 325 | register struct buffer *b; | ||
| 326 | |||
| 327 | buf = Fget_buffer (name); | ||
| 328 | if (!NILP (buf)) | ||
| 329 | error ("Buffer name `%s' is in use", XSTRING (name)->data); | ||
| 330 | |||
| 331 | base_buffer = Fget_buffer (base_buffer); | ||
| 332 | if (NILP (base_buffer)) | ||
| 333 | error ("No such buffer: `%s'", | ||
| 334 | XSTRING (XBUFFER (base_buffer)->name)->data); | ||
| 335 | |||
| 336 | if (XSTRING (name)->size == 0) | ||
| 337 | error ("Empty string for buffer name is not allowed"); | ||
| 338 | |||
| 339 | b = (struct buffer *) xmalloc (sizeof (struct buffer)); | ||
| 340 | |||
| 341 | b->size = sizeof (struct buffer) / sizeof (EMACS_INT); | ||
| 342 | |||
| 343 | if (XBUFFER (base_buffer)->base_buffer) | ||
| 344 | b->base_buffer = XBUFFER (base_buffer)->base_buffer; | ||
| 345 | else | ||
| 346 | b->base_buffer = XBUFFER (base_buffer); | ||
| 347 | |||
| 348 | /* Use the base buffer's text object. */ | ||
| 349 | b->text = b->base_buffer->text; | ||
| 350 | |||
| 351 | BUF_BEGV (b) = BUF_BEGV (b->base_buffer); | ||
| 352 | BUF_ZV (b) = BUF_ZV (b->base_buffer); | ||
| 353 | BUF_PT (b) = BUF_PT (b->base_buffer); | ||
| 354 | |||
| 355 | b->newline_cache = 0; | ||
| 356 | b->width_run_cache = 0; | ||
| 357 | b->width_table = Qnil; | ||
| 358 | |||
| 359 | /* Put this on the chain of all buffers including killed ones. */ | ||
| 360 | b->next = all_buffers; | ||
| 361 | all_buffers = b; | ||
| 362 | |||
| 363 | name = Fcopy_sequence (name); | ||
| 364 | INITIALIZE_INTERVAL (XSTRING (name), NULL_INTERVAL); | ||
| 365 | b->name = name; | ||
| 366 | |||
| 367 | reset_buffer (b); | ||
| 368 | reset_buffer_local_variables (b); | ||
| 369 | |||
| 370 | /* Put this in the alist of all live buffers. */ | ||
| 371 | XSETBUFFER (buf, b); | ||
| 372 | Vbuffer_alist = nconc2 (Vbuffer_alist, Fcons (Fcons (name, buf), Qnil)); | ||
| 373 | |||
| 374 | b->mark = Fmake_marker (); | ||
| 301 | b->name = name; | 375 | b->name = name; |
| 376 | |||
| 377 | /* Make sure the base buffer has markers for its narrowing. */ | ||
| 378 | if (NILP (b->base_buffer->pt_marker)) | ||
| 379 | { | ||
| 380 | b->base_buffer->pt_marker = Fmake_marker (); | ||
| 381 | Fset_marker (b->base_buffer->pt_marker, | ||
| 382 | make_number (BUF_PT (b->base_buffer)), base_buffer); | ||
| 383 | } | ||
| 384 | if (NILP (b->base_buffer->begv_marker)) | ||
| 385 | { | ||
| 386 | b->base_buffer->begv_marker = Fmake_marker (); | ||
| 387 | Fset_marker (b->base_buffer->begv_marker, | ||
| 388 | make_number (BUF_BEGV (b->base_buffer)), base_buffer); | ||
| 389 | } | ||
| 390 | if (NILP (b->base_buffer->zv_marker)) | ||
| 391 | { | ||
| 392 | b->base_buffer->zv_marker = Fmake_marker (); | ||
| 393 | Fset_marker (b->base_buffer->zv_marker, | ||
| 394 | make_number (BUF_ZV (b->base_buffer)), base_buffer); | ||
| 395 | } | ||
| 396 | |||
| 397 | /* Give the indirect buffer markers for its narrowing. */ | ||
| 398 | b->pt_marker = Fpoint_marker (); | ||
| 399 | b->begv_marker = Fpoint_min_marker (); | ||
| 400 | b->zv_marker = Fpoint_max_marker (); | ||
| 401 | |||
| 302 | return buf; | 402 | return buf; |
| 303 | } | 403 | } |
| 304 | 404 | ||
| @@ -312,7 +412,6 @@ reset_buffer (b) | |||
| 312 | b->filename = Qnil; | 412 | b->filename = Qnil; |
| 313 | b->directory = (current_buffer) ? current_buffer->directory : Qnil; | 413 | b->directory = (current_buffer) ? current_buffer->directory : Qnil; |
| 314 | b->modtime = 0; | 414 | b->modtime = 0; |
| 315 | b->save_modified = 1; | ||
| 316 | XSETFASTINT (b->save_length, 0); | 415 | XSETFASTINT (b->save_length, 0); |
| 317 | b->last_window_start = 1; | 416 | b->last_window_start = 1; |
| 318 | b->backed_up = Qnil; | 417 | b->backed_up = Qnil; |
| @@ -324,9 +423,6 @@ reset_buffer (b) | |||
| 324 | b->overlays_after = Qnil; | 423 | b->overlays_after = Qnil; |
| 325 | XSETFASTINT (b->overlay_center, 1); | 424 | XSETFASTINT (b->overlay_center, 1); |
| 326 | b->mark_active = Qnil; | 425 | b->mark_active = Qnil; |
| 327 | |||
| 328 | /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */ | ||
| 329 | INITIALIZE_INTERVAL (b, NULL_INTERVAL); | ||
| 330 | } | 426 | } |
| 331 | 427 | ||
| 332 | /* Reset buffer B's local variables info. | 428 | /* Reset buffer B's local variables info. |
| @@ -352,6 +448,7 @@ reset_buffer_local_variables (b) | |||
| 352 | b->upcase_table = Vascii_upcase_table; | 448 | b->upcase_table = Vascii_upcase_table; |
| 353 | b->case_canon_table = Vascii_canon_table; | 449 | b->case_canon_table = Vascii_canon_table; |
| 354 | b->case_eqv_table = Vascii_eqv_table; | 450 | b->case_eqv_table = Vascii_eqv_table; |
| 451 | b->buffer_file_type = Qnil; | ||
| 355 | #if 0 | 452 | #if 0 |
| 356 | b->sort_table = XSTRING (Vascii_sort_table); | 453 | b->sort_table = XSTRING (Vascii_sort_table); |
| 357 | b->folding_sort_table = XSTRING (Vascii_folding_sort_table); | 454 | b->folding_sort_table = XSTRING (Vascii_folding_sort_table); |
| @@ -440,6 +537,30 @@ No argument or nil as argument means use the current buffer.") | |||
| 440 | return XBUFFER (buffer)->filename; | 537 | return XBUFFER (buffer)->filename; |
| 441 | } | 538 | } |
| 442 | 539 | ||
| 540 | DEFUN ("buffer-base-buffer", Fbuffer_base_buffer, Sbuffer_base_buffer, | ||
| 541 | 0, 1, 0, | ||
| 542 | "Return the base buffer of indirect buffer BUFFER.\n\ | ||
| 543 | If BUFFER is not indirect, return nil.") | ||
| 544 | (buffer) | ||
| 545 | register Lisp_Object buffer; | ||
| 546 | { | ||
| 547 | struct buffer *base; | ||
| 548 | Lisp_Object base_buffer; | ||
| 549 | |||
| 550 | if (NILP (buffer)) | ||
| 551 | base = current_buffer->base_buffer; | ||
| 552 | else | ||
| 553 | { | ||
| 554 | CHECK_BUFFER (buffer, 0); | ||
| 555 | base = XBUFFER (buffer)->base_buffer; | ||
| 556 | } | ||
| 557 | |||
| 558 | if (! base) | ||
| 559 | return Qnil; | ||
| 560 | XSETBUFFER (base_buffer, base); | ||
| 561 | return base_buffer; | ||
| 562 | } | ||
| 563 | |||
| 443 | DEFUN ("buffer-local-variables", Fbuffer_local_variables, | 564 | DEFUN ("buffer-local-variables", Fbuffer_local_variables, |
| 444 | Sbuffer_local_variables, 0, 1, 0, | 565 | Sbuffer_local_variables, 0, 1, 0, |
| 445 | "Return an alist of variables that are buffer-local in BUFFER.\n\ | 566 | "Return an alist of variables that are buffer-local in BUFFER.\n\ |
| @@ -529,7 +650,7 @@ No argument or nil as argument means use current buffer as BUFFER.") | |||
| 529 | buf = XBUFFER (buffer); | 650 | buf = XBUFFER (buffer); |
| 530 | } | 651 | } |
| 531 | 652 | ||
| 532 | return buf->save_modified < BUF_MODIFF (buf) ? Qt : Qnil; | 653 | return BUF_SAVE_MODIFF (buf) < BUF_MODIFF (buf) ? Qt : Qnil; |
| 533 | } | 654 | } |
| 534 | 655 | ||
| 535 | DEFUN ("set-buffer-modified-p", Fset_buffer_modified_p, Sset_buffer_modified_p, | 656 | DEFUN ("set-buffer-modified-p", Fset_buffer_modified_p, Sset_buffer_modified_p, |
| @@ -549,7 +670,7 @@ A non-nil FLAG means mark the buffer modified.") | |||
| 549 | fn = current_buffer->filename; | 670 | fn = current_buffer->filename; |
| 550 | if (!NILP (fn)) | 671 | if (!NILP (fn)) |
| 551 | { | 672 | { |
| 552 | already = current_buffer->save_modified < MODIFF; | 673 | already = SAVE_MODIFF < MODIFF; |
| 553 | if (!already && !NILP (flag)) | 674 | if (!already && !NILP (flag)) |
| 554 | lock_file (fn); | 675 | lock_file (fn); |
| 555 | else if (already && NILP (flag)) | 676 | else if (already && NILP (flag)) |
| @@ -557,7 +678,7 @@ A non-nil FLAG means mark the buffer modified.") | |||
| 557 | } | 678 | } |
| 558 | #endif /* CLASH_DETECTION */ | 679 | #endif /* CLASH_DETECTION */ |
| 559 | 680 | ||
| 560 | current_buffer->save_modified = NILP (flag) ? MODIFF : 0; | 681 | SAVE_MODIFF = NILP (flag) ? MODIFF : 0; |
| 561 | update_mode_lines++; | 682 | update_mode_lines++; |
| 562 | return flag; | 683 | return flag; |
| 563 | } | 684 | } |
| @@ -762,7 +883,7 @@ with `delete-process'.") | |||
| 762 | 883 | ||
| 763 | /* Query if the buffer is still modified. */ | 884 | /* Query if the buffer is still modified. */ |
| 764 | if (INTERACTIVE && !NILP (b->filename) | 885 | if (INTERACTIVE && !NILP (b->filename) |
| 765 | && BUF_MODIFF (b) > b->save_modified) | 886 | && BUF_MODIFF (b) > BUF_SAVE_MODIFF (b)) |
| 766 | { | 887 | { |
| 767 | GCPRO2 (buf, bufname); | 888 | GCPRO2 (buf, bufname); |
| 768 | tem = do_yes_or_no_p (format1 ("Buffer %s modified; kill anyway? ", | 889 | tem = do_yes_or_no_p (format1 ("Buffer %s modified; kill anyway? ", |
| @@ -807,6 +928,26 @@ with `delete-process'.") | |||
| 807 | if (NILP (b->name)) | 928 | if (NILP (b->name)) |
| 808 | return Qnil; | 929 | return Qnil; |
| 809 | 930 | ||
| 931 | /* When we kill a base buffer, kill all its indirect buffers. | ||
| 932 | We do it at this stage so nothing terrible happens if they | ||
| 933 | ask questions or their hooks get errors. */ | ||
| 934 | if (! b->base_buffer) | ||
| 935 | { | ||
| 936 | struct buffer *other; | ||
| 937 | |||
| 938 | GCPRO1 (buf); | ||
| 939 | |||
| 940 | for (other = all_buffers; other; other = other->next) | ||
| 941 | if (other->base_buffer == b) | ||
| 942 | { | ||
| 943 | Lisp_Object buf; | ||
| 944 | XSETBUFFER (buf, other); | ||
| 945 | Fkill_buffer (buf); | ||
| 946 | } | ||
| 947 | |||
| 948 | UNGCPRO; | ||
| 949 | } | ||
| 950 | |||
| 810 | /* Make this buffer not be current. | 951 | /* Make this buffer not be current. |
| 811 | In the process, notice if this is the sole visible buffer | 952 | In the process, notice if this is the sole visible buffer |
| 812 | and give up if so. */ | 953 | and give up if so. */ |
| @@ -843,24 +984,32 @@ with `delete-process'.") | |||
| 843 | internal_delete_file (b->auto_save_file_name); | 984 | internal_delete_file (b->auto_save_file_name); |
| 844 | } | 985 | } |
| 845 | 986 | ||
| 846 | /* Unchain all markers of this buffer | 987 | if (! b->base_buffer) |
| 847 | and leave them pointing nowhere. */ | ||
| 848 | for (tem = b->markers; !EQ (tem, Qnil); ) | ||
| 849 | { | 988 | { |
| 850 | m = XMARKER (tem); | 989 | /* Unchain all markers of this buffer |
| 851 | m->buffer = 0; | 990 | and leave them pointing nowhere. */ |
| 852 | tem = m->chain; | 991 | for (tem = BUF_MARKERS (b); !EQ (tem, Qnil); ) |
| 853 | m->chain = Qnil; | 992 | { |
| 854 | } | 993 | m = XMARKER (tem); |
| 855 | b->markers = Qnil; | 994 | m->buffer = 0; |
| 995 | tem = m->chain; | ||
| 996 | m->chain = Qnil; | ||
| 997 | } | ||
| 998 | BUF_MARKERS (b) = Qnil; | ||
| 856 | 999 | ||
| 857 | /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */ | 1000 | #ifdef USE_TEXT_PROPERTIES |
| 858 | INITIALIZE_INTERVAL (b, NULL_INTERVAL); | 1001 | BUF_INTERVALS (b) = NULL_INTERVAL; |
| 859 | /* Perhaps we should explicitly free the interval tree here... */ | 1002 | #endif |
| 1003 | |||
| 1004 | /* Perhaps we should explicitly free the interval tree here... */ | ||
| 1005 | } | ||
| 860 | 1006 | ||
| 861 | b->name = Qnil; | 1007 | b->name = Qnil; |
| 1008 | |||
| 862 | BLOCK_INPUT; | 1009 | BLOCK_INPUT; |
| 863 | BUFFER_FREE (BUF_BEG_ADDR (b)); | 1010 | if (! b->base_buffer) |
| 1011 | BUFFER_FREE (BUF_BEG_ADDR (b)); | ||
| 1012 | |||
| 864 | if (b->newline_cache) | 1013 | if (b->newline_cache) |
| 865 | { | 1014 | { |
| 866 | free_region_cache (b->newline_cache); | 1015 | free_region_cache (b->newline_cache); |
| @@ -1029,6 +1178,49 @@ set_buffer_internal (b) | |||
| 1029 | current_buffer = b; | 1178 | current_buffer = b; |
| 1030 | last_known_column_point = -1; /* invalidate indentation cache */ | 1179 | last_known_column_point = -1; /* invalidate indentation cache */ |
| 1031 | 1180 | ||
| 1181 | if (old_buf) | ||
| 1182 | { | ||
| 1183 | /* Put the undo list back in the base buffer, so that it appears | ||
| 1184 | that an indirect buffer shares the undo list of its base. */ | ||
| 1185 | if (old_buf->base_buffer) | ||
| 1186 | old_buf->base_buffer->undo_list = old_buf->undo_list; | ||
| 1187 | |||
| 1188 | /* If the old current buffer has markers to record PT, BEGV and ZV | ||
| 1189 | when it is not current, update them now. */ | ||
| 1190 | if (! NILP (old_buf->pt_marker)) | ||
| 1191 | { | ||
| 1192 | Lisp_Object obuf; | ||
| 1193 | XSETBUFFER (obuf, old_buf); | ||
| 1194 | Fset_marker (old_buf->pt_marker, BUF_PT (old_buf), obuf); | ||
| 1195 | } | ||
| 1196 | if (! NILP (old_buf->begv_marker)) | ||
| 1197 | { | ||
| 1198 | Lisp_Object obuf; | ||
| 1199 | XSETBUFFER (obuf, old_buf); | ||
| 1200 | Fset_marker (old_buf->begv_marker, BUF_BEGV (old_buf), obuf); | ||
| 1201 | } | ||
| 1202 | if (! NILP (old_buf->zv_marker)) | ||
| 1203 | { | ||
| 1204 | Lisp_Object obuf; | ||
| 1205 | XSETBUFFER (obuf, old_buf); | ||
| 1206 | Fset_marker (old_buf->zv_marker, BUF_ZV (old_buf), obuf); | ||
| 1207 | } | ||
| 1208 | } | ||
| 1209 | |||
| 1210 | /* Get the undo list from the base buffer, so that it appears | ||
| 1211 | that an indirect buffer shares the undo list of its base. */ | ||
| 1212 | if (b->base_buffer) | ||
| 1213 | b->undo_list = b->base_buffer->undo_list; | ||
| 1214 | |||
| 1215 | /* If the new current buffer has markers to record PT, BEGV and ZV | ||
| 1216 | when it is not current, fetch them now. */ | ||
| 1217 | if (! NILP (b->pt_marker)) | ||
| 1218 | BUF_PT (b) = marker_position (b->pt_marker); | ||
| 1219 | if (! NILP (b->begv_marker)) | ||
| 1220 | BUF_BEGV (b) = marker_position (b->begv_marker); | ||
| 1221 | if (! NILP (b->zv_marker)) | ||
| 1222 | BUF_ZV (b) = marker_position (b->zv_marker); | ||
| 1223 | |||
| 1032 | /* Look down buffer's list of local Lisp variables | 1224 | /* Look down buffer's list of local Lisp variables |
| 1033 | to find and update any that forward into C variables. */ | 1225 | to find and update any that forward into C variables. */ |
| 1034 | 1226 | ||
| @@ -1060,6 +1252,55 @@ set_buffer_internal (b) | |||
| 1060 | } | 1252 | } |
| 1061 | } | 1253 | } |
| 1062 | 1254 | ||
| 1255 | /* Switch to buffer B temporarily for redisplay purposes. | ||
| 1256 | This avoids certain things thatdon't need to be done within redisplay. */ | ||
| 1257 | |||
| 1258 | void | ||
| 1259 | set_buffer_temp (b) | ||
| 1260 | struct buffer *b; | ||
| 1261 | { | ||
| 1262 | register struct buffer *old_buf; | ||
| 1263 | |||
| 1264 | if (current_buffer == b) | ||
| 1265 | return; | ||
| 1266 | |||
| 1267 | old_buf = current_buffer; | ||
| 1268 | current_buffer = b; | ||
| 1269 | |||
| 1270 | if (old_buf) | ||
| 1271 | { | ||
| 1272 | /* If the old current buffer has markers to record PT, BEGV and ZV | ||
| 1273 | when it is not current, update them now. */ | ||
| 1274 | if (! NILP (old_buf->pt_marker)) | ||
| 1275 | { | ||
| 1276 | Lisp_Object obuf; | ||
| 1277 | XSETBUFFER (obuf, old_buf); | ||
| 1278 | Fset_marker (old_buf->pt_marker, BUF_PT (old_buf), obuf); | ||
| 1279 | } | ||
| 1280 | if (! NILP (old_buf->begv_marker)) | ||
| 1281 | { | ||
| 1282 | Lisp_Object obuf; | ||
| 1283 | XSETBUFFER (obuf, old_buf); | ||
| 1284 | Fset_marker (old_buf->begv_marker, BUF_BEGV (old_buf), obuf); | ||
| 1285 | } | ||
| 1286 | if (! NILP (old_buf->zv_marker)) | ||
| 1287 | { | ||
| 1288 | Lisp_Object obuf; | ||
| 1289 | XSETBUFFER (obuf, old_buf); | ||
| 1290 | Fset_marker (old_buf->zv_marker, BUF_ZV (old_buf), obuf); | ||
| 1291 | } | ||
| 1292 | } | ||
| 1293 | |||
| 1294 | /* If the new current buffer has markers to record PT, BEGV and ZV | ||
| 1295 | when it is not current, fetch them now. */ | ||
| 1296 | if (! NILP (b->pt_marker)) | ||
| 1297 | BUF_PT (b) = marker_position (b->pt_marker); | ||
| 1298 | if (! NILP (b->begv_marker)) | ||
| 1299 | BUF_BEGV (b) = marker_position (b->begv_marker); | ||
| 1300 | if (! NILP (b->zv_marker)) | ||
| 1301 | BUF_ZV (b) = marker_position (b->zv_marker); | ||
| 1302 | } | ||
| 1303 | |||
| 1063 | DEFUN ("set-buffer", Fset_buffer, Sset_buffer, 1, 1, 0, | 1304 | DEFUN ("set-buffer", Fset_buffer, Sset_buffer, 1, 1, 0, |
| 1064 | "Make the buffer BUFFER current for editing operations.\n\ | 1305 | "Make the buffer BUFFER current for editing operations.\n\ |
| 1065 | BUFFER may be a buffer or the name of an existing buffer.\n\ | 1306 | BUFFER may be a buffer or the name of an existing buffer.\n\ |
| @@ -1207,7 +1448,7 @@ list_buffers_1 (files) | |||
| 1207 | XSETFASTINT (desired_point, PT); | 1448 | XSETFASTINT (desired_point, PT); |
| 1208 | write_string (b == old ? "." : " ", -1); | 1449 | write_string (b == old ? "." : " ", -1); |
| 1209 | /* Identify modified buffers */ | 1450 | /* Identify modified buffers */ |
| 1210 | write_string (BUF_MODIFF (b) > b->save_modified ? "*" : " ", -1); | 1451 | write_string (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b) ? "*" : " ", -1); |
| 1211 | /* The current buffer is special-cased to be marked read-only. | 1452 | /* The current buffer is special-cased to be marked read-only. |
| 1212 | It is actually made read-only by the call to | 1453 | It is actually made read-only by the call to |
| 1213 | Buffer-menu-mode, below. */ | 1454 | Buffer-menu-mode, below. */ |
| @@ -2540,6 +2781,13 @@ init_buffer_once () | |||
| 2540 | reset_buffer_local_variables (&buffer_defaults); | 2781 | reset_buffer_local_variables (&buffer_defaults); |
| 2541 | reset_buffer (&buffer_local_symbols); | 2782 | reset_buffer (&buffer_local_symbols); |
| 2542 | reset_buffer_local_variables (&buffer_local_symbols); | 2783 | reset_buffer_local_variables (&buffer_local_symbols); |
| 2784 | /* Prevent GC from getting confused. */ | ||
| 2785 | buffer_defaults.text = &buffer_defaults.own_text; | ||
| 2786 | buffer_local_symbols.text = &buffer_local_symbols.own_text; | ||
| 2787 | #ifdef USE_TEXT_PROPERTIES | ||
| 2788 | BUF_INTERVALS (&buffer_defaults) = 0; | ||
| 2789 | BUF_INTERVALS (&buffer_local_symbols) = 0; | ||
| 2790 | #endif | ||
| 2543 | XSETBUFFER (Vbuffer_defaults, &buffer_defaults); | 2791 | XSETBUFFER (Vbuffer_defaults, &buffer_defaults); |
| 2544 | XSETBUFFER (Vbuffer_local_symbols, &buffer_local_symbols); | 2792 | XSETBUFFER (Vbuffer_local_symbols, &buffer_local_symbols); |
| 2545 | 2793 | ||
| @@ -3124,10 +3372,12 @@ is a member of the list."); | |||
| 3124 | defsubr (&Sget_buffer); | 3372 | defsubr (&Sget_buffer); |
| 3125 | defsubr (&Sget_file_buffer); | 3373 | defsubr (&Sget_file_buffer); |
| 3126 | defsubr (&Sget_buffer_create); | 3374 | defsubr (&Sget_buffer_create); |
| 3375 | defsubr (&Smake_indirect_buffer); | ||
| 3127 | defsubr (&Sgenerate_new_buffer_name); | 3376 | defsubr (&Sgenerate_new_buffer_name); |
| 3128 | defsubr (&Sbuffer_name); | 3377 | defsubr (&Sbuffer_name); |
| 3129 | /*defsubr (&Sbuffer_number);*/ | 3378 | /*defsubr (&Sbuffer_number);*/ |
| 3130 | defsubr (&Sbuffer_file_name); | 3379 | defsubr (&Sbuffer_file_name); |
| 3380 | defsubr (&Sbuffer_base_buffer); | ||
| 3131 | defsubr (&Sbuffer_local_variables); | 3381 | defsubr (&Sbuffer_local_variables); |
| 3132 | defsubr (&Sbuffer_modified_p); | 3382 | defsubr (&Sbuffer_modified_p); |
| 3133 | defsubr (&Sset_buffer_modified_p); | 3383 | defsubr (&Sset_buffer_modified_p); |