From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Stefan Monnier Newsgroups: gmane.emacs.devel Subject: Re: [Emacs-diffs] /srv/bzr/emacs/trunk r109157: Compact buffers when idle. Date: Thu, 19 Jul 2012 06:00:42 -0400 Message-ID: References: NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: dough.gmane.org 1342692069 30013 80.91.229.3 (19 Jul 2012 10:01:09 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Thu, 19 Jul 2012 10:01:09 +0000 (UTC) Cc: emacs-devel@gnu.org To: Dmitry Antipov Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Thu Jul 19 12:01:08 2012 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1SrnXe-0001pR-9X for ged-emacs-devel@m.gmane.org; Thu, 19 Jul 2012 12:01:06 +0200 Original-Received: from localhost ([::1]:38768 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SrnXd-0005Xl-KW for ged-emacs-devel@m.gmane.org; Thu, 19 Jul 2012 06:01:05 -0400 Original-Received: from eggs.gnu.org ([208.118.235.92]:39463) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SrnXV-0005XO-AU for emacs-devel@gnu.org; Thu, 19 Jul 2012 06:01:03 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SrnXO-0002AS-Kk for emacs-devel@gnu.org; Thu, 19 Jul 2012 06:00:57 -0400 Original-Received: from pruche.dit.umontreal.ca ([132.204.246.22]:35079) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SrnXO-0002AO-GD for emacs-devel@gnu.org; Thu, 19 Jul 2012 06:00:50 -0400 Original-Received: from fmsmemgm.homelinux.net (lechon.iro.umontreal.ca [132.204.27.242]) by pruche.dit.umontreal.ca (8.14.1/8.14.1) with ESMTP id q6JA0hKT006181; Thu, 19 Jul 2012 06:00:44 -0400 Original-Received: by fmsmemgm.homelinux.net (Postfix, from userid 20848) id 959D2AECB5; Thu, 19 Jul 2012 06:00:42 -0400 (EDT) In-Reply-To: (Dmitry Antipov's message of "Thu, 19 Jul 2012 12:56:53 +0400") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.1.50 (gnu/linux) X-NAI-Spam-Flag: NO X-NAI-Spam-Threshold: 5 X-NAI-Spam-Score: 0 X-NAI-Spam-Rules: 1 Rules triggered RV4283=0 X-NAI-Spam-Version: 2.2.0.9309 : core <4283> : streams <787133> : uri <1169205> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 132.204.246.22 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:151755 Archived-At: As mentioned in my previous email, I think that the `compact' field of struct buffer already provides most of the benefits and we don't need the Elisp/idle part of this patch. Stefan >>>>> "Dmitry" == Dmitry Antipov writes: > ------------------------------------------------------------ > revno: 109157 > committer: Dmitry Antipov > branch nick: trunk > timestamp: Thu 2012-07-19 12:56:53 +0400 > message: > 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. > added: > lisp/compact.el > modified: > lisp/ChangeLog > src/ChangeLog > src/alloc.c > src/buffer.c > src/buffer.h > === modified file 'lisp/ChangeLog' > --- a/lisp/ChangeLog 2012-07-19 06:24:04 +0000 > +++ b/lisp/ChangeLog 2012-07-19 08:56:53 +0000 > @@ -1,3 +1,8 @@ > +2012-07-19 Dmitry Antipov > + > + Compact buffers when idle. > + * compact.el: New file. > + > 2012-07-19 Stefan Monnier > * subr.el (eventp): Presume that if it looks vaguely like an event, > === added file 'lisp/compact.el' > --- a/lisp/compact.el 1970-01-01 00:00:00 +0000 > +++ b/lisp/compact.el 2012-07-19 08:56:53 +0000 > @@ -0,0 +1,60 @@ > +;;; compact.el --- compact buffers when idle > + > +;; Copyright (C) 2012 Free Software Foundation, Inc. > + > +;; Maintainer: FSF > +;; Package: emacs > + > +;; This file is part of GNU Emacs. > + > +;; GNU Emacs is free software: you can redistribute it and/or modify > +;; it under the terms of the GNU General Public License as published by > +;; the Free Software Foundation, either version 3 of the License, or > +;; (at your option) any later version. > + > +;; GNU Emacs is distributed in the hope that it will be useful, > +;; but WITHOUT ANY WARRANTY; without even the implied warranty of > +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > +;; GNU General Public License for more details. > + > +;; You should have received a copy of the GNU General Public License > +;; along with GNU Emacs. If not, see . > + > +;;; Commentary: > + > +;; This package provides the ability to compact buffers when Emacs is idle. > +;; Initially written by Dmitry Antipov . > + > +;;; Code: > + > +(require 'timer) > + > +(defun compact-buffers () > + "Run `compact-buffer' for each buffer except current buffer. > +Schedule next compaction if `compact-buffers-when-idle' is greater than zero." > + (mapc (lambda (buffer) > + (and (not (eq buffer (current-buffer))) > + (compact-buffer buffer))) > + (buffer-list)) > + (compact-buffers-idle)) > + > +(defun compact-buffers-idle () > + "Compact buffers if `compact-buffers-when-idle' is greater than zero." > + (and (floatp compact-buffers-when-idle) > + (> compact-buffers-when-idle 0.0) > + (run-with-idle-timer compact-buffers-when-idle nil 'compact-buffers))) > + > +(defcustom compact-buffers-when-idle 1.0 > + "Compact all buffers when Emacs is idle more than this period of time. > +Compaction is done by truncating `buffer-undo-list' and shrinking the gap. > +Value less than or equal to zero disables idle compaction." > + :type 'float > + :group 'alloc > + :set (lambda (symbol value) > + (progn (set-default symbol value) > + (compact-buffers-idle))) > + :version "24.2") > + > +(provide 'compact) > + > +;;; compact.el ends here > === modified file 'src/ChangeLog' > --- a/src/ChangeLog 2012-07-19 03:55:59 +0000 > +++ b/src/ChangeLog 2012-07-19 08:56:53 +0000 > @@ -1,5 +1,14 @@ > 2012-07-19 Dmitry Antipov > + Buffer compaction primitive which may be used from Lisp. > + * buffer.c (compact_buffer, Fcompact_buffer): New function. > + (syms_of_buffer): Register Fcompact_buffer. > + * alloc.c (Fgarbage_collect): Use compact_buffer. > + * buffer.h (compact_buffer): New prototype. > + (struct buffer_text): New member. > + > +2012-07-19 Dmitry Antipov > + > New macro to iterate over all buffers, miscellaneous cleanups. > * lisp.h (all_buffers): Remove declaration. > * buffer.h (all_buffers): Add declaration, with comment. > === modified file 'src/alloc.c' > --- a/src/alloc.c 2012-07-19 03:55:59 +0000 > +++ b/src/alloc.c 2012-07-19 08:56:53 +0000 > @@ -5413,33 +5413,7 @@ > /* Don't keep undo information around forever. > Do this early on, so it is no problem if the user quits. */ > for_each_buffer (nextb) > - { > - /* If a buffer's undo list is Qt, that means that undo is > - turned off in that buffer. Calling truncate_undo_list on > - Qt tends to return NULL, which effectively turns undo back on. > - So don't call truncate_undo_list if undo_list is Qt. */ > - if (! NILP (nextb->BUFFER_INTERNAL_FIELD (name)) > - && ! EQ (nextb->BUFFER_INTERNAL_FIELD (undo_list), Qt)) > - truncate_undo_list (nextb); > - > - /* Shrink buffer gaps, but skip indirect and dead buffers. */ > - if (nextb->base_buffer == 0 && !NILP (nextb->BUFFER_INTERNAL_FIELD (name)) > - && ! nextb->text->inhibit_shrinking) > - { > - /* If a buffer's gap size is more than 10% of the buffer > - size, or larger than 2000 bytes, then shrink it > - accordingly. Keep a minimum size of 20 bytes. */ > - int size = min (2000, max (20, (nextb->text->z_byte / 10))); > - > - if (nextb->text->gap_size > size) > - { > - struct buffer *save_current = current_buffer; > - current_buffer = nextb; > - make_gap (-(nextb->text->gap_size - size)); > - current_buffer = save_current; > - } > - } > - } > + compact_buffer (nextb); > t1 = current_emacs_time (); > === modified file 'src/buffer.c' > --- a/src/buffer.c 2012-07-19 03:55:59 +0000 > +++ b/src/buffer.c 2012-07-19 08:56:53 +0000 > @@ -1434,14 +1434,59 @@ > return Qnil; > } > -/* > - DEFVAR_LISP ("kill-buffer-hook", ..., "\ > -Hook to be run (by `run-hooks', which see) when a buffer is killed.\n\ > -The buffer being killed will be current while the hook is running.\n\ > - > -Functions run by this hook are supposed to not change the current > -buffer. See `kill-buffer'." > -*/ > +/* Truncate undo list and shrink the gap of BUFFER. */ > + > +int > +compact_buffer (struct buffer *buffer) > +{ > + /* Skip dead buffers, indirect buffers and buffers > + which aren't changed since last compaction. */ > + if (!NILP (buffer->BUFFER_INTERNAL_FIELD (name)) > + && (buffer->base_buffer == NULL) > + && (buffer->text->compact != buffer->text->modiff)) > + { > + /* If a buffer's undo list is Qt, that means that undo is > + turned off in that buffer. Calling truncate_undo_list on > + Qt tends to return NULL, which effectively turns undo back on. > + So don't call truncate_undo_list if undo_list is Qt. */ > + if (!EQ (buffer->BUFFER_INTERNAL_FIELD (undo_list), Qt)) > + truncate_undo_list (buffer); > + > + /* Shrink buffer gaps. */ > + if (!buffer->text->inhibit_shrinking) > + { > + /* If a buffer's gap size is more than 10% of the buffer > + size, or larger than 2000 bytes, then shrink it > + accordingly. Keep a minimum size of 20 bytes. */ > + int size = min (2000, max (20, (buffer->text->z_byte / 10))); > + > + if (buffer->text->gap_size > size) > + { > + struct buffer *save_current = current_buffer; > + current_buffer = buffer; > + make_gap (-(buffer->text->gap_size - size)); > + current_buffer = save_current; > + } > + } > + buffer->text->compact = buffer->text->modiff; > + return 1; > + } > + return 0; > +} > + > +DEFUN ("compact-buffer", Fcompact_buffer, Scompact_buffer, 0, 1, 0, > + doc: /* Compact BUFFER by truncating undo list and shrinking the gap. > +If buffer is nil, compact current buffer. Compaction is performed > +only if buffer was changed since last compaction. Return t if > +buffer compaction was performed, and nil otherwise. */) > + (Lisp_Object buffer) > +{ > + if (NILP (buffer)) > + XSETBUFFER (buffer, current_buffer); > + CHECK_BUFFER (buffer); > + return compact_buffer (XBUFFER (buffer)) ? Qt : Qnil; > +} > + > DEFUN ("kill-buffer", Fkill_buffer, Skill_buffer, 0, 1, "bKill buffer: ", > doc: /* Kill the buffer specified by BUFFER-OR-NAME. > The argument may be a buffer or the name of an existing buffer. > @@ -5992,7 +6037,6 @@ > defsubr (&Smake_indirect_buffer); > defsubr (&Sgenerate_new_buffer_name); > defsubr (&Sbuffer_name); > -/*defsubr (&Sbuffer_number);*/ > defsubr (&Sbuffer_file_name); > defsubr (&Sbuffer_base_buffer); > defsubr (&Sbuffer_local_value); > @@ -6004,6 +6048,7 @@ > defsubr (&Srename_buffer); > defsubr (&Sother_buffer); > defsubr (&Sbuffer_enable_undo); > + defsubr (&Scompact_buffer); > defsubr (&Skill_buffer); > defsubr (&Sbury_buffer_internal); > defsubr (&Sset_buffer_major_mode); > === modified file 'src/buffer.h' > --- a/src/buffer.h 2012-07-19 03:55:59 +0000 > +++ b/src/buffer.h 2012-07-19 08:56:53 +0000 > @@ -436,6 +436,9 @@ > EMACS_INT overlay_modiff; /* Counts modifications to overlays. */ > + EMACS_INT compact; /* Set to modiff each time when compact_buffer > + is called for this buffer. */ > + > /* Minimum value of GPT - BEG since last redisplay that finished. */ > ptrdiff_t beg_unchanged; > @@ -903,6 +906,7 @@ > > extern void delete_all_overlays (struct buffer *); > extern void reset_buffer (struct buffer *); > +extern int compact_buffer (struct buffer *); > extern void evaporate_overlays (ptrdiff_t); > extern ptrdiff_t overlays_at (EMACS_INT pos, int extend, Lisp_Object **vec_ptr, > ptrdiff_t *len_ptr, ptrdiff_t *next_ptr, > _______________________________________________ > Emacs-diffs mailing list > Emacs-diffs@gnu.org > https://lists.gnu.org/mailman/listinfo/emacs-diffs