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)))))