sup 0.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/History.txt +5 -0
- data/LICENSE +280 -0
- data/Manifest.txt +52 -0
- data/README.txt +119 -0
- data/Rakefile +45 -0
- data/bin/sup +229 -0
- data/bin/sup-import +162 -0
- data/doc/FAQ.txt +38 -0
- data/doc/Philosophy.txt +59 -0
- data/doc/TODO +31 -0
- data/lib/sup.rb +141 -0
- data/lib/sup/account.rb +53 -0
- data/lib/sup/buffer.rb +391 -0
- data/lib/sup/colormap.rb +118 -0
- data/lib/sup/contact.rb +40 -0
- data/lib/sup/draft.rb +105 -0
- data/lib/sup/index.rb +353 -0
- data/lib/sup/keymap.rb +89 -0
- data/lib/sup/label.rb +41 -0
- data/lib/sup/logger.rb +42 -0
- data/lib/sup/mbox.rb +51 -0
- data/lib/sup/mbox/loader.rb +116 -0
- data/lib/sup/message.rb +302 -0
- data/lib/sup/mode.rb +79 -0
- data/lib/sup/modes/buffer-list-mode.rb +37 -0
- data/lib/sup/modes/compose-mode.rb +33 -0
- data/lib/sup/modes/contact-list-mode.rb +121 -0
- data/lib/sup/modes/edit-message-mode.rb +162 -0
- data/lib/sup/modes/forward-mode.rb +38 -0
- data/lib/sup/modes/help-mode.rb +19 -0
- data/lib/sup/modes/inbox-mode.rb +45 -0
- data/lib/sup/modes/label-list-mode.rb +89 -0
- data/lib/sup/modes/label-search-results-mode.rb +29 -0
- data/lib/sup/modes/line-cursor-mode.rb +133 -0
- data/lib/sup/modes/log-mode.rb +44 -0
- data/lib/sup/modes/person-search-results-mode.rb +29 -0
- data/lib/sup/modes/poll-mode.rb +24 -0
- data/lib/sup/modes/reply-mode.rb +136 -0
- data/lib/sup/modes/resume-mode.rb +18 -0
- data/lib/sup/modes/scroll-mode.rb +106 -0
- data/lib/sup/modes/search-results-mode.rb +31 -0
- data/lib/sup/modes/text-mode.rb +51 -0
- data/lib/sup/modes/thread-index-mode.rb +389 -0
- data/lib/sup/modes/thread-view-mode.rb +338 -0
- data/lib/sup/person.rb +120 -0
- data/lib/sup/poll.rb +80 -0
- data/lib/sup/sent.rb +46 -0
- data/lib/sup/tagger.rb +40 -0
- data/lib/sup/textfield.rb +83 -0
- data/lib/sup/thread.rb +358 -0
- data/lib/sup/update.rb +21 -0
- data/lib/sup/util.rb +260 -0
- metadata +123 -0
data/lib/sup/update.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
module Redwood
|
2
|
+
|
3
|
+
class UpdateManager
|
4
|
+
include Singleton
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@targets = {}
|
8
|
+
self.class.i_am_the_instance self
|
9
|
+
end
|
10
|
+
|
11
|
+
def register o; @targets[o] = true; end
|
12
|
+
def unregister o; @targets.delete o; end
|
13
|
+
|
14
|
+
def relay type, *args
|
15
|
+
meth = "handle_#{type}_update".intern
|
16
|
+
@targets.keys.each { |o| o.send meth, *args if o.respond_to? meth }
|
17
|
+
BufferManager.draw_screen ## TODO: think about this
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
data/lib/sup/util.rb
ADDED
@@ -0,0 +1,260 @@
|
|
1
|
+
class Module
|
2
|
+
def bool_reader *args
|
3
|
+
args.each { |sym| class_eval %{ def #{sym}?; @#{sym}; end } }
|
4
|
+
end
|
5
|
+
def bool_writer *args; attr_writer(*args); end
|
6
|
+
def bool_accessor *args
|
7
|
+
bool_reader(*args)
|
8
|
+
bool_writer(*args)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class Object
|
13
|
+
def ancestors
|
14
|
+
ret = []
|
15
|
+
klass = self.class
|
16
|
+
|
17
|
+
until klass == Object
|
18
|
+
ret << klass
|
19
|
+
klass = klass.superclass
|
20
|
+
end
|
21
|
+
ret
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class String
|
26
|
+
def camel_to_hyphy
|
27
|
+
self.gsub(/([a-z])([A-Z0-9])/, '\1-\2').downcase
|
28
|
+
end
|
29
|
+
|
30
|
+
def find_all_positions x
|
31
|
+
ret = []
|
32
|
+
start = 0
|
33
|
+
while start < length
|
34
|
+
pos = index x, start
|
35
|
+
break if pos.nil?
|
36
|
+
ret << pos
|
37
|
+
start = pos + 1
|
38
|
+
end
|
39
|
+
ret
|
40
|
+
end
|
41
|
+
|
42
|
+
def ucfirst
|
43
|
+
self[0 .. 0].upcase + self[1 .. -1]
|
44
|
+
end
|
45
|
+
|
46
|
+
## found on teh internets
|
47
|
+
def split_on_commas
|
48
|
+
split(/,\s*(?=(?:[^"]*"[^"]*")*(?![^"]*"))/)
|
49
|
+
end
|
50
|
+
|
51
|
+
def wrap len
|
52
|
+
ret = []
|
53
|
+
s = self
|
54
|
+
while s.length > len
|
55
|
+
cut = s[0 ... len].rindex(/\s/)
|
56
|
+
if cut
|
57
|
+
ret << s[0 ... cut] + "\n"
|
58
|
+
s = s[(cut + 1) .. -1]
|
59
|
+
else
|
60
|
+
ret << s[0 ... len] + "\n"
|
61
|
+
s = s[len .. -1]
|
62
|
+
end
|
63
|
+
end
|
64
|
+
ret << s
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
class Numeric
|
69
|
+
def clamp min, max
|
70
|
+
if self < min
|
71
|
+
min
|
72
|
+
elsif self > max
|
73
|
+
max
|
74
|
+
else
|
75
|
+
self
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def in? range; range.member? self; end
|
80
|
+
end
|
81
|
+
|
82
|
+
class Fixnum
|
83
|
+
def num_digits base=10
|
84
|
+
return 1 if self == 0
|
85
|
+
1 + (Math.log(self) / Math.log(10)).floor
|
86
|
+
end
|
87
|
+
|
88
|
+
def to_character
|
89
|
+
if self < 128 && self >= 0
|
90
|
+
chr
|
91
|
+
else
|
92
|
+
"<#{self}>"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
class Hash
|
98
|
+
def - o
|
99
|
+
Hash[*self.map { |k, v| [k, v] unless o.include? k }.compact.flatten_one_level]
|
100
|
+
end
|
101
|
+
|
102
|
+
def select_by_value v=true
|
103
|
+
select { |k, vv| vv == v }.map { |x| x.first }
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
module Enumerable
|
108
|
+
def map_with_index
|
109
|
+
ret = []
|
110
|
+
each_with_index { |x, i| ret << yield(x, i) }
|
111
|
+
ret
|
112
|
+
end
|
113
|
+
|
114
|
+
def sum; inject(0) { |x, y| x + y }; end
|
115
|
+
|
116
|
+
def map_to_hash
|
117
|
+
ret = {}
|
118
|
+
each { |x| ret[x] = yield(x) }
|
119
|
+
ret
|
120
|
+
end
|
121
|
+
|
122
|
+
# like find, except returns the value of the block rather than the
|
123
|
+
# element itself.
|
124
|
+
def argfind
|
125
|
+
ret = nil
|
126
|
+
find { |e| ret ||= yield(e) }
|
127
|
+
ret || nil # force
|
128
|
+
end
|
129
|
+
|
130
|
+
def argmin
|
131
|
+
best, bestval = nil, nil
|
132
|
+
each do |e|
|
133
|
+
val = yield e
|
134
|
+
if bestval.nil? || val < bestval
|
135
|
+
best, bestval = e, val
|
136
|
+
end
|
137
|
+
end
|
138
|
+
best
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
class Array
|
143
|
+
def flatten_one_level
|
144
|
+
inject([]) { |a, e| a + e }
|
145
|
+
end
|
146
|
+
|
147
|
+
def to_h; Hash[*flatten]; end
|
148
|
+
def rest; self[1..-1]; end
|
149
|
+
|
150
|
+
def to_boolean_h; Hash[*map { |x| [x, true] }.flatten]; end
|
151
|
+
|
152
|
+
## apparently uniq doesn't use ==. wtf.
|
153
|
+
def remove_successive_dupes
|
154
|
+
ret = []
|
155
|
+
last = nil
|
156
|
+
each do |e|
|
157
|
+
unless e == last
|
158
|
+
ret << e
|
159
|
+
last = e
|
160
|
+
end
|
161
|
+
end
|
162
|
+
ret
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
class Time
|
167
|
+
def to_indexable_s
|
168
|
+
sprintf "%012d", self
|
169
|
+
end
|
170
|
+
|
171
|
+
def nearest_hour
|
172
|
+
if min < 30
|
173
|
+
self
|
174
|
+
else
|
175
|
+
self + (60 - min) * 60
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def midnight # within a second
|
180
|
+
self - (hour * 60 * 60) - (min * 60) - sec
|
181
|
+
end
|
182
|
+
|
183
|
+
def is_the_same_day? other
|
184
|
+
(midnight - other.midnight).abs < 1
|
185
|
+
end
|
186
|
+
|
187
|
+
def is_the_day_before? other
|
188
|
+
other.midnight - midnight <= 24 * 60 * 60 + 1
|
189
|
+
end
|
190
|
+
|
191
|
+
def to_nice_distance_s from=Time.now
|
192
|
+
later_than = (self < from)
|
193
|
+
diff = (self.to_i - from.to_i).abs.to_f
|
194
|
+
text =
|
195
|
+
[ ["second", 60],
|
196
|
+
["minute", 60],
|
197
|
+
["hour", 24],
|
198
|
+
["day", 7],
|
199
|
+
["week", 4], # heh heh
|
200
|
+
["month", 12],
|
201
|
+
["year", nil],
|
202
|
+
].argfind do |unit, size|
|
203
|
+
if diff <= 1
|
204
|
+
"one #{unit}"
|
205
|
+
elsif size.nil? || diff < size
|
206
|
+
"#{diff} #{unit}s"
|
207
|
+
else
|
208
|
+
diff = (diff / size.to_f).round
|
209
|
+
false
|
210
|
+
end
|
211
|
+
end
|
212
|
+
if later_than
|
213
|
+
text + " ago"
|
214
|
+
else
|
215
|
+
"in " + text
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
TO_NICE_S_MAX_LEN = 11 # e.g. "Jul 31 2005"
|
220
|
+
def to_nice_s from=Time.now
|
221
|
+
if year != from.year
|
222
|
+
strftime "%b %e %Y"
|
223
|
+
elsif month != from.month
|
224
|
+
strftime "%b %e"
|
225
|
+
else
|
226
|
+
if is_the_same_day? from
|
227
|
+
strftime("%l:%M%P")
|
228
|
+
elsif is_the_day_before? from
|
229
|
+
"Yest." + nearest_hour.strftime("%l%P")
|
230
|
+
else
|
231
|
+
strftime "%b %e"
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
## simple singleton module. far less complete and insane than the ruby
|
238
|
+
## standard library one, but automatically forwards methods calls and
|
239
|
+
## allows for constructors that take arguments.
|
240
|
+
##
|
241
|
+
## You must have #initialize call "self.class.i_am_the_instance self"
|
242
|
+
## at some point or everything will fail horribly
|
243
|
+
module Singleton
|
244
|
+
module ClassMethods
|
245
|
+
def instance; @instance; end
|
246
|
+
def instantiated?; defined?(@instance) && !@instance.nil?; end
|
247
|
+
def method_missing meth, *a, &b
|
248
|
+
raise "no instance defined!" unless defined? @instance
|
249
|
+
@instance.send meth, *a, &b
|
250
|
+
end
|
251
|
+
def i_am_the_instance o
|
252
|
+
raise "there can be only one! (instance)" if defined? @instance
|
253
|
+
@instance = o
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
def self.included klass
|
258
|
+
klass.extend ClassMethods
|
259
|
+
end
|
260
|
+
end
|
metadata
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.8.11
|
3
|
+
specification_version: 1
|
4
|
+
name: sup
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 0.0.1
|
7
|
+
date: 2006-11-28 00:00:00 -08:00
|
8
|
+
summary: A console-based email client with the best features of GMail, mutt, and emacs. Features full text search, labels, tagged operations, multiple buffers, recent contacts, and more.
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: wmorgan-sup@masanjin.net
|
12
|
+
homepage: http://sup.rubyforge.org
|
13
|
+
rubyforge_project: sup
|
14
|
+
description: Sup is an attempt to take the UI innovations of web-based email readers (ok, really just GMail) and to combine them with the traditional wholesome goodness of a console-based email client. Sup is designed to work with massive amounts of email, potentially spread out across different mbox files, IMAP folders, and GMail accounts, and to pull them all together into a single interface. The goal of Sup is to become the email client of choice for nerds everywhere.
|
15
|
+
autorequire:
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: true
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
24
|
+
version:
|
25
|
+
platform: ruby
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
28
|
+
authors:
|
29
|
+
- William Morgan
|
30
|
+
files:
|
31
|
+
- History.txt
|
32
|
+
- Manifest.txt
|
33
|
+
- README.txt
|
34
|
+
- LICENSE
|
35
|
+
- Rakefile
|
36
|
+
- doc/FAQ.txt
|
37
|
+
- doc/Philosophy.txt
|
38
|
+
- doc/TODO
|
39
|
+
- bin/sup
|
40
|
+
- bin/sup-import
|
41
|
+
- lib/sup/mbox/loader.rb
|
42
|
+
- lib/sup/modes/line-cursor-mode.rb
|
43
|
+
- lib/sup/modes/reply-mode.rb
|
44
|
+
- lib/sup/modes/scroll-mode.rb
|
45
|
+
- lib/sup/modes/resume-mode.rb
|
46
|
+
- lib/sup/modes/contact-list-mode.rb
|
47
|
+
- lib/sup/modes/forward-mode.rb
|
48
|
+
- lib/sup/modes/label-search-results-mode.rb
|
49
|
+
- lib/sup/modes/search-results-mode.rb
|
50
|
+
- lib/sup/modes/compose-mode.rb
|
51
|
+
- lib/sup/modes/poll-mode.rb
|
52
|
+
- lib/sup/modes/edit-message-mode.rb
|
53
|
+
- lib/sup/modes/thread-index-mode.rb
|
54
|
+
- lib/sup/modes/person-search-results-mode.rb
|
55
|
+
- lib/sup/modes/inbox-mode.rb
|
56
|
+
- lib/sup/modes/thread-view-mode.rb
|
57
|
+
- lib/sup/modes/log-mode.rb
|
58
|
+
- lib/sup/modes/buffer-list-mode.rb
|
59
|
+
- lib/sup/modes/text-mode.rb
|
60
|
+
- lib/sup/modes/label-list-mode.rb
|
61
|
+
- lib/sup/modes/help-mode.rb
|
62
|
+
- lib/sup/logger.rb
|
63
|
+
- lib/sup/util.rb
|
64
|
+
- lib/sup/update.rb
|
65
|
+
- lib/sup/label.rb
|
66
|
+
- lib/sup/message.rb
|
67
|
+
- lib/sup/mode.rb
|
68
|
+
- lib/sup/keymap.rb
|
69
|
+
- lib/sup/textfield.rb
|
70
|
+
- lib/sup/contact.rb
|
71
|
+
- lib/sup/account.rb
|
72
|
+
- lib/sup/draft.rb
|
73
|
+
- lib/sup/mbox.rb
|
74
|
+
- lib/sup/poll.rb
|
75
|
+
- lib/sup/person.rb
|
76
|
+
- lib/sup/index.rb
|
77
|
+
- lib/sup/thread.rb
|
78
|
+
- lib/sup/buffer.rb
|
79
|
+
- lib/sup/sent.rb
|
80
|
+
- lib/sup/tagger.rb
|
81
|
+
- lib/sup/colormap.rb
|
82
|
+
- lib/sup.rb
|
83
|
+
test_files: []
|
84
|
+
|
85
|
+
rdoc_options: []
|
86
|
+
|
87
|
+
extra_rdoc_files: []
|
88
|
+
|
89
|
+
executables:
|
90
|
+
- sup
|
91
|
+
- sup-import
|
92
|
+
extensions: []
|
93
|
+
|
94
|
+
requirements: []
|
95
|
+
|
96
|
+
dependencies:
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: ferret
|
99
|
+
version_requirement:
|
100
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
101
|
+
requirements:
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: 0.10.13
|
105
|
+
version:
|
106
|
+
- !ruby/object:Gem::Dependency
|
107
|
+
name: ncurses
|
108
|
+
version_requirement:
|
109
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
110
|
+
requirements:
|
111
|
+
- - ">="
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: 0.9.1
|
114
|
+
version:
|
115
|
+
- !ruby/object:Gem::Dependency
|
116
|
+
name: rmail
|
117
|
+
version_requirement:
|
118
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
119
|
+
requirements:
|
120
|
+
- - ">="
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: "0.17"
|
123
|
+
version:
|