[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Reappearing marks--a clue!



Hi,

I think I've discovered why certain marks reappear.  I'm not (yet) sure
what to do about it...maybe it will be obvious to somebody.  Or at least
somebody can tell me whether I'm on the right track :)

Environment:  nnimap 0.97, pgnus 0.80 (with nnimap patches applied), GNU
              Emacs 20.3.2 

The problem:  None of my ticks go away if I untick all ticked articles in an
              nnimap group.  It *looks* like it works until I re-enter the
              group--then the ticks reappear.

              Say I have three articles ticked in a group.  If I untick any
              two of them everything works as expected.  If I untick *all*
              of them, *all* of the ticks come back when I re-enter the
              group.

Why oh why:   gnus-update-marks only calls <backend>-request-set-mark for a
              mark-type if gnus-newsgroup-<mark-type> is non-nil.  And when
              you untick all articles in a group, gnus-newsgroup-marked is
              set to nil.

              I guess that this doesn't matter for nnml (and other) groups
              because Gnus keeps track of marks in newsrc-alist.  But it's
              crucial for nnimap because it considers the marks set on the
              server to be authoratitive.

What to do:   If there's an obvious way to fix this, let me know!
              Otherwise I'll try to come up with something.

Many thanks!

Here's gnus-update-marks for your browsing pleasure:

(defun gnus-update-marks ()
  "Enter the various lists of marked articles into the newsgroup info list."
  (let ((types gnus-article-mark-lists)
	(info (gnus-get-info gnus-newsgroup-name))
	(uncompressed '(score bookmark killed))
	type list newmarked symbol delta-marks)
    (when info
      ;; Add all marks lists that are non-nil to the list of marks lists.
      (while (setq type (pop types))
	(when (setq list (symbol-value
			  (setq symbol
				(intern (format "gnus-newsgroup-%s"
						(car type))))))

	  ;; Get rid of the entries of the articles that have the
	  ;; default score.
	  (when (and (eq (cdr type) 'score)
		     gnus-save-score
		     list)
	    (let* ((arts list)
		   (prev (cons nil list))
		   (all prev))
	      (while arts
		(if (or (not (consp (car arts)))
			(= (cdar arts) gnus-summary-default-score))
		    (setcdr prev (cdr arts))
		  (setq prev arts))
		(setq arts (cdr arts)))
	      (setq list (cdr all))))

         (when (gnus-check-backend-function 'request-set-mark
                                            gnus-newsgroup-name)
           ;; score & bookmark are not proper flags (they are cons cells)
           ;; cache is a internal gnus flag
           (unless (memq (cdr type) '(cache score bookmark))
             (let* ((old (cdr (assq (cdr type) (gnus-info-marks info))))
                    (del (gnus-remove-from-range old list))
                    (add (gnus-remove-from-range list old)))
               (if add
                   (push (list add 'add (list (cdr type))) delta-marks))
               (if del
                   (push (list del 'del (list (cdr type))) delta-marks)))))

	  (push (cons (cdr type)
		      (if (memq (cdr type) uncompressed) list
			(gnus-compress-sequence
			 (set symbol (sort list '<)) t)))
		newmarked)))

      (if delta-marks
         (gnus-request-set-mark gnus-newsgroup-name delta-marks))

      ;; Enter these new marks into the info of the group.
      (if (nthcdr 3 info)
	  (setcar (nthcdr 3 info) newmarked)
	;; Add the marks lists to the end of the info.
	(when newmarked
	  (setcdr (nthcdr 2 info) (list newmarked))))

      ;; Cut off the end of the info if there's nothing else there.
      (let ((i 5))
	(while (and (> i 2)
		    (not (nth i info)))
	  (when (nthcdr (decf i) info)
	    (setcdr (nthcdr i info) nil)))))))

-- 
Mark Plaksin                                http://www.arches.uga.edu/~happy/