rmailedit.el 5.58 KB
Newer Older
1
;;; rmailedit.el --- "RMAIL edit mode"  Edit the current message
Eric S. Raymond's avatar
Eric S. Raymond committed
2

3
;; Copyright (C) 1985, 1994, 2001, 2002, 2003, 2004,
Glenn Morris's avatar
Glenn Morris committed
4
;;   2005, 2006, 2007, 2008 Free Software Foundation, Inc.
Eric S. Raymond's avatar
Eric S. Raymond committed
5

Eric S. Raymond's avatar
Eric S. Raymond committed
6
;; Maintainer: FSF
Eric S. Raymond's avatar
Eric S. Raymond committed
7
;; Keywords: mail
Eric S. Raymond's avatar
Eric S. Raymond committed
8

Joseph Arceneaux's avatar
Joseph Arceneaux committed
9 10
;; This file is part of GNU Emacs.

11
;; GNU Emacs is free software: you can redistribute it and/or modify
Joseph Arceneaux's avatar
Joseph Arceneaux committed
12
;; it under the terms of the GNU General Public License as published by
13 14
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
Joseph Arceneaux's avatar
Joseph Arceneaux committed
15 16 17 18 19 20 21

;; GNU Emacs 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
22
;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
Joseph Arceneaux's avatar
Joseph Arceneaux committed
23

24 25
;;; Commentary:

Eric S. Raymond's avatar
Eric S. Raymond committed
26
;;; Code:
Joseph Arceneaux's avatar
Joseph Arceneaux committed
27 28 29

