
Gnus has used obarrays as makeshift hash tables for groups: group names are coerced to unibyte and interned in custom obarrays, and their symbol-value set to whatever value needs to be stored. This patch replaces those obarrays with actual hash tables. * lisp/gnus/gnus-util.el (gnus-intern-safe, gnus-create-hash-size): Remove functions. (gnus-make-hashtable): Change to return a real hash table. (gnus-text-property-search): Utility similar to `text-property-any', but compares on `equal'. Needed because the 'gnus-group text property is now a string. * lisp/gnus/gnus.el (gnus-gethash, gnus-gethash-safe, gnus-sethash): Remove macros. (gnus-group-list): New variable holding all group names as an ordered list. Used because `gnus-newsrc-hashtb' used to preserve `gnus-newsrc-alist' ordering, but now doesn't. * lisp/gnus/nnmaildir.el (nnmaildir--servers): Change from obarray to alist. (nnmaildir--up2-1): Remove function. * lisp/thingatpt.el (thing-at-point-newsgroup-p): This was making use of Gnus obarrays, replace with a cond that can handle many different possibilities. * lisp/gnus/gnus-bcklg.el (gnus-backlog-articles): Remove gnus-backlog-hashtb, which wasn't doing anything. Just keep a list of ident strings in gnus-backlog-articles. (gnus-backlog-setup): Delete unnecessary function. (gnus-backlog-enter-article, gnus-backlog-remove-oldest-article, gnus-backlog-remove-article, gnus-backlog-request-article): Alter calls accordingly. * lisp/gnus/gnus-dup.el (gnus-duplicate-list-max-length): Rename from `gnus-duplicate-list-length', for accuracy. * lisp/gnus/gnus-start.el (gnus-active-to-gnus-format, gnus-groups-to-gnus-format, gnus-newsrc-to-gnus-format): Read group names as strings. (gnus-gnus-to-quick-newsrc-format): Write `gnus-newsrc-alist' using the ordering in `gnus-group-list'. * lisp/gnus/gnus-agent.el: * lisp/gnus/gnus-async.el: * lisp/gnus/gnus-cache.el: * lisp/gnus/gnus-group.el: * lisp/gnus/gnus-score.el: * lisp/gnus/gnus-sum.el: * lisp/gnus/gnus-topic.el: * lisp/gnus/message.el: * lisp/gnus/mml.el: * lisp/gnus/nnagent.el: * lisp/gnus/nnbabyl.el: * lisp/gnus/nnvirtual.el: * lisp/gnus/nnweb.el: In all files, change obarrays to hash-tables, and swap `gnus-sethash' for `puthash', `gnus-gethash' for `gethash', `mapatoms' for `maphash', etc. * test/lisp/gnus/gnus-test-headers.el (gnus-headers-make-dependency-table, gnus-headers-loop-dependencies): New tests to make sure we're building `gnus-newsgroup-dependencies' correctly.
141 lines
4.7 KiB
EmacsLisp
141 lines
4.7 KiB
EmacsLisp
;;; gnus-bcklg.el --- backlog functions for Gnus
|
|
|
|
;; Copyright (C) 1996-2019 Free Software Foundation, Inc.
|
|
|
|
;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
|
|
;; Keywords: news
|
|
|
|
;; 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 <https://www.gnu.org/licenses/>.
|
|
|
|
;;; Commentary:
|
|
|
|
;; The backlog caches the text of a certain number of read articles in
|
|
;; a separate buffer, so they can be retrieved quickly if the user
|
|
;; opens them again. Also see `gnus-keep-backlog'.
|
|
|
|
;;; Code:
|
|
|
|
(require 'gnus)
|
|
|
|
(defvar gnus-backlog-buffer " *Gnus Backlog*")
|
|
(defvar gnus-backlog-articles '())
|
|
|
|
(defun gnus-backlog-buffer ()
|
|
"Return the backlog buffer."
|
|
(or (get-buffer gnus-backlog-buffer)
|
|
(with-current-buffer (gnus-get-buffer-create gnus-backlog-buffer)
|
|
(buffer-disable-undo)
|
|
(setq buffer-read-only t)
|
|
(get-buffer gnus-backlog-buffer))))
|
|
|
|
(gnus-add-shutdown 'gnus-backlog-shutdown 'gnus)
|
|
|
|
(defun gnus-backlog-shutdown ()
|
|
"Clear all backlog variables and buffers."
|
|
(interactive)
|
|
(when (get-buffer gnus-backlog-buffer)
|
|
(gnus-kill-buffer gnus-backlog-buffer))
|
|
(setq gnus-backlog-articles nil))
|
|
|
|
(defun gnus-backlog-enter-article (group number buffer)
|
|
(when (and (numberp number)
|
|
(not (gnus-virtual-group-p group)))
|
|
(let ((ident (format "%s:%d" group number))
|
|
b)
|
|
(unless (member ident gnus-backlog-articles) ; It's already kept.
|
|
;; Remove the oldest article, if necessary.
|
|
(and (numberp gnus-keep-backlog)
|
|
(>= (length gnus-backlog-articles) gnus-keep-backlog)
|
|
(gnus-backlog-remove-oldest-article))
|
|
(push ident gnus-backlog-articles)
|
|
;; Insert the new article.
|
|
(with-current-buffer (gnus-backlog-buffer)
|
|
(let (buffer-read-only)
|
|
(goto-char (point-max))
|
|
(unless (bolp)
|
|
(insert "\n"))
|
|
(setq b (point))
|
|
(insert-buffer-substring buffer)
|
|
;; Tag the beginning of the article with the ident.
|
|
(if (> (point-max) b)
|
|
(put-text-property b (1+ b) 'gnus-backlog ident)
|
|
(gnus-error 3 "Article %d is blank" number))))))))
|
|
|
|
(defun gnus-backlog-remove-oldest-article ()
|
|
(with-current-buffer (gnus-backlog-buffer)
|
|
(goto-char (point-min))
|
|
(unless (zerop (buffer-size)) ; The buffer is empty.
|
|
(let ((ident (get-text-property (point) 'gnus-backlog))
|
|
buffer-read-only)
|
|
;; Remove the ident from the list of articles.
|
|
(when ident
|
|
(setq gnus-backlog-articles
|
|
(delete ident gnus-backlog-articles)))
|
|
;; Delete the article itself.
|
|
(delete-region
|
|
(point) (next-single-property-change
|
|
(1+ (point)) 'gnus-backlog nil (point-max)))))))
|
|
|
|
(defun gnus-backlog-remove-article (group number)
|
|
"Remove article NUMBER in GROUP from the backlog."
|
|
(when (numberp number)
|
|
(let ((ident (format "%s:%d" group number))
|
|
beg)
|
|
(when (member ident gnus-backlog-articles)
|
|
;; It was in the backlog.
|
|
(with-current-buffer (gnus-backlog-buffer)
|
|
(save-excursion
|
|
(let (buffer-read-only)
|
|
(goto-char (point-min))
|
|
(when (setq beg (gnus-text-property-search
|
|
'gnus-backlog ident))
|
|
;; Find the end (i. e., the beginning of the next article).
|
|
(goto-char
|
|
(next-single-property-change
|
|
(1+ beg) 'gnus-backlog (current-buffer) (point-max)))
|
|
(delete-region beg (point))
|
|
;; Return success.
|
|
t)))
|
|
(setq gnus-backlog-articles
|
|
(delete ident gnus-backlog-articles)))))))
|
|
|
|
(defun gnus-backlog-request-article (group number &optional buffer)
|
|
(when (and (numberp number)
|
|
(not (gnus-virtual-group-p group)))
|
|
(let ((ident (format "%s:%d" group number))
|
|
beg end)
|
|
(when (member ident gnus-backlog-articles)
|
|
;; It was in the backlog.
|
|
(with-current-buffer (gnus-backlog-buffer)
|
|
(if (not (setq beg (gnus-text-property-search
|
|
'gnus-backlog ident)))
|
|
;; It wasn't in the backlog after all.
|
|
(ignore
|
|
(setq gnus-backlog-articles
|
|
(delete ident gnus-backlog-articles)))
|
|
;; Find the end (i. e., the beginning of the next article).
|
|
(setq end
|
|
(next-single-property-change
|
|
(1+ beg) 'gnus-backlog (current-buffer) (point-max)))))
|
|
(with-current-buffer (or buffer (current-buffer))
|
|
(let ((inhibit-read-only t))
|
|
(erase-buffer)
|
|
(insert-buffer-substring gnus-backlog-buffer beg end)))
|
|
t))))
|
|
|
|
(provide 'gnus-bcklg)
|
|
|
|
;;; gnus-bcklg.el ends here
|