)
]
-;; For Emacs < 22.2.
-(eval-and-compile
- (unless (fboundp 'declare-function) (defmacro declare-function (&rest r))))
-
-(eval-and-compile
- (require 'nnheader)
- (require 'gnus)
- (require 'gnus-util)
- (require 'gnus-range)
- (require 'gnus-start)
- (require 'gnus-int)
- (require 'message))
+(require 'nnheader)
+(require 'gnus)
+(require 'gnus-util)
+(require 'gnus-range)
+(require 'gnus-start)
+(require 'gnus-int)
+(require 'message)
+(require 'nnmail)
+
(eval-when-compile
- (require 'cl)
- (require 'nnmail))
+ (require 'cl))
(defconst nnmaildir-version "Gnus")
+(defconst nnmaildir-flag-mark-mapping
+ '((?F . tick)
+ (?P . forward)
+ (?R . reply)
+ (?S . read))
+ "Alist mapping Maildir filename flags to Gnus marks.
+Maildir filenames are of the form \"unique-id:2,FLAGS\",
+where FLAGS are a string of characters in ASCII order.
+Some of the FLAGS correspond to Gnus marks.")
+
+(defsubst nnmaildir--mark-to-flag (mark)
+ "Find the Maildir flag that corresponds to MARK (an atom).
+Return a character, or nil if not found.
+See `nnmaildir-flag-mark-mapping'."
+ (car (rassq mark nnmaildir-flag-mark-mapping)))
+
+(defsubst nnmaildir--flag-to-mark (flag)
+ "Find the Gnus mark that corresponds to FLAG (a character).
+Return an atom, or nil if not found.
+See `nnmaildir-flag-mark-mapping'."
+ (cdr (assq flag nnmaildir-flag-mark-mapping)))
+
+(defun nnmaildir--ensure-suffix (filename)
+ "Ensure that FILENAME contains the suffix \":2,\"."
+ (if (gnus-string-match-p ":2," filename)
+ filename
+ (concat filename ":2,")))
+
+(defun nnmaildir--add-flag (flag suffix)
+ "Return a copy of SUFFIX where FLAG is set.
+SUFFIX should start with \":2,\"."
+ (unless (gnus-string-match-p "^:2," suffix)
+ (error "Invalid suffix `%s'" suffix))
+ (let* ((flags (substring suffix 3))
+ (flags-as-list (append flags nil))
+ (new-flags
+ (concat (gnus-delete-duplicates
+ ;; maildir flags must be sorted
+ (sort (cons flag flags-as-list) '<)))))
+ (concat ":2," new-flags)))
+
+(defun nnmaildir--remove-flag (flag suffix)
+ "Return a copy of SUFFIX where FLAG is cleared.
+SUFFIX should start with \":2,\"."
+ (unless (gnus-string-match-p "^:2," suffix)
+ (error "Invalid suffix `%s'" suffix))
+ (let* ((flags (substring suffix 3))
+ (flags-as-list (append flags nil))
+ (new-flags (concat (delq flag flags-as-list))))
+ (concat ":2," new-flags)))
+
(defvar nnmaildir-article-file-name nil
"*The filename of the most recently requested article. This variable is set
by nnmaildir-request-article.")
(gnm nil) ;; flag: split from mail-sources?
(target-prefix nil :type string)) ;; symlink target prefix
+(defun nnmaildir--article-set-flags (article new-suffix curdir)
+ (let* ((prefix (nnmaildir--art-prefix article))
+ (suffix (nnmaildir--art-suffix article))
+ (article-file (concat curdir prefix suffix))
+ (new-name (concat curdir prefix new-suffix)))
+ (unless (file-exists-p article-file)
+ (error "Couldn't find article file %s" article-file))
+ (rename-file article-file new-name 'replace)
+ (setf (nnmaildir--art-suffix article) new-suffix)))
+
(defun nnmaildir--expired-article (group article)
(setf (nnmaildir--art-nov article) nil)
(let ((flist (nnmaildir--grp-flist group))
(eval param))
(defmacro nnmaildir--with-nntp-buffer (&rest body)
- `(save-excursion
- (set-buffer nntp-server-buffer)
+ (declare (debug (body)))
+ `(with-current-buffer nntp-server-buffer
,@body))
(defmacro nnmaildir--with-work-buffer (&rest body)
- `(save-excursion
- (set-buffer (get-buffer-create " *nnmaildir work*"))
+ (declare (debug (body)))
+ `(with-current-buffer (get-buffer-create " *nnmaildir work*")
,@body))
(defmacro nnmaildir--with-nov-buffer (&rest body)
- `(save-excursion
- (set-buffer (get-buffer-create " *nnmaildir nov*"))
+ (declare (debug (body)))
+ `(with-current-buffer (get-buffer-create " *nnmaildir nov*")
,@body))
(defmacro nnmaildir--with-move-buffer (&rest body)
- `(save-excursion
- (set-buffer (get-buffer-create " *nnmaildir move*"))
+ (declare (debug (body)))
+ `(with-current-buffer (get-buffer-create " *nnmaildir move*")
,@body))
-(defmacro nnmaildir--subdir (dir subdir)
- `(file-name-as-directory (concat ,dir ,subdir)))
-(defmacro nnmaildir--srvgrp-dir (srv-dir gname)
- `(nnmaildir--subdir ,srv-dir ,gname))
-(defmacro nnmaildir--tmp (dir) `(nnmaildir--subdir ,dir "tmp"))
-(defmacro nnmaildir--new (dir) `(nnmaildir--subdir ,dir "new"))
-(defmacro nnmaildir--cur (dir) `(nnmaildir--subdir ,dir "cur"))
-(defmacro nnmaildir--nndir (dir) `(nnmaildir--subdir ,dir ".nnmaildir"))
-(defmacro nnmaildir--nov-dir (dir) `(nnmaildir--subdir ,dir "nov"))
-(defmacro nnmaildir--marks-dir (dir) `(nnmaildir--subdir ,dir "marks"))
-(defmacro nnmaildir--num-dir (dir) `(nnmaildir--subdir ,dir "num"))
+(defsubst nnmaildir--subdir (dir subdir)
+ (file-name-as-directory (concat dir subdir)))
+(defsubst nnmaildir--srvgrp-dir (srv-dir gname)
+ (nnmaildir--subdir srv-dir gname))
+(defsubst nnmaildir--tmp (dir) (nnmaildir--subdir dir "tmp"))
+(defsubst nnmaildir--new (dir) (nnmaildir--subdir dir "new"))
+(defsubst nnmaildir--cur (dir) (nnmaildir--subdir dir "cur"))
+(defsubst nnmaildir--nndir (dir) (nnmaildir--subdir dir ".nnmaildir"))
+(defsubst nnmaildir--nov-dir (dir) (nnmaildir--subdir dir "nov"))
+(defsubst nnmaildir--marks-dir (dir) (nnmaildir--subdir dir "marks"))
+(defsubst nnmaildir--num-dir (dir) (nnmaildir--subdir dir "num"))
(defmacro nnmaildir--unlink (file-arg)
`(let ((file ,file-arg))
;; given group, if non-nil, be the current group of the current server. Then
;; return the group object for the current group.
(defun nnmaildir--prepare (server group)
- (let (x groups)
- (catch 'return
- (if (null server)
- (unless (setq server nnmaildir--cur-server)
- (throw 'return nil))
- (unless (setq server (intern-soft server nnmaildir--servers))
+ (catch 'return
+ (if (null server)
+ (unless (setq server nnmaildir--cur-server)
(throw 'return nil))
- (setq server (symbol-value server)
- nnmaildir--cur-server server))
- (unless (setq groups (nnmaildir--srv-groups server))
+ (unless (setq server (intern-soft server nnmaildir--servers))
(throw 'return nil))
- (unless (nnmaildir--srv-method server)
- (setq x (concat "nnmaildir:" (nnmaildir--srv-address server))
- x (gnus-server-to-method x))
- (unless x (throw 'return nil))
- (setf (nnmaildir--srv-method server) x))
- (if (null group)
- (unless (setq group (nnmaildir--srv-curgrp server))
- (throw 'return nil))
- (unless (setq group (intern-soft group groups))
- (throw 'return nil))
- (setq group (symbol-value group)))
- group)))
+ (setq server (symbol-value server)
+ nnmaildir--cur-server server))
+ (let ((groups (nnmaildir--srv-groups server)))
+ (when groups
+ (unless (nnmaildir--srv-method server)
+ (setf (nnmaildir--srv-method server)
+ (or (gnus-server-to-method
+ (concat "nnmaildir:" (nnmaildir--srv-address server)))
+ (throw 'return nil))))
+ (if (null group)
+ (nnmaildir--srv-curgrp server)
+ (symbol-value (intern-soft group groups)))))))
(defun nnmaildir--tab-to-space (string)
(let ((pos 0))
string)
(defmacro nnmaildir--condcase (errsym body &rest handler)
+ (declare (debug (sexp form body)))
`(condition-case ,errsym
(let ((system-messages-locale "C")) ,body)
(error . ,handler)))
(srv-dir (nnmaildir--srv-dir server))
(storage-version 1) ;; [version article-number msgid [...nov...]]
dir gname pgname msgdir prefix suffix file attr mtime novdir novfile
- nov msgid nov-beg nov-mid nov-end field val old-extra num numdir
+ nov msgid nov-beg nov-mid nov-end field val old-extra num
deactivate-mark)
(catch 'return
(setq gname (nnmaildir--grp-name group)
"/" "\\057" 'literal)
":" "\\072" 'literal))
-(defun nnmaildir-request-type (group &optional article)
+(defun nnmaildir-request-type (_group &optional _article)
'mail)
(defun nnmaildir-status-message (&optional server)
(if (> (aref a 1) (aref b 1)) (throw 'return nil))
(string-lessp (aref a 2) (aref b 2))))
-(defun nnmaildir--scan (gname scan-msgs groups method srv-dir srv-ls)
+(defun nnmaildir--scan (gname scan-msgs groups _method srv-dir srv-ls)
(catch 'return
(let ((36h-ago (- (car (current-time)) 2))
absdir nndir tdir ndir cdir nattr cattr isnew pgname read-only ls
(dolist (file (funcall ls ndir nil "\\`[^.]" 'nosort))
(setq x (concat ndir file))
(and (time-less-p (nth 5 (file-attributes x)) (current-time))
- (rename-file x (concat cdir file ":2,"))))
+ (rename-file x (concat cdir (nnmaildir--ensure-suffix file)))))
(setf (nnmaildir--grp-new group) nattr))
(setq cattr (nth 5 (file-attributes cdir)))
(if (equal cattr (nnmaildir--grp-cur group))
cdir (nnmaildir--marks-dir nndir)
ndir (nnmaildir--subdir cdir "tick")
cdir (nnmaildir--subdir cdir "read"))
- (dolist (file files)
- (setq file (car file))
- (if (or (not (file-exists-p (concat cdir file)))
- (file-exists-p (concat ndir file)))
- (setq num (1+ num)))))
+ (dolist (prefix-suffix files)
+ (let ((prefix (car prefix-suffix))
+ (suffix (cdr prefix-suffix)))
+ ;; increase num for each unread or ticked article
+ (when (or
+ ;; first look for marks in suffix, if it's valid...
+ (when (and (stringp suffix)
+ (gnus-string-prefix-p ":2," suffix))
+ (or
+ (not (gnus-string-match-p
+ (string (nnmaildir--mark-to-flag 'read)) suffix))
+ (gnus-string-match-p
+ (string (nnmaildir--mark-to-flag 'tick)) suffix)))
+ ;; then look in marks directories
+ (not (file-exists-p (concat cdir prefix)))
+ (file-exists-p (concat ndir prefix)))
+ (incf num)))))
(setf (nnmaildir--grp-cache group) (make-vector num nil))
(let ((inhibit-quit t))
(set (intern gname groups) group))
(setf (nnmaildir--grp-cur group) cattr)))
t))
+(defvar nnmaildir-get-new-mail)
+(defvar nnmaildir-group-alist)
+(defvar nnmaildir-active-file)
+
(defun nnmaildir-request-scan (&optional scan-group server)
(let ((coding-system-for-write nnheader-file-coding-system)
(buffer-file-coding-system nil)
(nnmaildir-get-new-mail t)
(nnmaildir-group-alist nil)
(nnmaildir-active-file nil)
- x srv-ls srv-dir method groups target-prefix group dirs grp-dir seen
+ x srv-ls srv-dir method groups target-prefix dirs seen
deactivate-mark)
(nnmaildir--prepare server nil)
(setq srv-ls (nnmaildir--srv-ls nnmaildir--cur-server)
(nnmaildir--srv-groups nnmaildir--cur-server))))
t)
-(defun nnmaildir-request-newgroups (date &optional server)
+(defun nnmaildir-request-newgroups (_date &optional server)
(nnmaildir-request-list server))
(defun nnmaildir-retrieve-groups (groups &optional server)
'group)
(defun nnmaildir-request-update-info (gname info &optional server)
- (let ((group (nnmaildir--prepare server gname))
- pgname flist always-marks never-marks old-marks dotfile num dir
- markdirs marks mark ranges markdir article read end new-marks ls
- old-mmth new-mmth mtime mark-sym existing missing deactivate-mark
- article-list)
+ (let* ((group (nnmaildir--prepare server gname))
+ (curdir (nnmaildir--cur
+ (nnmaildir--srvgrp-dir
+ (nnmaildir--srv-dir nnmaildir--cur-server) gname)))
+ (curdir-mtime (nth 5 (file-attributes curdir)))
+ pgname flist always-marks never-marks old-marks dir
+ all-marks marks ranges markdir read ls
+ old-mmth new-mmth mtime existing missing deactivate-mark)
(catch 'return
(unless group
(setf (nnmaildir--srv-error nnmaildir--cur-server)
dir (nnmaildir--nndir dir)
dir (nnmaildir--marks-dir dir)
ls (nnmaildir--group-ls nnmaildir--cur-server pgname)
- markdirs (funcall ls dir nil "\\`[^.]" 'nosort)
- new-mmth (nnmaildir--up2-1 (length markdirs))
+ all-marks (gnus-delete-duplicates
+ ;; get mark names from mark dirs and from flag
+ ;; mappings
+ (append
+ (mapcar 'cdr nnmaildir-flag-mark-mapping)
+ (mapcar 'intern (funcall ls dir nil "\\`[^.]" 'nosort))))
+ new-mmth (nnmaildir--up2-1 (length all-marks))
new-mmth (make-vector new-mmth 0)
old-mmth (nnmaildir--grp-mmth group))
- (dolist (mark markdirs)
- (setq markdir (nnmaildir--subdir dir mark)
- mark-sym (intern mark)
+ (dolist (mark all-marks)
+ (setq markdir (nnmaildir--subdir dir (symbol-name mark))
ranges nil)
(catch 'got-ranges
- (if (memq mark-sym never-marks) (throw 'got-ranges nil))
- (when (memq mark-sym always-marks)
+ (if (memq mark never-marks) (throw 'got-ranges nil))
+ (when (memq mark always-marks)
(setq ranges existing)
(throw 'got-ranges nil))
- (setq mtime (nth 5 (file-attributes markdir)))
- (set (intern mark new-mmth) mtime)
- (when (equal mtime (symbol-value (intern-soft mark old-mmth)))
- (setq ranges (assq mark-sym old-marks))
+ ;; Find the mtime for this mark. If this mark can be expressed as
+ ;; a filename flag, get the later of the mtimes for markdir and
+ ;; curdir, otherwise only the markdir counts.
+ (setq mtime
+ (let ((markdir-mtime (nth 5 (file-attributes markdir))))
+ (cond
+ ((null (nnmaildir--mark-to-flag mark))
+ markdir-mtime)
+ ((null markdir-mtime)
+ curdir-mtime)
+ ((null curdir-mtime)
+ ;; this should never happen...
+ markdir-mtime)
+ ((time-less-p markdir-mtime curdir-mtime)
+ curdir-mtime)
+ (t
+ markdir-mtime))))
+ (set (intern (symbol-name mark) new-mmth) mtime)
+ (when (equal mtime (symbol-value (intern-soft (symbol-name mark) old-mmth)))
+ (setq ranges (assq mark old-marks))
(if ranges (setq ranges (cdr ranges)))
(throw 'got-ranges nil))
- (setq article-list nil)
- (dolist (prefix (funcall ls markdir nil "\\`[^.]" 'nosort))
- (setq article (nnmaildir--flist-art flist prefix))
- (if article
- (setq article-list
- (cons (nnmaildir--art-num article) article-list))))
- (setq ranges (gnus-add-to-range ranges (sort article-list '<))))
- (if (eq mark-sym 'read) (setq read ranges)
- (if ranges (setq marks (cons (cons mark-sym ranges) marks)))))
+ (let ((article-list nil))
+ ;; Consider the article marked if it either has the flag in the
+ ;; filename, or is in the markdir. As you'd rarely remove a
+ ;; flag/mark, this should avoid losing information in the most
+ ;; common usage pattern.
+ (or
+ (let ((flag (nnmaildir--mark-to-flag mark)))
+ ;; If this mark has a corresponding maildir flag...
+ (when flag
+ (let ((regexp
+ (concat "\\`[^.].*:2,[A-Z]*" (string flag))))
+ ;; ...then find all files with that flag.
+ (dolist (filename (funcall ls curdir nil regexp 'nosort))
+ (let* ((prefix (car (split-string filename ":2,")))
+ (article (nnmaildir--flist-art flist prefix)))
+ (when article
+ (push (nnmaildir--art-num article) article-list)))))))
+ ;; Also check Gnus-specific mark directory, if it exists.
+ (when (file-directory-p markdir)
+ (dolist (prefix (funcall ls markdir nil "\\`[^.]" 'nosort))
+ (let ((article (nnmaildir--flist-art flist prefix)))
+ (when article
+ (push (nnmaildir--art-num article) article-list))))))
+ (setq ranges (gnus-add-to-range ranges (sort article-list '<)))))
+ (if (eq mark 'read) (setq read ranges)
+ (if ranges (setq marks (cons (cons mark ranges) marks)))))
(gnus-info-set-read info (gnus-range-add read missing))
(gnus-info-set-marks info marks 'extend)
(setf (nnmaildir--grp-mmth group) new-mmth)
info)))
-(defun nnmaildir-request-group (gname &optional server fast)
+(defun nnmaildir-request-group (gname &optional server fast _info)
(let ((group (nnmaildir--prepare server gname))
deactivate-mark)
(catch 'return
(insert " " (gnus-replace-in-string gname " " "\\ " t) "\n")
t))))
-(defun nnmaildir-request-create-group (gname &optional server args)
+(defun nnmaildir-request-create-group (gname &optional server _args)
(nnmaildir--prepare server nil)
(catch 'return
(let ((target-prefix (nnmaildir--srv-target-prefix nnmaildir--cur-server))
(defun nnmaildir-retrieve-headers (articles &optional gname server fetch-old)
(let ((group (nnmaildir--prepare server gname))
- srv-dir dir nlist mlist article num start stop nov nlist2 insert-nov
+ nlist mlist article num start stop nov insert-nov
deactivate-mark)
(setq insert-nov
(lambda (article)
(erase-buffer)
(setq mlist (nnmaildir--grp-mlist group)
nlist (nnmaildir--grp-nlist group)
- gname (nnmaildir--grp-name group)
- srv-dir (nnmaildir--srv-dir nnmaildir--cur-server)
- dir (nnmaildir--srvgrp-dir srv-dir gname))
+ gname (nnmaildir--grp-name group))
(cond
((null nlist))
((and fetch-old (not (numberp fetch-old)))
(setf (nnmaildir--srv-error nnmaildir--cur-server)
"Article has expired")
(throw 'return nil))
- (save-excursion
- (set-buffer (or to-buffer nntp-server-buffer))
+ (with-current-buffer (or to-buffer nntp-server-buffer)
(erase-buffer)
(nnheader-insert-file-contents nnmaildir-article-file-name))
(cons gname num-msgid))))
-(defun nnmaildir-request-post (&optional server)
+(defun nnmaildir-request-post (&optional _server)
(let (message-required-mail-headers)
(funcall message-send-mail-function)))
(setf (nnmaildir--srv-error nnmaildir--cur-server)
(concat "File exists: " tmpfile))
(throw 'return nil))
- (save-excursion
- (set-buffer buffer)
+ (with-current-buffer buffer
(gmm-write-region (point-min) (point-max) tmpfile nil 'no-message nil
'excl))
(unix-sync) ;; no fsync :(
t)))
(defun nnmaildir-request-move-article (article gname server accept-form
- &optional last move-is-internal)
+ &optional _last _move-is-internal)
(let ((group (nnmaildir--prepare server gname))
pgname suffix result nnmaildir--file deactivate-mark)
(catch 'return
(nnmaildir--expired-article group article))
result)))
-(defun nnmaildir-request-accept-article (gname &optional server last)
+(defun nnmaildir-request-accept-article (gname &optional server _last)
(let ((group (nnmaildir--prepare server gname))
(coding-system-for-write nnheader-file-coding-system)
(buffer-file-coding-system nil)
(error
(gmm-write-region (point-min) (point-max) tmpfile nil 'no-message nil
'excl)
- (unix-sync))) ;; no fsync :(
+ (when (fboundp 'unix-sync)
+ (unix-sync)))) ;; no fsync :(
(nnheader-cancel-timer 24h)
(condition-case err
(add-name-to-file tmpfile curfile)
ga))
group-art)))))
-(defun nnmaildir-active-number (gname)
+(defun nnmaildir-active-number (_gname)
0)
(declare-function gnus-group-mark-article-read "gnus-group" (group article))
(defun nnmaildir-request-expire-articles (ranges &optional gname server force)
(let ((no-force (not force))
(group (nnmaildir--prepare server gname))
- pgname time boundary bound-iter high low target dir nlist nlist2
- stop article didnt nnmaildir--file nnmaildir-article-file-name
+ pgname time boundary bound-iter high low target dir nlist
+ didnt nnmaildir--file nnmaildir-article-file-name
deactivate-mark)
(catch 'return
(unless group
(if (eq time 'immediate)
(setq time 0)
(if (numberp time)
- (setq time (* time 86400)))))
+ (setq time (round (* time 86400))))))
(when no-force
(unless (integerp time) ;; handle 'never
(throw 'return (gnus-uncompress-range ranges)))
(erase-buffer))
didnt)))
+(defvar nnmaildir--article)
+
(defun nnmaildir-request-set-mark (gname actions &optional server)
- (let ((group (nnmaildir--prepare server gname))
- (coding-system-for-write nnheader-file-coding-system)
- (buffer-file-coding-system nil)
- (file-coding-system-alist nil)
- del-mark del-action add-action set-action marksdir nlist
- ranges begin end article all-marks todo-marks mdir mfile
- pgname ls permarkfile deactivate-mark)
- (setq del-mark
+ (let* ((group (nnmaildir--prepare server gname))
+ (curdir (nnmaildir--cur
+ (nnmaildir--srvgrp-dir
+ (nnmaildir--srv-dir nnmaildir--cur-server)
+ gname)))
+ (coding-system-for-write nnheader-file-coding-system)
+ (buffer-file-coding-system nil)
+ (file-coding-system-alist nil)
+ marksdir nlist
+ ranges all-marks todo-marks mdir mfile
+ pgname ls permarkfile deactivate-mark
+ (del-mark
(lambda (mark)
- (setq mfile (nnmaildir--subdir marksdir (symbol-name mark))
- mfile (concat mfile (nnmaildir--art-prefix article)))
- (nnmaildir--unlink mfile))
- del-action (lambda (article) (mapcar del-mark todo-marks))
- add-action
+ (let ((prefix (nnmaildir--art-prefix nnmaildir--article))
+ (suffix (nnmaildir--art-suffix nnmaildir--article))
+ (flag (nnmaildir--mark-to-flag mark)))
+ (when flag
+ ;; If this mark corresponds to a flag, remove the flag from
+ ;; the file name.
+ (nnmaildir--article-set-flags
+ nnmaildir--article (nnmaildir--remove-flag flag suffix)
+ curdir))
+ ;; We still want to delete the hardlink in the marks dir if
+ ;; present, regardless of whether this mark has a maildir flag or
+ ;; not, to avoid getting out of sync.
+ (setq mfile (nnmaildir--subdir marksdir (symbol-name mark))
+ mfile (concat mfile prefix))
+ (nnmaildir--unlink mfile))))
+ (del-action (lambda (article)
+ (let ((nnmaildir--article article))
+ (mapcar del-mark todo-marks))))
+ (add-action
(lambda (article)
(mapcar
(lambda (mark)
- (setq mdir (nnmaildir--subdir marksdir (symbol-name mark))
- permarkfile (concat mdir ":")
- mfile (concat mdir (nnmaildir--art-prefix article)))
- (nnmaildir--condcase err (add-name-to-file permarkfile mfile)
- (cond
- ((nnmaildir--eexist-p err))
- ((nnmaildir--enoent-p err)
- (nnmaildir--mkdir mdir)
- (nnmaildir--mkfile permarkfile)
- (add-name-to-file permarkfile mfile))
- ((nnmaildir--emlink-p err)
- (let ((permarkfilenew (concat permarkfile "{new}")))
- (nnmaildir--mkfile permarkfilenew)
- (rename-file permarkfilenew permarkfile 'replace)
- (add-name-to-file permarkfile mfile)))
- (t (signal (car err) (cdr err))))))
- todo-marks))
- set-action (lambda (article)
- (funcall add-action)
- (mapcar (lambda (mark)
- (unless (memq mark todo-marks)
- (funcall del-mark mark)))
- all-marks)))
+ (let ((prefix (nnmaildir--art-prefix article))
+ (suffix (nnmaildir--art-suffix article))
+ (flag (nnmaildir--mark-to-flag mark)))
+ (if flag
+ ;; If there is a corresponding maildir flag, just rename
+ ;; the file.
+ (nnmaildir--article-set-flags
+ article (nnmaildir--add-flag flag suffix) curdir)
+ ;; Otherwise, use nnmaildir-specific marks dir.
+ (setq mdir (nnmaildir--subdir marksdir (symbol-name mark))
+ permarkfile (concat mdir ":")
+ mfile (concat mdir prefix))
+ (nnmaildir--condcase err (add-name-to-file permarkfile mfile)
+ (cond
+ ((nnmaildir--eexist-p err))
+ ((nnmaildir--enoent-p err)
+ (nnmaildir--mkdir mdir)
+ (nnmaildir--mkfile permarkfile)
+ (add-name-to-file permarkfile mfile))
+ ((nnmaildir--emlink-p err)
+ (let ((permarkfilenew (concat permarkfile "{new}")))
+ (nnmaildir--mkfile permarkfilenew)
+ (rename-file permarkfilenew permarkfile 'replace)
+ (add-name-to-file permarkfile mfile)))
+ (t (signal (car err) (cdr err))))))))
+ todo-marks)))
+ (set-action (lambda (article)
+ (funcall add-action article)
+ (let ((nnmaildir--article article))
+ (mapcar (lambda (mark)
+ (unless (memq mark todo-marks)
+ (funcall del-mark mark)))
+ all-marks)))))
(catch 'return
(unless group
(setf (nnmaildir--srv-error nnmaildir--cur-server)
pgname (nnmaildir--pgname nnmaildir--cur-server gname)
ls (nnmaildir--group-ls nnmaildir--cur-server pgname)
all-marks (funcall ls marksdir nil "\\`[^.]" 'nosort)
- all-marks (mapcar 'intern all-marks))
+ all-marks (gnus-delete-duplicates
+ ;; get mark names from mark dirs and from flag
+ ;; mappings
+ (append
+ (mapcar 'cdr nnmaildir-flag-mark-mapping)
+ (mapcar 'intern all-marks))))
(dolist (action actions)
(setq ranges (car action)
todo-marks (caddr action))
(dolist (mark todo-marks)
- (add-to-list 'all-marks mark))
+ (pushnew mark all-marks :test #'equal))
(if (numberp (cdr ranges)) (setq ranges (list ranges)))
(nnmaildir--nlist-iterate nlist ranges
(cond ((eq 'del (cadr action)) del-action)
((eq 'add (cadr action)) add-action)
- (t set-action))))
+ ((eq 'set (cadr action)) set-action))))
nil)))
(defun nnmaildir-close-group (gname &optional server)
t)))
(defun nnmaildir-close-server (&optional server)
+ (defvar flist) (defvar ls) (defvar dirs) (defvar dir)
+ (defvar files) (defvar file) (defvar x)
(let (flist ls dirs dir files file x)
(nnmaildir--prepare server nil)
(when nnmaildir--cur-server