Function: gnus-group-change-level
gnus-group-change-level is a byte-compiled function defined in
gnus-start.el.gz.
Signature
(gnus-group-change-level ENTRY LEVEL &optional OLDLEVEL PREVIOUS FROMKILLED)
Documentation
Change level of group ENTRY to LEVEL.
This is the fundamental function for changing subscription levels
of newsgroups. This might mean just changing from level 1 to 2,
which is pretty trivial, from 2 to 6 or back again, which
subscribes/unsubscribes a group, which is equally trivial.
Changing from 1-7 to 8-9 means that you kill a group, and from
8-9 to 1-7 means that you remove the group from the list of
killed (or zombie) groups and add them to the (kinda) subscribed
groups. And last but not least, moving from 8 to 9 and 9 to 8,
which is trivial. ENTRY can either be a string (newsgroup name)
or a list (if FROMKILLED is t, it's a list on the format (NUM
INFO-LIST), otherwise it's a list in the format of the
gnus-newsrc-hashtb entries. LEVEL is the new level of the
group, OLDLEVEL is the old level and PREVIOUS is the group (a
string name) to insert this group before.
Source Code
;; Defined in /usr/src/emacs/lisp/gnus/gnus-start.el.gz
(defun gnus-group-change-level (entry level &optional oldlevel
previous fromkilled)
"Change level of group ENTRY to LEVEL.
This is the fundamental function for changing subscription levels
of newsgroups. This might mean just changing from level 1 to 2,
which is pretty trivial, from 2 to 6 or back again, which
subscribes/unsubscribes a group, which is equally trivial.
Changing from 1-7 to 8-9 means that you kill a group, and from
8-9 to 1-7 means that you remove the group from the list of
killed (or zombie) groups and add them to the (kinda) subscribed
groups. And last but not least, moving from 8 to 9 and 9 to 8,
which is trivial. ENTRY can either be a string (newsgroup name)
or a list (if FROMKILLED is t, it's a list on the format (NUM
INFO-LIST), otherwise it's a list in the format of the
`gnus-newsrc-hashtb' entries. LEVEL is the new level of the
group, OLDLEVEL is the old level and PREVIOUS is the group (a
string name) to insert this group before."
;; Glean what info we can from the arguments.
(let ((group (if (consp entry)
(if fromkilled (nth 1 entry) (car (nth 1 entry)))
entry))
info active num)
(when (and (stringp entry)
oldlevel
(< oldlevel gnus-level-zombie))
(setq entry (gnus-group-entry entry)))
(setq oldlevel (if (and (not oldlevel)
(consp entry))
(gnus-info-level (nth 1 entry))
(or oldlevel gnus-level-killed)))
;; This table is used for completion, so put a dummy entry there.
(unless (gethash group gnus-active-hashtb)
(setf (gethash group gnus-active-hashtb) nil))
;; Group is already subscribed.
(unless (and (>= oldlevel gnus-level-zombie)
(gnus-group-entry group))
(unless (gnus-ephemeral-group-p group)
(gnus-dribble-enter
(format "(gnus-group-change-level %S %S %S %S %S)"
group level oldlevel
(when previous
(cadr (member previous gnus-group-list)))
fromkilled)))
;; Then we remove the newgroup from any old structures, if needed.
;; If the group was killed, we remove it from the killed or zombie
;; list. If not, and it is in fact going to be killed, we remove
;; it from the newsrc hash table and assoc.
(cond
((>= oldlevel gnus-level-zombie)
;; oldlevel could be wrong.
(setq gnus-zombie-list (delete group gnus-zombie-list))
(setq gnus-killed-list (delete group gnus-killed-list)))
(t
(when (and (>= level gnus-level-zombie)
entry)
(remhash (car (nth 1 entry)) gnus-newsrc-hashtb)
(setq gnus-group-list (remove group gnus-group-list))
(setq gnus-newsrc-alist (delq (assoc group gnus-newsrc-alist)
gnus-newsrc-alist)))))
;; Finally we enter (if needed) the list where it is supposed to
;; go, and change the subscription level. If it is to be killed,
;; we enter it into the killed or zombie list.
(cond
((>= level gnus-level-zombie)
;; Remove from the hash table.
(remhash group gnus-newsrc-hashtb)
(setq gnus-group-list (remove group gnus-group-list))
(if (= level gnus-level-zombie)
(push group gnus-zombie-list)
(if (= oldlevel gnus-level-killed)
;; Remove from active hashtb.
(remhash group gnus-active-hashtb)
;; Don't add it into killed-list if it was killed.
(push group gnus-killed-list))))
(t
;; If the list is to be entered into the newsrc assoc, and
;; it was killed, we have to create an entry in the newsrc
;; hashtb format and fix the pointers in the newsrc assoc.
(if (< oldlevel gnus-level-zombie)
;; It was alive, and it is going to stay alive, so we
;; just change the level and don't change any pointers or
;; hash table entries.
(setcar (cdadr entry) level)
(if (listp entry)
(setq info (cdr entry)
num (car entry))
(setq active (gnus-active group))
(setq num
(if active (- (1+ (cdr active)) (car active)) t))
(let ((method (gnus-method-simplify
(or gnus-override-subscribe-method
(gnus-group-method group)))))
(setq info (gnus-info-make group level nil nil method))))
;; Add group. The exact ordering only matters for
;; `gnus-group-list', though we need to keep the dummy group
;; at the head of `gnus-newsrc-alist'.
(push info (cdr gnus-newsrc-alist))
(puthash group (list num info) gnus-newsrc-hashtb)
(when (and previous (stringp previous))
(setq previous (gnus-group-entry previous)))
(let ((idx (or (and previous
(seq-position gnus-group-list (caadr previous)))
(length gnus-group-list))))
(push group (nthcdr idx gnus-group-list)))
(gnus-dribble-enter
(format "(gnus-group-set-info '%S)" info)
(concat "^(gnus-group-set-info '(\"" (regexp-quote group) "\"")))))
(when gnus-group-change-level-function
(funcall gnus-group-change-level-function
group level oldlevel previous)))))