sup 0.0.8 → 0.1
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/HACKING +6 -36
- data/History.txt +11 -0
- data/Manifest.txt +5 -0
- data/README.txt +13 -31
- data/Rakefile +3 -3
- data/bin/sup +167 -89
- data/bin/sup-add +39 -29
- data/bin/sup-config +57 -31
- data/bin/sup-sync +60 -54
- data/bin/sup-sync-back +143 -0
- data/doc/FAQ.txt +56 -19
- data/doc/Philosophy.txt +34 -33
- data/doc/TODO +76 -46
- data/doc/UserGuide.txt +142 -122
- data/lib/sup.rb +76 -36
- data/lib/sup/account.rb +27 -19
- data/lib/sup/buffer.rb +130 -44
- data/lib/sup/contact.rb +1 -1
- data/lib/sup/draft.rb +1 -2
- data/lib/sup/imap.rb +64 -19
- data/lib/sup/index.rb +95 -16
- data/lib/sup/keymap.rb +1 -1
- data/lib/sup/label.rb +31 -5
- data/lib/sup/maildir.rb +7 -5
- data/lib/sup/mbox.rb +34 -15
- data/lib/sup/mbox/loader.rb +30 -12
- data/lib/sup/mbox/ssh-loader.rb +7 -5
- data/lib/sup/message.rb +93 -44
- data/lib/sup/modes/buffer-list-mode.rb +1 -1
- data/lib/sup/modes/completion-mode.rb +55 -0
- data/lib/sup/modes/compose-mode.rb +6 -25
- data/lib/sup/modes/contact-list-mode.rb +1 -1
- data/lib/sup/modes/edit-message-mode.rb +119 -29
- data/lib/sup/modes/file-browser-mode.rb +108 -0
- data/lib/sup/modes/forward-mode.rb +3 -20
- data/lib/sup/modes/inbox-mode.rb +9 -12
- data/lib/sup/modes/label-list-mode.rb +28 -46
- data/lib/sup/modes/label-search-results-mode.rb +1 -16
- data/lib/sup/modes/line-cursor-mode.rb +44 -5
- data/lib/sup/modes/person-search-results-mode.rb +1 -16
- data/lib/sup/modes/reply-mode.rb +18 -31
- data/lib/sup/modes/resume-mode.rb +6 -6
- data/lib/sup/modes/scroll-mode.rb +6 -5
- data/lib/sup/modes/search-results-mode.rb +6 -17
- data/lib/sup/modes/thread-index-mode.rb +70 -28
- data/lib/sup/modes/thread-view-mode.rb +65 -29
- data/lib/sup/person.rb +71 -30
- data/lib/sup/poll.rb +13 -4
- data/lib/sup/rfc2047.rb +61 -0
- data/lib/sup/sent.rb +7 -5
- data/lib/sup/source.rb +12 -9
- data/lib/sup/suicide.rb +36 -0
- data/lib/sup/tagger.rb +6 -6
- data/lib/sup/textfield.rb +76 -14
- data/lib/sup/thread.rb +97 -123
- data/lib/sup/util.rb +167 -1
- metadata +30 -5
data/HACKING
CHANGED
@@ -4,47 +4,17 @@ Invoke it like this:
|
|
4
4
|
|
5
5
|
ruby -I lib -w bin/sup
|
6
6
|
|
7
|
+
You'll have to install all gems mentioned in the Rakefile (look for the line
|
8
|
+
setting p.extra_deps). If you're on a Debian or Debian-based system (e.g.
|
9
|
+
Ubuntu), you'll have to make sure you have a complete Ruby installation,
|
10
|
+
especially libssl-ruby.
|
11
|
+
|
7
12
|
Coding standards
|
8
13
|
----------------
|
9
14
|
|
10
15
|
- Don't wrap code unless it really benefits from it. The days of
|
11
16
|
80-column displays are long over. But do wrap comments and other
|
12
17
|
text at whatever Emacs meta-Q does.
|
13
|
-
-
|
18
|
+
- I like poetry mode.
|
14
19
|
- Use {} for one-liner blocks and do/end for multi-line blocks.
|
15
20
|
|
16
|
-
How messages are updated in the index
|
17
|
-
-------------------------------------
|
18
|
-
|
19
|
-
Ferret doesn't have any concept of updating; to change message state
|
20
|
-
it must be deleted then re-added to the index.
|
21
|
-
|
22
|
-
Thus there are a couple situations where we'll have a message to be
|
23
|
-
"added", but it already exists in the index, and we need to decide
|
24
|
-
which parts of which version to keep:
|
25
|
-
|
26
|
-
1. The user has changed the state of the message, e.g. read it or
|
27
|
-
added a user label. In this case we want to use the state of the
|
28
|
-
version in memory, but keep everything else on disk.
|
29
|
-
|
30
|
-
This is the behavior of Index#update_message
|
31
|
-
|
32
|
-
2. We've received a new copy of the message. Crucially, this can
|
33
|
-
happen for two different reasons:
|
34
|
-
|
35
|
-
a. The message was sent to a mailing list to which the user is
|
36
|
-
subscribed, and we're now getting that message back, possibly
|
37
|
-
with altered content (subject mangling, signature adding, etc.)
|
38
|
-
|
39
|
-
b. The user has moved the message between sources. E.g. if the
|
40
|
-
primary inbox has a quota, and other sources are on local,
|
41
|
-
quota-less disk, the user may regularly move messages from the
|
42
|
-
inbox to the sources on disk.
|
43
|
-
|
44
|
-
In both of these cases, the solution is to keep the state from the
|
45
|
-
index, but use the new message contents.
|
46
|
-
|
47
|
-
This is the behavior of Index#update_or_add_message, which can be
|
48
|
-
also be called for new message.
|
49
|
-
|
50
|
-
|
data/History.txt
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
== 0.1 / 2007-07-17
|
2
|
+
* MIME attachment creation.
|
3
|
+
* i18n support: character set conversion and rfc2047 header decoding.
|
4
|
+
* Better MIME handling.
|
5
|
+
* Multiple account support.
|
6
|
+
* Locking and concurrent Sup process detection and killation.
|
7
|
+
* Thread autoloading when you scroll down.
|
8
|
+
* Batch deletion of messages marked deleted or spam from message
|
9
|
+
sources via sup-sync-back tool (mbox only).
|
10
|
+
* Millions of bugfixes.
|
11
|
+
|
1
12
|
== 0.0.8 / 2007-04-01
|
2
13
|
|
3
14
|
* Maildir support!
|
data/Manifest.txt
CHANGED
@@ -10,6 +10,7 @@ bin/sup-config
|
|
10
10
|
bin/sup-dump
|
11
11
|
bin/sup-recover-sources
|
12
12
|
bin/sup-sync
|
13
|
+
bin/sup-sync-back
|
13
14
|
doc/FAQ.txt
|
14
15
|
doc/Philosophy.txt
|
15
16
|
doc/TODO
|
@@ -33,9 +34,11 @@ lib/sup/mbox/ssh-loader.rb
|
|
33
34
|
lib/sup/message.rb
|
34
35
|
lib/sup/mode.rb
|
35
36
|
lib/sup/modes/buffer-list-mode.rb
|
37
|
+
lib/sup/modes/completion-mode.rb
|
36
38
|
lib/sup/modes/compose-mode.rb
|
37
39
|
lib/sup/modes/contact-list-mode.rb
|
38
40
|
lib/sup/modes/edit-message-mode.rb
|
41
|
+
lib/sup/modes/file-browser-mode.rb
|
39
42
|
lib/sup/modes/forward-mode.rb
|
40
43
|
lib/sup/modes/help-mode.rb
|
41
44
|
lib/sup/modes/inbox-mode.rb
|
@@ -54,8 +57,10 @@ lib/sup/modes/thread-index-mode.rb
|
|
54
57
|
lib/sup/modes/thread-view-mode.rb
|
55
58
|
lib/sup/person.rb
|
56
59
|
lib/sup/poll.rb
|
60
|
+
lib/sup/rfc2047.rb
|
57
61
|
lib/sup/sent.rb
|
58
62
|
lib/sup/source.rb
|
63
|
+
lib/sup/suicide.rb
|
59
64
|
lib/sup/tagger.rb
|
60
65
|
lib/sup/textfield.rb
|
61
66
|
lib/sup/thread.rb
|
data/README.txt
CHANGED
@@ -4,9 +4,10 @@ sup
|
|
4
4
|
|
5
5
|
== DESCRIPTION:
|
6
6
|
|
7
|
-
Sup is a console-based email client
|
8
|
-
|
9
|
-
|
7
|
+
Sup is a console-based email client for people with a lot of email.
|
8
|
+
It supports tagging, very fast full-text search, automatic contact-
|
9
|
+
list management, and more. If you're the type of person who treats
|
10
|
+
email as an extension of your long-term memory, Sup is for you.
|
10
11
|
|
11
12
|
Sup makes it easy to:
|
12
13
|
- Handle massive amounts of email.
|
@@ -84,24 +85,15 @@ Current limitations which will be fixed:
|
|
84
85
|
|
85
86
|
== SYNOPSYS:
|
86
87
|
|
87
|
-
|
88
|
-
|
89
|
-
3. edit ~/.sup/config.yaml for the (very few) settings sup has
|
90
|
-
|
91
|
-
Where <source> is a filename (for mbox files), an imap or imaps URI,
|
92
|
-
or a mbox+ssh URI (for remote mbox files). You will be prompted for
|
93
|
-
a username and password if required.
|
94
|
-
|
95
|
-
sup-import has several options which control whether you want
|
96
|
-
messages from particular mailboxes not to be added to the inbox, or
|
97
|
-
not to be marked as new, so run it with -h for help.
|
88
|
+
0. sup-config
|
89
|
+
1. sup
|
98
90
|
|
99
91
|
Note that Sup never changes the contents of any mailboxes; it only
|
100
92
|
indexes in to them. So it shouldn't ever corrupt your mail. The flip
|
101
93
|
side is that if you change a mailbox (e.g. delete messages, or, in
|
102
94
|
the case of mbox files, read an unread message) then Sup will be
|
103
95
|
unable to load messages from that source and will ask you to run
|
104
|
-
sup-
|
96
|
+
sup-sync --changed.
|
105
97
|
|
106
98
|
== REQUIREMENTS:
|
107
99
|
|
@@ -109,28 +101,18 @@ Current limitations which will be fixed:
|
|
109
101
|
* ncurses
|
110
102
|
* rmail
|
111
103
|
* highline
|
112
|
-
* trollop
|
113
104
|
* net-ssh
|
105
|
+
* trollop >= 1.7
|
106
|
+
* lockfile
|
107
|
+
* mime-types
|
114
108
|
|
115
109
|
== INSTALL:
|
116
110
|
|
117
111
|
* gem install sup -y
|
118
112
|
|
119
|
-
==
|
120
|
-
|
121
|
-
|
122
|
-
certain messages with attachments, in rmail, change line 159 of
|
123
|
-
multipart.rb to:
|
124
|
-
chunk = chunk[0..start]
|
125
|
-
This is because RubyMail hasn't been updated since like Ruby 1.8.2.
|
126
|
-
Please bug Matt Lickey.
|
127
|
-
* Occasionally Ferret produces something the Ruby GC doesn't like
|
128
|
-
(particularly when importing messages from very large sources).
|
129
|
-
No worries, just re-run sup-import. (This is unresolved atm.)
|
130
|
-
* If you are using IMAP or Maildir and see this error:
|
131
|
-
/usr/local/lib/ruby/1.8/yaml.rb:133:in `transfer': allocator undefined for Bignum (TypeError)
|
132
|
-
then you need to upgrade to Ruby 1.8.5. YAML in earlier versions
|
133
|
-
can't parse BigNums.
|
113
|
+
== PROBLEMS:
|
114
|
+
|
115
|
+
See FAQ.txt for some common problems and their solutions.
|
134
116
|
|
135
117
|
== LICENSE:
|
136
118
|
|
data/Rakefile
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'rubygems'
|
4
4
|
require 'hoe'
|
5
|
-
require '
|
5
|
+
require 'sup'
|
6
6
|
|
7
7
|
class Hoe
|
8
8
|
def extra_deps; @extra_deps.reject { |x| Array(x).first == "hoe" } end
|
@@ -16,14 +16,14 @@ Hoe.new('sup', Redwood::VERSION) do |p|
|
|
16
16
|
p.url = p.paragraphs_of('README.txt', 0).first.split(/\n/)[2].gsub(/^\s+/, "")
|
17
17
|
p.changes = p.paragraphs_of('History.txt', 0..0).join("\n\n")
|
18
18
|
p.email = "wmorgan-sup@masanjin.net"
|
19
|
-
p.extra_deps = [['ferret', '>= 0.10.13'], ['ncurses', '>= 0.9.1'], ['rmail', '>= 0.17'], 'highline', 'net-ssh', ['trollop', '>= 1.
|
19
|
+
p.extra_deps = [['ferret', '>= 0.10.13'], ['ncurses', '>= 0.9.1'], ['rmail', '>= 0.17'], 'highline', 'net-ssh', ['trollop', '>= 1.7'], 'lockfile', 'mime-types']
|
20
20
|
end
|
21
21
|
|
22
22
|
rule 'ss?.png' => 'ss?-small.png' do |t|
|
23
23
|
end
|
24
24
|
|
25
25
|
## is there really no way to make a rule for this?
|
26
|
-
WWW_FILES = %w(www/index.html README.txt doc/Philosophy.txt doc/FAQ.txt doc/UserGuide.txt)
|
26
|
+
WWW_FILES = %w(www/index.html README.txt doc/Philosophy.txt doc/FAQ.txt doc/UserGuide.txt www/main.css)
|
27
27
|
|
28
28
|
SCREENSHOTS = FileList["www/ss?.png"]
|
29
29
|
SCREENSHOTS_SMALL = []
|
data/bin/sup
CHANGED
@@ -2,8 +2,23 @@
|
|
2
2
|
|
3
3
|
require 'rubygems'
|
4
4
|
require 'ncurses'
|
5
|
+
require 'fileutils'
|
6
|
+
require 'trollop'
|
5
7
|
require "sup"
|
6
8
|
|
9
|
+
$opts = Trollop::options do
|
10
|
+
version "sup v#{Redwood::VERSION}"
|
11
|
+
banner <<EOS
|
12
|
+
Sup is a curses-based email client.
|
13
|
+
|
14
|
+
Usage:
|
15
|
+
sup [options]
|
16
|
+
|
17
|
+
Options are:
|
18
|
+
EOS
|
19
|
+
opt :no_threads, "Turn of threading. Helps with debugging. (Necessarily disables background polling for new messages.)"
|
20
|
+
end
|
21
|
+
|
7
22
|
Thread.abort_on_exception = true # make debugging possible
|
8
23
|
|
9
24
|
module Redwood
|
@@ -31,31 +46,60 @@ def start_cursing
|
|
31
46
|
Ncurses.stdscr.keypad 1
|
32
47
|
Ncurses.curs_set 0
|
33
48
|
Ncurses.start_color
|
49
|
+
$cursing = true
|
34
50
|
end
|
35
51
|
|
36
52
|
def stop_cursing
|
53
|
+
return unless $cursing
|
37
54
|
Ncurses.curs_set 1
|
38
55
|
Ncurses.echo
|
39
56
|
Ncurses.endwin
|
40
57
|
end
|
41
58
|
module_function :start_cursing, :stop_cursing
|
42
59
|
|
43
|
-
|
44
|
-
|
60
|
+
Index.new
|
61
|
+
begin
|
62
|
+
Index.lock
|
63
|
+
rescue Index::LockError => e
|
64
|
+
require 'highline'
|
45
65
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
Index.add_source DraftManager.new_source
|
50
|
-
end
|
66
|
+
h = HighLine.new
|
67
|
+
h.wrap_at = :auto
|
68
|
+
h.say Index.fancy_lock_error_message_for(e)
|
51
69
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
70
|
+
case h.ask("Should I ask that process to kill itself? ")
|
71
|
+
when /^\s*y\s*$/i
|
72
|
+
h.say "Ok, suggesting sepuku..."
|
73
|
+
FileUtils.touch Redwood::SUICIDE_FN
|
74
|
+
sleep SuicideManager::DELAY * 2
|
75
|
+
FileUtils.rm_f Redwood::SUICIDE_FN
|
76
|
+
h.say "Let's try that again."
|
77
|
+
retry
|
78
|
+
else
|
79
|
+
h.say <<EOS
|
80
|
+
Ok, giving up. If the process crashed and left a stale lockfile, you
|
81
|
+
can fix this by manually deleting #{Index.lockfile}.
|
82
|
+
EOS
|
83
|
+
exit
|
84
|
+
end
|
56
85
|
end
|
57
86
|
|
58
87
|
begin
|
88
|
+
Redwood::start
|
89
|
+
Index.load
|
90
|
+
|
91
|
+
if(s = Index.source_for DraftManager.source_name)
|
92
|
+
DraftManager.source = s
|
93
|
+
else
|
94
|
+
Index.add_source DraftManager.new_source
|
95
|
+
end
|
96
|
+
|
97
|
+
if(s = Index.source_for SentManager.source_name)
|
98
|
+
SentManager.source = s
|
99
|
+
else
|
100
|
+
Index.add_source SentManager.new_source
|
101
|
+
end
|
102
|
+
|
59
103
|
log "starting curses"
|
60
104
|
start_cursing
|
61
105
|
|
@@ -65,6 +109,8 @@ begin
|
|
65
109
|
c.add :index_old_color, Ncurses::COLOR_WHITE, Ncurses::COLOR_BLACK
|
66
110
|
c.add :index_new_color, Ncurses::COLOR_WHITE, Ncurses::COLOR_BLACK,
|
67
111
|
Ncurses::A_BOLD
|
112
|
+
c.add :index_starred_color, Ncurses::COLOR_YELLOW, Ncurses::COLOR_BLACK,
|
113
|
+
Ncurses::A_BOLD
|
68
114
|
c.add :labellist_old_color, Ncurses::COLOR_WHITE, Ncurses::COLOR_BLACK
|
69
115
|
c.add :labellist_new_color, Ncurses::COLOR_WHITE, Ncurses::COLOR_BLACK,
|
70
116
|
Ncurses::A_BOLD
|
@@ -73,7 +119,7 @@ begin
|
|
73
119
|
c.add :message_patina_color, Ncurses::COLOR_BLACK, Ncurses::COLOR_GREEN
|
74
120
|
c.add :alternate_patina_color, Ncurses::COLOR_BLACK, Ncurses::COLOR_BLUE
|
75
121
|
c.add :missing_message_color, Ncurses::COLOR_BLACK, Ncurses::COLOR_RED
|
76
|
-
c.add :
|
122
|
+
c.add :attachment_color, Ncurses::COLOR_CYAN, Ncurses::COLOR_BLACK
|
77
123
|
c.add :quote_patina_color, Ncurses::COLOR_YELLOW, Ncurses::COLOR_BLACK
|
78
124
|
c.add :sig_patina_color, Ncurses::COLOR_YELLOW, Ncurses::COLOR_BLACK
|
79
125
|
c.add :quote_color, Ncurses::COLOR_YELLOW, Ncurses::COLOR_BLACK
|
@@ -91,6 +137,8 @@ begin
|
|
91
137
|
Ncurses::A_BOLD
|
92
138
|
c.add :draft_notification_color, Ncurses::COLOR_RED, Ncurses::COLOR_BLACK,
|
93
139
|
Ncurses::A_BOLD
|
140
|
+
c.add :completion_character_color, Ncurses::COLOR_WHITE,
|
141
|
+
Ncurses::COLOR_BLACK, Ncurses::A_BOLD
|
94
142
|
end
|
95
143
|
|
96
144
|
log "initializing buffer manager"
|
@@ -98,7 +146,7 @@ begin
|
|
98
146
|
|
99
147
|
log "initializing mail index buffer"
|
100
148
|
imode = InboxMode.new
|
101
|
-
ibuf = bm.spawn "
|
149
|
+
ibuf = bm.spawn "Inbox", imode
|
102
150
|
|
103
151
|
log "ready for interaction!"
|
104
152
|
Logger.make_buf
|
@@ -122,99 +170,129 @@ begin
|
|
122
170
|
end if s.respond_to? :connect
|
123
171
|
end
|
124
172
|
|
125
|
-
imode.load_threads :num => ibuf.content_height, :when_done => lambda { reporting_thread { sleep 1; PollManager.poll } }
|
173
|
+
imode.load_threads :num => ibuf.content_height, :when_done => lambda { reporting_thread { sleep 1; PollManager.poll } unless $opts[:no_threads] }
|
126
174
|
|
127
|
-
|
175
|
+
unless $opts[:no_threads]
|
176
|
+
PollManager.start
|
177
|
+
SuicideManager.start
|
178
|
+
Index.start_lock_update_thread
|
179
|
+
end
|
128
180
|
|
129
|
-
until $exception
|
130
|
-
bm.draw_screen
|
181
|
+
until $exception || SuicideManager.die?
|
131
182
|
c = Ncurses.nonblocking_getch
|
183
|
+
next unless c
|
132
184
|
bm.erase_flash
|
133
185
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
when :recall_draft
|
181
|
-
case Index.num_results_for :label => :draft
|
182
|
-
when 0
|
183
|
-
bm.flash "No draft messages."
|
184
|
-
when 1
|
185
|
-
m = nil
|
186
|
-
Index.each_id_by_date(:label => :draft) { |mid, builder| m = builder.call }
|
187
|
-
r = ResumeMode.new(m)
|
188
|
-
BufferManager.spawn "Edit message", r
|
189
|
-
r.edit
|
190
|
-
else
|
191
|
-
b = BufferManager.spawn_unless_exists(:draft) do
|
192
|
-
mode = LabelSearchResultsMode.new [:draft]
|
193
|
-
end
|
194
|
-
b.mode.load_threads :num => b.content_height
|
186
|
+
unless bm.handle_input(c)
|
187
|
+
x = global_keymap.action_for c
|
188
|
+
case x
|
189
|
+
when :quit
|
190
|
+
break if bm.kill_all_buffers_safely
|
191
|
+
when :help
|
192
|
+
curmode = bm.focus_buf.mode
|
193
|
+
bm.spawn_unless_exists("<help for #{curmode.name}>") { HelpMode.new curmode, global_keymap }
|
194
|
+
when :roll_buffers
|
195
|
+
bm.roll_buffers
|
196
|
+
when :roll_buffers_backwards
|
197
|
+
bm.roll_buffers_backwards
|
198
|
+
when :kill_buffer
|
199
|
+
bm.kill_buffer_safely bm.focus_buf
|
200
|
+
when :list_buffers
|
201
|
+
bm.spawn_unless_exists("Buffer List") { BufferListMode.new }
|
202
|
+
when :list_contacts
|
203
|
+
b = bm.spawn_unless_exists("Contact List") { ContactListMode.new }
|
204
|
+
b.mode.load_in_background
|
205
|
+
when :search
|
206
|
+
text = bm.ask :search, "query: "
|
207
|
+
next unless text && text !~ /^\s*$/
|
208
|
+
|
209
|
+
begin
|
210
|
+
qobj = Index.parse_user_query_string text
|
211
|
+
short_text = text.length < 20 ? text : text[0 ... 20] + "..."
|
212
|
+
log "built query from #{text.inspect}: #{qobj}"
|
213
|
+
mode = SearchResultsMode.new qobj
|
214
|
+
bm.spawn "search: \"#{short_text}\"", mode
|
215
|
+
mode.load_threads :num => mode.buffer.content_height
|
216
|
+
rescue Ferret::QueryParser::QueryParseException => e
|
217
|
+
bm.flash "Couldn't parse query."
|
218
|
+
end
|
219
|
+
when :list_labels
|
220
|
+
labels = LabelManager.listable_label_strings
|
221
|
+
user_label = bm.ask_with_completions :label, "Show threads with label (enter for listing): ", labels
|
222
|
+
user_label = bm.spawn_modal("Label list", LabelListMode.new) if user_label && user_label.empty?
|
223
|
+
|
224
|
+
label = LabelManager.label_for user_label if user_label
|
225
|
+
case label
|
226
|
+
when nil
|
227
|
+
when :inbox
|
228
|
+
BufferManager.raise_to_front InboxMode.instance.buffer
|
229
|
+
else
|
230
|
+
b = BufferManager.spawn_unless_exists("All threads with label '#{user_label}'") do
|
231
|
+
mode = LabelSearchResultsMode.new([label])
|
195
232
|
end
|
196
|
-
|
197
|
-
|
198
|
-
|
233
|
+
b.mode.load_threads :num => b.content_height
|
234
|
+
end
|
235
|
+
|
236
|
+
when :compose
|
237
|
+
mode = ComposeMode.new
|
238
|
+
bm.spawn "New Message", mode
|
239
|
+
mode.edit
|
240
|
+
when :poll
|
241
|
+
# bm.raise_to_front PollManager.buffer
|
242
|
+
reporting_thread { PollManager.poll }
|
243
|
+
when :recall_draft
|
244
|
+
case Index.num_results_for :label => :draft
|
245
|
+
when 0
|
246
|
+
bm.flash "No draft messages."
|
247
|
+
when 1
|
248
|
+
m = nil
|
249
|
+
Index.each_id_by_date(:label => :draft) { |mid, builder| m = builder.call }
|
250
|
+
r = ResumeMode.new(m)
|
251
|
+
BufferManager.spawn "Edit message", r
|
252
|
+
r.edit
|
199
253
|
else
|
200
|
-
|
254
|
+
b = BufferManager.spawn_unless_exists("All drafts") do
|
255
|
+
mode = LabelSearchResultsMode.new [:draft]
|
256
|
+
end
|
257
|
+
b.mode.load_threads :num => b.content_height
|
201
258
|
end
|
259
|
+
when :nothing
|
260
|
+
when :redraw
|
261
|
+
bm.completely_redraw_screen
|
262
|
+
else
|
263
|
+
bm.flash "Unknown key press '#{c.to_character}' for #{bm.focus_buf.mode.name}."
|
202
264
|
end
|
203
265
|
end
|
266
|
+
|
267
|
+
bm.draw_screen
|
204
268
|
end
|
205
269
|
rescue Exception => e
|
206
270
|
$exception ||= e
|
207
271
|
ensure
|
272
|
+
unless $opts[:no_threads]
|
273
|
+
PollManager.stop if PollManager.instantiated?
|
274
|
+
SuicideManager.stop if PollManager.instantiated?
|
275
|
+
Index.stop_lock_update_thread
|
276
|
+
end
|
277
|
+
|
208
278
|
Redwood::finish
|
209
279
|
stop_cursing
|
210
|
-
|
211
|
-
|
280
|
+
Redwood::log "stopped cursing"
|
281
|
+
|
282
|
+
if SuicideManager.instantiated? && SuicideManager.die?
|
283
|
+
Redwood::log "I've been ordered to commit sepuku. I obey!"
|
284
|
+
end
|
285
|
+
|
286
|
+
case $exception
|
287
|
+
when nil
|
288
|
+
Redwood::log "no fatal errors. good job, william."
|
289
|
+
Index.save
|
212
290
|
else
|
213
|
-
Redwood::log "
|
291
|
+
Redwood::log "oh crap, an exception"
|
214
292
|
end
|
215
|
-
end
|
216
293
|
|
217
|
-
Index.
|
294
|
+
Index.unlock
|
295
|
+
end
|
218
296
|
|
219
297
|
if $exception
|
220
298
|
$stderr.puts <<EOS
|
@@ -222,14 +300,14 @@ if $exception
|
|
222
300
|
I'm very sorry, but it seems that an error occurred in Sup.
|
223
301
|
Please accept my sincere apologies. If you don't mind, please
|
224
302
|
send the backtrace below and a brief report of the circumstances
|
225
|
-
to
|
303
|
+
to sup-talk at rubyforge dot orgs so that I might address this
|
226
304
|
problem. Thank you!
|
227
305
|
|
228
306
|
Sincerely,
|
229
307
|
William
|
230
308
|
----------------------------------------------------------------
|
231
309
|
|
232
|
-
The problem was: #{$exception.message} (error type #{$exception.class.name})
|
310
|
+
The problem was: '#{$exception.message}' (error type #{$exception.class.name})
|
233
311
|
A backtrace follows:
|
234
312
|
EOS
|
235
313
|
raise $exception
|