+(defun nnfolder-open-nov (group)
+ (or (cdr (assoc group nnfolder-nov-buffer-alist))
+ (let ((buffer (get-buffer-create (format " *nnfolder overview %s*" group))))
+ (with-current-buffer buffer
+ (set (make-local-variable 'nnfolder-nov-buffer-file-name)
+ (nnfolder-group-nov-pathname group))
+ (erase-buffer)
+ (when (file-exists-p nnfolder-nov-buffer-file-name)
+ (nnheader-insert-file-contents nnfolder-nov-buffer-file-name)))
+ (push (cons group buffer) nnfolder-nov-buffer-alist)
+ buffer)))
+
+(defun nnfolder-save-nov ()
+ (save-excursion
+ (while nnfolder-nov-buffer-alist
+ (when (buffer-name (cdar nnfolder-nov-buffer-alist))
+ (set-buffer (cdar nnfolder-nov-buffer-alist))
+ (when (buffer-modified-p)
+ (gnus-make-directory (file-name-directory
+ nnfolder-nov-buffer-file-name))
+ (nnmail-write-region 1 (point-max) nnfolder-nov-buffer-file-name
+ nil 'nomesg))
+ (set-buffer-modified-p nil)
+ (kill-buffer (current-buffer)))
+ (setq nnfolder-nov-buffer-alist (cdr nnfolder-nov-buffer-alist)))))
+
+(defun nnfolder-nov-delete-article (group article)
+ (with-current-buffer (nnfolder-open-nov group)
+ (when (nnheader-find-nov-line article)
+ (delete-region (point) (progn (forward-line 1) (point))))
+ t))
+
+(defun nnfolder-retrieve-headers-with-nov (articles &optional fetch-old)
+ (if (or gnus-nov-is-evil nnfolder-nov-is-evil)
+ nil
+ (let ((nov (nnfolder-group-nov-pathname nnfolder-current-group)))
+ (when (file-exists-p nov)
+ (with-current-buffer nntp-server-buffer
+ (erase-buffer)
+ (nnheader-insert-file-contents nov)
+ (if (and fetch-old
+ (not (numberp fetch-old)))
+ t ; Don't remove anything.
+ (nnheader-nov-delete-outside-range
+ (if fetch-old (max 1 (- (car articles) fetch-old))
+ (car articles))
+ (car (last articles)))
+ t))))))
+
+(defun nnfolder-parse-head (&optional number b e)
+ "Parse the head of the current buffer."
+ (let ((buf (current-buffer))
+ chars)
+ (save-excursion
+ (unless b
+ (setq b (if (nnmail-search-unix-mail-delim-backward)
+ (point) (point-min)))
+ (forward-line 1)
+ (setq e (if (nnmail-search-unix-mail-delim)
+ (point) (point-max))))
+ (setq chars (- e b))
+ (unless (zerop chars)
+ (goto-char b)
+ (if (search-forward "\n\n" e t) (setq e (1- (point)))))
+ (with-temp-buffer
+ (insert-buffer-substring buf b e)
+ (let ((headers (nnheader-parse-naked-head)))
+ (mail-header-set-chars headers chars)
+ (mail-header-set-number headers number)
+ headers)))))
+
+(defun nnfolder-add-nov (group article headers)
+ "Add a nov line for the GROUP base."
+ (with-current-buffer (nnfolder-open-nov group)
+ (goto-char (point-max))
+ (mail-header-set-number headers article)
+ (nnheader-insert-nov headers)))
+
+(deffoo nnfolder-request-set-mark (group actions &optional server)
+ (when (and server
+ (not (nnfolder-server-opened server)))
+ (nnfolder-open-server server))
+ (unless nnfolder-marks-is-evil
+ (nnfolder-open-marks group server)
+ (setq nnfolder-marks (nnheader-update-marks-actions nnfolder-marks actions))
+ (nnfolder-save-marks group server))
+ nil)
+
+(deffoo nnfolder-request-marks (group info &optional server)
+ ;; Change servers.
+ (when (and server
+ (not (nnfolder-server-opened server)))
+ (nnfolder-open-server server))
+ (when (and (not nnfolder-marks-is-evil) (nnfolder-marks-changed-p group))
+ (nnheader-message 8 "Updating marks for %s..." group)
+ (nnfolder-open-marks group server)
+ ;; Update info using `nnfolder-marks'.
+ (mapc (lambda (pred)
+ (unless (memq (cdr pred) gnus-article-unpropagated-mark-lists)
+ (gnus-info-set-marks
+ info
+ (gnus-update-alist-soft
+ (cdr pred)
+ (cdr (assq (cdr pred) nnfolder-marks))
+ (gnus-info-marks info))
+ t)))
+ gnus-article-mark-lists)
+ (let ((seen (cdr (assq 'read nnfolder-marks))))
+ (gnus-info-set-read info
+ (if (and (integerp (car seen))
+ (null (cdr seen)))
+ (list (cons (car seen) (car seen)))
+ seen)))
+ (nnheader-message 8 "Updating marks for %s...done" group))
+ info)
+
+(defun nnfolder-group-marks-pathname (group)
+ "Make pathname for GROUP NOV."
+ (let ((nnfolder-directory (or nnfolder-marks-directory nnfolder-directory)))
+ (concat (nnfolder-group-pathname group) nnfolder-marks-file-suffix)))
+
+(defun nnfolder-marks-changed-p (group)
+ (let ((file (nnfolder-group-marks-pathname group)))
+ (if (null (gnus-gethash file nnfolder-marks-modtime))
+ t ;; never looked at marks file, assume it has changed
+ (not (equal (gnus-gethash file nnfolder-marks-modtime)
+ (nth 5 (file-attributes file)))))))
+
+(defun nnfolder-save-marks (group server)
+ (let ((file-name-coding-system nnmail-pathname-coding-system)
+ (file (nnfolder-group-marks-pathname group)))
+ (condition-case err
+ (progn
+ (with-temp-file file
+ (erase-buffer)
+ (gnus-prin1 nnfolder-marks)
+ (insert "\n"))
+ (gnus-sethash file
+ (nth 5 (file-attributes file))
+ nnfolder-marks-modtime))
+ (error (or (gnus-yes-or-no-p
+ (format "Could not write to %s (%s). Continue? " file err))
+ (error "Cannot write to %s (%s)" file err))))))
+
+(defun nnfolder-open-marks (group server)
+ (let ((file (nnfolder-group-marks-pathname group)))
+ (if (file-exists-p file)
+ (condition-case err
+ (with-temp-buffer
+ (gnus-sethash file (nth 5 (file-attributes file))
+ nnfolder-marks-modtime)
+ (nnheader-insert-file-contents file)
+ (setq nnfolder-marks (read (current-buffer)))
+ (dolist (el gnus-article-unpropagated-mark-lists)
+ (setq nnfolder-marks (gnus-remassoc el nnfolder-marks))))
+ (error (or (gnus-yes-or-no-p
+ (format "Error reading nnfolder marks file %s (%s). Continuing will use marks from .newsrc.eld. Continue? " file err))
+ (error "Cannot read nnfolder marks file %s (%s)" file err))))
+ ;; User didn't have a .marks file. Probably first time
+ ;; user of the .marks stuff. Bootstrap it from .newsrc.eld.
+ (let ((info (gnus-get-info
+ (gnus-group-prefixed-name
+ group
+ (gnus-server-to-method (format "nnfolder:%s" server))))))
+ (nnheader-message 7 "Bootstrapping marks for %s..." group)
+ (setq nnfolder-marks (gnus-info-marks info))
+ (push (cons 'read (gnus-info-read info)) nnfolder-marks)
+ (dolist (el gnus-article-unpropagated-mark-lists)
+ (setq nnfolder-marks (gnus-remassoc el nnfolder-marks)))
+ (nnfolder-save-marks group server)
+ (nnheader-message 7 "Bootstrapping marks for %s...done" group)))))
+