Mercurial > hg > xemacs-beta
diff lisp/vm/vm-edit.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-edit.el Mon Aug 13 08:45:50 2007 +0200 @@ -0,0 +1,234 @@ +;;; Editing VM messages +;;; Copyright (C) 1990, 1991, 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-edit) + +(defun vm-edit-message (&optional prefix-argument) + "Edit the current message. Prefix arg means mark as unedited instead. +If editing, the current message is copied into a temporary buffer, and +this buffer is selected for editing. The major mode of this buffer is +controlled by the variable vm-edit-message-mode. The hooks specified +in vm-edit-message-hook are run just prior to returning control to the user +for editing. + +Use C-c ESC when you have finished editing the message. The message +will be inserted into its folder replacing the old version of the +message. If you don't want your edited version of the message to +replace the original, use C-c C-] and the edit will be aborted." + (interactive "P") + (vm-follow-summary-cursor) + (vm-select-folder-buffer) + (vm-check-for-killed-summary) + (vm-error-if-folder-read-only) + (vm-error-if-folder-empty) + (if (and (vm-virtual-message-p (car vm-message-pointer)) + (null (vm-virtual-messages-of (car vm-message-pointer)))) + (error "Can't edit unmirrored virtual messages.")) + (if prefix-argument + (if (vm-edited-flag (car vm-message-pointer)) + (progn + (vm-set-edited-flag-of (car vm-message-pointer) nil) + (vm-update-summary-and-mode-line))) + (let ((mp vm-message-pointer) + (offset (- (point) (vm-headers-of (car vm-message-pointer)))) + (edit-buf (vm-edit-buffer-of (car vm-message-pointer))) + (folder-buffer (current-buffer))) + (if (not (and edit-buf (buffer-name edit-buf))) + (progn + (vm-save-restriction + (widen) + (setq edit-buf + (generate-new-buffer + (format "edit of %s's note re: %s" + (vm-su-full-name (car vm-message-pointer)) + (vm-su-subject (car vm-message-pointer))))) + (vm-set-edit-buffer-of (car mp) edit-buf) + (copy-to-buffer edit-buf + (vm-headers-of (car mp)) + (vm-text-end-of (car mp)))) + (set-buffer edit-buf) + (set-buffer-modified-p nil) + (goto-char (point-min)) + (if (< offset 0) + (search-forward "\n\n" nil t) + (forward-char offset)) + (funcall (or vm-edit-message-mode 'text-mode)) + (use-local-map vm-edit-message-map) + ;; (list (car mp)) because a different message may + ;; later be stuffed into a cons linked that is linked + ;; into the folder's message list. + (setq vm-message-pointer (list (car mp)) + vm-mail-buffer folder-buffer + vm-system-state 'editing) + (run-hooks 'vm-edit-message-hook) + (message + (substitute-command-keys + "Type \\[vm-edit-message-end] to end edit, \\[vm-edit-message-abort] to abort with no change."))) + (set-buffer edit-buf)) + (if (and vm-frame-per-edit (vm-multiple-frames-possible-p)) + (let ((w (vm-get-buffer-window edit-buf))) + (if (null w) + (progn + (vm-goto-new-frame 'edit) + (vm-set-hooks-for-frame-deletion)) + (save-excursion + (select-window w) + (and vm-warp-mouse-to-new-frame + (vm-warp-mouse-to-frame-maybe (vm-window-frame w))))))) + (vm-display edit-buf t '(vm-edit-message vm-edit-message-other-frame) + (list this-command 'editing-message))))) + +(defun vm-edit-message-other-frame (&optional prefix) + "Like vm-edit-message, but run in a newly created frame." + (interactive "P") + (if (vm-multiple-frames-possible-p) + (vm-goto-new-frame 'edit)) + (let ((vm-search-other-frames nil) + (vm-frame-per-edit nil)) + (vm-edit-message prefix)) + (if (vm-multiple-frames-possible-p) + (vm-set-hooks-for-frame-deletion))) + +(defun vm-discard-cached-data (&optional count) + "Discard cached information about the current message. +When VM gathers information from the headers of a message, it stores it +internally for future reference. This command causes VM to forget this +information, and VM will be forced to search the headers of the message +again for these data. VM will also have to decide again which headers +should be displayed and which should not. Therefore this command is +useful if you change the value of vm-visible-headers or +vm-invisible-header-regexp in the midst of a VM session. + +Numeric prefix argument N means to discard data from the current message +plus the next N-1 messages. A negative N means discard data from the +current message and the previous N-1 messages. + +When invoked on marked messages (via vm-next-command-uses-marks), +data is discarded only from the marked messages in the current folder." + (interactive "p") + (or count (setq count 1)) + (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)) m) + (while mlist + (setq m (vm-real-message-of (car mlist))) + (if vm-thread-obarray + (vm-unthread-message m t)) + (fillarray (vm-cache-of m) nil) + (vm-set-vheaders-of m nil) + (vm-set-vheaders-regexp-of m nil) + (vm-set-text-of m nil) + (if vm-thread-obarray + (vm-build-threads (list m))) + (if vm-summary-show-threads + (vm-sort-messages "thread")) + (let ((v-list (vm-virtual-messages-of m))) + (save-excursion + (while v-list + (set-buffer (vm-buffer-of (car v-list))) + (if vm-thread-obarray + (vm-build-threads (list (car v-list)))) + (if vm-summary-show-threads + (vm-sort-messages "thread")) + (setq v-list (cdr v-list))))) + (vm-mark-for-summary-update m) + (setq mlist (cdr mlist)))) + (vm-display nil nil '(vm-discard-cached-data) '(vm-discard-cached-data)) + (vm-update-summary-and-mode-line)) + +(defun vm-edit-message-end () + "End the edit of a message and copy the result to its folder." + (interactive) + (if (null vm-message-pointer) + (error "This is not a VM message edit buffer.")) + (if (null (buffer-name (vm-buffer-of (car vm-message-pointer)))) + (error "The folder buffer for this message has been killed.")) + ;; make sure the message ends with a newline + (goto-char (point-max)) + (and (/= (preceding-char) ?\n) (insert ?\n)) + ;; munge message separators found in the edited message to + ;; prevent message from being split into several messages. + (vm-munge-message-separators (vm-message-type-of (car vm-message-pointer)) + (point-min) (point-max)) + ;; for From_-with-Content-Length recompute the Content-Length header + (if (eq (vm-message-type-of (car vm-message-pointer)) + 'From_-with-Content-Length) + (let ((buffer-read-only nil) + length) + (goto-char (point-min)) + ;; first delete all copies of Content-Length + (while (and (re-search-forward vm-content-length-search-regexp nil t) + (null (match-beginning 1)) + (progn (goto-char (match-beginning 0)) + (vm-match-header vm-content-length-header))) + (delete-region (vm-matched-header-start) (vm-matched-header-end))) + ;; now compute the message body length + (goto-char (point-min)) + (search-forward "\n\n" nil 0) + (setq length (- (point-max) (point))) + ;; insert the header + (goto-char (point-min)) + (insert vm-content-length-header " " (int-to-string length) "\n"))) + (let ((edit-buf (current-buffer)) + (mp vm-message-pointer)) + (if (buffer-modified-p) + (progn + (widen) + (save-excursion + (set-buffer (vm-buffer-of (vm-real-message-of (car mp)))) + (if (not (memq (vm-real-message-of (car mp)) vm-message-list)) + (error "The original copy of this message has been expunged.")) + (vm-save-restriction + (widen) + (goto-char (vm-headers-of (vm-real-message-of (car mp)))) + (let ((vm-message-pointer mp) + opoint + (buffer-read-only nil)) + (setq opoint (point)) + (insert-buffer-substring edit-buf) + (delete-region + (point) (vm-text-end-of (vm-real-message-of (car mp)))) + (vm-discard-cached-data)) + (vm-set-edited-flag-of (car mp) t) + (vm-set-edit-buffer-of (car mp) nil)) + (set-buffer (vm-buffer-of (car mp))) + (if (eq (vm-real-message-of (car mp)) + (vm-real-message-of (car vm-message-pointer))) + (vm-preview-current-message) + (vm-update-summary-and-mode-line)))) + (message "No change.")) + (vm-display edit-buf nil '(vm-edit-message-end) + '(vm-edit-message-end reading-message startup)) + (set-buffer-modified-p nil) + (kill-buffer edit-buf))) + +(defun vm-edit-message-abort () + "Abort the edit of a message, forgetting changes to the message." + (interactive) + (if (null vm-message-pointer) + (error "This is not a VM message edit buffer.")) + (if (null (buffer-name (vm-buffer-of (vm-real-message-of (car vm-message-pointer))))) + (error "The folder buffer for this message has been killed.")) + (vm-set-edit-buffer-of (car vm-message-pointer) nil) + (vm-display (current-buffer) nil + '(vm-edit-message-abort) + '(vm-edit-message-abort reading-message startup)) + (set-buffer-modified-p nil) + (kill-buffer (current-buffer)) + (message "Aborted, no change."))