(defun message-change-subject-interactively (&optional new-subj) ;gnus-subject-interactive "Change the Subject, bracketing with \"(was...)\" if necessary." (interactive "*") (undo-boundary) (save-excursion (save-restriction (message-narrow-to-headers-or-head) (let* ((subject (message-fetch-field "Subject")) (case-fold-search t)) (if (null subject) (setq new-subj (read-from-minibuffer "New Subject: ")) ;; There was already a subject (when (string-match "\\s-+\\'" subject) ; remove trailing spaces (setq subject (replace-match "" t t subject))) (if (and (not new-subj) (string-match "^[Rr][Ee]\\>" subject)) ;; only ask if it wasn't our subject (setq new-subj (read-from-minibuffer (concat "New Subject: (was " subject ") ")))) ;; new-subj is nil if we already have an original subject (not starting with "Re:") ;; It is a string if we are following-up (so might want to remove "(was ...)") (if (and new-subj (or ;(re-search-forward "\\s-*\\((was\\>.*\\)" subject-end t) (string-match "\\s-*\\([[(,;]\\s-*was\\>.*\\)" subject) (string-match "\\s-*\\<\\(was:?\\s-+[Rr][Ee]:.*\\)" subject) (string-match "\\s-*[[(,;]\\s-*\\([Rr][Ee]:.*\\)" subject)) (or (not (string= new-subj "")) ; if replacing, force removal (y-or-n-p (concat "Remove \"" (match-string 1 subject) "\" from Subject: line? ")))) (setq new-subj (replace-match "" t t subject) subject nil)) (if (or (null new-subj) (string= "" new-subj)) ;; No true change in subject (setq new-subj subject subject nil) ;; User changed the subject ;; first undo RFC-822 line-wrap (while (and subject (string-match "\n[ \t]" subject)) (setq subject (replace-match " " t t subject))) ;; might be a followup to a forwarded message, so trim [...] too (while (and subject (string-match message-change-subject-ignored-prefixes subject)) (setq subject (replace-match "" t t subject))) ;; Trim subject line to 75 chars (leaving room for a recipient to add "Re: ") ;; "Subject: "(9) + new-subj + "(was: "(6) + subject + "...)"(1 or 4) <=75 ;; means subject<=(59 - new-subj) or trim to (56 - new-subj) (if (and subject (> (length subject) (- 59 (length new-subj)))) (let ((maxlen (- 56 (length new-subj)))) (if (<= maxlen 0) (setq subject "...") ;; keep one extra char, so we know if last char is a word-boundary (setq subject (substring subject 0 (1+ maxlen))) (if (string-match "\\s-*\\(\\B.\\|\\<.\\)*\\'" subject) (setq subject (replace-match "..." t t subject)))))))) (widen) (when new-subj (if (and subject (not (string= "" subject))) (setq new-subj (concat new-subj " (was: " subject ")"))) (message-goto-subject) (message-delete-line) (insert "Subject: " new-subj "\n"))))))