olm 0.0.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+