Reduce the cluttering in the agenda display due to ISO weeks.
[org-mode.git] / org-mhe.el
blobe1d75657c2ed60069c4640d8855283ddf5a02125
1 ;;; org-mhe.el - Support for links to MHE messages in Org-mode
3 ;; Copyright (C) 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
5 ;; Author: Carsten Dominik <carsten at orgmode dot org>
6 ;; Keywords: outlines, hypermedia, calendar, wp
7 ;; Homepage: http://orgmode.org
8 ;; Version: 1.0
9 ;;
10 ;; This file is part of GNU Emacs.
12 ;; GNU Emacs is free software; you can redistribute it and/or modify
13 ;; it under the terms of the GNU General Public License as published by
14 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; any later version.
17 ;; GNU Emacs is distributed in the hope that it will be useful,
18 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 ;; GNU General Public License for more details.
22 ;; You should have received a copy of the GNU General Public License
23 ;; along with GNU Emacs; see the file COPYING. If not, write to the
24 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
25 ;; Boston, MA 02110-1301, USA.
26 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
28 ;;; Commentary:
30 ;; This file implements links to MHE messages for Org-mode.
31 ;; Org-mode loads this module by default - if this is not what you want,
32 ;; configure the variable `org-modules'.
34 (require 'org)
36 ;; Customization variables
37 (defcustom org-mhe-search-all-folders nil
38 "Non-nil means, that the search for the mh-message will be extended to
39 all folders if the message cannot be found in the folder given in the link.
40 Searching all folders is very efficient with one of the search engines
41 supported by MH-E, but will be slow with pick."
42 :group 'org-link-follow
43 :type 'boolean)
45 ;; Declare external functions and variables
46 (declare-function mh-display-msg "mh-show" (msg-num folder-name))
47 (declare-function mh-find-path "mh-utils" ())
48 (declare-function mh-get-header-field "mh-utils" (field))
49 (declare-function mh-get-msg-num "mh-utils" (error-if-no-message))
50 (declare-function mh-header-display "mh-show" ())
51 (declare-function mh-index-previous-folder "mh-search" ())
52 (declare-function mh-normalize-folder-name "mh-utils"
53 (folder &optional empty-string-okay dont-remove-trailing-slash
54 return-nil-if-folder-empty))
55 (declare-function mh-search "mh-search"
56 (folder search-regexp &optional redo-search-flag
57 window-config))
58 (declare-function mh-search-choose "mh-search" (&optional searcher))
59 (declare-function mh-show "mh-show" (&optional message redisplay-flag))
60 (declare-function mh-show-buffer-message-number "mh-comp" (&optional buffer))
61 (declare-function mh-show-header-display "mh-show" t t)
62 (declare-function mh-show-msg "mh-show" (msg))
63 (declare-function mh-show-show "mh-show" t t)
64 (declare-function mh-visit-folder "mh-folder" (folder &optional
65 range index-data))
66 (defvar mh-progs)
67 (defvar mh-current-folder)
68 (defvar mh-show-folder-buffer)
69 (defvar mh-index-folder)
70 (defvar mh-searcher)
72 ;; Install the link type
73 (org-add-link-type "mhe" 'org-mhe-open)
74 (add-hook 'org-store-link-functions 'org-mhe-store-link)
76 ;; Implementation
77 (defun org-mhe-store-link ()
78 "Store a link to an MHE folder or message."
79 (when (or (equal major-mode 'mh-folder-mode)
80 (equal major-mode 'mh-show-mode))
81 (let ((from (org-mhe-get-header "From:"))
82 (to (org-mhe-get-header "To:"))
83 (message-id (org-mhe-get-header "Message-Id:"))
84 (subject (org-mhe-get-header "Subject:"))
85 link desc)
86 (org-store-link-props :type "mh" :from from :to to
87 :subject subject :message-id message-id)
88 (setq desc (org-email-link-description))
89 (setq link (org-make-link "mhe:" (org-mhe-get-message-real-folder) "#"
90 (org-remove-angle-brackets message-id)))
91 (org-add-link-props :link link :description desc)
92 link)))
94 (defun org-mhe-open (path)
95 "Follow an MHE message link."
96 (let (folder article)
97 (if (not (string-match "\\`\\([^#]+\\)\\(#\\(.*\\)\\)?" path))
98 (error "Error in MHE link"))
99 (setq folder (match-string 1 path)
100 article (match-string 3 path))
101 (org-mhe-follow-link folder article)))
103 ;;; mh-e integration based on planner-mode
104 (defun org-mhe-get-message-real-folder ()
105 "Return the name of the current message real folder, so if you use
106 sequences, it will now work."
107 (save-excursion
108 (let* ((folder
109 (if (equal major-mode 'mh-folder-mode)
110 mh-current-folder
111 ;; Refer to the show buffer
112 mh-show-folder-buffer))
113 (end-index
114 (if (boundp 'mh-index-folder)
115 (min (length mh-index-folder) (length folder))))
117 ;; a simple test on mh-index-data does not work, because
118 ;; mh-index-data is always nil in a show buffer.
119 (if (and (boundp 'mh-index-folder)
120 (string= mh-index-folder (substring folder 0 end-index)))
121 (if (equal major-mode 'mh-show-mode)
122 (save-window-excursion
123 (let (pop-up-frames)
124 (when (buffer-live-p (get-buffer folder))
125 (progn
126 (pop-to-buffer folder)
127 (org-mhe-get-message-folder-from-index)
130 (org-mhe-get-message-folder-from-index)
132 folder
136 (defun org-mhe-get-message-folder-from-index ()
137 "Returns the name of the message folder in a index folder buffer."
138 (save-excursion
139 (mh-index-previous-folder)
140 (re-search-forward "^\\(+.*\\)$" nil t)
141 (message "%s" (match-string 1))))
143 (defun org-mhe-get-message-folder ()
144 "Return the name of the current message folder. Be careful if you
145 use sequences."
146 (save-excursion
147 (if (equal major-mode 'mh-folder-mode)
148 mh-current-folder
149 ;; Refer to the show buffer
150 mh-show-folder-buffer)))
152 (defun org-mhe-get-message-num ()
153 "Return the number of the current message. Be careful if you
154 use sequences."
155 (save-excursion
156 (if (equal major-mode 'mh-folder-mode)
157 (mh-get-msg-num nil)
158 ;; Refer to the show buffer
159 (mh-show-buffer-message-number))))
161 (defun org-mhe-get-header (header)
162 "Return a header of the message in folder mode. This will create a
163 show buffer for the corresponding message. If you have a more clever
164 idea..."
165 (let* ((folder (org-mhe-get-message-folder))
166 (num (org-mhe-get-message-num))
167 (buffer (get-buffer-create (concat "show-" folder)))
168 (header-field))
169 (with-current-buffer buffer
170 (mh-display-msg num folder)
171 (if (equal major-mode 'mh-folder-mode)
172 (mh-header-display)
173 (mh-show-header-display))
174 (set-buffer buffer)
175 (setq header-field (mh-get-header-field header))
176 (if (equal major-mode 'mh-folder-mode)
177 (mh-show)
178 (mh-show-show))
179 header-field)))
181 (defun org-mhe-follow-link (folder article)
182 "Follow an MHE link to FOLDER and ARTICLE.
183 If ARTICLE is nil FOLDER is shown. If the configuration variable
184 `org-mhe-search-all-folders' is t and `mh-searcher' is pick,
185 ARTICLE is searched in all folders. Indexed searches (swish++,
186 namazu, and others supported by MH-E) will always search in all
187 folders."
188 (require 'mh-e)
189 (require 'mh-search)
190 (require 'mh-utils)
191 (mh-find-path)
192 (if (not article)
193 (mh-visit-folder (mh-normalize-folder-name folder))
194 (setq article (org-add-angle-brackets article))
195 (mh-search-choose)
196 (if (equal mh-searcher 'pick)
197 (progn
198 (mh-search folder (list "--message-id" article))
199 (when (and org-mhe-search-all-folders
200 (not (org-mhe-get-message-real-folder)))
201 (kill-this-buffer)
202 (mh-search "+" (list "--message-id" article))))
203 (mh-search "+" article))
204 (if (org-mhe-get-message-real-folder)
205 (mh-show-msg 1)
206 (kill-this-buffer)
207 (error "Message not found"))))
209 (provide 'org-mhe)
211 ;;; org-mhe.el ends here