;;; Virtual folders for VM;;; Copyright (C) 1990-1997 Kyle E. Jones;;;;;; This program is free software; you can redistribute it and/or modify;;; it under the terms of the GNU General Public License as published by;;; the Free Software Foundation; either version 1, or (at your option);;; any later version.;;;;;; This program is distributed in the hope that it will be useful,;;; but WITHOUT ANY WARRANTY; without even the implied warranty of;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the;;; GNU General Public License for more details.;;;;;; You should have received a copy of the GNU General Public License;;; along with this program; if not, write to the Free Software;;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.(provide'vm-virtual)(defunvm-build-virtual-message-list(new-messages&optionaldont-finalize)"Builds a list of messages matching the virtual folder definitionstored in the variable vm-virtual-folder-definition.If the NEW-MESSAGES argument is nil, the message list isderived from the folders listed in the virtual folderdefinition and selected by the various selectors. Theresulting message list is assigned to vm-message-list unlessDONT-FINALIZE is non-nil.If NEW-MESSAGES is non-nil then it is a list of messages tobe tried against the selector parts of the virtual folderdefinition. Matching messages are added to vm-message-list,instead of replacing it.The messages in the NEW-MESSAGES list, if any, must all be in thesame real folder.The list of matching virtual messages is returned.If DONT-FINALIZE is nil, in addition to vm-message-list beingset, the virtual messages are added to the virtual messagelists of their real messages, the current buffer is added tovm-virtual-buffers list of each real folder buffer representedin the virtual list, and vm-real-buffers is set to a list ofall the real folder buffers involved."(let((clauses(cdrvm-virtual-folder-definition))(message-set(make-vector3110))(vbuffer(current-buffer))(mirroredvm-virtual-mirror)(case-fold-searcht)(tail-cons(ifdont-finalizenil(vm-lastvm-message-list)))(new-message-listnil)virtuallocation-vectormessagempfoldersfolderselectorssel-listselectorarglistireal-buffers-used)(ifdont-finalizenil;; Since there is at most one virtual message in the folder;; buffer of a virtual folder, the location data vector (and;; the markers in it) of all virtual messages in a virtual;; folder is shared. We initialize the vector here if it;; hasn't been created already.(ifvm-message-list(setqlocation-vector(vm-location-data-of(carvm-message-pointer)))(setqi0location-vector(make-vectorvm-location-data-vector-lengthnil))(while(<ivm-location-data-vector-length)(asetlocation-vectori(vm-markernil))(vm-incrementi)));; To keep track of the messages in a virtual folder to;; prevent duplicates we create and maintain a set that;; contain all the real messages.(setqmpvm-message-list)(whilemp(intern(vm-message-id-number-of(vm-real-message-of(carmp)))message-set)(setqmp(cdrmp))));; now select the messages(save-excursion(whileclauses(setqfolders(car(carclauses))selectors(cdr(carclauses)))(whilefolders(setqfolder(carfolders))(and(stringpfolder)(setqfolder(expand-file-namefoldervm-folder-directory)))(and(listpfolder)(setqfolder(evalfolder)))(cond((nullfolder);; folder was a s-expr which returned nil;; skip itnil)((and(stringpfolder)(file-directory-pfolder))(setqfolders(nconcfolders(vm-delete-backup-file-names(vm-delete-auto-save-file-names(vm-delete-directory-file-names(directory-filesfoldertnil)))))))((or(nullnew-messages);; If we're assimilating messages into an;; existing virtual folder, only allow selectors;; that would be normally applied to this folder.(and(bufferpfolder)(eq(vm-buffer-of(carnew-messages))folder))(and(stringpfolder)(eq(vm-buffer-of(carnew-messages));; letter bomb protection;; set inhibit-local-variables to t for v18 Emacses;; set enable-local-variables to nil;; for newer Emacses(let((inhibit-local-variablest)(enable-local-evalnil)(enable-local-variablesnil))(find-file-noselectfolder)))))(set-buffer(or(and(bufferpfolder)folder)(vm-get-file-bufferfolder)(let((inhibit-local-variablest)(enable-local-evalnil)(enable-local-variablesnil))(find-file-noselectfolder))))(if(eqmajor-mode'vm-virtual-mode)(setqvirtualtreal-buffers-used(appendvm-real-buffersreal-buffers-used))(setqvirtualnil)(if(not(memq(current-buffer)real-buffers-used))(setqreal-buffers-used(cons(current-buffer)real-buffers-used)))(if(not(eqmajor-mode'vm-mode))(vm-mode)));; change (sexpr) into ("/file" "/file2" ...);; this assumes that there will never be (sexpr sexpr2);; in a virtual folder spec.(if(bufferpfolder)(ifvirtual(setcar(carclauses)(delqnil(mapcar'buffer-file-namevm-real-buffers)))(ifbuffer-file-name(setcar(carclauses)(listbuffer-file-name)))));; if new-messages non-nil use it instead of the;; whole message list(setqmp(ornew-messagesvm-message-list))(whilemp(if(and(ordont-finalize(not(intern-soft(vm-message-id-number-of(vm-real-message-of(carmp)))message-set)))(ifvirtual(save-excursion(set-buffer(vm-buffer-of(vm-real-message-of(carmp))))(apply'vm-vs-or(carmp)selectors))(apply'vm-vs-or(carmp)selectors)))(progn(ordont-finalize(intern(vm-message-id-number-of(vm-real-message-of(carmp)))message-set))(setqmessage(copy-sequence(vm-real-message-of(carmp))))(ifmirrored()(vm-set-mirror-data-ofmessage(make-vectorvm-mirror-data-vector-lengthnil))(vm-set-virtual-messages-sym-ofmessage(make-symbol"<v>"))(vm-set-virtual-messages-ofmessagenil)(vm-set-attributes-ofmessage(make-vectorvm-attributes-vector-lengthnil)))(vm-set-location-data-ofmessagelocation-vector)(vm-set-softdata-ofmessage(make-vectorvm-softdata-vector-lengthnil))(vm-set-real-message-sym-ofmessage(vm-real-message-sym-of(carmp)))(vm-set-message-type-ofmessagevm-folder-type)(vm-set-message-access-method-ofmessagevm-folder-access-method)(vm-set-message-id-number-ofmessagevm-message-id-number)(vm-incrementvm-message-id-number)(vm-set-buffer-ofmessagevbuffer)(vm-set-reverse-link-sym-ofmessage(make-symbol"<--"))(vm-set-reverse-link-ofmessagetail-cons)(if(nulltail-cons)(setqnew-message-list(listmessage)tail-consnew-message-list)(setcdrtail-cons(listmessage))(if(nullnew-message-list)(setqnew-message-list(cdrtail-cons)))(setqtail-cons(cdrtail-cons)))))(setqmp(cdrmp)))))(setqfolders(cdrfolders)))(setqclauses(cdrclauses))))(ifdont-finalizenew-message-list;; this doesn't need to work currently, but it might someday;; (if virtual;; (setq real-buffers-used (vm-delete-duplicates real-buffers-used)))(vm-incrementvm-modification-counter);; Until this point the user doesn't really have a virtual;; folder, as the virtual messages haven't been linked to the;; real messages, virtual buffers to the real buffers, and no;; message list has been installed.;;;; Now we tie it all together, with this section of code being;; uninterruptible.(let((inhibit-quitt)(label-obarrayvm-label-obarray))(if(nullvm-real-buffers)(setqvm-real-buffersreal-buffers-used))(save-excursion(whilereal-buffers-used(set-buffer(carreal-buffers-used));; inherit the global label lists of all the associated;; real folders.(mapatoms(function(lambda(x)(intern(symbol-namex)label-obarray)))vm-label-obarray)(if(not(memqvbuffervm-virtual-buffers))(setqvm-virtual-buffers(consvbuffervm-virtual-buffers)))(setqreal-buffers-used(cdrreal-buffers-used))))(setqmpnew-message-list)(whilemp(vm-set-virtual-messages-of(vm-real-message-of(carmp))(cons(carmp)(vm-virtual-messages-of(vm-real-message-of(carmp)))))(setqmp(cdrmp)))(ifvm-message-list(progn(vm-set-summary-redo-start-pointnew-message-list)(vm-set-numbering-redo-start-pointnew-message-list))(vm-set-summary-redo-start-pointt)(vm-set-numbering-redo-start-pointt)(setqvm-message-listnew-message-list))new-message-list))))(defunvm-create-virtual-folder(selector&optionalargread-onlyname)"Create a new virtual folder from messages in the current folder.The messages will be chosen by applying the selector you specify,which is normally read from the minibuffer.Prefix arg means the new virtual folder should be visited read only."(interactive(let((last-commandlast-command)(this-commandthis-command)(prefixcurrent-prefix-arg))(vm-select-folder-buffer)(nconc(vm-read-virtual-selector"Create virtual folder of messages: ")(listprefix))))(vm-select-folder-buffer)(vm-check-for-killed-summary)(vm-error-if-folder-empty)(let((use-marks(eqlast-command'vm-next-command-uses-marks))vm-virtual-folder-alist)(if(nullname)(ifarg(setqname(format"%s %s %s"(buffer-name)selectorarg))(setqname(format"%s %s"(buffer-name)selector))))(setqvm-virtual-folder-alist(list(listname(list(list(list'get-buffer(buffer-name)))(ifuse-marks(list'and'(marked)(ifarg(listselectorarg)(listselector)))(ifarg(listselectorarg)(listselector)))))))(vm-visit-virtual-foldernameread-only));; have to do this again here because the known virtual;; folder menu is now hosed because we installed it while;; vm-virtual-folder-alist was bound to the temp value above(ifvm-use-menus(vm-menu-install-known-virtual-folders-menu)))(defunvm-apply-virtual-folder(name&optionalread-only)"Apply the selectors of a named virtual folder to the current folderand create a virtual folder containing the selected messages.Prefix arg means the new virtual folder should be visited read only."(interactive(let((last-commandlast-command)(this-commandthis-command))(list(completing-read"Apply this virtual folder's selectors: "vm-virtual-folder-alistnilt)current-prefix-arg)))(vm-select-folder-buffer)(vm-check-for-killed-summary)(vm-error-if-folder-empty)(let((vfolder(assocnamevm-virtual-folder-alist))(use-marks(eqlast-command'vm-next-command-uses-marks))clausesvm-virtual-folder-alist)(orvfolder(error"No such virtual folder, %s"name))(setqvfolder(vm-copyvfolder))(setqclauses(cdrvfolder))(whileclauses(setcar(carclauses)(list(list'get-buffer(buffer-name))))(ifuse-marks(setcdr(carclauses)(list(list'and'(marked)(nconc(list'or)(cdr(carclauses)))))))(setqclauses(cdrclauses)))(setcarvfolder(format"%s/%s"(buffer-name)(carvfolder)))(setqvm-virtual-folder-alist(listvfolder))(vm-visit-virtual-folder(carvfolder)read-only));; have to do this again here because the "known virtual;; folder" menu is now hosed because we installed it while;; vm-virtual-folder-alist was bound to the temp value above(ifvm-use-menus(vm-menu-install-known-virtual-folders-menu)))(defunvm-create-virtual-folder-same-subject()(interactive)(vm-follow-summary-cursor)(vm-select-folder-buffer)(vm-error-if-folder-empty)(vm-check-for-killed-summary)(let*((subject(vm-so-sortable-subject(carvm-message-pointer)))(displayed-subjectsubject))(if(equalsubject"")(setqsubject"^$"displayed-subject"\"\"")(setqsubject(regexp-quotesubject)))(vm-create-virtual-folder'sortable-subjectsubjectnil(format"%s %s %s"(buffer-name)'subjectdisplayed-subject))))(defunvm-create-virtual-folder-same-author()(interactive)(vm-follow-summary-cursor)(vm-select-folder-buffer)(vm-error-if-folder-empty)(vm-check-for-killed-summary)(let*((author(vm-su-from(carvm-message-pointer)))(displayed-authorauthor))(if(equalauthor"")(setqauthor"^$"displayed-author"<none>")(setqauthor(regexp-quoteauthor)))(vm-create-virtual-folder'authorauthornil(format"%s %s %s"(buffer-name)'authordisplayed-author))))(defunvm-toggle-virtual-mirror()(interactive)(vm-select-folder-buffer)(vm-check-for-killed-summary)(if(not(eqmajor-mode'vm-virtual-mode))(error"This is not a virtual folder."))(let((mpvm-message-list)(inhibit-quitt)modifiedundo-list)(setqundo-listvm-saved-undo-record-listvm-saved-undo-record-listvm-undo-record-listvm-undo-record-listundo-listvm-undo-record-pointerundo-list)(setqmodifiedvm-saved-buffer-modified-pvm-saved-buffer-modified-p(buffer-modified-p))(set-buffer-modified-pmodified)(ifvm-virtual-mirror(whilemp(vm-set-attributes-of(carmp)(or(vm-saved-virtual-attributes-of(carmp))(make-vectorvm-attributes-vector-lengthnil)))(vm-set-mirror-data-of(carmp)(or(vm-saved-virtual-mirror-data-of(carmp))(make-vectorvm-mirror-data-vector-lengthnil)))(vm-mark-for-summary-update(carmp)t)(setqmp(cdrmp)))(whilemp;; mark for summary update _before_ we set this message to;; be mirrored. this will prevent the real message and;; the other messages that will share attributes with;; this message from having their summaries;; updated... they don't need it.(vm-mark-for-summary-update(carmp)t)(vm-set-saved-virtual-attributes-of(carmp)(vm-attributes-of(carmp)))(vm-set-saved-virtual-mirror-data-of(carmp)(vm-mirror-data-of(carmp)))(vm-set-attributes-of(carmp)(vm-attributes-of(vm-real-message-of(carmp))))(vm-set-mirror-data-of(carmp)(vm-mirror-data-of(vm-real-message-of(carmp))))(setqmp(cdrmp))))(setqvm-virtual-mirror(notvm-virtual-mirror))(vm-incrementvm-modification-counter))(vm-update-summary-and-mode-line)(message"Virtual folder now %s the underlying real folder%s."(ifvm-virtual-mirror"mirrors""does not mirror")(if(cdrvm-real-buffers)"s""")))(defunvm-virtual-help()(interactive)(vm-displaynilnil'(vm-virtual-help)'(vm-virtual-help))(message"VV = visit, VX = apply selectors, VC = create, VM = toggle virtual mirror"))(defunvm-vs-or(m&restselectors)(let((resultnil)selectorarglist)(whileselectors(setqselector(car(carselectors))arglist(cdr(carselectors))result(apply(cdr(assqselectorvm-virtual-selector-function-alist))marglist)selectors(ifresultnil(cdrselectors))))result))(defunvm-vs-and(m&restselectors)(let((resultt)selectorarglist)(whileselectors(setqselector(car(carselectors))arglist(cdr(carselectors))result(apply(cdr(assqselectorvm-virtual-selector-function-alist))marglist)selectors(if(nullresult)nil(cdrselectors))))result))(defunvm-vs-not(marg)(let((selector(cararg))(arglist(cdrarg)))(not(apply(cdr(assqselectorvm-virtual-selector-function-alist))marglist))))(defunvm-vs-any(m)t)(defunvm-vs-author(marg)(or(string-matcharg(vm-su-full-namem))(string-matcharg(vm-su-fromm))))(defunvm-vs-recipient(marg)(or(string-matcharg(vm-su-tom))(string-matcharg(vm-su-to-namesm))))(defunvm-vs-author-or-recipient(marg)(or(vm-vs-authormarg)(vm-vs-recipientmarg)))(defunvm-vs-subject(marg)(string-matcharg(vm-su-subjectm)))(defunvm-vs-sortable-subject(marg)(string-matcharg(vm-so-sortable-subjectm)))(defunvm-vs-sent-before(marg)(string<(vm-so-sortable-datestringm)(vm-timezone-make-date-sortablearg)))(defunvm-vs-sent-after(marg)(string<(vm-timezone-make-date-sortablearg)(vm-so-sortable-datestringm)))(defunvm-vs-header(marg)(save-excursion(save-restriction(widen)(goto-char(vm-headers-of(vm-real-message-ofm)))(re-search-forwardarg(vm-text-of(vm-real-message-ofm))t))))(defunvm-vs-label(marg)(vm-memberarg(vm-labels-ofm)))(defunvm-vs-text(marg)(save-excursion(save-restriction(widen)(goto-char(vm-text-of(vm-real-message-ofm)))(re-search-forwardarg(vm-text-end-of(vm-real-message-ofm))t))))(defunvm-vs-header-or-text(marg)(save-excursion(save-restriction(widen)(goto-char(vm-headers-of(vm-real-message-ofm)))(re-search-forwardarg(vm-text-end-of(vm-real-message-ofm))t))))(defunvm-vs-more-chars-than(marg)(>(string-to-int(vm-su-byte-countm))arg))(defunvm-vs-less-chars-than(marg)(<(string-to-int(vm-su-byte-countm))arg))(defunvm-vs-more-lines-than(marg)(>(string-to-int(vm-su-line-countm))arg))(defunvm-vs-less-lines-than(marg)(<(string-to-int(vm-su-line-countm))arg))(defunvm-vs-virtual-folder-member(m)(vm-virtual-messages-ofm))(defunvm-vs-new(m)(vm-new-flagm))(fset'vm-vs-recent'vm-vs-new)(defunvm-vs-unread(m)(vm-unread-flagm))(fset'vm-vs-unseen'vm-vs-unread)(defunvm-vs-read(m)(not(or(vm-new-flagm)(vm-unread-flagm))))(defunvm-vs-deleted(m)(vm-deleted-flagm))(defunvm-vs-replied(m)(vm-replied-flagm))(fset'vm-vs-answered'vm-vs-replied)(defunvm-vs-forwarded(m)(vm-forwarded-flagm))(defunvm-vs-redistributed(m)(vm-redistributed-flagm))(defunvm-vs-filed(m)(vm-filed-flagm))(defunvm-vs-written(m)(vm-written-flagm))(defunvm-vs-marked(m)(vm-mark-ofm))(defunvm-vs-edited(m)(vm-edited-flagm))(defunvm-vs-undeleted(m)(not(vm-deleted-flagm)))(defunvm-vs-unreplied(m)(not(vm-replied-flagm)))(fset'vm-vs-unanswered'vm-vs-unreplied)(defunvm-vs-unforwarded(m)(not(vm-forwarded-flagm)))(defunvm-vs-unredistributed(m)(not(vm-redistributed-flagm)))(defunvm-vs-unfiled(m)(not(vm-filed-flagm)))(defunvm-vs-unwritten(m)(not(vm-written-flagm)))(defunvm-vs-unmarked(m)(not(vm-mark-ofm)))(defunvm-vs-unedited(m)(not(vm-edited-flagm)))(put'header'vm-virtual-selector-clause"with header matching")(put'label'vm-virtual-selector-clause"with label of")(put'text'vm-virtual-selector-clause"with text matching")(put'header-or-text'vm-virtual-selector-clause"with header or text matching")(put'recipient'vm-virtual-selector-clause"with recipient matching")(put'author-or-recipient'vm-virtual-selector-clause"with author or recipient matching")(put'author'vm-virtual-selector-clause"with author matching")(put'subject'vm-virtual-selector-clause"with subject matching")(put'sent-before'vm-virtual-selector-clause"sent before")(put'sent-after'vm-virtual-selector-clause"sent after")(put'more-chars-than'vm-virtual-selector-clause"with more characters than")(put'less-chars-than'vm-virtual-selector-clause"with less characters than")(put'more-lines-than'vm-virtual-selector-clause"with more lines than")(put'less-lines-than'vm-virtual-selector-clause"with less lines than")(put'header'vm-virtual-selector-arg-type'string)(put'label'vm-virtual-selector-arg-type'label)(put'text'vm-virtual-selector-arg-type'string)(put'header-or-text'vm-virtual-selector-arg-type'string)(put'recipient'vm-virtual-selector-arg-type'string)(put'author-or-recipient'vm-virtual-selector-arg-type'string)(put'author'vm-virtual-selector-arg-type'string)(put'subject'vm-virtual-selector-arg-type'string)(put'sent-before'vm-virtual-selector-arg-type'string)(put'sent-after'vm-virtual-selector-arg-type'string)(put'more-chars-than'vm-virtual-selector-arg-type'number)(put'less-chars-than'vm-virtual-selector-arg-type'number)(put'more-lines-than'vm-virtual-selector-arg-type'number)(put'less-lines-than'vm-virtual-selector-arg-type'number)(defunvm-read-virtual-selector(prompt)(let(selector(argnil))(setqselector(vm-read-stringpromptvm-supported-interactive-virtual-selectors)selector(internselector))(let((arg-type(getselector'vm-virtual-selector-arg-type)))(if(nullarg-type)nil(setqprompt(concat(substringprompt0-2)" "(getselector'vm-virtual-selector-clause)": "))(raise-frame(selected-frame))(cond((eqarg-type'number)(setqarg(vm-read-numberprompt)))((eqarg-type'label)(let((vm-completion-auto-correctnil)(completion-ignore-caset))(setqarg(downcase(vm-read-stringprompt(vm-obarray-to-string-listvm-label-obarray)nil)))))(t(setqarg(read-stringprompt))))))(or(fboundp(intern(concat"vm-vs-"(symbol-nameselector))))(error"Invalid selector"))(listselectorarg)));; clear away links between real and virtual folders when;; a vm-quit is performed in either type folder.(defunvm-virtual-quit()(save-excursion(cond((eqmajor-mode'vm-virtual-mode);; don't trust blindly, user might have killed some of;; these buffers.(setqvm-real-buffers(vm-delete'buffer-namevm-real-bufferst))(let((bpvm-real-buffers)(mpvm-message-list)(b(current-buffer));; lock out interrupts here(inhibit-quitt))(whilebp(set-buffer(carbp))(setqvm-virtual-buffers(delqbvm-virtual-buffers)bp(cdrbp)))(whilemp(vm-set-virtual-messages-of(vm-real-message-of(carmp))(delq(carmp)(vm-virtual-messages-of(vm-real-message-of(carmp)))))(setqmp(cdrmp)))))((eqmajor-mode'vm-mode);; don't trust blindly, user might have killed some of;; these buffers.(setqvm-virtual-buffers(vm-delete'buffer-namevm-virtual-bufferst))(let((bpvm-virtual-buffers)(mpvm-message-list)vmp(b(current-buffer));; lock out interrupts here(inhibit-quitt))(whilemp(setqvmp(vm-virtual-messages-of(carmp)))(whilevmp;; we'll clear these messages from the virtual;; folder by looking for messages that have a "Q";; id number associated with them.(vm-set-message-id-number-of(carvmp)"Q")(setqvmp(cdrvmp)))(vm-set-virtual-messages-of(carmp)nil)(setqmp(cdrmp)))(whilebp(set-buffer(carbp))(setqvm-real-buffers(delqbvm-real-buffers));; set the message pointer to a new value if it is;; now invalid.(cond((andvm-message-pointer(equal"Q"(vm-message-id-number-of(carvm-message-pointer))))(vm-garbage-collect-message)(setqvmpvm-message-pointer)(while(andvm-message-pointer(equal"Q"(vm-message-id-number-of(carvm-message-pointer))))(setqvm-message-pointer(cdrvm-message-pointer)));; if there were no good messages ahead, try going;; backward.(if(nullvm-message-pointer)(progn(setqvm-message-pointervmp)(while(andvm-message-pointer(equal"Q"(vm-message-id-number-of(carvm-message-pointer))))(setqvm-message-pointer(vm-reverse-link-of(carvm-message-pointer))))))));; expunge the virtual messages associated with;; real messages that are going away.(setqvm-message-list(vm-delete(function(lambda(m)(equal"Q"(vm-message-id-number-ofm))))vm-message-listnil))(if(nullvm-message-pointer)(setqvm-message-pointervm-message-list));; same for vm-last-message-pointer(if(nullvm-last-message-pointer)(setqvm-last-message-pointernil))(vm-clear-virtual-quit-invalidated-undos)(vm-reverse-link-messages)(vm-set-numbering-redo-start-pointt)(vm-set-summary-redo-start-pointt)(ifvm-message-pointer(vm-preview-current-message)(vm-update-summary-and-mode-line))(setqbp(cdrbp))))))))(defunvm-virtual-save-folder(prefix)(save-excursion;; don't trust blindly, user might have killed some of;; these buffers.(setqvm-real-buffers(vm-delete'buffer-namevm-real-bufferst))(let((bpvm-real-buffers))(whilebp(set-buffer(carbp))(vm-save-folderprefix)(setqbp(cdrbp)))))(vm-set-buffer-modified-pnil)(vm-clear-modification-flag-undos)(vm-update-summary-and-mode-line))(defunvm-virtual-get-new-mail()(save-excursion;; don't trust blindly, user might have killed some of;; these buffers.(setqvm-real-buffers(vm-delete'buffer-namevm-real-bufferst))(let((bpvm-real-buffers))(whilebp(set-buffer(carbp))(condition-caseerror-data(vm-get-new-mail)(folder-read-only(message"Folder is read only: %s"(orbuffer-file-name(buffer-name)))(sit-for1))(unrecognized-folder-type(message"Folder type is unrecognized: %s"(orbuffer-file-name(buffer-name)))(sit-for1)))(setqbp(cdrbp)))))(vm-emit-totals-blurb))(defunvm-make-virtual-copy(m)(widen)(let((virtual-buffer(current-buffer))(real-m(vm-real-message-ofm))(buffer-read-onlynil)(modified(buffer-modified-p)))(unwind-protect(save-excursion(set-buffer(vm-buffer-ofreal-m))(save-restriction(widen);; must reference this now so that headers will be in;; their final position before the message is copied.;; otherwise the vheader offset computed below will be wrong.(vm-vheaders-ofreal-m)(copy-to-buffervirtual-buffer(vm-start-ofreal-m)(vm-end-ofreal-m))))(set-buffer-modified-pmodified))(set-marker(vm-start-ofm)(point-min))(set-marker(vm-headers-ofm)(+(vm-start-ofm)(-(vm-headers-ofreal-m)(vm-start-ofreal-m))))(set-marker(vm-vheaders-ofm)(+(vm-start-ofm)(-(vm-vheaders-ofreal-m)(vm-start-ofreal-m))))(set-marker(vm-text-ofm)(+(vm-start-ofm)(-(vm-text-ofreal-m)(vm-start-ofreal-m))))(set-marker(vm-text-end-ofm)(+(vm-start-ofm)(-(vm-text-end-ofreal-m)(vm-start-ofreal-m))))(set-marker(vm-end-ofm)(+(vm-start-ofm)(-(vm-end-ofreal-m)(vm-start-ofreal-m))))))