branch: elpa/gc-buffers commit 5593630e62ee5a272005aabbc62fa36747b88b8f Author: Akib Azmain Turja <a...@disroot.org> Commit: Akib Azmain Turja <a...@disroot.org>
Add buffer killer and option to kill elisp-flymake buffers --- README.org | 43 ++++++++++++++++++++++ gc-buffers.el | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 156 insertions(+) diff --git a/README.org b/README.org new file mode 100644 index 0000000000..7b9b5ef335 --- /dev/null +++ b/README.org @@ -0,0 +1,43 @@ +#+title: GC Buffers - Kill garbage buffer + +There are many packages that create temporary buffers but don't kill those +buffers, either because they don't do that or any unhandled error prevents +it from doing that. Over time, these "garbage" buffer can pile up and eat +up your memory. For example, there were 1359 garbage buffers created by +Flymake Emacs Lisp byte compiler backend over 5 days, which ate up half of +my memory. + +This package's purpose is to clear them automatically, so you can use your +memory to edit more files, run more commands and to use other programs. + +* Installation + +~gc-buffers~ isn't available on any ELPA right now. So, you must follow +one of the following methods: + +** Quelpa + +#+begin_src emacs-lisp +(quelpa '(gc-buffers + :fetcher git + :url "https://codeberg.org/akib/emacs-gc-buffers.git")) +#+end_src + +** Straight.el + +#+begin_src emacs-lisp +(straight-use-package + '(gc-buffers :type git + :repo "https://codeberg.org/akib/emacs-gc-buffers.git")) +#+end_src + +** Manual + +Download the ~gc-buffers.el~ file and put it in your ~load-path~. + +* Usage + +Clean garbage buffers with =M-x gc-buffers=. To enable automatically +doing this, do =M-x gc-buffers-mode=. + +Don't let buggy packages to make Emacs "Emacs Makes A Computer Slow"! diff --git a/gc-buffers.el b/gc-buffers.el new file mode 100644 index 0000000000..2995e1d6a4 --- /dev/null +++ b/gc-buffers.el @@ -0,0 +1,113 @@ +;;; gc-buffers.el --- Kill garbage buffers automatically -*- lexical-binding: t; -*- + +;; Copyright (C) 2022 Akib Azmain Turja. + +;; Author: Akib Azmain Turja <a...@disroot.org> +;; Created: 2022-05-20 +;; Version: 0.1 +;; Package-Requires: ((emacs "24.1")) +;; Keywords: internal +;; Homepage: https://codeberg.org/akib/emacs-gc-buffers + +;; This file is not part of GNU Emacs. + +;; This file 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, or (at your option) +;; any later version. + +;; This program 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. + +;; For a full copy of the GNU General Public License +;; see <https://www.gnu.org/licenses/>. + +;;; Commentary: + +;; There are many packages that create temporary buffers but don't kill +;; those buffers, either because they don't do that or any unhandled error +;; prevents it from doing that. Over time, these "garbage" buffer can be +;; pile up and eat up your memory. For example, there were 1359 garbage +;; buffers created by Flymake Emacs Lisp byte compiler backend over 5 days, +;; which ate up half of my memory. + +;; This package's purpose is to clear them automatically, so you can use +;; your memory to edit more files, run more commands and to use other +;; programs. + +;; Clean garbage buffers with M-x gc-buffers. To enable automatically +;; doing this, do M-x gc-buffers-mode. + +;; Don't let buggy packages to make Emacs "Emacs Makes A Computer Slow"! + +;;; Code: + +(defgroup gc-buffers nil + "Kill garbage buffers automatically." + :group 'internal + :link '(url-link "https://codeberg.org/akib/emacs-gc-buffers") + :prefix "gc-buffers-") + +(defcustom gc-buffers-functions (list #'gc-buffers-elisp-flymake) + "Functions to find garbage buffers. + +Each function is called with the buffer to test, and if any of the +functions returns non-nil, kill that buffer. The functions should not have +any side-effect. + +Warning: Putting wrong functions here may delete working buffers. For +example, never put `always' here, that would delete all buffers." + :type 'hook + :options (list #'gc-buffers-elisp-flymake)) + +(defcustom gc-buffers-delay 60 + "Kill garbage buffers after idling for this many seconds." + :type 'number) + +;;;###autoload +(defun gc-buffers () + "Kill garbage buffers." + (interactive) + (while-no-input + (let ((inhibit-quit (called-interactively-p 'interactive)) + (kill-buffer-query-functions nil) + (count 0)) + (dolist (buffer (buffer-list)) + (when (and (not (get-buffer-window buffer 'all-frames)) + (run-hook-with-args-until-success 'gc-buffers-functions + buffer)) + (kill-buffer buffer) + (setq count (1+ count)))) + (when (called-interactively-p 'interactive) + (message "%s garbage buffer%s killed" + (if (zerop count) "No" (number-to-string count)) + (if (> count 1) "s" "")))))) + +(defun gc-buffers-elisp-flymake (buffer) + "Kill garbage buffers generated by `elisp-flymake-byte-compile'. + +Test if BUFFER is a garbage generated by `elisp-flymake-byte-compile'." + (and (string-match-p (rx string-start " *elisp-flymake-byte-compile*" + (zero-or-one "-" (zero-or-more digit)) + string-end) + (buffer-name buffer)) + (not (get-buffer-process buffer)))) + +(defvar gc-buffers--idle-timer nil) + +;;;###autoload +(define-minor-mode gc-buffers-mode + "Toggle killing garbage buffers automatically." + :global t + :lighter " GC-Buffers" + (when gc-buffers--idle-timer + (cancel-timer gc-buffers--idle-timer) + (setq gc-buffers--idle-timer nil)) + (when gc-buffers-mode + (setq gc-buffers--idle-timer + (run-with-idle-timer gc-buffers-delay t #'gc-buffers)))) + +(provide 'gc-buffers) +;;; gc-buffers.el ends here