Skip to content

Instantly share code, notes, and snippets.

@offby1
Created December 29, 2009 02:12
Show Gist options
  • Select an option

  • Save offby1/265101 to your computer and use it in GitHub Desktop.

Select an option

Save offby1/265101 to your computer and use it in GitHub Desktop.
;; in ~/.emacs.el ...
(load "reaper")
;; reaper.el
(if (fboundp 'buffer-creation-time)
(progn
(defun kill-them-buffers ()
(mapc
(lambda (p)
(flet ((time->string
(time)
(format-seconds "%Y, %D, %H, %M, %z%S" (float-time time))))
(let ((victim (get-buffer (car p))))
(when victim
;; if the buffer is not old enough, spare its life.
(let ((allotted-lifespan (cdr p))
(age (time-subtract
(current-time)
(with-current-buffer victim
;; Ideally we'd consider the
;; last-modification time of the buffer
;; too, and kill it only if _both_ those
;; times are old. But we don't keep
;; track of that time (yet :-).
(buffer-creation-time)))))
(if (time-less-p allotted-lifespan age)
(progn
;; if it's displayed in some window, nix the window.
(let ((window-victim (get-buffer-window victim t)))
(while window-victim
(delete-window window-victim)
(setq window-victim (get-buffer-window victim t))))
(message "Killing buffer %s -- it's %s old (which is more than %s)!!"
victim
(time->string age)
(time->string allotted-lifespan))
(kill-buffer victim))
(message "Spared buffer %s -- it's only %s old"
victim
(time->string age))))))))
;; These are buffers whose names make them likely to get in my
;; way when I'm looking for some other, similarly-named,
;; buffer. Ido probably makes this problem worse.
`(
;; Times are pairs of (HIGH LOW) seconds; see 'current-time'
("*Completions*" . (0 3))
("*Shell Command Output*" . (0 120))
("*vc-diff*" . (0 60))
)))
(setq *reaper-timer*
(run-with-idle-timer 5 t 'kill-them-buffers))
(when nil
(cancel-timer *reaper-timer*)))
(message "There's no function named buffer-creation-time, so I cannot start the reaper."))
;; Apply this patch
commit 6bc11c1aede88bf4bfbb8a1eea9f429446b93072
Author: Eric Hanchrow <erich@cozi.com>
Date: Sat Aug 22 13:56:51 2009 -0700
buffer.c: new function "buffer-creation-time"
diff --git a/src/buffer.c b/src/buffer.c
index 580d5f0..2ef0ac1 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -361,6 +361,8 @@ even if it is dead. The return value is never nil. */)
b->text = &b->own_text;
b->base_buffer = 0;
+ b->creation_time = time (NULL);
+
BUF_GAP_SIZE (b) = 20;
BLOCK_INPUT;
/* We allocate extra 1-byte at the tail and keep it always '\0' for
@@ -682,8 +684,8 @@ delete_all_overlays (b)
eassert (b->overlays_after == NULL);
}
-/* Reinitialize everything about a buffer except its name and contents
- and local variables.
+/* Reinitialize everything about a buffer except its name, contents,
+ local variables, and creation time.
If called on an already-initialized buffer, the list of overlays
should be deleted before calling this function, otherwise we end up
with overlays that claim to belong to the buffer but the buffer
@@ -724,6 +726,13 @@ reset_buffer (b)
b->display_error_modiff = 0;
}
+DEFUN ("buffer-creation-time", Fbuffer_creation_time, Sbuffer_creation_time,
+ 0, 0, 0, doc: /* Return the time the current buffer was created. */)
+ ()
+{
+ return make_time ((time_t) current_buffer->creation_time);
+}
+
/* Reset buffer B's local variables info.
Don't use this on a buffer that has already been in use;
it does not treat permanent locals consistently.
@@ -2203,7 +2212,7 @@ DEFUN ("buffer-swap-text", Fbuffer_swap_text, Sbuffer_swap_text,
other_buffer = XBUFFER (buffer);
if (NILP (other_buffer->name))
- error ("Cannot swap a dead buffer's text");
+ error ("Cannot swap a dead buffer's text");
/* Actually, it probably works just fine.
* if (other_buffer == current_buffer)
@@ -4350,7 +4359,7 @@ add_overlay_mod_hooklist (functionlist, overlay)
int oldsize = XVECTOR (last_overlay_modification_hooks)->size;
if (last_overlay_modification_hooks_used == oldsize)
- last_overlay_modification_hooks = larger_vector
+ last_overlay_modification_hooks = larger_vector
(last_overlay_modification_hooks, oldsize * 2, Qnil);
ASET (last_overlay_modification_hooks, last_overlay_modification_hooks_used,
functionlist); last_overlay_modification_hooks_used++;
@@ -6284,6 +6293,7 @@ The function `kill-all-local-variables' runs this before doing anything else. *
defsubr (&Sget_file_buffer);
defsubr (&Sget_buffer_create);
defsubr (&Smake_indirect_buffer);
+ defsubr (&Sbuffer_creation_time);
defsubr (&Sgenerate_new_buffer_name);
defsubr (&Sbuffer_name);
/*defsubr (&Sbuffer_number);*/
diff --git a/src/buffer.h b/src/buffer.h
index 7e6e8da..e861091 100644
--- a/src/buffer.h
+++ b/src/buffer.h
@@ -509,6 +509,8 @@ struct buffer
0 means visited file modtime unknown; in no case complain
about any mismatch on next save attempt. */
int modtime;
+ /* Set once when the buffer is created; not changed thereafter. */
+ int creation_time;
/* The value of text->modiff at the last auto-save. */
int auto_save_modified;
/* The value of text->modiff at the last display error.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment