From mboxrd@z Thu Jan 1 00:00:00 1970 From: Iain Houston Subject: mac-message for Growl 2 Date: Sun, 4 Aug 2013 21:39:38 +0100 Message-ID: Mime-Version: 1.0 (Mac OS X Mail 6.5 \(1508\)) Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: quoted-printable Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:39872) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V655n-0007ze-Ox for emacs-orgmode@gnu.org; Sun, 04 Aug 2013 16:40:00 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1V655i-0007Ca-OK for emacs-orgmode@gnu.org; Sun, 04 Aug 2013 16:39:55 -0400 Received: from leo.misfits-server.net ([81.137.126.121]:53028) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V655i-0007AK-A4 for emacs-orgmode@gnu.org; Sun, 04 Aug 2013 16:39:50 -0400 Received: from localhost (localhost [127.0.0.1]) by leo.misfits-server.net (Postfix) with ESMTP id 08677B36531 for ; Sun, 4 Aug 2013 21:39:42 +0100 (BST) Received: from leo.misfits-server.net ([127.0.0.1]) by localhost (leo.misfits-server.net [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id VAIkBI7GvCnv for ; Sun, 4 Aug 2013 21:39:40 +0100 (BST) Received: from macbook-wifi.home (macbook-wifi.home [192.168.1.69]) by leo.misfits-server.net (Postfix) with ESMTPSA id 4F63FB36524 for ; Sun, 4 Aug 2013 21:39:40 +0100 (BST) List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org Sender: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org To: emacs-orgmode@gnu.org I encountered a few problems with org-mac-mail bundled with emacs = 24.3.1; some errors interfacing with Growl (2.1) so the patch below = works for me and I wondered whether it would be of use to anyone else. I adapted the insertion of flagged mail to look at all active mail = accounts rather than having to name any particular one. This is how I use org-mac-message: and below is the patch. (require 'org) (load "org-mac-message") (global-set-key [(shift f10)] (lambda() (interactive) (progn (find-file-noselect = "~/Dropbox/org/refile.org") (org-mac-message-insert-flagged = "refile.org" "Flagged mail")))) diff --git a/org-mac-message.el b/org-mac-message.el index 5df68f5..be2a654 100644 --- a/org-mac-message.el +++ b/org-mac-message.el @@ -95,86 +95,89 @@ This will use the command `open' with the message = URL." "return theLinkList as string\n" "end tell"))) =20 -(defun as-get-flagged-mail () - "AppleScript to create links to flagged messages in Mail.app." - (do-applescript - (concat - ;; Is Growl installed? - "tell application \"System Events\"\n" - "set growlHelpers to the name of every process whose creator type = contains \"GRRR\"\n" - "if (count of growlHelpers) > 0 then\n" - "set growlHelperApp to item 1 of growlHelpers\n" - "else\n" - "set growlHelperApp to \"\"\n" - "end if\n" - "end tell\n" - - ;; Get links - "tell application \"Mail\"\n" - "set theMailboxes to every mailbox of account \"" = org-mac-mail-account "\"\n" - "set theLinkList to {}\n" - "repeat with aMailbox in theMailboxes\n" - "set theSelection to (every message in aMailbox whose flagged = status =3D true)\n" - "repeat with theMessage in theSelection\n" - "set theID to message id of theMessage\n" - "set theSubject to subject of theMessage\n" - "set theLink to \"message://\" & theID & \"::split::\" & theSubject = & \"\n\"\n" - "copy theLink to end of theLinkList\n" - - ;; Report progress through Growl - ;; This "double tell" idiom is described in detail at - ;; http://macscripter.net/viewtopic.php?id=3D24570 The - ;; script compiler needs static knowledge of the - ;; growlHelperApp. Hmm, since we're compiling - ;; on-the-fly here, this is likely to be way less - ;; portable than I'd hoped. It'll work when the name - ;; is still "GrowlHelperApp", though. - "if growlHelperApp is not \"\" then\n" - "tell application \"GrowlHelperApp\"\n" - "tell application growlHelperApp\n" - "set the allNotificationsList to {\"FlaggedMail\"}\n" - "set the enabledNotificationsList to allNotificationsList\n" - "register as application \"FlaggedMail\" all notifications = allNotificationsList default notifications enabledNotificationsList icon = of application \"Mail\"\n" - "notify with name \"FlaggedMail\" title \"Importing flagged = message\" description theSubject application name \"FlaggedMail\"\n" - "end tell\n" - "end tell\n" - "end if\n" - "end repeat\n" - "end repeat\n" - "return theLinkList as string\n" - "end tell"))) +(defun as-get-flagged-mail () + "AppleScript to create links to flagged messages in all Mail.app = accounts" + ;; Revised use of Growl interface and no need for variable = org-mac-mail-account + (do-applescript + (concat + ;; Is Growl running? Use API as recommended at = http://growl.info/documentation/applescript-support.php=20 + "tell application \"System Events\"\n" + "set growlIsRunning to (count of (every process whose bundle = identifier is \"com.Growl.GrowlHelperApp\")) > 0\n" + "end tell\n" + + "set theLinkList to {}\n" + "set isNotRegisteredToGrowl to true\n" + "tell application \"Mail\"\n" + "set theAccountList to the name of every account\n" + "repeat with theMailAccount in theAccountList\n" + "set theMailboxes to every mailbox of account theMailAccount\n" + "repeat with aMailbox in theMailboxes\n" + "set theSelection to (every message in aMailbox whose flagged = status =3D true)\n" + "repeat with theMessage in theSelection\n" + "set theID to message id of theMessage\n" + "set theSubject to subject of theMessage\n" + "set theLink to \"message://\" & theID & \"::split::\" & = theSubject & \"\n\"\n" + "copy theLink to end of theLinkList\n" + =20 + "if growlIsRunning then\n" + "tell application id \"com.Growl.GrowlHelperApp\"\n" + "if isNotRegisteredToGrowl then\n" + "set the allNotificationsList to {\"FlaggedMail\"}\n" + "set the enabledNotificationsList to allNotificationsList\n" + "register as application \"FlaggedMail\" all notifications = allNotificationsList default notifications enabledNotificationsList icon = of application \"Mail\"\n" + "set isNotRegisteredToGrowl to false\n" + "end if\n" + "notify with name \"FlaggedMail\" title \"Importing flagged = message\" description theSubject application name \"FlaggedMail\"\n" + "end tell\n" + "end if\n" + =20 + "end repeat\n" + "end repeat\n" + "end repeat\n" + "end tell\n" + "return theLinkList as string\n" + )) + ) =20 (defun org-mac-message-get-links (&optional select-or-flag) - "Create links to the messages currently selected or flagged in = Mail.app. + "Overridden function. +Create links to the messages currently selected or flagged in Mail.app. This will use AppleScript to get the message-id and the subject of the messages in Mail.app and make a link out of it. When SELECT-OR-FLAG is \"s\", get the selected messages (this is also the default). When SELECT-OR-FLAG is \"f\", get the flagged messages. The Org-syntax text will be pushed to the kill ring, and also = returned." - (interactive "sLink to (s)elected or (f)lagged messages: ") - (setq select-or-flag (or select-or-flag "s")) - (message "AppleScript: searching mailboxes...") - (let* ((as-link-list - (if (string=3D select-or-flag "s") - (as-get-selected-mail) - (if (string=3D select-or-flag "f") - (as-get-flagged-mail) - (error "Please select \"s\" or \"f\"")))) - (link-list - (mapcar - (lambda (x) (if (string-match "\\`\"\\(.*\\)\"\\'" x) (setq x = (match-string 1 x))) x) - (split-string as-link-list "[\r\n]+"))) - split-link URL description orglink orglink-insert rtn = orglink-list) - (while link-list - (setq split-link (split-string (pop link-list) "::split::")) - (setq URL (car split-link)) - (setq description (cadr split-link)) - (when (not (string=3D URL "")) - (setq orglink (org-make-link-string URL description)) - (push orglink orglink-list))) - (setq rtn (mapconcat 'identity orglink-list "\n")) - (kill-new rtn) - rtn)) + (interactive "sLink to (s)elected or (f)lagged messages: ") + (setq select-or-flag (or select-or-flag "s")) + (let* ((as-link-list + (if (string=3D select-or-flag "s") + (progn + (message "AppleScript: searching mailboxes for = selected message") + (as-get-selected-mail)) + (if (string=3D select-or-flag "f") + (progn =20 + ;; searching for all flagged messages can take tens = of seconds + ;; so user needs to be told of progress even if = Growl is also notifying=20 + (message "AppleScript: searching mailboxes for = flagged messages") + (as-get-flagged-mail)) + (error "Please select \"s\" or \"f\"")))) + (link-list + (mapcar + (lambda (x) (if (string-match "\\`\"\\(.*\\)\"\\'" x) = (setq x (match-string 1 x))) x) + (split-string as-link-list "[\r\n]+"))) + split-link URL description orglink orglink-insert rtn = orglink-list) + (while link-list + (setq split-link (split-string (pop link-list) "::split::")) + (setq URL (car split-link)) + (setq description (cadr split-link)) + (when (not (string=3D URL "")) + (setq orglink (org-make-link-string URL description)) + (push orglink orglink-list))) + (setq rtn (mapconcat 'identity orglink-list "\n")) + (kill-new rtn) + ;; "searching" message will remain in echo area until replaced + (message "AppleScript: finished searching mailboxes.") + rtn)) =20 (defun org-mac-message-insert-selected () "Insert a link to the messages currently selected in Mail.app. @@ -186,30 +189,41 @@ active mail in Mail.app and make a link out of = it." ;; The following line is for backward compatibility (defalias 'org-mac-message-insert-link = 'org-mac-message-insert-selected) =20 -(defun org-mac-message-insert-flagged (org-buffer org-heading) - "Asks for an org buffer and a heading within it, and replace message = links. +(eval-after-load "org-mac-message" + '(defun org-mac-message-insert-flagged (org-buffer org-heading) + "Asks for an org buffer and a heading within it, and replace = message links. If heading exists, delete all message:// links within heading's first level. If heading doesn't exist, create it at point-max. Insert list of message:// links to flagged mail after heading." - (interactive "bBuffer in which to insert links: \nsHeading after = which to insert links: ") - (with-current-buffer org-buffer - (goto-char (point-min)) - (let ((isearch-forward t) - (message-re = "\\[\\[\\(message:\\)\\([^]]+\\)\\]\\(\\[\\([^]]+\\)\\]\\)?\\]")) - (if (org-goto-local-search-headings org-heading nil t) - (if (not (eobp)) - (progn - (save-excursion - (while (re-search-forward - message-re (save-excursion = (outline-next-heading)) t) - (delete-region (match-beginning 0) (match-end 0))) - (insert "\n" (org-mac-message-get-links "f"))) - (flush-lines "^$" (point) (outline-next-heading))) - (insert "\n" (org-mac-message-get-links "f"))) - (goto-char (point-max)) - (insert "\n") - (org-insert-heading nil t) - (insert org-heading "\n" (org-mac-message-get-links "f")))))) + (interactive "bBuffer in which to insert links: \nsHeading after = which to insert links: ") + (with-current-buffer org-buffer + (goto-char (point-min)) + (let ((isearch-forward t) + (message-re = "\\[\\[\\(message:\\)\\([^]]+\\)\\]\\(\\[\\([^]]+\\)\\]\\)?\\]")) + (if (org-goto-local-search-headings org-heading nil t) + (if (not (eobp)) + (progn + (save-excursion + ;; delete previously recorded flagged messages + (while (re-search-forward + message-re (save-excursion = (outline-next-heading)) t) + (delete-region (match-beginning 0) (match-end = 0))) + (insert "\n" (org-mac-message-get-links "f"))) + ;; apparently also delete empty lines. + ;; allow for situation where there is no next-heading + ;; to avoid previously ocurring Lisp errors + (let ( + (frm (point)) + (tom (outline-next-heading))) + (if (null tom) (setq tom (point-max))) + (flush-lines "^$" frm tom))) + + (insert "\n" (org-mac-message-get-links "f"))) + (goto-char (point-max)) + (insert "\n") + (org-insert-heading nil t) + (insert org-heading "\n" (org-mac-message-get-links "f")))))) + ) =20 (provide 'org-mac-message) =20