diff --git a/emacs/Makefile.am b/emacs/Makefile.am index 110ccebd..4b5d3c9e 100644 --- a/emacs/Makefile.am +++ b/emacs/Makefile.am @@ -1,4 +1,4 @@ -## Copyright (C) 2008-2011 Dirk-Jan C. Binnema +## Copyright (C) 2008-2012 Dirk-Jan C. Binnema ## ## 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 @@ -35,6 +35,7 @@ elisp_DATA= \ mu4e-view.el \ mu4e-proc.el \ mu4e-send.el \ - mu4e-version.el + mu4e-version.el \ + org-mu4e.el EXTRA_DIST=$(elisp_DATA) diff --git a/emacs/mu4e-hdrs.el b/emacs/mu4e-hdrs.el index d3b49c6e..14194cd8 100644 --- a/emacs/mu4e-hdrs.el +++ b/emacs/mu4e-hdrs.el @@ -1,11 +1,9 @@ -;; mu4e-hdrs.el -- part of mm, the mu mail user agent +;; mu4e-hdrs.el -- part of mu4e, the mu mail user agent ;; -;; Copyright (C) 2011 Dirk-Jan C. Binnema +;; Copyright (C) 2011-2012 Dirk-Jan C. Binnema ;; Author: Dirk-Jan C. Binnema ;; Maintainer: Dirk-Jan C. Binnema -;; Keywords: email -;; Version: 0.0 ;; This file is not part of GNU Emacs. ;; @@ -28,8 +26,6 @@ ;; descriptions of emails, aka 'headers' (not to be confused with headers like ;; 'To:' or 'Subject:') -;; mm - ;; Code: (eval-when-compile (require 'cl)) @@ -39,7 +35,6 @@ ;;;; internal variables/constants ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defvar mu4e-last-expr nil "*internal* The most recent search expression.") - (defconst mu4e-hdrs-buffer-name "*mu4e-headers*" "*internal* Name of the buffer for message headers.") @@ -322,6 +317,15 @@ after the end of the search results." (fset 'mu4e-hdrs-mode-map mu4e-hdrs-mode-map) + ;; we register our handler functions for the mu4e-proc (mu server) output +(setq mu4e-proc-error-func 'mu4e-hdrs-error-handler) +(setq mu4e-proc-update-func 'mu4e-hdrs-update-handler) +(setq mu4e-proc-header-func 'mu4e-hdrs-header-handler) +(setq mu4e-proc-found-func 'mu4e-hdrs-found-handler) +(setq mu4e-proc-view-func 'mu4e-hdrs-view-handler) +(setq mu4e-proc-remove-func 'mu4e-hdrs-remove-handler) +;; this last one is defined in mu4e-send.el +(setq mu4e-proc-compose-func 'mu4e-send-compose-handler) (defun mu4e-hdrs-mode () "Major mode for displaying mua search results." @@ -336,16 +340,6 @@ after the end of the search results." (make-local-variable 'mu4e-msg-map) (make-local-variable 'mu4e-thread-info-map) - ;; we register our handler functions for the mu4e-proc (mu server) output - (setq mu4e-proc-error-func 'mu4e-hdrs-error-handler) - (setq mu4e-proc-update-func 'mu4e-hdrs-update-handler) - (setq mu4e-proc-header-func 'mu4e-hdrs-header-handler) - (setq mu4e-proc-found-func 'mu4e-hdrs-found-handler) - (setq mu4e-proc-view-func 'mu4e-hdrs-view-handler) - (setq mu4e-proc-remove-func 'mu4e-hdrs-remove-handler) - ;; this last one is defined in mu4e-send.el - (setq mu4e-proc-compose-func 'mu4e-send-compose-handler) - (setq mu4e-marks-map (make-hash-table :size 16 :rehash-size 2) mu4e-msg-map (make-hash-table :size 1024 :rehash-size 2 :weakness nil) @@ -356,7 +350,7 @@ after the end of the search results." buffer-undo-list t ;; don't record undo information buffer-read-only t overwrite-mode 'overwrite-mode-binary) - + (setq header-line-format (cons (make-string (floor (fringe-columns 'left t)) ?\s) @@ -583,6 +577,7 @@ work well." (unless docid (error "No message at point.")) (mu4e-proc-view-msg docid))) + (defun mu4e-hdrs-compose (compose-type) "Compose either a reply/forward based on the message at point. or start editing it. COMPOSE-TYPE is either `reply', `forward' or @@ -619,12 +614,10 @@ start editing it. COMPOSE-TYPE is either `reply', `forward' or (defun mu4e-ignore-marks () "If there are still marks in the header list, warn the user." (if mu4e-marks-map - (let* - ((num - (hash-table-count mu4e-marks-map)) - (unmark (or (= 0 num) - (y-or-n-p - (format "Sure you want to unmark %d message(s)?" num))))) + (let* ((num (hash-table-count mu4e-marks-map)) + (unmark (or (= 0 num) + (y-or-n-p + (format "Sure you want to unmark %d message(s)?" num))))) (message nil) unmark)) t) diff --git a/emacs/mu4e-proc.el b/emacs/mu4e-proc.el index b504d4f9..452add99 100644 --- a/emacs/mu4e-proc.el +++ b/emacs/mu4e-proc.el @@ -1,11 +1,9 @@ -;;; mu4e-proc.el -- part of mm, the mu mail user agent +;;; mu4e-proc.el -- part of mu4e, the mu mail user agent ;; -;; Copyright (C) 2011 Dirk-Jan C. Binnema +;; Copyright (C) 2011-2012 Dirk-Jan C. Binnema ;; Author: Dirk-Jan C. Binnema ;; Maintainer: Dirk-Jan C. Binnema -;; Keywords: email -;; Version: 0.0 ;; This file is not part of GNU Emacs. ;; @@ -418,10 +416,12 @@ set to e.g. '/drafts'; if this works, we will receive (:info :path response." (mu4e-proc-send-command "ping")) -(defun mu4e-proc-view-msg (docid) - "Get one particular message based on its DOCID. The result will +(defun mu4e-proc-view-msg (docid-or-msgid) + "Get one particular message based on its DOCID-OR-MSGID. The result will be delivered to the function registered as `mu4e-proc-message-func'." - (mu4e-proc-send-command "view %d" docid)) + (if (stringp docid-or-msgid) + (mu4e-proc-send-command "view %s" docid-or-msgid) + (mu4e-proc-send-command "view %d" docid-or-msgid))) (defun mu4e-proc-compose (compose-type docid) "Start composing a message with DOCID and COMPOSE-TYPE (a symbol, @@ -452,5 +452,6 @@ and update the database afterwards." (with-current-buffer buf (kill-buffer-and-window)))) - (provide 'mu4e-proc) + +;; End of mu4e-proc.el diff --git a/emacs/mu4e-view.el b/emacs/mu4e-view.el index f7b2ac5b..5e07acde 100644 --- a/emacs/mu4e-view.el +++ b/emacs/mu4e-view.el @@ -1,11 +1,9 @@ ;; mu4e-view.el -- part of mu4e, the mu mail user agent ;; -;; Copyright (C) 2011 Dirk-Jan C. Binnema +;; Copyright (C) 2011-2012 Dirk-Jan C. Binnema ;; Author: Dirk-Jan C. Binnema ;; Maintainer: Dirk-Jan C. Binnema -;; Keywords: email -;; Version: 0.0 ;; This file is not part of GNU Emacs. ;; @@ -49,6 +47,12 @@ (defvar mu4e-current-msg nil "*internal* The plist describing the current message.") +(defun mu4e-view-message-with-msgid (msgid) + "View message with MSGID. This is meant for external programs +wanting to show specific messages - for example, `mu4e-org'." + (mu4e-proc-view-msg msgid)) + + (defun mu4e-view (msg hdrsbuf &optional update) "Display the message MSG in a new buffer, and keep in sync with HDRSBUF. 'In sync' here means that moving to the next/previous message in @@ -118,7 +122,7 @@ marking if it still had that." (mu4e-mark-footer) (mu4e-make-urls-clickable) - + (unless update (mu4e-view-mark-as-read-maybe))))) @@ -387,7 +391,7 @@ Seen; if the message is not New/Unread, do nothing." (lexical-let ((url url)) (lambda () (interactive) - (browse-url url)))) + (browse-url url)))) @@ -411,7 +415,7 @@ number them so they can be opened using `mu4e-view-go-to-url'." (replace-match (concat url (propertize (format "[%d]" num) 'face 'mu4e-view-url-number-face)))))))) - + ;; raw mode ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -506,37 +510,34 @@ number them so they can be opened using `mu4e-view-go-to-url'." ;; functions for org-contacts -(defun mu4e-org-contacts-from (name-or-email) - "Get a message field if we are in view mode; NAME-OR-EMAIL should -be either 'name or 'email to get the corresponding field. If the -field is not found, \"\" is returned. Use this with org-contact -with a template like: +(defun mu4e-view-snarf-from (name-or-email) + "Get the From:-data for the current message; NAME-OR-EMAIL should +be a symbol 'name or 'email to get the corresponding field. If the +field is not found, \"\" is returned. +You can use this with e.g. org-contact with a template like: (\"c\" \"Contacts\" entry (file \"~/Org/contacts.org\") - \"* %(mu4e-org-contacts-from 'name) + \"* %(mu4e-view-snarf-from 'name) :PROPERTIES: - :EMAIL: %(mu4e-org-contacts-from 'email) + :EMAIL: %(mu4e-view-snarf-from 'email) :END:\"))) See the `org-contacts' documentation for more details." - (with-current-buffer mu4e-view-buffer-name ;; hackish... - (unless (eq major-mode 'mu4e-view-mode) - (error "Not in mu4e-view mode.")) - (unless mu4e-current-msg - (error "No current message.")) - (let ((from (car-safe (plist-get mu4e-current-msg :from)))) - (cond - ((not from) "") ;; nothing found - ((eq name-or-email 'name) - (or (car-safe from) "")) - ((eq name-or-email 'email) - (or (cdr-safe from) "")) - (t (error "Not supported: %S" name-or-email)))))) + (unless (eq major-mode 'mu4e-view-mode) + (error "Not in mu4e-view mode.")) + (unless mu4e-current-msg + (error "No current message.")) + (let ((from (car-safe (plist-get mu4e-current-msg :from)))) + (cond + ((not from) "") ;; nothing found + ((eq name-or-email 'name) + (or (car-safe from) "")) + ((eq name-or-email 'email) + (or (cdr-safe from) "")) + (t (error "Not supported: %S" name-or-email))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - - ;; Interactive functions diff --git a/emacs/org-mu4e.el b/emacs/org-mu4e.el new file mode 100644 index 00000000..df844ed6 --- /dev/null +++ b/emacs/org-mu4e.el @@ -0,0 +1,77 @@ +;;; org-mu4e -- Support for links to mu4e messages/queries from within org-mode +;; +;; Copyright (C) 2012 Dirk-Jan C. Binnema + +;; Author: Dirk-Jan C. Binnema +;; Maintainer: Dirk-Jan C. Binnema +;; Keywords: outlines, hypermedia, calendar, mail +;; Version: 0.0 + +;; This file is not part of GNU Emacs. +;; +;; GNU Emacs 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 3 of the License, or +;; (at your option) any later version. + +;; 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 +;; along with GNU Emacs. If not, see . + +;;; Commentary: + +;;; Code: + +(require 'org) +(eval-when-compile (require 'cl)) +(eval-when-compile (require 'mu4e)) + +(defun org-mu4e-store-link () + "Store a link to a mu4e query or message." + (cond + ;; storing links to queries + ((eq major-mode 'mu4e-hdrs-mode) + (let* ((query mu4e-last-expr) + desc link) + (org-store-link-props :type "mu4e" :query query) + (setq + desc (org-make-link "mu4e:query:" query) + link desc) + (org-add-link-props :link link :description desc) + link)) + + ;; storing links to messages + ((eq major-mode 'mu4e-view-mode) + (let* ((msg mu4e-current-msg) + (msgid (or (plist-get msg :message-id) "")) + (subject (or (plist-get msg :subject) "No subject")) + link) + (org-store-link-props :type "mu4e" :link link + :message-id msgid :subject subject) + (setq link (org-make-link "mu4e:msgid:" msgid)) + (org-add-link-props :link link :description subject) + link)))) + +(org-add-link-type "mu4e" 'org-mu4e-open) +(add-hook 'org-store-link-functions 'org-mu4e-store-link) + +(defun org-mu4e-open (path) + "Open the mu4e message (for paths starting with 'msgid:') or run +the query (for paths starting with 'query:')." + (require 'mu4e) + (cond + ((string-match "^msgid:\\(.+\\)" path) + (mu4e-view-message-with-msgid (match-string 1 path))) + ((string-match "^query:\\(.+\\)" path) + (mu4e-search (match-string 1 path))) + (t (message "mu4e: unrecognized link type '%s'" path)))) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(provide 'org-mu4e) + +;;; org-mu4e.el ends here diff --git a/man/mu-server.1 b/man/mu-server.1 index 3bfdaaba..7f22d053 100644 --- a/man/mu-server.1 +++ b/man/mu-server.1 @@ -1,8 +1,8 @@ -.TH MU-SERVER 1 "December 2011" "User Manuals" +.TH MU-SERVER 1 "January 2012" "User Manuals" .SH NAME -mu server \- the mu backend for the mm e-mail cleint +mu server \- the mu backend for the mu4e e-mail cleint .SH DESCRIPTION @@ -131,7 +131,7 @@ Using the \fBview\fR command, we can all information (including the body) of a particular e-mail message. .nf --> view +-> view <- (:view ) .fi diff --git a/src/mu-cmd-server.c b/src/mu-cmd-server.c index 367399d6..93c7f8ad 100644 --- a/src/mu-cmd-server.c +++ b/src/mu-cmd-server.c @@ -1,6 +1,6 @@ /* -*-mode: c; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-*/ /* -** Copyright (C) 2010-2011 Dirk-Jan C. Binnema +** Copyright (C) 2011-2012 Dirk-Jan C. Binnema ** ** 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 @@ -441,8 +441,6 @@ get_docid_from_msgid (MuQuery *query, const char *str, GError **err) } - - /* the string contains either a number (docid) or a message-id if it * doesn't look like a number, and the query param is non-nil, try to * locale the message with message-id in the database, and return its @@ -720,15 +718,15 @@ cmd_open (MuStore *store, GSList *args, GError **err) static MuError -cmd_view (MuStore *store, GSList *args, GError **err) +cmd_view (MuStore *store, MuQuery *query, GSList *args, GError **err) { MuMsg *msg; unsigned docid; char *sexp; - return_if_fail_param_num (args, 1, 1, "view "); + return_if_fail_param_num (args, 1, 1, "view |"); - docid = get_docid (NULL, (const char*)args->data, err); + docid = get_docid (query, (const char*)args->data, err); if (docid == MU_STORE_INVALID_DOCID) return server_error (err, MU_ERROR_IN_PARAMETERS, "invalid docid"); @@ -901,7 +899,7 @@ handle_command (Cmd cmd, MuStore *store, MuQuery *query, GSList *args, case CMD_REMOVE: rv = cmd_remove (store, args, err); break; case CMD_SAVE: rv = cmd_save (store, args, err); break; case CMD_PING: rv = cmd_ping (store, args, err); break; - case CMD_VIEW: rv = cmd_view (store, args, err); break; + case CMD_VIEW: rv = cmd_view (store, query, args, err); break; case CMD_IGNORE: return TRUE; default: