Reset media/current-information when the song terminates (or if there is a player...
[elisp.git] / vm
diff --git a/vm b/vm
index 6f41d75..75e3b13 100644 (file)
--- a/vm
+++ b/vm
 ;; along with this program. If not, see <http://www.gnu.org/licenses/>.  ;;
 ;;                                                                       ;;
 ;; Written by and Copyright (C) Francois Fleuret                         ;;
-;; Contact < francois@fleuret.org > for comments & bug reports             ;;
+;; Contact <francois@fleuret.org> for comments & bug reports             ;;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; A fast indexed / search in mbox
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; This is one of my own things, check my web page to get it
+
+(when (ff/load-or-alert "~/sources/gpl/mymail/mymail-vm.el")
+
+  (define-key vm-summary-mode-map "\\" 'mymail/vm-visit-folder)
+  (define-key global-map [S-f7] 'mymail/vm-visit-folder)
+  (setq mymail/default-search-request "today"
+        mymail/default-additional-search-requests "!s ^\\[SPAM\\],!s \\] STATUS,")
+  (add-to-list 'recentf-exclude "/tmp/mymail-vm-.*\.mbox")
+)
+
 (setq-default vm-summary-show-threads t)
 
-(setq vm-startup-message-displayed t ;; Yes, we already saw it, no need to insist
-      vm-use-menus nil
-      vm-skip-deleted-messages nil
-      vm-skip-read-messages nil
-      vm-use-toolbar nil
+;; (setq vm-preview-lines nil)
+
+;; (setq vm-auto-displayed-mime-content-types '("text"));; "multipart"));; "image/xpm"
+
+(setq vm-mime-thumbnail-max-geometry nil)
+
+(setq vm-auto-displayed-mime-content-types '(
+                                             "text"
+                                             ;; "image/jpeg"
+                                             ;; "image/png"
+                                             "multipart"
+                                             "message/rfc822"
+                                             ))
+
+
+(setq
+      ;; browse-url-mozilla-program "iceweasel"
+      ;; mail-complete-style nil
+      ;; mail-from-style nil
+      ;; vm-coding-system-priorities '(utf-8)
+      ;; vm-highlighted-header-regexp "From:\\|Subject:\\|Cc:\\|To:\\|Bcc:\\|Reply-To:"
+      ;; vm-included-text-attribution-format "\nOn %w, %m %d, at %H, you wrote:\n\n"
       ;; vm-jump-to-new-messages nil
-      vm-startup-with-summary t
+      ;; vm-mime-7bit-composition-charset "latin-1"
+      ;; vm-mime-8bit-composition-charset "utf-8"
       ;; vm-preview-read-messages t
-      vm-preview-lines nil
+      ;; vm-summary-format " %*%A %-3.3m %2d %5US %I%UA  %s\n"
+      ;; vm-summary-uninteresting-senders-arrow "->"
+      ;; vm-summary-uninteresting-senders-arrow "►"
+      ;; vm-summary-uninteresting-senders-arrow "➔"
+      ;; vm-summary-uninteresting-senders-arrow "➤"
+      bbdb-send-mail-style 'vm
+      bbdb/mail-auto-create-p nil
+      mail-signature t
+      mail-specify-envelope-from t
+      vm-auto-folder-case-fold-search t
       vm-auto-get-new-mail t
       vm-circular-folders nil
       vm-confirm-new-folders t
-      vm-mutable-windows t
-      vm-mutable-frames nil
-      vm-summary-thread-indent-level 1
-      vm-summary-uninteresting-senders-arrow "->"
-      vm-summary-arrow "> "
-      vm-included-text-prefix " > "
+      vm-delete-after-archiving t
+      vm-delete-after-saving t
       vm-forwarding-digest-type "mime"
-      vm-mime-attachment-save-directory "~/"
-      vm-use-toolbar nil
+      vm-forwarding-subject-format "(forwarded from %F) %s"
       vm-frame-per-folder nil
       vm-frame-per-summary nil
-      vm-mime-yank-attachments nil
-
-      ;; vm-mime-7bit-composition-charset "latin-1"
-      vm-mime-8bit-composition-charset "iso-8859-1"
-      ;; vm-mime-8bit-composition-charset "utf-8"
-      ;; browse-url-mozilla-program "iceweasel"
-      vm-netscape-program browse-url-mozilla-program
-      ;; vm-coding-system-priorities '(utf-8)
-      ;; mail-from-style nil
-      ;; mail-complete-style nil
-
-      ;; vm-summary-format " %*%A %-3.3m %2d %5US %I%UA  %s\n"
-      vm-summary-format " %*%a %-3.3m %2d %5US %I%UA  %s\n"
-      ;; vm-highlighted-header-regexp "From:\\|Subject:\\|Cc:\\|To:\\|Bcc:\\|Reply-To:"
-      vm-highlighted-header-regexp "From:\\|Subject:"
-
-      vm-auto-folder-case-fold-search t
-
-      vm-keep-sent-messages nil
-      vm-delete-after-saving t
-      vm-delete-after-archiving t
-
-      vm-forwarding-subject-format "(forwarded from %F) %s"
+      vm-highlighted-header-regexp "From:\\|Subject:\\|Reply-To:"
       vm-in-reply-to-format nil
       vm-included-text-attribution-format "\nOn %w, %m %d, %y (%h), %F wrote:\n\n"
-      ;; vm-included-text-attribution-format "\nOn %w, %m %d, at %H, you wrote:\n\n"
+      vm-included-text-prefix " > "
+      vm-keep-sent-messages nil
+      vm-mime-8bit-composition-charset "iso-8859-1"
+      vm-mime-attachment-save-directory "~/misc/attachments"
+      vm-mime-yank-attachments nil
+      vm-mutable-frames nil
+      vm-mutable-windows t
+      vm-netscape-program browse-url-mozilla-program
+      vm-preview-lines nil
       vm-reply-subject-prefix "Re: "
-
-      mail-signature t
-      mail-specify-envelope-from t
-
-      bbdb/mail-auto-create-p nil
-      bbdb-send-mail-style 'vm
-
+      vm-skip-deleted-messages nil
+      vm-skip-read-messages nil
+      vm-startup-message-displayed t
+      vm-startup-with-summary t
+      vm-summary-arrow "> "
+      vm-summary-format " %*%a %-3.3m %2d %5US %I%UA  %s\n"
+      vm-summary-thread-indent-level 1
+      vm-summary-uninteresting-senders-arrow ">"
+      vm-use-menus nil
+      vm-use-toolbar nil
+      vm-use-toolbar nil
       )
 
-;; (add-to-list 'vm-visible-headers "Reply-To:" t)
+;; (add-to-list 'vm-visible-headers "From " t)
+(add-to-list 'vm-visible-headers "Reply-To:" t)
 ;; (add-to-list 'vm-visible-headers "X-Mailer:" t)
 ;; (add-to-list 'vm-visible-headers "X-from-in-bbdb:" t)
 ;; (add-to-list 'vm-visible-headers "Return-Path:")
 
 (setq
 
- ;; vm-auto-displayed-mime-content-types '("text/plain" "text" "image" "multipart")
- ;; vm-display-using-mime t
- ;; vm-coding-system-priorities '(iso-8859-1 iso-8859-15 utf-8)
-
  vm-infer-mime-types t
  vm-mime-use-image-strips nil
- vm-mime-base64-decoder-program "mimencode"
- vm-mime-base64-decoder-switches '("-u")
- vm-mime-base64-encoder-program "mimencode"
+ vm-mime-base64-decoder-program "base64"
+ vm-mime-base64-decoder-switches '("-d")
+ vm-mime-base64-encoder-program "base64"
  vm-mime-base64-encoder-switches '()
 
- vm-auto-displayed-mime-content-types '(
-                                        ;; "plain text"
-                                        "text"
-                                        "multipart"
-                                        "image/xpm"
-                                        )
-
- ;; vm-auto-displayed-mime-content-type-exceptions '("text/html")
-
  vm-mime-internal-content-types '(
                                   "multipart"
                                   "text"
                                   )
 
  ;; To force it to be converted to plain text
- vm-mime-internal-content-type-exceptions '("text/html")
;; vm-mime-internal-content-type-exceptions '("text/html")
 
  vm-mime-external-content-types-alist  '(
                                          ("application/x-dvi"      "xdvi")
                                          ("image/postscript"       "gv")
                                          ("application/pdf"        "xpdf")
-                                         ;; ("application/pdf"        "epdfview")
                                          ("application/postscript" "gv")
-                                         ;;("image"                  "feh")
+                                         ("image"                  "pho")
                                          ("video"                  "mplayer")
-                                         ;; ("text/html"             "iceweasel")
+                                         ;; ("text/html"              "firefox")
+                                         ;; ("application/pdf"        "epdfview")
                                          )
 
  )
 
 (require 'vm-rfaddons)
 
+;; The two following lines deal with windows-1252 buggy encoding
+
+;;**;; ;; First, don't display iso-8859-1 as-is in default face
+;;**;; (delete "iso-8859-1" vm-mime-default-face-charsets)
+;;**;; ;; Then substitute windows-1252 for iso-8859-1
+;;**;; (add-to-list 'vm-mime-mule-charset-to-coding-alist '("iso-8859-1" windows-1252))
+
+;; (setq vm-mime-default-face-charsets t)
+
 ;; (add-to-list 'vm-mime-default-face-charsets  "utf-8")
 
-(add-to-list 'vm-mime-default-face-charsets  "iso-8859-1")
+;; (add-to-list 'vm-mime-default-face-charsets "iso-8859-1")
+;; (add-to-list 'vm-mime-default-face-charsets "Windows-1251")
+;; (add-hook 'vm-mail-send-hook 'ff/vm-remove-non-7bits-in-headers)
+
 (add-hook 'vm-mail-send-hook 'vm-mime-encode-headers)
 (add-hook 'vm-mail-send-hook 'vm-mail-check-recipients)
 (add-hook 'vm-reply-hook (lambda () (set-buffer-modified-p nil)))
                ;; "html2text -style pretty -nobs"
                ;; ))
 
-(add-to-list 'vm-mime-type-converter-alist
-             '("text/html" "text/plain"
-               "html2text.sh"
-               ))
+;; (add-to-list 'vm-mime-type-converter-alist
+             ;; '("text/html" "text/plain"
+               ;; "html2text.sh"
+               ;; ))
 
 (add-to-list 'vm-mime-type-converter-alist
              '("image" "image/xpm"
 
 ;; (add-hook 'vm-mail-send-hook 'ff/vm-remove-properties)
 
-(defun ff/vm-mime-save-all-files (&optional delete)
-  "Save all the mail attachments. With delete argument, remove
-the attachement from mail."
-  (interactive "P")
-  (let ((vm-mime-delete-after-saving delete))
-    (while (and (vm-mime-reader-map-save-file)
-                (condition-case nil (vm-move-to-next-button 1)
-                  (error nil)))))
-  )
+;; (defun ff/vm-mime-save-all-files (&optional delete)
+  ;; "Save all the mail attachments. With delete argument, remove
+;; the attachement from mail."
+  ;; (interactive "P")
+  ;; (let ((vm-mime-delete-after-saving delete))
+    ;; (while (and (vm-mime-reader-map-save-file)
+                ;; (condition-case nil (vm-move-to-next-button 1)
+                  ;; (error nil)))))
+  ;; )
 
 (defun ff/vm-mime-save-file (&optional delete)
   "Save the current attachement. With delete argument, remove the
@@ -255,7 +281,9 @@ attachement from mail."
 (defun vm-summary-function-S (&optional message)
   (let ((s (string-to-int (vm-su-byte-count message))))
     (if (> s 32768)
-        (propertize (concat (int-to-string (/ s 1024)) "k") 'face 'bold)
+        (propertize (concat (int-to-string (/ s 1024)) "k")
+                    'face 'italic
+                    )
       "")))
 
 (defun ff/vm-delete-and-go-down () (interactive)
@@ -263,7 +291,10 @@ attachement from mail."
   (vm-delete-message 1)
   (condition-case nil (vm-next-message-no-skip 1) (error nil)))
 
-(add-hook 'vm-quit-hook 'vm-expunge-folder)
+(defun ff/vm-expunge-folder ()
+  (unless vm-folder-read-only (vm-expunge-folder)))
+
+(add-hook 'vm-quit-hook 'ff/vm-expunge-folder)
 (add-hook 'vm-quit-hook 'bbdb-save-db)
 (add-hook 'vm-retrieved-spooled-mail-hook 'display-time-update)
 
@@ -283,6 +314,7 @@ attachement from mail."
   (flyspell-mode)
   (auto-fill-mode)
   (mail-abbrevs-setup)
+  (yas/minor-mode)
 
   ;; (setq fill-paragraph-function 'mail-mode-fill-paragraph)
 
@@ -305,7 +337,9 @@ attachement from mail."
 ;; To have a slightly darker background for headers
 
 (ff/configure-faces
- '((ff/mail-header-face :background "#c8c8ff"))
+ ;; '((ff/mail-header-face :background "#c8c8ff"))
+ '((ff/mail-header-face :background "#f0f0f0"))
+ ;; '((ff/mail-header-face :foreground "blue4"))
  )
 
 (defun ff/colorize-headers () (interactive)
@@ -456,6 +490,21 @@ an attachment")
 
   )
 
+(defun ff/check-no-prolematic-dest ()
+  "Check that there are no \">,[^\ $]\" in the header"
+  (let ((s "no-subject"))
+    (save-excursion
+      (goto-char (point-min))
+      (let ((end-header (re-search-forward (concat "^" mail-header-separator "$") nil t)))
+        (when end-header
+          (goto-char (point-min))
+          (re-search-forward ">,[^\ ]" end-header t nil)
+          )
+        )
+      )
+    s))
+
+
 ;; You can not have a line starting with "From:" in a pure text
 ;; mail. The smtp server would add a leading character to prevent it.
 
@@ -513,17 +562,28 @@ an attachment")
 (add-hook 'vm-mail-send-hook 'ff/check-no-leading-from)
 (add-hook 'vm-mail-send-hook 'ff/check-no-excess-wording)
 (add-hook 'vm-mail-send-hook 'flyspell-mode-off)
+
+(defadvice vm-mail-send-and-exit (before ff/switch-flyspell-off nil activate)
+  (flyspell-mode-off))
+
 ;; Append so that it happens after the mime encoding
 ;; (add-hook 'vm-mail-send-hook 'ff/check-badly-encoded-address t)
+
 ;; Append this hook so that it runs after all other checks
 (add-hook 'vm-mail-send-hook 'ff/dissociate-file-from-vm-mail-buffer t)
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; If we can, encrypt!
 
+(add-hook 'vm-mode-hook 'mc-install-read-mode)
+(add-hook 'vm-summary-mode-hook 'mc-install-read-mode)
+(add-hook 'vm-virtual-mode-hook 'mc-install-read-mode)
+(add-hook 'vm-mail-mode-hook 'mc-install-write-mode)
+(add-hook 'vm-presentation-mode-hook 'mc-install-read-mode)
+
 ;; (defun ff/encrypt-mail-if-possible () (interactive)
-;; (condition-case nil (mc-encrypt)
-;; (error nil)))
+  ;; (condition-case nil (mc-encrypt-message)
+    ;; (error nil)))
 
 ;; (add-hook 'vm-mail-send-hook 'ff/encrypt-mail-if-possible t)
 
@@ -536,7 +596,8 @@ an attachment")
 (defun ff/goto-next-mail-field () (interactive)
   (let ((field (save-excursion
                  (end-of-line)
-                 (re-search-backward (concat "\\(^[a-zA-Z\-]*: \\|^" mail-header-separator "$\\)") nil t)
+                 (re-search-backward
+                  (concat "\\(^[a-zA-Z\-]*: \\|^" mail-header-separator "$\\)") nil t)
                  (match-string 1))))
 
     (cond ((string= field "To: ")
@@ -571,6 +632,7 @@ an attachment")
           t)
 
 (substitute-key-definition 'next-line 'mail-abbrev-next-line vm-mail-mode-map global-map)
+
 (substitute-key-definition 'end-of-buffer 'mail-abbrev-end-of-buffer vm-mail-mode-map global-map)
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -585,9 +647,9 @@ an attachment")
         (ff/first-buffer-in-mode (cdr l) m))))
 
 (defun ff/compose-mail (&optional force-new)
-  "Switch to an existing buffer with major mode `mail-mode',
+  "Cycles through an existing buffers with major mode `mail-mode',
 or invoke `vm-compose-mail' if none can be found or if FORCE-NEW
-is t. If already in a mail buffer, burry it and go to the next."
+is t."
   (interactive "P")
   (when (eq major-mode 'mail-mode) (bury-buffer))
   (let ((buf (and (not force-new)
@@ -605,9 +667,6 @@ is t. If already in a mail buffer, burry it and go to the next."
 
 (when (load "bbdb-vm" t)
 
-  ;; (defadvice define-mail-abbrev (before ff/remove-explicit-name (name definition &optional from-mailrc-file) activate)
-  ;; (message "%s -> %s" name definition))
-
   (defun ff/mail-aliases-from-bbdb ()
     "Creates automatically mail aliases from the bbdb records. For
 instance, someone in bbdb named \"Paul Smith\" would generate an alias
@@ -618,8 +677,10 @@ instance, someone in bbdb named \"Paul Smith\" would generate an alias
         (let* ((record (car records))
                (name (concat (elt record 0) " " (elt record 1)))
                (email (car (elt record 6)))
-               (alias (downcase (replace-regexp-in-string "\\([a-zA-Z]?\\)[^- ]*[- ]*" "\\1" name))))
-          (if (and (> (length alias) 1)
+               (alias (downcase (replace-regexp-in-string
+                                 "\\([a-zA-Z]?\\)[^- ]*[- ]*" "\\1" name))))
+          (if (and email
+                   (> (length alias) 1)
                    ;; Do not overwrite an existing alias
                    (not (and mail-abbrevs (intern-soft alias mail-abbrevs))))
               (define-mail-abbrev alias email))
@@ -629,3 +690,108 @@ instance, someone in bbdb named \"Paul Smith\" would generate an alias
     (bbdb-insinuate-vm)
     (ff/mail-aliases-from-bbdb))
   )
+
+(defun ff/pipe-to-tmp () (interactive)
+  (let ((link "/tmp/attach")
+        (dir (format-time-string "/tmp/attach-%Y%m%d-%H%M%S" (current-time))))
+    (mkdir dir)
+    (when (file-symlink-p link) (delete-file link))
+    (unless (file-exists-p link)
+      (make-symbolic-link dir "/tmp/attach" 1))
+    (vm-pipe-message-to-command (concat "munpack -C " dir))
+    (message "Wrote files to %s" dir)
+    )
+  )
+
+(defun ff/make-nonexisting-filename (filename)
+  (let ((root filename)
+        (extension "")
+        (result filename))
+    (when (file-exists-p result)
+      (when (string-match "^\\(.*\\)\\(\\.[^\\.]*\\)$" filename)
+        (setq root (match-string 1 filename)
+              extension (match-string 2 filename)))
+      (let ((n 0))
+        (while (file-exists-p (setq result (format "%s_%03d%s" root n extension)))
+          (setq n (+ n 1)))))
+    result))
+
+(defun ff/vm-mime-save-all-attachments (&optional count
+                                               directory
+                                               no-delete-after-saving)
+  "Save all attachments in the next COUNT messages or marked
+messages.  For the purpose of this function, an \"attachment\" is
+a mime part part which has \"attachment\" as its disposition or
+simply has an associated filename.  Any mime types that match
+`vm-mime-savable-types' but not `vm-mime-savable-type-exceptions'
+are also included.
+
+The attachments are saved to the specified DIRECTORY.  The
+variables `vm-all-attachments-directory' or
+`vm-mime-attachment-save-directory' can be used to set the
+default location.  When directory does not exist it will be
+created."
+  (interactive
+   (list current-prefix-arg
+         (vm-read-file-name
+          "Attachment directory: "
+          (or vm-mime-all-attachments-directory
+              vm-mime-attachment-save-directory
+              default-directory)
+          (or vm-mime-all-attachments-directory
+              vm-mime-attachment-save-directory
+              default-directory)
+          nil nil
+          vm-mime-save-all-attachments-history)))
+
+  (vm-check-for-killed-summary)
+  (if (interactive-p) (vm-follow-summary-cursor))
+
+  (let ((n 0))
+    (vm-mime-action-on-all-attachments
+     count
+     ;; the action to be performed BEGIN
+     (lambda (msg layout type file)
+       (let ((directory (if (functionp directory)
+                            (funcall directory msg)
+                          directory)))
+         (setq file
+              (if file
+                  (expand-file-name (file-name-nondirectory file) directory)
+                (vm-read-file-name
+                 (format "Save %s to file: " type)
+                 (or directory
+                     vm-mime-all-attachments-directory
+                     vm-mime-attachment-save-directory)
+                 (or directory
+                     vm-mime-all-attachments-directory
+                     vm-mime-attachment-save-directory)
+                 nil nil
+                 vm-mime-save-all-attachments-history)
+                ))
+
+         (setq file (ff/make-nonexisting-filename file))
+
+         (when file
+           (message "Saving `%s%s" type (if file (format " (%s)" file) ""))
+           (make-directory (file-name-directory file) t)
+           (vm-mime-send-body-to-file layout file file)
+           (if vm-mime-delete-after-saving
+               (let ((vm-mime-confirm-delete nil))
+                 (vm-mime-discard-layout-contents
+                 layout (expand-file-name file))))
+           (setq n (+ 1 n)))))
+     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; the action to be performed END
+     ;; attachment filters
+     vm-mime-savable-types
+     vm-mime-savable-type-exceptions)
+
+    (when (interactive-p)
+      (vm-discard-cached-data)
+      (vm-preview-current-message))
+
+    (if (> n 0)
+        (message "%d attachment%s saved" n (if (= n 1) "" "s"))
+      (message "No attachments to be saved!"))))
+
+(define-key vm-summary-mode-map [(control c) (control s)] 'ff/vm-mime-save-all-attachments)