sup 0.2 → 0.3
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of sup might be problematic. Click here for more details.
- data/History.txt +10 -0
- data/bin/sup +50 -68
- data/doc/NewUserGuide.txt +11 -7
- data/doc/TODO +34 -22
- data/lib/sup.rb +30 -24
- data/lib/sup/buffer.rb +124 -39
- data/lib/sup/colormap.rb +4 -4
- data/lib/sup/draft.rb +1 -1
- data/lib/sup/hook.rb +18 -5
- data/lib/sup/imap.rb +11 -13
- data/lib/sup/index.rb +52 -14
- data/lib/sup/keymap.rb +1 -1
- data/lib/sup/logger.rb +1 -0
- data/lib/sup/maildir.rb +9 -0
- data/lib/sup/mbox.rb +3 -1
- data/lib/sup/message-chunks.rb +21 -7
- data/lib/sup/message.rb +31 -15
- data/lib/sup/mode.rb +2 -0
- data/lib/sup/modes/buffer-list-mode.rb +7 -3
- data/lib/sup/modes/compose-mode.rb +14 -16
- data/lib/sup/modes/contact-list-mode.rb +2 -2
- data/lib/sup/modes/edit-message-mode.rb +55 -23
- data/lib/sup/modes/forward-mode.rb +22 -5
- data/lib/sup/modes/inbox-mode.rb +3 -7
- data/lib/sup/modes/label-list-mode.rb +30 -10
- data/lib/sup/modes/label-search-results-mode.rb +12 -0
- data/lib/sup/modes/line-cursor-mode.rb +13 -0
- data/lib/sup/modes/log-mode.rb +0 -6
- data/lib/sup/modes/poll-mode.rb +0 -3
- data/lib/sup/modes/reply-mode.rb +19 -11
- data/lib/sup/modes/scroll-mode.rb +111 -20
- data/lib/sup/modes/search-results-mode.rb +21 -0
- data/lib/sup/modes/text-mode.rb +10 -2
- data/lib/sup/modes/thread-index-mode.rb +200 -90
- data/lib/sup/modes/thread-view-mode.rb +27 -10
- data/lib/sup/person.rb +1 -0
- data/lib/sup/poll.rb +15 -7
- data/lib/sup/source.rb +6 -1
- data/lib/sup/suicide.rb +1 -1
- data/lib/sup/textfield.rb +14 -14
- data/lib/sup/thread.rb +6 -2
- data/lib/sup/util.rb +111 -9
- metadata +13 -6
data/History.txt
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
== 0.3 / 2007-10-29
|
2
|
+
* In-buffer search (finally!)
|
3
|
+
* Subscribe to/unsubscribe from mailing list commands.
|
4
|
+
* IMAP speedups.
|
5
|
+
* More hooks: set status bar, set terminal title bar, modify message headers
|
6
|
+
and bodies before editing, etc.
|
7
|
+
* Optionally use chronic gem to allow for natural-language dates in searches.
|
8
|
+
* Many, many bugfixes and minor improvements.
|
9
|
+
* Tomorrow is Sup's first birthday!
|
10
|
+
|
1
11
|
== 0.2 / 2007-10-29
|
2
12
|
* Complete hook system for user-inserted code.
|
3
13
|
* GPG signature verification and decryption.
|
data/bin/sup
CHANGED
@@ -7,6 +7,7 @@ require 'fileutils'
|
|
7
7
|
require 'trollop'
|
8
8
|
require "sup"
|
9
9
|
|
10
|
+
$exceptions = []
|
10
11
|
$opts = Trollop::options do
|
11
12
|
version "sup v#{Redwood::VERSION}"
|
12
13
|
banner <<EOS
|
@@ -19,6 +20,7 @@ Options are:
|
|
19
20
|
EOS
|
20
21
|
opt :list_hooks, "List all hooks and descriptions thereof, and quit."
|
21
22
|
opt :no_threads, "Turn of threading. Helps with debugging. (Necessarily disables background polling for new messages.)"
|
23
|
+
opt :search, "Search for threads ", :type => String
|
22
24
|
end
|
23
25
|
|
24
26
|
if $opts[:list_hooks]
|
@@ -39,10 +41,11 @@ global_keymap = Keymap.new do |k|
|
|
39
41
|
k.add :list_buffers, "List all buffers", 'B'
|
40
42
|
k.add :list_contacts, "List contacts", 'C'
|
41
43
|
k.add :redraw, "Redraw screen", :ctrl_l
|
42
|
-
k.add :search, "Search messages", '
|
44
|
+
k.add :search, "Search all messages", '\\', 'F'
|
43
45
|
k.add :list_labels, "List labels", 'L'
|
44
46
|
k.add :poll, "Poll for new messages", 'P'
|
45
|
-
k.add :compose, "Compose new message", 'm'
|
47
|
+
k.add :compose, "Compose new message", 'm', 'c'
|
48
|
+
k.add :nothing, "Do nothing", :ctrl_g
|
46
49
|
k.add :recall_draft, "Edit most recent draft message", 'R'
|
47
50
|
end
|
48
51
|
|
@@ -92,26 +95,26 @@ EOS
|
|
92
95
|
end
|
93
96
|
|
94
97
|
begin
|
95
|
-
extend CanSpawnComposeMode
|
96
98
|
Redwood::start
|
97
99
|
Index.load
|
98
100
|
|
99
101
|
if(s = Index.source_for DraftManager.source_name)
|
100
102
|
DraftManager.source = s
|
101
103
|
else
|
104
|
+
Redwood::log "no draft source, auto-adding..."
|
102
105
|
Index.add_source DraftManager.new_source
|
103
106
|
end
|
104
107
|
|
105
108
|
if(s = Index.source_for SentManager.source_name)
|
106
109
|
SentManager.source = s
|
107
110
|
else
|
111
|
+
Redwood::log "no sent mail source, auto-adding..."
|
108
112
|
Index.add_source SentManager.new_source
|
109
113
|
end
|
110
114
|
|
111
115
|
log "starting curses"
|
112
116
|
start_cursing
|
113
117
|
|
114
|
-
log "initializing colormap"
|
115
118
|
Colormap.new do |c|
|
116
119
|
c.add :status_color, Ncurses::COLOR_WHITE, Ncurses::COLOR_BLUE, Ncurses::A_BOLD
|
117
120
|
c.add :index_old_color, Ncurses::COLOR_WHITE, Ncurses::COLOR_BLACK
|
@@ -154,9 +157,9 @@ begin
|
|
154
157
|
c.add :reply_mode_selected_color, Ncurses::COLOR_YELLOW, Ncurses::COLOR_BLACK, Ncurses::A_BOLD
|
155
158
|
c.add :reply_mode_unselected_color, Ncurses::COLOR_CYAN, Ncurses::COLOR_BLACK
|
156
159
|
c.add :reply_mode_label_color, Ncurses::COLOR_CYAN, Ncurses::COLOR_BLACK
|
160
|
+
c.add :search_highlight_color, Ncurses::COLOR_BLACK, Ncurses::COLOR_YELLOW, Ncurses::A_BOLD, :highlight => :search_highlight_color
|
157
161
|
end
|
158
162
|
|
159
|
-
log "initializing buffer manager"
|
160
163
|
bm = BufferManager.new
|
161
164
|
|
162
165
|
log "initializing mail index buffer"
|
@@ -168,24 +171,18 @@ begin
|
|
168
171
|
|
169
172
|
bm.draw_screen
|
170
173
|
|
171
|
-
begin
|
172
|
-
Index.usual_sources.each { |s| s.check }
|
173
|
-
rescue SourceError
|
174
|
-
# do nothing! we'll report it at the next step
|
175
|
-
end
|
176
|
-
Redwood::report_broken_sources
|
177
|
-
|
178
174
|
Index.usual_sources.each do |s|
|
179
|
-
|
175
|
+
next unless s.respond_to? :connect
|
176
|
+
reporting_thread("call #connect on #{s}") do
|
180
177
|
begin
|
181
178
|
s.connect
|
182
179
|
rescue SourceError => e
|
183
180
|
Redwood::log "fatal error loading from #{s}: #{e.message}"
|
184
181
|
end
|
185
|
-
end
|
182
|
+
end
|
186
183
|
end
|
187
|
-
|
188
|
-
imode.load_threads :num => ibuf.content_height, :when_done => lambda { reporting_thread { sleep 1; PollManager.poll } unless $opts[:no_threads] }
|
184
|
+
|
185
|
+
imode.load_threads :num => ibuf.content_height, :when_done => lambda { reporting_thread("poll after loading inbox") { sleep 1; PollManager.poll } unless $opts[:no_threads] }
|
189
186
|
|
190
187
|
unless $opts[:no_threads]
|
191
188
|
PollManager.start
|
@@ -193,7 +190,11 @@ begin
|
|
193
190
|
Index.start_lock_update_thread
|
194
191
|
end
|
195
192
|
|
196
|
-
|
193
|
+
if $opts[:search]
|
194
|
+
SearchResultsMode.spawn_from_query $opts[:search]
|
195
|
+
end
|
196
|
+
|
197
|
+
until $exceptions.nonempty? || SuicideManager.die?
|
197
198
|
c = Ncurses.nonblocking_getch
|
198
199
|
next unless c
|
199
200
|
bm.erase_flash
|
@@ -215,48 +216,26 @@ begin
|
|
215
216
|
when :list_buffers
|
216
217
|
bm.spawn_unless_exists("Buffer List") { BufferListMode.new }
|
217
218
|
when :list_contacts
|
218
|
-
b = bm.spawn_unless_exists("Contact List") { ContactListMode.new }
|
219
|
-
b.mode.load_in_background
|
219
|
+
b, new = bm.spawn_unless_exists("Contact List") { ContactListMode.new }
|
220
|
+
b.mode.load_in_background if new
|
220
221
|
when :search
|
221
|
-
|
222
|
-
next unless
|
223
|
-
|
224
|
-
begin
|
225
|
-
qobj = Index.parse_user_query_string text
|
226
|
-
short_text = text.length < 20 ? text : text[0 ... 20] + "..."
|
227
|
-
log "built query from #{text.inspect}: #{qobj}"
|
228
|
-
mode = SearchResultsMode.new qobj
|
229
|
-
bm.spawn "search: \"#{short_text}\"", mode
|
230
|
-
mode.load_threads :num => mode.buffer.content_height
|
231
|
-
rescue Ferret::QueryParser::QueryParseException => e
|
232
|
-
bm.flash "Couldn't parse query."
|
233
|
-
end
|
222
|
+
query = BufferManager.ask :search, "search all messages: "
|
223
|
+
next unless query && query !~ /^\s*$/
|
224
|
+
SearchResultsMode.spawn_from_query query
|
234
225
|
when :list_labels
|
235
226
|
labels = LabelManager.listable_labels.map { |l| LabelManager.string_for l }
|
236
227
|
user_label = bm.ask_with_completions :label, "Show threads with label (enter for listing): ", labels
|
237
|
-
user_label
|
238
|
-
|
239
|
-
|
240
|
-
bm.spawn_modal("Label list", LabelListMode.new) if user_label && user_label.empty?
|
228
|
+
unless user_label.nil?
|
229
|
+
if user_label.empty?
|
230
|
+
bm.spawn_unless_exists("Label list") { LabelListMode.new } if user_label && user_label.empty?
|
241
231
|
else
|
242
|
-
|
232
|
+
LabelSearchResultsMode.spawn_nicely user_label
|
243
233
|
end
|
244
|
-
|
245
|
-
case user_label
|
246
|
-
when nil
|
247
|
-
when :inbox
|
248
|
-
BufferManager.raise_to_front InboxMode.instance.buffer
|
249
|
-
else
|
250
|
-
b = BufferManager.spawn_unless_exists("All threads with label '#{user_label}'") do
|
251
|
-
mode = LabelSearchResultsMode.new([user_label])
|
252
|
-
end
|
253
|
-
b.mode.load_threads :num => b.content_height
|
254
234
|
end
|
255
|
-
|
256
235
|
when :compose
|
257
|
-
|
236
|
+
ComposeMode.spawn_nicely
|
258
237
|
when :poll
|
259
|
-
reporting_thread { PollManager.poll }
|
238
|
+
reporting_thread("user-invoked poll") { PollManager.poll }
|
260
239
|
when :recall_draft
|
261
240
|
case Index.num_results_for :label => :draft
|
262
241
|
when 0
|
@@ -268,23 +247,21 @@ begin
|
|
268
247
|
BufferManager.spawn "Edit message", r
|
269
248
|
r.edit_message
|
270
249
|
else
|
271
|
-
b = BufferManager.spawn_unless_exists("All drafts")
|
272
|
-
|
273
|
-
end
|
274
|
-
b.mode.load_threads :num => b.content_height
|
250
|
+
b, new = BufferManager.spawn_unless_exists("All drafts") { LabelSearchResultsMode.new [:draft] }
|
251
|
+
b.mode.load_threads :num => b.content_height if new
|
275
252
|
end
|
276
253
|
when :nothing
|
277
254
|
when :redraw
|
278
255
|
bm.completely_redraw_screen
|
279
256
|
else
|
280
|
-
bm.flash "Unknown
|
257
|
+
bm.flash "Unknown keypress '#{c.to_character}' for #{bm.focus_buf.mode.name}."
|
281
258
|
end
|
282
259
|
end
|
283
260
|
|
284
261
|
bm.draw_screen
|
285
262
|
end
|
286
263
|
rescue Exception => e
|
287
|
-
$
|
264
|
+
$exceptions << [e, "main"]
|
288
265
|
ensure
|
289
266
|
unless $opts[:no_threads]
|
290
267
|
PollManager.stop if PollManager.instantiated?
|
@@ -300,8 +277,7 @@ ensure
|
|
300
277
|
Redwood::log "I've been ordered to commit sepuku. I obey!"
|
301
278
|
end
|
302
279
|
|
303
|
-
|
304
|
-
when nil
|
280
|
+
if $exceptions.empty?
|
305
281
|
Redwood::log "no fatal errors. good job, william."
|
306
282
|
Index.save
|
307
283
|
else
|
@@ -311,23 +287,29 @@ ensure
|
|
311
287
|
Index.unlock
|
312
288
|
end
|
313
289
|
|
314
|
-
|
290
|
+
unless $exceptions.empty?
|
291
|
+
File.open("sup-exception-log.txt", "w") do |f|
|
292
|
+
$exceptions.each do |e, name|
|
293
|
+
f.puts "--- #{e.class.name} from thread: #{name}"
|
294
|
+
f.puts e.message, e.backtrace
|
295
|
+
end
|
296
|
+
end
|
315
297
|
$stderr.puts <<EOS
|
316
298
|
----------------------------------------------------------------
|
317
|
-
I'm very sorry
|
318
|
-
|
319
|
-
|
320
|
-
to sup-talk at rubyforge dot orgs so that I might
|
321
|
-
problem. Thank you!
|
299
|
+
I'm very sorry. It seems that an error occurred in Sup. Please
|
300
|
+
accept my sincere apologies. If you don't mind, please send the
|
301
|
+
contents of sup-exception-log.txt and a brief report of the
|
302
|
+
circumstances to sup-talk at rubyforge dot orgs so that I might
|
303
|
+
address this problem. Thank you!
|
322
304
|
|
323
305
|
Sincerely,
|
324
306
|
William
|
325
307
|
----------------------------------------------------------------
|
326
|
-
|
327
|
-
The problem was: '#{$exception.message}' (error type #{$exception.class.name})
|
328
|
-
A backtrace follows:
|
329
308
|
EOS
|
330
|
-
|
309
|
+
$exceptions.each do |e, name|
|
310
|
+
puts "--- #{e.class.name} from thread: #{name}"
|
311
|
+
puts e.message, e.backtrace
|
312
|
+
end
|
331
313
|
end
|
332
314
|
|
333
315
|
end
|
data/doc/NewUserGuide.txt
CHANGED
@@ -135,20 +135,24 @@ scrollable list of all the labels you've ever used, along with some
|
|
135
135
|
special labels (Draft, Starred, Sent, Spam, etc.). Highlight a label
|
136
136
|
and press enter to view all the messages with that label.
|
137
137
|
|
138
|
-
What you just did was actually a specific search. For a general
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
138
|
+
What you just did was actually a specific search. For a general search,
|
139
|
+
press "\" (backslash---forward slash is used for in-buffer search,
|
140
|
+
following console conventions). Now type in your query (again, Ctrl-G to
|
141
|
+
cancel at any point.) You can just type in arbitrary text, which will be
|
142
|
+
matched on a per-word basis against the bodies of all email in the
|
143
|
+
index, or you can make use of the full Ferret query syntax:
|
143
144
|
|
144
145
|
- Phrasal queries using double-quotes, e.g.: "three contiguous words"
|
145
146
|
- Queries against a particular field using <field name>:<query>,
|
146
147
|
e.g.: label:ruby-talk, or from:matz@ruby-lang.org. (Fields include:
|
147
148
|
body, from, to, and subject.)
|
148
|
-
- Force non-occurrence by -, e.g. -body:"hot soup"
|
149
|
+
- Force non-occurrence by -, e.g. -body:"hot soup".
|
150
|
+
- If you have the chronic gem installed, date queries like
|
151
|
+
"before:today", "on:today", "after:yesterday", "after:(2 days ago)"
|
152
|
+
(parentheses required for multi-word descriptions).
|
149
153
|
|
150
154
|
You can combine those all together. For example:
|
151
|
-
label:ruby-talk subject:\[ANN\] -rails
|
155
|
+
label:ruby-talk subject:\[ANN\] -rails on:today
|
152
156
|
|
153
157
|
Play around with the search, and see the Ferret documentation for
|
154
158
|
details on more sophisticated queries (date ranges, "within n words",
|
data/doc/TODO
CHANGED
@@ -1,43 +1,37 @@
|
|
1
|
-
for 0.
|
2
|
-
-------
|
3
|
-
|
4
|
-
x bugfix: contacts.txt isn't parsed correctly when there are spaces in
|
5
|
-
aliases
|
6
|
-
x bugfix: @ signs in names make sendmail die silently
|
7
|
-
x bugfix: sent.mbox and >From
|
8
|
-
x bugfix: tokenized email addresses (amazon.com, etc)
|
9
|
-
x bugfix: trailing spaces in buffermanager.ask
|
10
|
-
x bugfix: need to URL-unescape maildir folders
|
11
|
-
x bugfix: downcasing tab completion
|
12
|
-
x warnings: top-posting, missing attachment
|
13
|
-
x hookability
|
14
|
-
|
15
|
-
for 0.3
|
1
|
+
for 0.4
|
16
2
|
-------
|
17
3
|
_ mark thread as unread should remember the unread messages and mark
|
18
|
-
|
4
|
+
only them as unread, just like gmail
|
19
5
|
_ mark thread as unread should have a version within thread-view-mode
|
20
|
-
|
6
|
+
which then also closes the buffer
|
21
7
|
_ bugfix: time zone parsing broken?
|
22
|
-
_ mailing list auto-subscribe/unsubscribe
|
23
8
|
_ forwards optionally include attachments
|
24
9
|
_ attach messages
|
25
10
|
_ flesh out gpg integration: sign & encrypt outgoing
|
26
|
-
_ mbox: don't keep filehandles open, and protect all reads with
|
11
|
+
_ mbox: don't keep filehandles open, and protect all reads with
|
12
|
+
dotlockfile
|
13
|
+
_ imap: share connection to the same server.
|
27
14
|
_ bugfix: screwing with the headers when editing causes a crash
|
28
15
|
_ need a better way to force an address to a particular name,
|
29
|
-
|
16
|
+
for things like evite addresses
|
30
17
|
_ pressing A in thread-view-mode should jump to next message
|
31
18
|
_ imap "add all folders on this server" option in sup-add
|
32
19
|
_ for new message flashes, add new message counts until keypress
|
33
20
|
_ bugfix: missing sources should be handled better
|
34
21
|
_ search results: highlight relevant snippets and open to relevant
|
35
|
-
|
22
|
+
portion of thread
|
36
23
|
_ have "notes" (treated as emails to oneself, never sent) as
|
37
|
-
|
24
|
+
first-class objects.
|
38
25
|
|
39
26
|
future
|
40
27
|
------
|
28
|
+
_ ldbd support
|
29
|
+
_ don't use a people.txt; store email addresses directly in the index. too many
|
30
|
+
problems with email addresses that occur with multiple names.
|
31
|
+
_ infix match instead of prefix match for tab completion (maybe!)
|
32
|
+
_ fix killed threads contributing to unread message count problem (prob. need
|
33
|
+
to maintain all killed message ids and our own unread message count for
|
34
|
+
inbox).
|
41
35
|
_ emlx support (some os x thing)
|
42
36
|
_ tab completion for mid-text cursors
|
43
37
|
_ bugfix: not horizontal scrolling for ncurses text field entry
|
@@ -83,6 +77,24 @@ x gmail support: obsoleted by imap
|
|
83
77
|
|
84
78
|
done
|
85
79
|
----
|
80
|
+
x multi-thread dump upon crash
|
81
|
+
x hook manager caches values of any proc "variables"
|
82
|
+
x bugfix: remove delay on startup if a usual imap source exists
|
83
|
+
x bugfix: broken source handling still needs to be improved
|
84
|
+
x speed up querying
|
85
|
+
x bugfix: sources sometimes aren't added by sup-add
|
86
|
+
x more widgets: terminal title, statusbar
|
87
|
+
x mailing list auto-subscribe/unsubscribe
|
88
|
+
x bugfix: contacts.txt isn't parsed correctly when there are spaces in
|
89
|
+
aliases
|
90
|
+
x bugfix: @ signs in names make sendmail die silently
|
91
|
+
x bugfix: sent.mbox and >From
|
92
|
+
x bugfix: tokenized email addresses (amazon.com, etc)
|
93
|
+
x bugfix: trailing spaces in buffermanager.ask
|
94
|
+
x bugfix: need to URL-unescape maildir folders
|
95
|
+
x bugfix: downcasing tab completion
|
96
|
+
x warnings: top-posting, missing attachment
|
97
|
+
x hookability
|
86
98
|
x bugfix: deadlock (on rubyforge) (? still valid ?)
|
87
99
|
x bugfix: ferret corrupt index problem at index.c:901. see http://ferret.davebalmain.com/trac/ticket/279
|
88
100
|
x tab completion for to: and cc: in compose-mode
|
data/lib/sup.rb
CHANGED
@@ -32,7 +32,7 @@ class Module
|
|
32
32
|
end
|
33
33
|
|
34
34
|
module Redwood
|
35
|
-
VERSION = "0.
|
35
|
+
VERSION = "0.3"
|
36
36
|
|
37
37
|
BASE_DIR = ENV["SUP_BASE"] || File.join(ENV["HOME"], ".sup")
|
38
38
|
CONFIG_FN = File.join(BASE_DIR, "config.yaml")
|
@@ -60,8 +60,7 @@ module Redwood
|
|
60
60
|
end
|
61
61
|
|
62
62
|
## record exceptions thrown in threads nicely
|
63
|
-
|
64
|
-
def reporting_thread
|
63
|
+
def reporting_thread name
|
65
64
|
if $opts[:no_threads]
|
66
65
|
yield
|
67
66
|
else
|
@@ -69,11 +68,8 @@ module Redwood
|
|
69
68
|
begin
|
70
69
|
yield
|
71
70
|
rescue Exception => e
|
72
|
-
|
73
|
-
|
74
|
-
f.puts e.message, e.backtrace
|
75
|
-
end
|
76
|
-
$exception ||= e
|
71
|
+
$exceptions ||= []
|
72
|
+
$exceptions << [e, name]
|
77
73
|
raise
|
78
74
|
end
|
79
75
|
end
|
@@ -124,12 +120,16 @@ module Redwood
|
|
124
120
|
end
|
125
121
|
|
126
122
|
## not really a good place for this, so I'll just dump it here.
|
123
|
+
##
|
124
|
+
## a source error is either a FatalSourceError or an OutOfSyncSourceError.
|
125
|
+
## the superclass SourceError is just a generic.
|
127
126
|
def report_broken_sources opts={}
|
128
127
|
return unless BufferManager.instantiated?
|
129
128
|
|
130
|
-
broken_sources = Index.
|
129
|
+
broken_sources = Index.sources.select { |s| s.error.is_a? FatalSourceError }
|
131
130
|
unless broken_sources.empty?
|
132
|
-
BufferManager.
|
131
|
+
BufferManager.spawn_unless_exists("Broken source notification for #{broken_sources.join(',')}", opts) do
|
132
|
+
TextMode.new(<<EOM)
|
133
133
|
Source error notification
|
134
134
|
-------------------------
|
135
135
|
|
@@ -140,11 +140,13 @@ be viewed, and new messages will not be detected.
|
|
140
140
|
#{broken_sources.map { |s| "Source: " + s.to_s + "\n Error: " + s.error.message.wrap(70).join("\n ")}.join("\n\n")}
|
141
141
|
EOM
|
142
142
|
#' stupid ruby-mode
|
143
|
+
end
|
143
144
|
end
|
144
145
|
|
145
|
-
desynced_sources = Index.
|
146
|
+
desynced_sources = Index.sources.select { |s| s.error.is_a? OutOfSyncSourceError }
|
146
147
|
unless desynced_sources.empty?
|
147
|
-
BufferManager.
|
148
|
+
BufferManager.spawn_unless_exists("Out-of-sync source notification for #{broken_sources.join(',')}", opts) do
|
149
|
+
TextMode.new(<<EOM)
|
148
150
|
Out-of-sync source notification
|
149
151
|
-------------------------------
|
150
152
|
|
@@ -162,6 +164,7 @@ and new messages will not be detected. Luckily, this is easy to correct!
|
|
162
164
|
end}
|
163
165
|
EOM
|
164
166
|
#' stupid ruby-mode
|
167
|
+
end
|
165
168
|
end
|
166
169
|
end
|
167
170
|
|
@@ -198,6 +201,7 @@ else
|
|
198
201
|
:edit_signature => false,
|
199
202
|
:ask_for_cc => true,
|
200
203
|
:ask_for_bcc => false,
|
204
|
+
:ask_for_subject => true,
|
201
205
|
:confirm_no_attachments => true,
|
202
206
|
:confirm_top_posting => true,
|
203
207
|
}
|
@@ -217,6 +221,20 @@ require "sup/hook"
|
|
217
221
|
## time.
|
218
222
|
Redwood::HookManager.new Redwood::HOOK_DIR
|
219
223
|
|
224
|
+
## everything we need to get logging working
|
225
|
+
require "sup/buffer"
|
226
|
+
require "sup/keymap"
|
227
|
+
require "sup/mode"
|
228
|
+
require "sup/modes/scroll-mode"
|
229
|
+
require "sup/modes/text-mode"
|
230
|
+
require "sup/modes/log-mode"
|
231
|
+
require "sup/logger"
|
232
|
+
module Redwood
|
233
|
+
def log s; Logger.log s; end
|
234
|
+
module_function :log
|
235
|
+
end
|
236
|
+
|
237
|
+
## now everything else (which can feel free to call Redwood::log at load time)
|
220
238
|
require "sup/update"
|
221
239
|
require "sup/suicide"
|
222
240
|
require "sup/message-chunks"
|
@@ -230,9 +248,6 @@ require "sup/account"
|
|
230
248
|
require "sup/thread"
|
231
249
|
require "sup/index"
|
232
250
|
require "sup/textfield"
|
233
|
-
require "sup/buffer"
|
234
|
-
require "sup/keymap"
|
235
|
-
require "sup/mode"
|
236
251
|
require "sup/colormap"
|
237
252
|
require "sup/label"
|
238
253
|
require "sup/contact"
|
@@ -240,8 +255,6 @@ require "sup/tagger"
|
|
240
255
|
require "sup/draft"
|
241
256
|
require "sup/poll"
|
242
257
|
require "sup/crypto"
|
243
|
-
require "sup/modes/scroll-mode"
|
244
|
-
require "sup/modes/text-mode"
|
245
258
|
require "sup/modes/line-cursor-mode"
|
246
259
|
require "sup/modes/help-mode"
|
247
260
|
require "sup/modes/edit-message-mode"
|
@@ -258,18 +271,11 @@ require "sup/modes/search-results-mode"
|
|
258
271
|
require "sup/modes/person-search-results-mode"
|
259
272
|
require "sup/modes/inbox-mode"
|
260
273
|
require "sup/modes/buffer-list-mode"
|
261
|
-
require "sup/modes/log-mode"
|
262
274
|
require "sup/modes/poll-mode"
|
263
275
|
require "sup/modes/file-browser-mode"
|
264
276
|
require "sup/modes/completion-mode"
|
265
|
-
require "sup/logger"
|
266
277
|
require "sup/sent"
|
267
278
|
|
268
|
-
module Redwood
|
269
|
-
def log s; Logger.log s; end
|
270
|
-
module_function :log
|
271
|
-
end
|
272
|
-
|
273
279
|
$:.each do |base|
|
274
280
|
d = File.join base, "sup/share/modes/"
|
275
281
|
Redwood::Mode.load_all_modes d if File.directory? d
|