Mercurial > hg > xemacs-beta
diff lisp/vm/vm-mark.el @ 0:376386a54a3c r19-14
Import from CVS: tag r19-14
author | cvs |
---|---|
date | Mon, 13 Aug 2007 08:45:50 +0200 |
parents | |
children | 859a2309aef8 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lisp/vm/vm-mark.el Mon Aug 13 08:45:50 2007 +0200 @@ -0,0 +1,309 @@ +;;; Commands for handling messages marks +;;; Copyright (C) 1990, 1993, 1994 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-mark) + +(defun vm-clear-all-marks () + "Removes all message marks in the current folder." + (interactive) + (vm-select-folder-buffer) + (vm-check-for-killed-summary) + (vm-error-if-folder-empty) + (let ((mp vm-message-list)) + (while mp + (if (vm-mark-of (car mp)) + (progn + (vm-set-mark-of (car mp) nil) + (vm-mark-for-summary-update (car mp) t))) + (setq mp (cdr mp)))) + (vm-display nil nil '(vm-clear-all-marks) + '(vm-clear-all-marks marking-message)) + (vm-update-summary-and-mode-line)) + +(defun vm-mark-all-messages () + "Mark all messages in the current folder." + (interactive) + (vm-select-folder-buffer) + (vm-check-for-killed-summary) + (vm-error-if-folder-empty) + (let ((mp vm-message-list)) + (while mp + (vm-set-mark-of (car mp) t) + (vm-mark-for-summary-update (car mp) t) + (setq mp (cdr mp)))) + (vm-display nil nil '(vm-mark-all-messages) + '(vm-mark-all-messages marking-message)) + (vm-update-summary-and-mode-line)) + +(defun vm-mark-message (count) + "Mark the current message. +Numeric prefix argument N means mark the current message and the next +N-1 messages. A negative N means mark the current message and the +previous N-1 messages." + (interactive "p") + (if (interactive-p) + (vm-follow-summary-cursor)) + (vm-select-folder-buffer) + (vm-check-for-killed-summary) + (vm-error-if-folder-empty) + (let ((direction (if (< count 0) 'backward 'forward)) + (count (vm-abs count)) + (oldmp vm-message-pointer) + (vm-message-pointer vm-message-pointer)) + (while (not (zerop count)) + (if (not (vm-mark-of (car vm-message-pointer))) + (progn + (vm-set-mark-of (car vm-message-pointer) t) + (vm-mark-for-summary-update (car vm-message-pointer) t))) + (vm-decrement count) + (if (not (zerop count)) + (vm-move-message-pointer direction)))) + (vm-display nil nil '(vm-mark-message) + '(vm-mark-message marking-message)) + (vm-update-summary-and-mode-line)) + +(defun vm-unmark-message (count) + "Remove the mark from the current message. +Numeric prefix argument N means unmark the current message and the next +N-1 messages. A negative N means unmark the current message and the +previous N-1 messages." + (interactive "p") + (if (interactive-p) + (vm-follow-summary-cursor)) + (vm-select-folder-buffer) + (vm-check-for-killed-summary) + (vm-error-if-folder-empty) + (let ((mlist (vm-select-marked-or-prefixed-messages count))) + (while mlist + (if (vm-mark-of (car mlist)) + (progn + (vm-set-mark-of (car mlist) nil) + (vm-mark-for-summary-update (car mlist) t))) + (setq mlist (cdr mlist)))) + (vm-display nil nil '(vm-unmark-message) + '(vm-unmark-message marking-message)) + (vm-update-summary-and-mode-line)) + +(defun vm-mark-or-unmark-messages-with-selector (val selector arg) + (let ((mlist vm-message-list) + (virtual (eq major-mode 'vm-virtual-mode)) + (arglist (if arg (list arg) nil)) + (count 0)) + (setq selector (intern (concat "vm-vs-" (symbol-name selector)))) + (while mlist + (if (if virtual + (save-excursion + (set-buffer + (vm-buffer-of + (vm-real-message-of + (car mlist)))) + (apply selector (vm-real-message-of (car mlist)) arglist)) + (apply selector (car mlist) arglist)) + (progn + (vm-set-mark-of (car mlist) val) + (vm-mark-for-summary-update (car mlist) t) + (vm-increment count))) + (setq mlist (cdr mlist))) + (vm-display nil nil + '(vm-mark-matching-messages vm-unmark-matching-messages) + (list this-command 'marking-message)) + (vm-update-summary-and-mode-line) + (message "%d message%s %smarked" + count + (if (= 1 count) "" "s") + (if val "" "un")))) + +(defun vm-mark-matching-messages (selector &optional arg) + "Mark messages matching some criterion. +You can use any of the virtual folder selectors, except for the +`and', `or' and `not' selectors. See the documentation for the +variable vm-virtual-folder-alist for more information." + (interactive + (let ((last-command last-command) + (this-command this-command)) + (vm-select-folder-buffer) + (vm-read-virtual-selector "Mark messages: "))) + (vm-select-folder-buffer) + (vm-check-for-killed-summary) + (vm-error-if-folder-empty) + (vm-mark-or-unmark-messages-with-selector t selector arg)) + +(defun vm-unmark-matching-messages (selector &optional arg) + "Unmark messages matching some criterion. +You can use any of the virtual folder selectors, except for the +`and', `or' and `not' selectors. See the documentation for the +variable vm-virtual-folder-alist for more information." + (interactive + (let ((last-command last-command) + (this-command this-command)) + (vm-select-folder-buffer) + (vm-read-virtual-selector "Unmark messages: "))) + (vm-select-folder-buffer) + (vm-check-for-killed-summary) + (vm-error-if-folder-empty) + (vm-mark-or-unmark-messages-with-selector nil selector arg)) + +(defun vm-mark-thread-subtree () + "Mark all messages in the thread tree rooted at the current message." + (interactive) + (vm-follow-summary-cursor) + (vm-select-folder-buffer) + (vm-check-for-killed-summary) + (vm-error-if-folder-empty) + (vm-mark-or-unmark-thread-subtree t)) + +(defun vm-unmark-thread-subtree () + "Unmark all messages in the thread tree rooted at the current message." + (interactive) + (vm-follow-summary-cursor) + (vm-select-folder-buffer) + (vm-check-for-killed-summary) + (vm-error-if-folder-empty) + (vm-mark-or-unmark-thread-subtree nil)) + +(defun vm-mark-or-unmark-thread-subtree (mark) + (vm-build-threads-if-unbuilt) + (let ((list (list (car vm-message-pointer))) + (loop-obarray (make-vector 29 0)) + subject-sym id-sym) + (while list + (if (not (eq (vm-mark-of (car list)) mark)) + (progn + (vm-set-mark-of (car list) mark) + (vm-mark-for-summary-update (car list)))) + (setq id-sym (car (vm-last (vm-th-thread-list (car list))))) + (if (null (intern-soft (symbol-name id-sym) loop-obarray)) + (progn + (intern (symbol-name id-sym) loop-obarray) + (nconc list (copy-sequence (get id-sym 'children))) + (setq subject-sym (intern (vm-so-sortable-subject (car list)) + vm-thread-subject-obarray)) + (if (and (boundp subject-sym) + (eq id-sym (aref (symbol-value subject-sym) 0))) + (nconc list (copy-sequence + (aref (symbol-value subject-sym) 2)))))) + (setq list (cdr list)))) + (vm-display nil nil + '(vm-mark-thread-subtree vm-unmark-thread-subtree) + (list this-command 'marking-message)) + (vm-update-summary-and-mode-line)) + +(defun vm-mark-messages-same-subject () + "Mark all messages with the same subject as the current message." + (interactive) + (vm-follow-summary-cursor) + (vm-select-folder-buffer) + (vm-check-for-killed-summary) + (vm-error-if-folder-empty) + (vm-mark-or-unmark-messages-same-subject t)) + +(defun vm-unmark-messages-same-subject () + "Unmark all messages with the same subject as the current message." + (interactive) + (vm-follow-summary-cursor) + (vm-select-folder-buffer) + (vm-check-for-killed-summary) + (vm-error-if-folder-empty) + (vm-mark-or-unmark-messages-same-subject nil)) + +(defun vm-mark-or-unmark-messages-same-subject (mark) + (let ((mp vm-message-list) + (mark-count 0) + (subject (vm-so-sortable-subject (car vm-message-pointer)))) + (while mp + (if (and (not (eq (vm-mark-of (car mp)) mark)) + (string-equal subject (vm-so-sortable-subject (car mp)))) + (progn + (vm-set-mark-of (car mp) mark) + (vm-increment mark-count) + (vm-mark-for-summary-update (car mp) t))) + (setq mp (cdr mp))) + (if (zerop mark-count) + (message "No messages %smarked" (if mark "" "un")) + (message "%d message%s %smarked" + mark-count + (if (= 1 mark-count) "" "s") + (if mark "" "un")))) + (vm-display nil nil + '(vm-mark-messages-same-subject + vm-unmark-messages-same-subject) + (list this-command 'marking-message)) + (vm-update-summary-and-mode-line)) + +(defun vm-mark-messages-same-author () + "Mark all messages with the same author as the current message." + (interactive) + (vm-follow-summary-cursor) + (vm-select-folder-buffer) + (vm-check-for-killed-summary) + (vm-error-if-folder-empty) + (vm-mark-or-unmark-messages-same-author t)) + +(defun vm-unmark-messages-same-author () + "Unmark all messages with the same author as the current message." + (interactive) + (vm-follow-summary-cursor) + (vm-select-folder-buffer) + (vm-check-for-killed-summary) + (vm-error-if-folder-empty) + (vm-mark-or-unmark-messages-same-author nil)) + +(defun vm-mark-or-unmark-messages-same-author (mark) + (let ((mp vm-message-list) + (mark-count 0) + (author (vm-su-from (car vm-message-pointer)))) + (while mp + (if (and (not (eq (vm-mark-of (car mp)) mark)) + (string-equal author (vm-su-from (car mp)))) + (progn + (vm-set-mark-of (car mp) mark) + (vm-increment mark-count) + (vm-mark-for-summary-update (car mp) t))) + (setq mp (cdr mp))) + (if (zerop mark-count) + (message "No messages %smarked" (if mark "" "un")) + (message "%d message%s %smarked" + mark-count + (if (= 1 mark-count) "" "s") + (if mark "" "un")))) + (vm-display nil nil + '(vm-mark-messages-same-author + vm-unmark-messages-same-author) + (list this-command 'marking-message)) + (vm-update-summary-and-mode-line)) + +(defun vm-next-command-uses-marks () + "Does nothing except insure that the next VM command will operate only +on the marked messages in the current folder." + (interactive) + (setq this-command 'vm-next-command-uses-marks) + (vm-unsaved-message "Next command uses marks...") + (vm-display nil nil '(vm-next-command-uses-marks) + '(vm-next-command-uses-marks))) + +(defun vm-marked-messages () + (let (list (mp vm-message-list)) + (while mp + (if (vm-mark-of (car mp)) + (setq list (cons (car mp) list))) + (setq mp (cdr mp))) + (nreverse list))) + +(defun vm-mark-help () + (interactive) + (vm-display nil nil '(vm-mark-help) '(vm-mark-help)) + (message "MM = mark, MU = unmark, Mm = mark all, Mu = unmark all, MN = use marks, ..."))