aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDmitry Antipov2012-07-19 12:56:53 +0400
committerDmitry Antipov2012-07-19 12:56:53 +0400
commit9cd47b72e021f76a6e2481d986ce4b0cb0b859d3 (patch)
tree73912e8be2147fe90acf8f5dd20bb1c238d354df /src
parent1d6fc0df363db43f2c1db696fad40f068287500b (diff)
downloademacs-9cd47b72e021f76a6e2481d986ce4b0cb0b859d3.tar.gz
emacs-9cd47b72e021f76a6e2481d986ce4b0cb0b859d3.zip
Compact buffers when idle.
* lisp/compact.el: New file. * src/buffer.c (compact_buffer, Fcompact_buffer): New function. (syms_of_buffer): Register Fcompact_buffer. * src/alloc.c (Fgarbage_collect): Use compact_buffer. * src/buffer.h (compact_buffer): New prototype. (struct buffer_text): New member.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog9
-rw-r--r--src/alloc.c28
-rw-r--r--src/buffer.c61
-rw-r--r--src/buffer.h4
4 files changed, 67 insertions, 35 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 73632c26bff..7a0942f9c7e 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,14 @@
12012-07-19 Dmitry Antipov <dmantipov@yandex.ru> 12012-07-19 Dmitry Antipov <dmantipov@yandex.ru>
2 2
3 Buffer compaction primitive which may be used from Lisp.
4 * buffer.c (compact_buffer, Fcompact_buffer): New function.
5 (syms_of_buffer): Register Fcompact_buffer.
6 * alloc.c (Fgarbage_collect): Use compact_buffer.
7 * buffer.h (compact_buffer): New prototype.
8 (struct buffer_text): New member.
9
102012-07-19 Dmitry Antipov <dmantipov@yandex.ru>
11
3 New macro to iterate over all buffers, miscellaneous cleanups. 12 New macro to iterate over all buffers, miscellaneous cleanups.
4 * lisp.h (all_buffers): Remove declaration. 13 * lisp.h (all_buffers): Remove declaration.
5 * buffer.h (all_buffers): Add declaration, with comment. 14 * buffer.h (all_buffers): Add declaration, with comment.
diff --git a/src/alloc.c b/src/alloc.c
index 166f5b72449..233137e368e 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -5413,33 +5413,7 @@ See Info node `(elisp)Garbage Collection'. */)
5413 /* Don't keep undo information around forever. 5413 /* Don't keep undo information around forever.
5414 Do this early on, so it is no problem if the user quits. */ 5414 Do this early on, so it is no problem if the user quits. */
5415 for_each_buffer (nextb) 5415 for_each_buffer (nextb)
5416 { 5416 compact_buffer (nextb);
5417 /* If a buffer's undo list is Qt, that means that undo is
5418 turned off in that buffer. Calling truncate_undo_list on
5419 Qt tends to return NULL, which effectively turns undo back on.
5420 So don't call truncate_undo_list if undo_list is Qt. */
5421 if (! NILP (nextb->BUFFER_INTERNAL_FIELD (name))
5422 && ! EQ (nextb->BUFFER_INTERNAL_FIELD (undo_list), Qt))
5423 truncate_undo_list (nextb);
5424
5425 /* Shrink buffer gaps, but skip indirect and dead buffers. */
5426 if (nextb->base_buffer == 0 && !NILP (nextb->BUFFER_INTERNAL_FIELD (name))
5427 && ! nextb->text->inhibit_shrinking)
5428 {
5429 /* If a buffer's gap size is more than 10% of the buffer
5430 size, or larger than 2000 bytes, then shrink it
5431 accordingly. Keep a minimum size of 20 bytes. */
5432 int size = min (2000, max (20, (nextb->text->z_byte / 10)));
5433
5434 if (nextb->text->gap_size > size)
5435 {
5436 struct buffer *save_current = current_buffer;
5437 current_buffer = nextb;
5438 make_gap (-(nextb->text->gap_size - size));
5439 current_buffer = save_current;
5440 }
5441 }
5442 }
5443 5417
5444 t1 = current_emacs_time (); 5418 t1 = current_emacs_time ();
5445 5419
diff --git a/src/buffer.c b/src/buffer.c
index 40370460b9f..0fc5dd0b9c3 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -1434,14 +1434,59 @@ No argument or nil as argument means do this for the current buffer. */)
1434 return Qnil; 1434 return Qnil;
1435} 1435}
1436 1436
1437/* 1437/* Truncate undo list and shrink the gap of BUFFER. */
1438 DEFVAR_LISP ("kill-buffer-hook", ..., "\ 1438
1439Hook to be run (by `run-hooks', which see) when a buffer is killed.\n\ 1439int
1440The buffer being killed will be current while the hook is running.\n\ 1440compact_buffer (struct buffer *buffer)
1441{
1442 /* Skip dead buffers, indirect buffers and buffers
1443 which aren't changed since last compaction. */
1444 if (!NILP (buffer->BUFFER_INTERNAL_FIELD (name))
1445 && (buffer->base_buffer == NULL)
1446 && (buffer->text->compact != buffer->text->modiff))
1447 {
1448 /* If a buffer's undo list is Qt, that means that undo is
1449 turned off in that buffer. Calling truncate_undo_list on
1450 Qt tends to return NULL, which effectively turns undo back on.
1451 So don't call truncate_undo_list if undo_list is Qt. */
1452 if (!EQ (buffer->BUFFER_INTERNAL_FIELD (undo_list), Qt))
1453 truncate_undo_list (buffer);
1454
1455 /* Shrink buffer gaps. */
1456 if (!buffer->text->inhibit_shrinking)
1457 {
1458 /* If a buffer's gap size is more than 10% of the buffer
1459 size, or larger than 2000 bytes, then shrink it
1460 accordingly. Keep a minimum size of 20 bytes. */
1461 int size = min (2000, max (20, (buffer->text->z_byte / 10)));
1462
1463 if (buffer->text->gap_size > size)
1464 {
1465 struct buffer *save_current = current_buffer;
1466 current_buffer = buffer;
1467 make_gap (-(buffer->text->gap_size - size));
1468 current_buffer = save_current;
1469 }
1470 }
1471 buffer->text->compact = buffer->text->modiff;
1472 return 1;
1473 }
1474 return 0;
1475}
1476
1477DEFUN ("compact-buffer", Fcompact_buffer, Scompact_buffer, 0, 1, 0,
1478 doc: /* Compact BUFFER by truncating undo list and shrinking the gap.
1479If buffer is nil, compact current buffer. Compaction is performed
1480only if buffer was changed since last compaction. Return t if
1481buffer compaction was performed, and nil otherwise. */)
1482 (Lisp_Object buffer)
1483{
1484 if (NILP (buffer))
1485 XSETBUFFER (buffer, current_buffer);
1486 CHECK_BUFFER (buffer);
1487 return compact_buffer (XBUFFER (buffer)) ? Qt : Qnil;
1488}
1441 1489
1442Functions run by this hook are supposed to not change the current
1443buffer. See `kill-buffer'."
1444*/
1445DEFUN ("kill-buffer", Fkill_buffer, Skill_buffer, 0, 1, "bKill buffer: ", 1490DEFUN ("kill-buffer", Fkill_buffer, Skill_buffer, 0, 1, "bKill buffer: ",
1446 doc: /* Kill the buffer specified by BUFFER-OR-NAME. 1491 doc: /* Kill the buffer specified by BUFFER-OR-NAME.
1447The argument may be a buffer or the name of an existing buffer. 1492The argument may be a buffer or the name of an existing buffer.
@@ -5992,7 +6037,6 @@ and `bury-buffer-internal'. */);
5992 defsubr (&Smake_indirect_buffer); 6037 defsubr (&Smake_indirect_buffer);
5993 defsubr (&Sgenerate_new_buffer_name); 6038 defsubr (&Sgenerate_new_buffer_name);
5994 defsubr (&Sbuffer_name); 6039 defsubr (&Sbuffer_name);
5995/*defsubr (&Sbuffer_number);*/
5996 defsubr (&Sbuffer_file_name); 6040 defsubr (&Sbuffer_file_name);
5997 defsubr (&Sbuffer_base_buffer); 6041 defsubr (&Sbuffer_base_buffer);
5998 defsubr (&Sbuffer_local_value); 6042 defsubr (&Sbuffer_local_value);
@@ -6004,6 +6048,7 @@ and `bury-buffer-internal'. */);
6004 defsubr (&Srename_buffer); 6048 defsubr (&Srename_buffer);
6005 defsubr (&Sother_buffer); 6049 defsubr (&Sother_buffer);
6006 defsubr (&Sbuffer_enable_undo); 6050 defsubr (&Sbuffer_enable_undo);
6051 defsubr (&Scompact_buffer);
6007 defsubr (&Skill_buffer); 6052 defsubr (&Skill_buffer);
6008 defsubr (&Sbury_buffer_internal); 6053 defsubr (&Sbury_buffer_internal);
6009 defsubr (&Sset_buffer_major_mode); 6054 defsubr (&Sset_buffer_major_mode);
diff --git a/src/buffer.h b/src/buffer.h
index 8c596835fcc..6f090479a24 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -436,6 +436,9 @@ struct buffer_text
436 436
437 EMACS_INT overlay_modiff; /* Counts modifications to overlays. */ 437 EMACS_INT overlay_modiff; /* Counts modifications to overlays. */
438 438
439 EMACS_INT compact; /* Set to modiff each time when compact_buffer
440 is called for this buffer. */
441
439 /* Minimum value of GPT - BEG since last redisplay that finished. */ 442 /* Minimum value of GPT - BEG since last redisplay that finished. */
440 ptrdiff_t beg_unchanged; 443 ptrdiff_t beg_unchanged;
441 444
@@ -903,6 +906,7 @@ extern struct buffer buffer_local_symbols;
903 906
904extern void delete_all_overlays (struct buffer *); 907extern void delete_all_overlays (struct buffer *);
905extern void reset_buffer (struct buffer *); 908extern void reset_buffer (struct buffer *);
909extern int compact_buffer (struct buffer *);
906extern void evaporate_overlays (ptrdiff_t); 910extern void evaporate_overlays (ptrdiff_t);
907extern ptrdiff_t overlays_at (EMACS_INT pos, int extend, Lisp_Object **vec_ptr, 911extern ptrdiff_t overlays_at (EMACS_INT pos, int extend, Lisp_Object **vec_ptr,
908 ptrdiff_t *len_ptr, ptrdiff_t *next_ptr, 912 ptrdiff_t *len_ptr, ptrdiff_t *next_ptr,