olm 0.0.1 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (8) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -4
  3. data/lib/olm.rb +85 -35
  4. data/lib/olm/app.rb +183 -115
  5. data/olm.el +654 -334
  6. data/olm.gemspec +23 -23
  7. data/org-olm.el +71 -0
  8. metadata +4 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 77901d067605eff56e7e15a667f55f05a4197121
4
- data.tar.gz: 80565d0c2965b67bd6cbc088ff206f4cfa88e83e
3
+ metadata.gz: db7cda4f3e27835b3b26399e44dea7aa04b15d6d
4
+ data.tar.gz: 5482397fd3792fe35b5e3e1b117ddf9e1b379a58
5
5
  SHA512:
6
- metadata.gz: 009f350ea5b13ab5b8efe2bc16f2a7f630563fbbf1428e17794aab0962edfce028b7cf1cf9027434119971d26fe0f8e3330c5b5150f0ab15b1eb28cafd93a038
7
- data.tar.gz: 187eaa27cdc99f9cbe60ddd474e76b2ea0e5ab1698bff4d2a43d6354cabf027e66ba5d469855e8d2ff52226ce6896bf975e7291d7c2f65b7085a6de960009f22
6
+ metadata.gz: 9b56a55ac4f45c0c6d8381cc4ffe78322d49c2b46a264b890494f171de0300250aa78c6dab0ad058c085118272ae7784dbe05b1f2096dcbb6ba97538c44a6233
7
+ data.tar.gz: 71e4613f81231c36ca43bede715aeadb7720ae8e48a8070e7d10dfcb10bd47896bf539cf9d7803ee3477c1026566470b7bf34df5d92abdf5651b8131f53b9305
data/README.md CHANGED
@@ -1,4 +1 @@
1
- olm
2
- ===
3
-
4
- TBA
1
+ Outlook 以外禁止されている? よろしい,ならば Emacs だ.
data/lib/olm.rb CHANGED
@@ -1,35 +1,85 @@
1
- require 'olm/app'
2
-
3
- module Olm
4
- VERSION = '0.0.1'
5
-
6
- extend self
7
-
8
- def ls(folder_id = nil)
9
- puts Olm::App.instance.ls(folder_id)
10
- end
11
-
12
- def send_and_receive
13
- Olm::App.instance.send_and_receive
14
- end
15
-
16
- def message(entry_id)
17
- puts Olm::App.instance.message(entry_id)
18
- end
19
-
20
- def toggle_task_flag(entry_id)
21
- Olm::App.instance.toggle_task_flag(entry_id)
22
- end
23
-
24
- def mark_as_read(entry_id)
25
- Olm::App.instance.mark_as_read(entry_id)
26
- end
27
-
28
- def save_message
29
- Olm::App.instance.create_message(ARGF).Save
30
- end
31
-
32
- def send_message
33
- Olm::App.instance.create_message(ARGF).Send
34
- end
35
- end
1
+ require 'olm/app'
2
+
3
+ module Olm
4
+ VERSION = '0.1.3'
5
+
6
+ extend self
7
+
8
+ def app
9
+ Olm::App.instance
10
+ end
11
+
12
+ def default_folder_id
13
+ puts app.default_folder.EntryID
14
+ end
15
+
16
+ def deleted_items_folder_id
17
+ puts app.deleted_items_folder.EntryID
18
+ end
19
+
20
+ def ls(folder_id = nil)
21
+ app.ls(folder_id).each do |line|
22
+ $stdout.puts(line)
23
+ end
24
+ end
25
+
26
+ def send_and_receive
27
+ app.send_and_receive
28
+ end
29
+
30
+ def message(entry_id)
31
+ app.message(entry_id).each do |line|
32
+ $stdout.puts line
33
+ end
34
+ end
35
+
36
+ def toggle_task_flag(entry_id)
37
+ app.toggle_task_flag(entry_id)
38
+ end
39
+
40
+ def mark_as_read(entry_id)
41
+ app.mark_as_read(entry_id)
42
+ end
43
+
44
+ def save_message
45
+ app.create_message(ARGF).Save
46
+ end
47
+
48
+ def send_message
49
+ app.create_message(ARGF).Send
50
+ end
51
+
52
+ def create_reply_all_message(entry_id)
53
+ reply_mail_entry_id = app.create_reply_all_message(entry_id)
54
+ message(reply_mail_entry_id)
55
+ end
56
+
57
+ def create_forward_message(entry_id)
58
+ forward_mail_entry_id = app.create_forward_message(entry_id)
59
+ message(forward_mail_entry_id)
60
+ end
61
+
62
+ def update_message_body_and_save
63
+ app.update_message_body(ARGF).Save
64
+ end
65
+
66
+ def update_message_body_and_send
67
+ app.update_message_body(ARGF).Send
68
+ end
69
+
70
+ def update_forward_message_body_and_save
71
+ app.update_forward_message_body(ARGF).Save
72
+ end
73
+
74
+ def update_forward_message_body_and_send
75
+ app.update_forward_message_body(ARGF).Send
76
+ end
77
+
78
+ def save_attachments(entry_id, path)
79
+ app.save_attachments(entry_id, path)
80
+ end
81
+
82
+ def execute_refile
83
+ app.execute_refile(ARGF)
84
+ end
85
+ end
data/lib/olm/app.rb CHANGED
@@ -1,115 +1,183 @@
1
- require 'win32ole'
2
- require 'singleton'
3
- require 'nkf'
4
-
5
- module Olm
6
- class App
7
- include Singleton
8
-
9
- def initialize
10
- @app = WIN32OLE.connect("Outlook.Application")
11
- @ns = @app.Session
12
- @enc = @ns.Folders.GetFirst.Name.encoding
13
- const_load(self.class)
14
- end
15
-
16
- def ls(folder_id = nil)
17
- f = folder_id ? @ns.GetFolderFromID(folder_id) : default_folder
18
- res = "#{f.Items.Count}\n"
19
- f.Items.each do |m|
20
- entry_id = m.EntryID
21
- received_at = m.ReceivedTime.to_s.split(' ').first
22
- from = m.SenderName
23
- subject = m.Subject
24
- flag = m.IsMarkedAsTask ? '!' : ' '
25
- res << sprintf("%s %s %-12.12s %-20.20s %s\n",
26
- entry_id, flag, received_at, u(from), u(subject))
27
- end
28
- res
29
- end
30
-
31
- def send_and_receive
32
- @ns.SendAndReceive(false)
33
- end
34
-
35
- def message(entry_id)
36
- m = @ns.GetItemFromID(entry_id)
37
- res = ''
38
- res << sprintf("From: %s\n", m.SenderName)
39
- res << sprintf("To: %s\n", m.To)
40
- res << sprintf("Cc: %s\n", m.CC) if m.CC.to_s.length > 0
41
- res << sprintf("Subject: %s\n", m.Subject)
42
- res << sprintf("ReceivedAt: %s\n", m.ReceivedTime)
43
- res << sprintf("---- \n")
44
- if m.BodyFormat != OlFormatPlain
45
- m2 = m.Copy
46
- m2.BodyFormat = OlFormatPlain
47
- res << m2.Body
48
- m2.Move(@ns.GetDefaultFolder(OlFolderDeletedItems))
49
- else
50
- res << m.Body
51
- end
52
- NKF.nkf('-w -Lu', res)
53
- end
54
-
55
- def toggle_task_flag(entry_id)
56
- m = @ns.GetItemFromID(entry_id)
57
- if m.IsMarkedAsTask
58
- m.ClearTaskFlag()
59
- else
60
- m.MarkAsTask(OlMarkNoDate)
61
- end
62
- m.Save
63
- end
64
-
65
- def mark_as_read(entry_id)
66
- m = @ns.GetItemFromID(entry_id)
67
- m.UnRead = false
68
- m.Save
69
- end
70
-
71
- def create_message(io)
72
- x = {:body => ''}
73
- header = true
74
- io.each_line do |line|
75
- line.chomp!
76
- if header
77
- if line.empty? || /^---- / =~ line
78
- header = false
79
- else
80
- next unless /^(.*?): (.*)/ =~ line
81
- x[$1] = $2
82
- p $1, $2
83
- end
84
- else
85
- x[:body] << line
86
- x[:body] << "\n"
87
- p x[:body]
88
- end
89
- end
90
- m = @app.CreateItem(OlMailItem)
91
- m.BodyFormat = OlFormatPlain
92
- m.To = x['To'] if x['To']
93
- m.CC = x['Cc'] if x['Cc']
94
- m.BCC = x['Bcc'] if x['Bcc']
95
- m.Subject = NKF.nkf('-s', x['Subject']) if x['Subject']
96
- m.Body = NKF.nkf('-s', x[:body]) if x[:body]
97
- m
98
- end
99
-
100
-
101
- private
102
-
103
- def const_load(klass)
104
- WIN32OLE.const_load(@app, klass)
105
- end
106
-
107
- def default_folder
108
- @ns.GetDefaultFolder(OlFolderInbox)
109
- end
110
-
111
- def u(str)
112
- str.encode(Encoding::UTF_8)
113
- end
114
- end
115
- end
1
+ require 'win32ole'
2
+ require 'singleton'
3
+
4
+ module Olm
5
+ class App
6
+ include Singleton
7
+
8
+ def initialize
9
+ @app = WIN32OLE.connect("Outlook.Application")
10
+ @ns = @app.Session
11
+ const_load(self.class)
12
+ end
13
+
14
+ def default_folder
15
+ @ns.GetDefaultFolder(OlFolderInbox)
16
+ end
17
+
18
+ def deleted_items_folder
19
+ @ns.GetDefaultFolder(OlFolderDeletedItems)
20
+ end
21
+
22
+ def ls(folder_id = nil)
23
+ f = folder_id ? @ns.GetFolderFromID(folder_id) : default_folder
24
+ n = [f.Items.Count, 100].min
25
+ s = f.Items.Count - n + 1
26
+ t = f.Items.Count
27
+ res = []
28
+ s.upto(t) do |i|
29
+ m = f.Items(i)
30
+ unless m.Class == OlMail
31
+ n -= 1
32
+ next
33
+ end
34
+ entry_id = m.EntryID
35
+ received_at = m.ReceivedTime.to_s.split(' ').first
36
+ from = m.SenderName
37
+ subject = m.Subject
38
+ flag = m.IsMarkedAsTask ? '!' : ' '
39
+ res << sprintf("%s %s %-12.12s %-20.20s %s",
40
+ entry_id, flag, received_at, from, subject)
41
+ end
42
+ res.unshift(n.to_s)
43
+ end
44
+
45
+ def send_and_receive
46
+ @ns.SendAndReceive(false)
47
+ end
48
+
49
+ def message(entry_id)
50
+ m = @ns.GetItemFromID(entry_id)
51
+ res = [entry_id]
52
+ res << sprintf("From: %s", m.SenderName)
53
+ res << sprintf("To: %s", m.To)
54
+ res << sprintf("Cc: %s", m.CC) if m.CC.to_s.length > 0
55
+ res << sprintf("Subject: %s", m.Subject)
56
+ res << sprintf("ReceivedAt: %s", m.ReceivedTime)
57
+ if m.Attachments.Count > 0
58
+ buf = []
59
+ m.Attachments.each do |a|
60
+ buf << a.DisplayName
61
+ end
62
+ res << sprintf("Attachments: %s", buf.join("; "))
63
+ end
64
+ res << sprintf("---- ")
65
+ if m.BodyFormat != OlFormatPlain
66
+ m2 = m.Copy
67
+ m2.BodyFormat = OlFormatPlain
68
+ res << m2.Body.split("\r\n")
69
+ m2.Move(deleted_items_folder)
70
+ else
71
+ res << m.Body.split("\r\n")
72
+ end
73
+ res
74
+ end
75
+
76
+ def toggle_task_flag(entry_id)
77
+ m = @ns.GetItemFromID(entry_id)
78
+ if m.IsMarkedAsTask
79
+ m.ClearTaskFlag()
80
+ else
81
+ m.MarkAsTask(OlMarkNoDate)
82
+ end
83
+ m.Save
84
+ end
85
+
86
+ def mark_as_read(entry_id)
87
+ m = @ns.GetItemFromID(entry_id)
88
+ m.UnRead = false
89
+ m.Save
90
+ end
91
+
92
+ def create_message(io)
93
+ d = read_draft(io)
94
+ m = @app.CreateItem(OlMailItem)
95
+ m.BodyFormat = OlFormatPlain
96
+ m.To = d[:to] if d[:to]
97
+ m.CC = d[:cc] if d[:cc]
98
+ m.BCC = d[:bcc] if d[:bcc]
99
+ m.Subject = d[:subject] if d[:subject]
100
+ m.Body = d[:body] if d[:body]
101
+ m
102
+ end
103
+
104
+ def create_reply_all_message(entry_id)
105
+ m = @ns.GetItemFromID(entry_id)
106
+ r = m.ReplyAll
107
+ r.BodyFormat = OlFormatPlain
108
+ r.Save
109
+ r.EntryID
110
+ end
111
+
112
+ def create_forward_message(entry_id)
113
+ m = @ns.GetItemFromID(entry_id)
114
+ r = m.Forward
115
+ r.BodyFormat = OlFormatPlain
116
+ r.Save
117
+ r.EntryID
118
+ end
119
+
120
+ def update_message_body(io)
121
+ d = read_draft(io)
122
+ m = @ns.GetItemFromID(d[:entry_id])
123
+ m.BodyFormat = OlFormatPlain
124
+ m.Body = d[:body]
125
+ m.BCC = d[:bcc] if d[:bcc]
126
+ m
127
+ end
128
+
129
+ def update_forward_message_body(io)
130
+ d = read_draft(io)
131
+ m = @ns.GetItemFromID(d[:entry_id])
132
+ m.BodyFormat = OlFormatPlain
133
+ m.Body = d[:body]
134
+ m.To = d[:to] if d[:to]
135
+ m.BCC = d[:bcc] if d[:bcc]
136
+ m
137
+ end
138
+
139
+ def save_attachments(entry_id, path)
140
+ m = @ns.GetItemFromID(entry_id)
141
+ m.Attachments.each do |a|
142
+ a.SaveAsFile(path + a.DisplayName)
143
+ end
144
+ end
145
+
146
+ def execute_refile(io)
147
+ io.each_line do |line|
148
+ line.chomp!
149
+ next unless /^(\h+) (\h+)/ =~ line
150
+ move($1, $2)
151
+ end
152
+ end
153
+
154
+ private
155
+
156
+ def read_draft(io)
157
+ {}.update(entry_id: io.readline.chomp)
158
+ .update(read_draft_headers(io))
159
+ .update(body: io.readlines.map { |s| s.chomp }.join("\r\n"))
160
+ end
161
+
162
+ def read_draft_headers(io)
163
+ headers = {}
164
+ io.each_line do |line|
165
+ break if /^---- / =~ line
166
+ line.chomp!
167
+ next unless /^([^:]+): (.*)/ =~ line
168
+ headers[$1.downcase.intern] = $2
169
+ end
170
+ headers
171
+ end
172
+
173
+ def const_load(klass)
174
+ WIN32OLE.const_load(@app, klass)
175
+ end
176
+
177
+ def move(from, to)
178
+ item = @ns.GetItemFromID(from)
179
+ folder = @ns.GetFolderFromID(to)
180
+ item.Move(folder)
181
+ end
182
+ end
183
+ end
data/olm.el CHANGED
@@ -1,334 +1,654 @@
1
- (require 'dash)
2
-
3
- (defvar olm-folder-id nil)
4
- (defvar olm-default-bcc nil)
5
-
6
- (defun olm
7
- ()
8
- (interactive)
9
- (olm-scan))
10
-
11
- (defun olm-scan
12
- ()
13
- (interactive)
14
- (let* ((ret (olm-ls))
15
- (lbuf (olm-buf-ls))
16
- (n (with-current-buffer lbuf
17
- (goto-char (point-min))
18
- (let ((point (point)))
19
- (forward-word)
20
- (string-to-int (buffer-substring point (point))))))
21
- (sbuf (let ((buf (olm-buf-summary)))
22
- (with-current-buffer buf
23
- (setq-local buffer-read-only nil)
24
- (erase-buffer))
25
- buf))
26
- (ibuf (let ((buf (olm-buf-entry-ids)))
27
- (with-current-buffer buf
28
- (erase-buffer))
29
- buf)))
30
- (with-current-buffer lbuf
31
- (--dotimes n
32
- (progn
33
- (forward-line)
34
- (let* ((p0 (point))
35
- (p1 (progn
36
- (forward-word)
37
- (point)))
38
- (entry-id (buffer-substring p0 p1))
39
- (item-line (buffer-substring p1 (line-end-position))))
40
- (with-current-buffer sbuf
41
- (insert item-line "\n"))
42
- (with-current-buffer ibuf
43
- (insert entry-id "\n"))))))
44
- (with-current-buffer sbuf
45
- (olm-summary-mode))
46
- (switch-to-buffer sbuf)))
47
-
48
- ;;; A helper function invoked by olm-scan
49
- (defun olm-ls
50
- ()
51
- (with-current-buffer (olm-buf-ls)
52
- (setq-local buffer-read-only nil)
53
- (erase-buffer)
54
- (let ((command (if olm-folder-id
55
- (concat "Olm.ls '" olm-folder-id "'")
56
- "Olm.ls")))
57
- (olm-do-command command t))))
58
-
59
-
60
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
61
- ;;;
62
- ;;; gereral helper functions
63
- ;;;
64
- (defun olm-do-command
65
- (command &optional buf)
66
- (let ((buf (or buf (get-buffer-create "*Messages*"))))
67
- (call-process "ruby" nil buf nil
68
- "-r" "rubygems" "-r" "olm" "-e" command)))
69
-
70
- (defun olm-sync
71
- ()
72
- (interactive)
73
- (with-current-buffer (get-buffer-create "*olm-sync*")
74
- (message "Olm: synchronizing all objects ...")
75
- (olm-do-command "Olm.send_and_receive" t)
76
- (message "Olm: synchronizing all objects ...")
77
- (sit-for 1)
78
- (let ((w 3))
79
- (--dotimes w
80
- (progn
81
- (message (number-to-string (- w it)))
82
- (sit-for 1))))
83
- (message "done.")))
84
-
85
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
86
- ;;;
87
- ;;; buffers
88
- ;;;
89
- (defun olm-buf-ls
90
- ()
91
- (get-buffer-create "*olm-ls*"))
92
-
93
- (defun olm-buf-summary
94
- ()
95
- (get-buffer-create "*olm-summary*"))
96
-
97
- (defun olm-buf-entry-ids
98
- ()
99
- (get-buffer-create "*olm-entry-ids*"))
100
-
101
- (defun olm-buf-message
102
- ()
103
- (let ((buf (get-buffer-create "*olm-message*")))
104
- (with-current-buffer buf
105
- (setq-local buffer-read-only nil)
106
- (erase-buffer))
107
- buf))
108
-
109
- (defun olm-buf-draft
110
- ()
111
- (let ((buf (get-buffer-create "*olm-draft*")))
112
- (with-current-buffer buf
113
- (setq-local buffer-read-only nil)
114
- (erase-buffer)
115
- (insert "To: \n")
116
- (insert "Cc: \n")
117
- (when olm-default-bcc
118
- (insert "Bcc: " olm-default-bcc "\n"))
119
- (insert "Subject: \n")
120
- (insert "---- \n"))
121
- buf))
122
-
123
-
124
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
125
- ;;;
126
- ;;; olm-message
127
- ;;;
128
- (defvar olm-message-mode-map nil)
129
- (defvar olm-message-mode-hook nil)
130
-
131
- (defun olm-message-mode
132
- ()
133
- (interactive)
134
- (setq major-mode 'olm-summary-mode)
135
- (setq mode-name "Olm Message")
136
- (font-lock-mode 1)
137
- (setq-local buffer-read-only t)
138
- (setq-local line-move-ignore-invisible t)
139
- (run-hooks 'olm-message-mode-hook))
140
-
141
- (defun olm-message-mode-keyword
142
- ()
143
- (font-lock-add-keywords
144
- nil
145
- '(("^From:" . font-lock-keyword-face)
146
- ("^To:" . font-lock-keyword-face)
147
- ("^Cc:" . font-lock-keyword-face)
148
- ("^Subject:" . font-lock-keyword-face)
149
- ("^ReceivedAt:" . font-lock-keyword-face)
150
- ("^> .*$" . font-lock-comment-face)
151
- ("^From: \\(.*\\)$" 1 font-lock-warning-face)
152
- ("^To: \\(.*\\)$" 1 font-lock-negation-char-face)
153
- ("^Cc: \\(.*\\)$" 1 font-lock-constant-face)
154
- ("^Subject: \\(.*\\)$" 1 font-lock-variable-name-face)
155
- ("^ReceivedAt: \\(.*\\)$" 1 font-lock-type-face))))
156
-
157
- (add-hook 'olm-message-mode-hook 'olm-message-mode-keyword)
158
-
159
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
160
- ;;;
161
- ;;; olm-summary
162
- ;;;
163
- (defvar olm-summary-mode-map nil)
164
- (defvar olm-summary-mode-hook nil)
165
- (defvar olm-summary-scroll-lines 12)
166
-
167
- (unless olm-summary-mode-map
168
- (setq olm-summary-mode-map (make-sparse-keymap))
169
- (define-key olm-summary-mode-map "s" 'olm-scan)
170
- (define-key olm-summary-mode-map "i" 'olm-summary-inc)
171
- (define-key olm-summary-mode-map "q" 'olm-summary-quit)
172
- (define-key olm-summary-mode-map "." 'olm-summary-open-message)
173
- (define-key olm-summary-mode-map " " 'olm-summary-scroll-message-forward)
174
- (define-key olm-summary-mode-map [backspace] 'olm-summary-scroll-message-backward)
175
- (define-key olm-summary-mode-map "p" 'olm-summary-display-up)
176
- (define-key olm-summary-mode-map "n" 'olm-summary-display-down)
177
- (define-key olm-summary-mode-map "!" 'olm-summary-toggle-flag)
178
- (define-key olm-summary-mode-map "w" 'olm-summary-write))
179
-
180
- (defun olm-summary-inc
181
- ()
182
- (interactive)
183
- (olm-sync)
184
- (olm-scan))
185
-
186
- (defun olm-summary-quit
187
- ()
188
- (interactive)
189
- (delete-other-windows-vertically)
190
- (quit-window))
191
-
192
- (defun olm-summary-mode
193
- ()
194
- (interactive)
195
- (use-local-map olm-summary-mode-map)
196
- (setq major-mode 'olm-summary-mode)
197
- (setq mode-name "Olm Summary")
198
- (setq-local buffer-read-only t)
199
- (setq-local truncate-lines t)
200
- (setq-local line-move-ignore-invisible t)
201
- (run-hooks 'olm-summary-mode-hook))
202
-
203
- (defun olm-summary-open-message
204
- ()
205
- (interactive)
206
- (delete-other-windows-vertically)
207
- (let* ((ln0 (line-number-at-pos))
208
- (msg-window (split-window-below 10))
209
- (mbuf (olm-buf-message))
210
- (entry-id (progn
211
- (goto-line ln0)
212
- (olm-mail-item-entry-id-at))))
213
- (with-current-buffer mbuf
214
- (setq-local buffer-file-coding-system 'utf-8-dos))
215
- (olm-do-command (concat "Olm.message '" entry-id "'") mbuf)
216
- (with-current-buffer mbuf
217
- (olm-message-mode)
218
- (goto-char (point-min)))
219
- (set-window-buffer msg-window mbuf)
220
- (olm-summary-mark-message-as-read)))
221
-
222
- (defun olm-summary-mark-message-as-read
223
- ()
224
- (interactive)
225
- (olm-do-command (concat "Olm.mark_as_read '"
226
- (olm-mail-item-entry-id-at)
227
- "'")))
228
-
229
- (defun olm-summary-scroll-message-forward
230
- ()
231
- (interactive)
232
- (recenter)
233
- (scroll-other-window olm-summary-scroll-lines))
234
-
235
- (defun olm-summary-scroll-message-backward
236
- ()
237
- (interactive)
238
- (recenter)
239
- (scroll-other-window (- olm-summary-scroll-lines)))
240
-
241
- (defun olm-summary-display-up
242
- ()
243
- (interactive)
244
- (forward-line -1)
245
- (recenter)
246
- (olm-summary-open-message))
247
-
248
- (defun olm-summary-display-down
249
- ()
250
- (interactive)
251
- (forward-line 1)
252
- (recenter)
253
- (olm-summary-open-message))
254
-
255
- (defun olm-summary-toggle-flag
256
- ()
257
- (interactive)
258
- (let ((n (line-number-at-pos)))
259
- (olm-do-command (concat "Olm.toggle_task_flag '"
260
- (olm-mail-item-entry-id-at)
261
- "'"))
262
- (olm-scan)
263
- (goto-line n)))
264
-
265
- (defun olm-summary-write
266
- ()
267
- (interactive)
268
- (delete-other-windows-vertically)
269
- (let ((buf (olm-buf-draft)))
270
- (with-current-buffer buf
271
- (olm-draft-mode))
272
- (switch-to-buffer buf)))
273
-
274
-
275
- ;;; A helper function for olm-summary-mode functions.
276
- (defun olm-mail-item-entry-id-at
277
- ()
278
- (interactive)
279
- (let ((n (line-number-at-pos)))
280
- (with-current-buffer (olm-buf-entry-ids)
281
- (goto-line n)
282
- (buffer-substring (line-beginning-position) (line-end-position)))))
283
-
284
-
285
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
286
- ;;;
287
- ;;; olm-draft
288
- ;;;
289
- (defvar olm-draft-mode-map nil)
290
- (defvar olm-draft-mode-hook nil)
291
-
292
- (unless olm-draft-mode-map
293
- (setq olm-draft-mode-map (make-sparse-keymap))
294
- (define-key olm-draft-mode-map "\C-c\C-q" 'olm-draft-kill)
295
- (define-key olm-draft-mode-map "\C-c\C-c" 'olm-draft-send-message)
296
- (define-key olm-draft-mode-map "\C-c\C-s" 'olm-draft-save-message))
297
-
298
- (defun olm-draft-mode
299
- ()
300
- (interactive)
301
- (setq major-mode 'olm-draft-mode)
302
- (setq mode-name "Olm Draft")
303
- (setq-local line-move-ignore-invisible t)
304
- (font-lock-mode 1)
305
- (use-local-map olm-draft-mode-map)
306
- (run-hooks 'olm-draft-mode-hook))
307
-
308
- (add-hook 'olm-draft-mode-hook 'olm-message-mode-keyword)
309
-
310
- (defun olm-draft-kill
311
- ()
312
- (interactive)
313
- (kill-buffer)
314
- (olm-scan))
315
-
316
- (defun olm-draft-do-message
317
- (command)
318
- (call-process-region (point-min) (point-max)
319
- "ruby" nil (get-buffer-create "*Messages*") nil
320
- "-r" "rubygems" "-r" "olm" "-e" command))
321
-
322
- (defun olm-draft-save-message
323
- ()
324
- (interactive)
325
- (message "Olm: saving message ...")
326
- (olm-draft-do-message "Olm.save_message")
327
- (olm-draft-kill))
328
-
329
- (defun olm-draft-send-message
330
- ()
331
- (interactive)
332
- (message "Olm: sending message ...")
333
- (olm-draft-do-message "Olm.send_message")
334
- (olm-draft-kill))
1
+ ;;; olm.el --- Outlook Mail in Emacs
2
+
3
+ ;; Copyright (C) 2014 Takahiro Noda
4
+
5
+ ;; Author: Takahiro Noda <takahiro.noda+github@gmail.com>
6
+ ;; Version: 0.1.3
7
+ ;; Keywords: mail
8
+ ;; Package-Requires: ((dash "2.8.0"))
9
+
10
+ ;; This program is free software; you can redistribute it and/or modify
11
+ ;; it under the terms of the GNU General Public License as published by
12
+ ;; the Free Software Foundation, either version 3 of the License, or
13
+ ;; (at your option) any later version.
14
+
15
+ ;; This program is distributed in the hope that it will be useful,
16
+ ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17
+ ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
+ ;; GNU General Public License for more details.
19
+
20
+ ;; You should have received a copy of the GNU General Public License
21
+ ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
22
+
23
+ ;;; Commentary:
24
+
25
+ ;; Outlook Mail in Emacs
26
+
27
+ ;;; Code:
28
+
29
+ (require 'dash)
30
+
31
+ (defvar olm-folder-id nil)
32
+ (defvar olm-folder-name nil)
33
+ (defvar olm-default-bcc nil)
34
+ (defvar olm-attachment-path nil)
35
+ (defvar olm-ruby-executable "ruby")
36
+ (defvar olm-deleted-items-folder-id nil)
37
+
38
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
39
+ ;;;
40
+ ;;; olm-folder-alist
41
+ ;;;
42
+ (defvar olm-folder-alist nil)
43
+
44
+ (defun olm-folder-names ()
45
+ (--map (car it) olm-folder-alist))
46
+
47
+ (unless olm-folder-id
48
+ (setq olm-folder-id (cadr olm-folder-alist)))
49
+ (unless olm-folder-name
50
+ (setq olm-folder-name (caar olm-folder-alist)))
51
+
52
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
53
+ ;;;
54
+ ;;; olm command
55
+ ;;;
56
+ (defun olm ()
57
+ (interactive)
58
+ (olm-init)
59
+ (olm-scan))
60
+
61
+ (defun olm-init ()
62
+ (unless olm-folder-id
63
+ (setq olm-folder-id (cadr olm-folder-alist)
64
+ olm-folder-name (caar olm-folder-alist)))
65
+ (unless olm-folder-id
66
+ (setq olm-folder-id (olm-default-folder-id)
67
+ olm-folder-name "inbox"))
68
+ (unless olm-deleted-items-folder-id
69
+ (setq olm-deleted-items-folder-id (olm-deleted-items-folder-id))))
70
+
71
+ (defun olm-scan ()
72
+ (interactive)
73
+ (let* ((ret (olm-ls))
74
+ (lbuf (olm-buf-ls))
75
+ (n (with-current-buffer lbuf
76
+ (goto-char (point-min))
77
+ (let ((point (point)))
78
+ (forward-word)
79
+ (string-to-int (buffer-substring point (point))))))
80
+ (sbuf (let ((buf (olm-buf-summary)))
81
+ (with-current-buffer buf
82
+ (setq-local buffer-read-only nil)
83
+ (erase-buffer))
84
+ buf))
85
+ (ibuf (olm-buf-entry-ids t)))
86
+ (with-current-buffer lbuf
87
+ (--dotimes n
88
+ (progn
89
+ (forward-line)
90
+ (let* ((p0 (point))
91
+ (p1 (progn
92
+ (forward-word)
93
+ (point)))
94
+ (entry-id (buffer-substring p0 p1))
95
+ (item-line (buffer-substring p1 (line-end-position))))
96
+ (with-current-buffer sbuf
97
+ (insert item-line "\n"))
98
+ (with-current-buffer ibuf
99
+ (insert entry-id "\n"))))))
100
+ (with-current-buffer sbuf
101
+ (olm-summary-mode))
102
+ (switch-to-buffer sbuf)))
103
+
104
+ ;;; A helper function invoked by olm-scan
105
+ (defun olm-ls ()
106
+ (with-current-buffer (olm-buf-ls)
107
+ (setq-local buffer-read-only nil)
108
+ (erase-buffer)
109
+ (let ((command (if olm-folder-id
110
+ (format "Olm.ls %S" olm-folder-id)
111
+ "Olm.ls")))
112
+ (olm-do-command command t))))
113
+
114
+
115
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
116
+ ;;;
117
+ ;;; general helper functions
118
+ ;;;
119
+ (defun olm-do-command (command &optional buf)
120
+ (let ((buf (or buf (get-buffer-create "*Messages*"))))
121
+ (call-process olm-ruby-executable nil buf nil
122
+ "-r" "rubygems" "-r" "olm" "-e" command)))
123
+
124
+ (defun olm-do-command-buf (command &optional msg)
125
+ (when msg (message msg))
126
+ (save-restriction
127
+ (widen)
128
+ (call-process-region (point-min) (point-max)
129
+ olm-ruby-executable
130
+ nil (get-buffer-create "*Messages*") nil
131
+ "-r" "rubygems" "-r" "olm" "-e" command)))
132
+
133
+ (defun olm-sync ()
134
+ (interactive)
135
+ (with-current-buffer (get-buffer-create "*olm-sync*")
136
+ (message "Olm: synchronizing all objects ...")
137
+ (olm-do-command "Olm.send_and_receive" t)
138
+ (message "Olm: synchronizing all objects ...")
139
+ (sit-for 1)
140
+ (let ((w 5))
141
+ (--dotimes w
142
+ (progn
143
+ (message (number-to-string (- w it)))
144
+ (sit-for 1))))
145
+ (message "done.")))
146
+
147
+ (defun olm-hide-entry-id-line ()
148
+ (interactive)
149
+ (let ((inhibit-read-only t))
150
+ (put-text-property (progn
151
+ (goto-char (point-min))
152
+ (point))
153
+ (line-end-position)
154
+ 'read-only
155
+ nil))
156
+ (save-excursion
157
+ (narrow-to-region (progn
158
+ (goto-line 2)
159
+ (point))
160
+ (point-max))))
161
+
162
+ (defun olm-default-folder-id ()
163
+ (with-current-buffer (get-buffer-create "*olm-default-folder-id*")
164
+ (erase-buffer)
165
+ (olm-do-command "Olm.default_folder_id" (current-buffer))
166
+ (buffer-substring-no-properties (point-min) (1- (point-max)))))
167
+
168
+ (defun olm-deleted-items-folder-id ()
169
+ (with-current-buffer (get-buffer-create "*olm-deleted-items-folder-id*")
170
+ (erase-buffer)
171
+ (olm-do-command "Olm.deleted_items_folder_id" (current-buffer))
172
+ (buffer-substring-no-properties (point-min) (1- (point-max)))))
173
+
174
+ (defun olm-pick-a-folder ()
175
+ (assoc-default (completing-read "Refile to: "
176
+ (olm-folder-names)
177
+ nil
178
+ t)
179
+ olm-folder-alist))
180
+
181
+
182
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
183
+ ;;;
184
+ ;;; buffers
185
+ ;;;
186
+ (defun olm-buf-ls ()
187
+ (get-buffer-create "*olm-ls*"))
188
+
189
+ (defun olm-buf-summary ()
190
+ (let ((buf (get-buffer-create "*olm-summary*")))
191
+ (with-current-buffer buf
192
+ (setq-local inherit-process-coding-system t))
193
+ buf))
194
+
195
+ (defun olm-buf-entry-ids (&optional erase-buffer)
196
+ (let ((buf(get-buffer-create "*olm-entry-ids*")))
197
+ (when erase-buffer
198
+ (with-current-buffer buf
199
+ (setq-local buffer-read-only nil)
200
+ (erase-buffer)))
201
+ buf))
202
+
203
+ (defun olm-buf-message ()
204
+ (let ((buf (get-buffer-create "*olm-message*")))
205
+ (with-current-buffer buf
206
+ (setq-local buffer-read-only nil)
207
+ (erase-buffer))
208
+ buf))
209
+
210
+ (defun olm-buf-draft ()
211
+ (let ((buf (get-buffer-create "*olm-draft*")))
212
+ (with-current-buffer buf
213
+ (setq-local buffer-read-only nil)
214
+ (erase-buffer)
215
+ (insert "\n")
216
+ (insert "To: \n")
217
+ (insert "Cc: \n")
218
+ (when olm-default-bcc
219
+ (insert "Bcc: " olm-default-bcc "\n"))
220
+ (insert "Subject: \n")
221
+ (insert "---- \n"))
222
+ buf))
223
+
224
+ (defun olm-buf-draft-command (entry-id command from-line mode &optional header-locked)
225
+ (let ((buf (generate-new-buffer "*olm-draft-reply-all*")))
226
+ (with-current-buffer buf
227
+ (olm-do-command (format command entry-id) t)
228
+ (goto-char (point-min))
229
+ (re-search-forward "^From: ")
230
+ (insert from-line)
231
+ (when olm-default-bcc
232
+ (goto-char (point-min))
233
+ (re-search-forward "^---- ")
234
+ (beginning-of-line)
235
+ (insert "Bcc: " olm-default-bcc "\n"))
236
+ (funcall mode)
237
+ (when header-locked
238
+ (let ((inhibit-read-only t))
239
+ (put-text-property (progn
240
+ (goto-char (point-min))
241
+ (point))
242
+ (progn
243
+ (re-search-forward "^---- ")
244
+ (point))
245
+ 'read-only
246
+ t)))
247
+ (olm-hide-entry-id-line)
248
+ (forward-line))
249
+ buf))
250
+
251
+ (defun olm-buf-draft-reply-all (entry-id)
252
+ (olm-buf-draft-command entry-id
253
+ "Olm.create_reply_all_message %S"
254
+ "***Reply All***"
255
+ 'olm-draft-reply-all-mode
256
+ t))
257
+
258
+ (defun olm-buf-draft-forward (entry-id)
259
+ (olm-buf-draft-command entry-id
260
+ "Olm.create_forward_message %S"
261
+ "***Forward***"
262
+ 'olm-draft-forward-mode))
263
+
264
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
265
+ ;;;
266
+ ;;; olm-message
267
+ ;;;
268
+ (defvar olm-message-mode-map nil)
269
+ (defvar olm-message-mode-hook nil)
270
+
271
+ (unless olm-message-mode-map
272
+ (setq olm-message-mode-map (make-sparse-keymap))
273
+ (define-key olm-message-mode-map "\C-c\C-a" 'olm-message-save-attachments)
274
+ (define-key olm-message-mode-map "\C-c\C-r" 'olm-message-reply-all))
275
+
276
+ (defun olm-message-mode ()
277
+ (interactive)
278
+ (use-local-map olm-message-mode-map)
279
+ (setq major-mode 'olm-message-mode)
280
+ (setq mode-name (format "Olm Message" olm-folder-name))
281
+ (font-lock-mode 1)
282
+ (setq-local buffer-read-only t)
283
+ (setq-local line-move-ignore-invisible t)
284
+ (run-hooks 'olm-message-mode-hook))
285
+
286
+ (defun olm-message-mode-keyword ()
287
+ (font-lock-add-keywords
288
+ nil
289
+ '(("^From:" . font-lock-keyword-face)
290
+ ("^To:" . font-lock-keyword-face)
291
+ ("^Cc:" . font-lock-keyword-face)
292
+ ("^Subject:" . font-lock-keyword-face)
293
+ ("^ReceivedAt:" . font-lock-keyword-face)
294
+ ("^Attachments:" . font-lock-keyword-face)
295
+ ("^> .*$" . font-lock-comment-face)
296
+ ("^From: \\(.*\\)$" 1 font-lock-warning-face)
297
+ ("^To: \\(.*\\)$" 1 font-lock-negation-char-face)
298
+ ("^Cc: \\(.*\\)$" 1 font-lock-constant-face)
299
+ ("^Subject: \\(.*\\)$" 1 font-lock-variable-name-face)
300
+ ("^ReceivedAt: \\(.*\\)$" 1 font-lock-type-face))))
301
+
302
+ (add-hook 'olm-message-mode-hook 'olm-message-mode-keyword)
303
+
304
+ (defun olm-message-save-attachments ()
305
+ (interactive)
306
+ (let ((entry-id (olm-message-entry-id)))
307
+ (message (format "Olm: saving attachments into %S ..."
308
+ olm-attachment-path))
309
+ (olm-do-command (format "Olm.save_attachments(%S, %S)"
310
+ entry-id
311
+ olm-attachment-path))))
312
+
313
+ (defun olm-message-reply-all ()
314
+ (interactive)
315
+ (-> (olm-message-entry-id)
316
+ olm-buf-draft-reply-all
317
+ switch-to-buffer))
318
+
319
+
320
+ ;;; A helper function for olm-message-mode
321
+ (defun olm-message-entry-id ()
322
+ (interactive)
323
+ (save-excursion
324
+ (save-restriction
325
+ (widen)
326
+ (goto-line 1)
327
+ (buffer-substring-no-properties (line-beginning-position)
328
+ (line-end-position)))))
329
+
330
+
331
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
332
+ ;;;
333
+ ;;; olm-summary
334
+ ;;;
335
+ (defvar olm-summary-mode-map nil)
336
+ (defvar olm-summary-mode-hook nil)
337
+ (defvar olm-summary-scroll-lines 12)
338
+
339
+ (unless olm-summary-mode-map
340
+ (setq olm-summary-mode-map (make-sparse-keymap))
341
+ (define-key olm-summary-mode-map "s" 'olm-scan)
342
+ (define-key olm-summary-mode-map "i" 'olm-summary-inc)
343
+ (define-key olm-summary-mode-map "q" 'olm-summary-quit)
344
+ (define-key olm-summary-mode-map "." 'olm-summary-open-message)
345
+ (define-key olm-summary-mode-map " " 'olm-summary-scroll-message-forward)
346
+ (define-key olm-summary-mode-map "\r" 'olm-summary-scroll-message-forward-line)
347
+ (define-key olm-summary-mode-map [backspace] 'olm-summary-scroll-message-backward)
348
+ (define-key olm-summary-mode-map "p" 'olm-summary-display-up)
349
+ (define-key olm-summary-mode-map "n" 'olm-summary-display-down)
350
+ (define-key olm-summary-mode-map "!" 'olm-summary-toggle-flag)
351
+ (define-key olm-summary-mode-map "w" 'olm-summary-write)
352
+ (define-key olm-summary-mode-map "A" 'olm-summary-reply-all)
353
+ (define-key olm-summary-mode-map "f" 'olm-summary-forward)
354
+ (define-key olm-summary-mode-map "g" 'olm-summary-goto-folder)
355
+ (define-key olm-summary-mode-map "o" 'olm-summary-refile)
356
+ (define-key olm-summary-mode-map "d" 'olm-summary-delete)
357
+ (define-key olm-summary-mode-map "x" 'olm-summary-exec)
358
+ (define-key olm-summary-mode-map "*" 'olm-summary-review)
359
+ (define-key olm-summary-mode-map "mo" 'olm-summary-mark-refile))
360
+
361
+ (defun olm-summary-inc ()
362
+ (interactive)
363
+ (olm-sync)
364
+ (olm-scan))
365
+
366
+ (defun olm-summary-quit ()
367
+ (interactive)
368
+ (delete-other-windows-vertically)
369
+ (quit-window))
370
+
371
+ (defun olm-summary-mode ()
372
+ (interactive)
373
+ (use-local-map olm-summary-mode-map)
374
+ (setq major-mode 'olm-summary-mode)
375
+ (setq mode-name (format "Olm Summary [%s]" olm-folder-name))
376
+ (font-lock-mode 1)
377
+ (setq-local buffer-read-only t)
378
+ (setq-local truncate-lines t)
379
+ (setq-local line-move-ignore-invisible t)
380
+ (run-hooks 'olm-summary-mode-hook))
381
+
382
+ (defun olm-summary-mode-keyword ()
383
+ (font-lock-add-keywords
384
+ nil
385
+ '(("^o.*$" . font-lock-builtin-face)
386
+ ("^D.*$" . font-lock-warning-face)
387
+ ("^\\*.*$" . font-lock-comment-face))))
388
+
389
+ (add-hook 'olm-summary-mode-hook 'olm-summary-mode-keyword)
390
+
391
+ (defun olm-summary-open-message ()
392
+ (interactive)
393
+ (delete-other-windows-vertically)
394
+ (let* ((ln0 (line-number-at-pos))
395
+ (msg-window (split-window-below 12))
396
+ (entry-id (progn
397
+ (goto-line ln0)
398
+ (olm-summary-message-entry-id))))
399
+ (olm-open-message entry-id msg-window))
400
+ (olm-summary-mark-message-as-read))
401
+
402
+ (defun olm-summary-mark-message-as-read ()
403
+ (interactive)
404
+ (olm-do-command (format "Olm.mark_as_read %S" (olm-summary-message-entry-id))))
405
+
406
+ (defun olm-summary-scroll-message-forward ()
407
+ (interactive)
408
+ (recenter)
409
+ (scroll-other-window olm-summary-scroll-lines))
410
+
411
+ (defun olm-summary-scroll-message-forward-line ()
412
+ (interactive)
413
+ (recenter)
414
+ (scroll-other-window 1))
415
+
416
+ (defun olm-summary-scroll-message-backward ()
417
+ (interactive)
418
+ (recenter)
419
+ (scroll-other-window (- olm-summary-scroll-lines)))
420
+
421
+ (defun olm-summary-display-up ()
422
+ (interactive)
423
+ (forward-line -1)
424
+ (recenter)
425
+ (olm-summary-open-message))
426
+
427
+ (defun olm-summary-display-down ()
428
+ (interactive)
429
+ (forward-line 1)
430
+ (recenter)
431
+ (olm-summary-open-message))
432
+
433
+ (defun olm-summary-toggle-flag ()
434
+ (interactive)
435
+ (let ((n (line-number-at-pos)))
436
+ (olm-do-command (format "Olm.toggle_task_flag %S"
437
+ (olm-summary-message-entry-id)))
438
+ (olm-scan)
439
+ (goto-line n)))
440
+
441
+ (defun olm-summary-write ()
442
+ (interactive)
443
+ (delete-other-windows-vertically)
444
+ (let ((buf (olm-buf-draft)))
445
+ (with-current-buffer buf
446
+ (olm-hide-entry-id-line)
447
+ (olm-draft-mode))
448
+ (switch-to-buffer buf)))
449
+
450
+ (defun olm-summary-reply-all ()
451
+ (interactive)
452
+ (let ((buf (olm-buf-draft-reply-all (olm-summary-message-entry-id))))
453
+ (delete-other-windows-vertically)
454
+ (switch-to-buffer buf)))
455
+
456
+ (defun olm-summary-forward ()
457
+ (interactive)
458
+ (let ((buf (olm-buf-draft-forward (olm-summary-message-entry-id))))
459
+ (delete-other-windows-vertically)
460
+ (switch-to-buffer buf)))
461
+
462
+ (defun olm-summary-goto-folder ()
463
+ (interactive)
464
+ (setq olm-folder-name (completing-read "Exchange folder: "
465
+ (olm-folder-names)
466
+ nil
467
+ t))
468
+ (setq olm-folder-id (assoc-default olm-folder-name olm-folder-alist))
469
+ (olm-scan))
470
+
471
+ (defun olm-summary-refile (&optional to mark)
472
+ (interactive)
473
+ (let ((from (olm-summary-message-entry-id))
474
+ (to (or to (olm-pick-a-folder)))
475
+ (mark (or mark "o"))
476
+ (n (line-number-at-pos)))
477
+ ;; insert the destination entry id into the org-ids buffer
478
+ (with-current-buffer (olm-buf-entry-ids)
479
+ (goto-line n)
480
+ (re-search-forward "^[0-9A-Z]\\{140\\}")
481
+ (delete-region (point) (point-at-eol))
482
+ (insert " " to))
483
+ (olm-summary-insert-mark mark)))
484
+
485
+ (defun olm-summary-delete ()
486
+ (interactive)
487
+ (olm-summary-refile olm-deleted-items-folder-id "D"))
488
+
489
+ (defun olm-summary-exec ()
490
+ "Process marked messages."
491
+ (interactive)
492
+ (with-current-buffer (olm-buf-entry-ids)
493
+ (olm-do-command-buf "Olm.execute_refile"))
494
+ (olm-scan))
495
+
496
+ (defun olm-summary-review ()
497
+ "Put the review mark (`*')."
498
+ (interactive)
499
+ (olm-summary-insert-mark "*"))
500
+
501
+ (defun olm-summary-mark-refile ()
502
+ (interactive)
503
+ (let ((to (olm-pick-a-folder)))
504
+ (goto-char (point-min))
505
+ (while (re-search-forward "^\\*" nil t)
506
+ (olm-summary-refile to "o"))))
507
+
508
+ ;;; A helper function for olm-summary-mode functions.
509
+ (defun olm-summary-message-entry-id ()
510
+ (let ((n (line-number-at-pos)))
511
+ (with-current-buffer (olm-buf-entry-ids)
512
+ (goto-line n)
513
+ (re-search-forward "\\b[0-9A-Z]\\{140\\}\\b" nil t)
514
+ (match-string-no-properties 0))))
515
+
516
+ (defun olm-summary-insert-mark (mark)
517
+ (beginning-of-line)
518
+ (setq-local buffer-read-only nil)
519
+ (delete-char 1)
520
+ (insert mark)
521
+ (setq-local buffer-read-only t))
522
+
523
+ (defun olm-open-message (entry-id &optional window)
524
+ (let ((mbuf (olm-buf-message)))
525
+ (with-current-buffer mbuf
526
+ (olm-do-command (format "Olm.message %S" entry-id) t)
527
+ (let ((inhibit-read-only t))
528
+ (olm-hide-entry-id-line)
529
+ (olm-message-mode)
530
+ (goto-char (point-min))))
531
+ (if window
532
+ (set-window-buffer window mbuf)
533
+ (switch-to-buffer mbuf))))
534
+
535
+
536
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
537
+ ;;;
538
+ ;;; olm-draft
539
+ ;;;
540
+ (defvar olm-draft-mode-map nil)
541
+ (defvar olm-draft-mode-hook nil)
542
+
543
+ (unless olm-draft-mode-map
544
+ (setq olm-draft-mode-map (make-sparse-keymap))
545
+ (define-key olm-draft-mode-map "\C-c\C-q" 'olm-draft-kill)
546
+ (define-key olm-draft-mode-map "\C-c\C-c" 'olm-draft-send-message)
547
+ (define-key olm-draft-mode-map "\C-c\C-s" 'olm-draft-save-message))
548
+
549
+ (defun olm-draft-mode ()
550
+ (interactive)
551
+ (setq major-mode 'olm-draft-mode)
552
+ (setq mode-name "Olm Draft")
553
+ (setq-local line-move-ignore-invisible t)
554
+ (font-lock-mode 1)
555
+ (use-local-map olm-draft-mode-map)
556
+ (run-hooks 'olm-draft-mode-hook))
557
+
558
+ (add-hook 'olm-draft-mode-hook 'olm-message-mode-keyword)
559
+
560
+ (defun olm-draft-kill ()
561
+ (interactive)
562
+ (kill-buffer)
563
+ (olm-scan))
564
+
565
+ (defun olm-draft-save-message ()
566
+ (interactive)
567
+ (olm-do-command-buf "Olm.save_message"
568
+ "Olm: saving message ...")
569
+ (olm-draft-kill))
570
+
571
+ (defun olm-draft-send-message ()
572
+ (interactive)
573
+ (message "Olm: sending message ...")
574
+ (olm-do-command-buf "Olm.send_message"
575
+ "Olm: sending message ...")
576
+ (olm-draft-kill))
577
+
578
+
579
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
580
+ ;;;
581
+ ;;; olm-draft-reply-all
582
+ ;;;
583
+ (defvar olm-draft-reply-all-map nil)
584
+ (defvar olm-draft-reply-all-hook nil)
585
+
586
+ (unless olm-draft-reply-all-map
587
+ (setq olm-draft-reply-all-map (make-sparse-keymap))
588
+ (define-key olm-draft-reply-all-map "\C-c\C-q" 'olm-draft-kill)
589
+ (define-key olm-draft-reply-all-map "\C-c\C-c" 'olm-draft-reply-all-send-message)
590
+ (define-key olm-draft-reply-all-map "\C-c\C-s" 'olm-draft-reply-all-save-message))
591
+
592
+ (defun olm-draft-reply-all-mode ()
593
+ (interactive)
594
+ (setq major-mode 'olm-draft-reply-all-mode)
595
+ (setq mode-name "Olm Draft Reply All")
596
+ (setq-local line-move-ignore-invisible t)
597
+ (font-lock-mode 1)
598
+ (use-local-map olm-draft-reply-all-map)
599
+ (run-hooks 'olm-draft-reply-all-hook))
600
+
601
+ (defun olm-draft-reply-all-save-message ()
602
+ (interactive)
603
+ (olm-do-command-buf "Olm.update_message_body_and_save"
604
+ "Olm: saving message ...")
605
+ (olm-draft-kill))
606
+
607
+ (defun olm-draft-reply-all-send-message ()
608
+ (interactive)
609
+ (olm-do-command-buf "Olm.update_message_body_and_send"
610
+ "Olm: sending message ...")
611
+ (olm-draft-kill))
612
+
613
+ (add-hook 'olm-draft-reply-all-hook 'olm-message-mode-keyword)
614
+
615
+
616
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
617
+ ;;;
618
+ ;;; olm-draft-forward
619
+ ;;;
620
+ (defvar olm-draft-forward-map nil)
621
+ (defvar olm-draft-forward-hook nil)
622
+
623
+ (unless olm-draft-forward-map
624
+ (setq olm-draft-forward-map (make-sparse-keymap))
625
+ (define-key olm-draft-forward-map "\C-c\C-q" 'olm-draft-kill)
626
+ (define-key olm-draft-forward-map "\C-c\C-c" 'olm-draft-forward-send-message)
627
+ (define-key olm-draft-forward-map "\C-c\C-s" 'olm-draft-forward-save-message))
628
+
629
+ (defun olm-draft-forward-mode ()
630
+ (interactive)
631
+ (setq major-mode 'olm-draft-forward-mode)
632
+ (setq mode-name "Olm Draft Forward")
633
+ (setq-local line-move-ignore-invisible t)
634
+ (font-lock-mode 1)
635
+ (use-local-map olm-draft-forward-map)
636
+ (run-hooks 'olm-draft-forward-hook))
637
+
638
+ (defun olm-draft-forward-save-message ()
639
+ (interactive)
640
+ (olm-do-command-buf "Olm.update_forward_message_body_and_save"
641
+ "Olm: saving message ...")
642
+ (olm-draft-kill))
643
+
644
+ (defun olm-draft-forward-send-message ()
645
+ (interactive)
646
+ (olm-do-command-buf "Olm.update_forward_message_body_and_send"
647
+ "Olm: sending message ...")
648
+ (olm-draft-kill))
649
+
650
+ (add-hook 'olm-draft-forward-hook 'olm-message-mode-keyword)
651
+
652
+ (provide 'olm)
653
+ ;;; olm.el ends here
654
+