(require 'rmail)

Gerd Moellmann's avatar
Gerd Moellmann committed
30 31 32
(defcustom rmail-edit-mode-hook nil
  "List of functions to call when editing an RMAIL message."
  :type 'hook
33
  :version "21.1"
Gerd Moellmann's avatar
Gerd Moellmann committed
34 35
  :group 'rmail-edit)

36 37
(defvar rmail-old-text)

Joseph Arceneaux's avatar
Joseph Arceneaux committed
38 39 40
(defvar rmail-edit-map nil)
(if rmail-edit-map
    nil
41
  ;; Make a keymap that inherits text-mode-map.
42 43
  (setq rmail-edit-map (make-sparse-keymap))
  (set-keymap-parent rmail-edit-map text-mode-map)
Joseph Arceneaux's avatar
Joseph Arceneaux committed
44 45 46 47 48 49
  (define-key rmail-edit-map "\C-c\C-c" 'rmail-cease-edit)
  (define-key rmail-edit-map "\C-c\C-]" 'rmail-abort-edit))

;; Rmail Edit mode is suitable only for specially formatted data.
(put 'rmail-edit-mode 'mode-class 'special)

50 51 52
(declare-function rmail-summary-disable "" ())
(declare-function rmail-summary-enable "rmailsum" ())

Joseph Arceneaux's avatar
Joseph Arceneaux committed
53 54 55 56
(defun rmail-edit-mode ()
  "Major mode for editing the contents of an RMAIL message.
The editing commands are the same as in Text mode, together with two commands
to return to regular RMAIL:
Gerd Moellmann's avatar
Gerd Moellmann committed
57
  *  \\[rmail-abort-edit] cancels the changes
Joseph Arceneaux's avatar
Joseph Arceneaux committed
58
     you have made and returns to RMAIL
Gerd Moellmann's avatar
Gerd Moellmann committed
59 60
  *  \\[rmail-cease-edit] makes them permanent.
This functions runs the normal hook `rmail-edit-mode-hook'.
Joseph Arceneaux's avatar
Joseph Arceneaux committed
61
\\{rmail-edit-map}"
62
  (delay-mode-hooks (text-mode))
Joseph Arceneaux's avatar
Joseph Arceneaux committed
63 64 65 66 67 68
  (use-local-map rmail-edit-map)
  (setq major-mode 'rmail-edit-mode)
  (setq mode-name "RMAIL Edit")
  (if (boundp 'mode-line-modified)
      (setq mode-line-modified (default-value 'mode-line-modified))
    (setq mode-line-format (default-value 'mode-line-format)))
69
  (if (rmail-summary-exists)
Karl Heuer's avatar
Karl Heuer committed
70 71 72
      (save-excursion
	(set-buffer rmail-summary-buffer)
	(rmail-summary-disable)))
73
  (run-mode-hooks 'rmail-edit-mode-hook))
Joseph Arceneaux's avatar
Joseph Arceneaux committed
74

75 76 77
(defvar rmail-old-pruned nil)
(put 'rmail-old-pruned 'permanent-local t)

78 79 80
(defvar rmail-edit-saved-coding-system nil)
(put 'rmail-edit-saved-coding-system 'permanent-local t)

81
;;;###autoload
Joseph Arceneaux's avatar
Joseph Arceneaux committed
82 83 84
(defun rmail-edit-current-message ()
  "Edit the contents of this message."
  (interactive)
85 86
  (make-local-variable 'rmail-old-pruned)
  (setq rmail-old-pruned (rmail-msg-is-pruned))
87 88
  (make-local-variable 'rmail-edit-saved-coding-system)
  (setq rmail-edit-saved-coding-system save-buffer-coding-system)
89
  (rmail-toggle-header 0)
Joseph Arceneaux's avatar
Joseph Arceneaux committed
90
  (rmail-edit-mode)
91 92 93 94
  ;; As the local value of save-buffer-coding-system is deleted by
  ;; rmail-edit-mode, we restore the original value.
  (make-local-variable 'save-buffer-coding-system)
  (setq save-buffer-coding-system rmail-edit-saved-coding-system)
Joseph Arceneaux's avatar
Joseph Arceneaux committed
95 96 97
  (make-local-variable 'rmail-old-text)
  (setq rmail-old-text (buffer-substring (point-min) (point-max)))
  (setq buffer-read-only nil)
98
  (force-mode-line-update)
Joseph Arceneaux's avatar
Joseph Arceneaux committed
99 100 101
  (if (and (eq (key-binding "\C-c\C-c") 'rmail-cease-edit)
	   (eq (key-binding "\C-c\C-]") 'rmail-abort-edit))
      (message "Editing: Type C-c C-c to return to Rmail, C-c C-] to abort")
102
    (message "%s" (substitute-command-keys
103
		   "Editing: Type \\[rmail-cease-edit] to return to Rmail, \\[rmail-abort-edit] to abort"))))
Joseph Arceneaux's avatar
Joseph Arceneaux committed
104 105 106 107

(defun rmail-cease-edit ()
  "Finish editing message; switch back to Rmail proper."
  (interactive)
108
  (if (rmail-summary-exists)
Karl Heuer's avatar
Karl Heuer committed
109 110 111
      (save-excursion
	(set-buffer rmail-summary-buffer)
	(rmail-summary-enable)))
Joseph Arceneaux's avatar
Joseph Arceneaux committed
112 113 114 115 116 117 118 119 120
  ;; Make sure buffer ends with a newline.
  (save-excursion
    (goto-char (point-max))
    (if (/= (preceding-char) ?\n)
	(insert "\n"))
    ;; Adjust the marker that points to the end of this message.
    (set-marker (aref rmail-message-vector (1+ rmail-current-message))
		(point)))
  (let ((old rmail-old-text))
121
    (force-mode-line-update)
122
    (kill-all-local-variables)
Joseph Arceneaux's avatar
Joseph Arceneaux committed
123
    (rmail-mode-1)
124
    (set (make-local-variable 'tool-bar-map) rmail-tool-bar-map)
125
    (rmail-variables)
126 127 128
    ;; As the local value of save-buffer-coding-system is changed by
    ;; rmail-variables, we restore the original value.
    (setq save-buffer-coding-system rmail-edit-saved-coding-system)
Joseph Arceneaux's avatar
Joseph Arceneaux committed
129 130 131 132 133 134 135 136 137 138
    (if (and (= (length old) (- (point-max) (point-min)))
	     (string= old (buffer-substring (point-min) (point-max))))
	()
      (setq old nil)
      (rmail-set-attribute "edited" t)
      (if (boundp 'rmail-summary-vector)
	  (progn
	    (aset rmail-summary-vector (1- rmail-current-message) nil)
	    (save-excursion
	      (rmail-widen-to-current-msgbeg
139
		(function (lambda ()
Joseph Arceneaux's avatar
Joseph Arceneaux committed
140 141 142 143 144
			    (forward-line 2)
			    (if (looking-at "Summary-line: ")
				(let ((buffer-read-only nil))
				  (delete-region (point)
						 (progn (forward-line 1)
145 146
							(point))))))))))))
    (save-excursion
147 148
      (rmail-show-message)
      (rmail-toggle-header (if rmail-old-pruned 1 0))))
149
  (run-hooks 'rmail-mode-hook)
Joseph Arceneaux's avatar
Joseph Arceneaux committed
150 151 152 153 154 155 156
  (setq buffer-read-only t))

(defun rmail-abort-edit ()
  "Abort edit of current message; restore original contents."
  (interactive)
  (delete-region (point-min) (point-max))
  (insert rmail-old-text)
157 158
  (rmail-cease-edit)
  (rmail-highlight-headers))
Joseph Arceneaux's avatar
Joseph Arceneaux committed
159

Markus Rost's avatar
Markus Rost committed
160 161
(provide 'rmailedit)

162
;; arch-tag: 93c22709-a14a-46c1-ab91-52c3f5a0ec12
Eric S. Raymond's avatar
Eric S. Raymond committed
163
;;; rmailedit.el ends here