sup 0.8.1 → 0.9
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/CONTRIBUTORS +13 -6
- data/History.txt +19 -0
- data/ReleaseNotes +35 -0
- data/bin/sup +82 -77
- data/bin/sup-add +7 -7
- data/bin/sup-config +104 -85
- data/bin/sup-dump +4 -5
- data/bin/sup-recover-sources +9 -10
- data/bin/sup-sync +121 -100
- data/bin/sup-sync-back +18 -15
- data/bin/sup-tweak-labels +24 -21
- data/lib/sup.rb +53 -33
- data/lib/sup/account.rb +0 -2
- data/lib/sup/buffer.rb +47 -22
- data/lib/sup/colormap.rb +6 -6
- data/lib/sup/contact.rb +0 -2
- data/lib/sup/crypto.rb +34 -23
- data/lib/sup/draft.rb +6 -14
- data/lib/sup/ferret_index.rb +471 -0
- data/lib/sup/hook.rb +30 -43
- data/lib/sup/hook.rb.BACKUP.8625.rb +158 -0
- data/lib/sup/hook.rb.BACKUP.8681.rb +158 -0
- data/lib/sup/hook.rb.BASE.8625.rb +155 -0
- data/lib/sup/hook.rb.BASE.8681.rb +155 -0
- data/lib/sup/hook.rb.LOCAL.8625.rb +142 -0
- data/lib/sup/hook.rb.LOCAL.8681.rb +142 -0
- data/lib/sup/hook.rb.REMOTE.8625.rb +145 -0
- data/lib/sup/hook.rb.REMOTE.8681.rb +145 -0
- data/lib/sup/imap.rb +18 -8
- data/lib/sup/index.rb +70 -528
- data/lib/sup/interactive-lock.rb +74 -0
- data/lib/sup/keymap.rb +26 -26
- data/lib/sup/label.rb +2 -4
- data/lib/sup/logger.rb +54 -35
- data/lib/sup/maildir.rb +41 -6
- data/lib/sup/mbox.rb +1 -1
- data/lib/sup/mbox/loader.rb +18 -6
- data/lib/sup/mbox/ssh-file.rb +1 -7
- data/lib/sup/message-chunks.rb +36 -23
- data/lib/sup/message.rb +126 -46
- data/lib/sup/mode.rb +3 -2
- data/lib/sup/modes/console-mode.rb +108 -0
- data/lib/sup/modes/edit-message-mode.rb +15 -5
- data/lib/sup/modes/inbox-mode.rb +2 -4
- data/lib/sup/modes/label-list-mode.rb +1 -1
- data/lib/sup/modes/line-cursor-mode.rb +18 -18
- data/lib/sup/modes/log-mode.rb +29 -16
- data/lib/sup/modes/poll-mode.rb +7 -9
- data/lib/sup/modes/reply-mode.rb +5 -3
- data/lib/sup/modes/scroll-mode.rb +2 -2
- data/lib/sup/modes/search-results-mode.rb +9 -11
- data/lib/sup/modes/text-mode.rb +2 -2
- data/lib/sup/modes/thread-index-mode.rb +26 -16
- data/lib/sup/modes/thread-view-mode.rb +84 -39
- data/lib/sup/person.rb +6 -8
- data/lib/sup/poll.rb +46 -47
- data/lib/sup/rfc2047.rb +1 -5
- data/lib/sup/sent.rb +27 -20
- data/lib/sup/source.rb +90 -13
- data/lib/sup/textfield.rb +4 -4
- data/lib/sup/thread.rb +15 -13
- data/lib/sup/undo.rb +0 -1
- data/lib/sup/update.rb +0 -1
- data/lib/sup/util.rb +51 -43
- data/lib/sup/xapian_index.rb +566 -0
- metadata +57 -46
- data/lib/sup/suicide.rb +0 -36
data/lib/sup/hook.rb
CHANGED
@@ -1,33 +1,11 @@
|
|
1
1
|
module Redwood
|
2
2
|
|
3
3
|
class HookManager
|
4
|
-
## there's probably a better way to do this, but to evaluate a hook
|
5
|
-
## with a bunch of pre-set "local variables" i define a function
|
6
|
-
## per variable and then instance_evaluate the code.
|
7
|
-
##
|
8
|
-
## how does rails do it, when you pass :locals into a partial?
|
9
|
-
##
|
10
|
-
## i don't bother providing setters, since i'm pretty sure the
|
11
|
-
## charade will fall apart pretty quickly with respect to scoping.
|
12
|
-
## "fail-fast", we'll call it.
|
13
4
|
class HookContext
|
14
5
|
def initialize name
|
15
6
|
@__say_id = nil
|
16
7
|
@__name = name
|
17
|
-
@
|
18
|
-
end
|
19
|
-
|
20
|
-
attr_writer :__locals
|
21
|
-
|
22
|
-
def method_missing m, *a
|
23
|
-
case @__locals[m]
|
24
|
-
when Proc
|
25
|
-
@__locals[m] = @__locals[m].call(*a) # only call the proc once
|
26
|
-
when nil
|
27
|
-
super
|
28
|
-
else
|
29
|
-
@__locals[m]
|
30
|
-
end
|
8
|
+
@__cache = {}
|
31
9
|
end
|
32
10
|
|
33
11
|
def say s
|
@@ -40,7 +18,7 @@ class HookManager
|
|
40
18
|
end
|
41
19
|
|
42
20
|
def log s
|
43
|
-
|
21
|
+
info "hook[#@__name]: #{s}"
|
44
22
|
end
|
45
23
|
|
46
24
|
def ask_yes_or_no q
|
@@ -60,12 +38,24 @@ class HookManager
|
|
60
38
|
HookManager.tags[tag] = value
|
61
39
|
end
|
62
40
|
|
63
|
-
def
|
64
|
-
binding
|
65
|
-
|
66
|
-
|
67
|
-
|
41
|
+
def __run __hook, __filename, __locals
|
42
|
+
__binding = binding
|
43
|
+
__lprocs, __lvars = __locals.partition { |k, v| v.is_a?(Proc) }
|
44
|
+
eval __lvars.map { |k, v| "#{k} = __locals[#{k.inspect}];" }.join, __binding
|
45
|
+
## we also support closures for delays evaluation. unfortunately
|
46
|
+
## we have to do this via method calls, so you don't get all the
|
47
|
+
## semantics of a regular variable. not ideal.
|
48
|
+
__lprocs.each do |k, v|
|
49
|
+
self.class.instance_eval do
|
50
|
+
define_method k do
|
51
|
+
@__cache[k] ||= v.call
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
ret = eval __hook, __binding, __filename
|
68
56
|
BufferManager.clear @__say_id if @__say_id
|
57
|
+
@__cache = {}
|
58
|
+
ret
|
69
59
|
end
|
70
60
|
end
|
71
61
|
|
@@ -79,8 +69,6 @@ class HookManager
|
|
79
69
|
@tags = {}
|
80
70
|
|
81
71
|
Dir.mkdir dir unless File.exists? dir
|
82
|
-
|
83
|
-
self.class.i_am_the_instance self
|
84
72
|
end
|
85
73
|
|
86
74
|
attr_reader :tags
|
@@ -88,18 +76,16 @@ class HookManager
|
|
88
76
|
def run name, locals={}
|
89
77
|
hook = hook_for(name) or return
|
90
78
|
context = @contexts[hook] ||= HookContext.new(name)
|
91
|
-
context.__locals = locals
|
92
79
|
|
93
80
|
result = nil
|
94
81
|
begin
|
95
|
-
result = context.
|
82
|
+
result = context.__run hook, fn_for(name), locals
|
96
83
|
rescue Exception => e
|
97
84
|
log "error running hook: #{e.message}"
|
98
85
|
log e.backtrace.join("\n")
|
99
86
|
@hooks[name] = nil # disable it
|
100
87
|
BufferManager.flash "Error running hook: #{e.message}" if BufferManager.instantiated?
|
101
88
|
end
|
102
|
-
context.__cleanup
|
103
89
|
result
|
104
90
|
end
|
105
91
|
|
@@ -125,19 +111,20 @@ EOS
|
|
125
111
|
|
126
112
|
def enabled? name; !hook_for(name).nil? end
|
127
113
|
|
114
|
+
def clear; @hooks.clear; end
|
115
|
+
|
128
116
|
private
|
129
117
|
|
130
118
|
def hook_for name
|
131
119
|
unless @hooks.member? name
|
132
|
-
@hooks[name] =
|
133
|
-
|
134
|
-
|
135
|
-
log "read '#{name}' from #{fn_for(name)}"
|
136
|
-
end
|
137
|
-
rescue SystemCallError => e
|
138
|
-
#log "disabled hook for '#{name}': #{e.message}"
|
139
|
-
nil
|
120
|
+
@hooks[name] = begin
|
121
|
+
returning IO.read(fn_for(name)) do
|
122
|
+
debug "read '#{name}' from #{fn_for(name)}"
|
140
123
|
end
|
124
|
+
rescue SystemCallError => e
|
125
|
+
#debug "disabled hook for '#{name}': #{e.message}"
|
126
|
+
nil
|
127
|
+
end
|
141
128
|
end
|
142
129
|
|
143
130
|
@hooks[name]
|
@@ -148,7 +135,7 @@ private
|
|
148
135
|
end
|
149
136
|
|
150
137
|
def log m
|
151
|
-
|
138
|
+
info("hook: " + m)
|
152
139
|
end
|
153
140
|
end
|
154
141
|
|
@@ -0,0 +1,158 @@
|
|
1
|
+
module Redwood
|
2
|
+
|
3
|
+
class HookManager
|
4
|
+
class HookContext
|
5
|
+
def initialize name
|
6
|
+
@__say_id = nil
|
7
|
+
@__name = name
|
8
|
+
<<<<<<< HEAD:lib/sup/hook.rb
|
9
|
+
@__cache = {}
|
10
|
+
=======
|
11
|
+
@__locals = {}
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_writer :__locals
|
15
|
+
def method_missing m, *a
|
16
|
+
case @__locals[m]
|
17
|
+
when Proc
|
18
|
+
@__locals[m] = @__locals[m].call(*a) # only call the proc once
|
19
|
+
when nil
|
20
|
+
super
|
21
|
+
else
|
22
|
+
@__locals[m]
|
23
|
+
end
|
24
|
+
>>>>>>> custom-search-hook:lib/sup/hook.rb
|
25
|
+
end
|
26
|
+
|
27
|
+
def say s
|
28
|
+
if BufferManager.instantiated?
|
29
|
+
@__say_id = BufferManager.say s, @__say_id
|
30
|
+
BufferManager.draw_screen
|
31
|
+
else
|
32
|
+
log s
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def log s
|
37
|
+
info "hook[#@__name]: #{s}"
|
38
|
+
end
|
39
|
+
|
40
|
+
def ask_yes_or_no q
|
41
|
+
if BufferManager.instantiated?
|
42
|
+
BufferManager.ask_yes_or_no q
|
43
|
+
else
|
44
|
+
print q
|
45
|
+
gets.chomp.downcase == 'y'
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def get tag
|
50
|
+
HookManager.tags[tag]
|
51
|
+
end
|
52
|
+
|
53
|
+
def set tag, value
|
54
|
+
HookManager.tags[tag] = value
|
55
|
+
end
|
56
|
+
|
57
|
+
def __run __hook, __filename, __locals
|
58
|
+
__binding = binding
|
59
|
+
__lprocs, __lvars = __locals.partition { |k, v| v.is_a?(Proc) }
|
60
|
+
eval __lvars.map { |k, v| "#{k} = __locals[#{k.inspect}];" }.join, __binding
|
61
|
+
## we also support closures for delays evaluation. unfortunately
|
62
|
+
## we have to do this via method calls, so you don't get all the
|
63
|
+
## semantics of a regular variable. not ideal.
|
64
|
+
__lprocs.each do |k, v|
|
65
|
+
self.class.instance_eval do
|
66
|
+
define_method k do
|
67
|
+
@__cache[k] ||= v.call
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
ret = eval __hook, __binding, __filename
|
72
|
+
BufferManager.clear @__say_id if @__say_id
|
73
|
+
@__cache = {}
|
74
|
+
ret
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
include Singleton
|
79
|
+
|
80
|
+
def initialize dir
|
81
|
+
@dir = dir
|
82
|
+
@hooks = {}
|
83
|
+
@descs = {}
|
84
|
+
@contexts = {}
|
85
|
+
@tags = {}
|
86
|
+
|
87
|
+
Dir.mkdir dir unless File.exists? dir
|
88
|
+
end
|
89
|
+
|
90
|
+
attr_reader :tags
|
91
|
+
|
92
|
+
def run name, locals={}
|
93
|
+
hook = hook_for(name) or return
|
94
|
+
context = @contexts[hook] ||= HookContext.new(name)
|
95
|
+
|
96
|
+
result = nil
|
97
|
+
begin
|
98
|
+
result = context.__run hook, fn_for(name), locals
|
99
|
+
rescue Exception => e
|
100
|
+
log "error running hook: #{e.message}"
|
101
|
+
log e.backtrace.join("\n")
|
102
|
+
@hooks[name] = nil # disable it
|
103
|
+
BufferManager.flash "Error running hook: #{e.message}" if BufferManager.instantiated?
|
104
|
+
end
|
105
|
+
result
|
106
|
+
end
|
107
|
+
|
108
|
+
def register name, desc
|
109
|
+
@descs[name] = desc
|
110
|
+
end
|
111
|
+
|
112
|
+
def print_hooks f=$stdout
|
113
|
+
puts <<EOS
|
114
|
+
Have #{@descs.size} registered hooks:
|
115
|
+
|
116
|
+
EOS
|
117
|
+
|
118
|
+
@descs.sort.each do |name, desc|
|
119
|
+
f.puts <<EOS
|
120
|
+
#{name}
|
121
|
+
#{"-" * name.length}
|
122
|
+
File: #{fn_for name}
|
123
|
+
#{desc}
|
124
|
+
EOS
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def enabled? name; !hook_for(name).nil? end
|
129
|
+
|
130
|
+
def clear; @hooks.clear; end
|
131
|
+
|
132
|
+
private
|
133
|
+
|
134
|
+
def hook_for name
|
135
|
+
unless @hooks.member? name
|
136
|
+
@hooks[name] = begin
|
137
|
+
returning IO.read(fn_for(name)) do
|
138
|
+
debug "read '#{name}' from #{fn_for(name)}"
|
139
|
+
end
|
140
|
+
rescue SystemCallError => e
|
141
|
+
#debug "disabled hook for '#{name}': #{e.message}"
|
142
|
+
nil
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
@hooks[name]
|
147
|
+
end
|
148
|
+
|
149
|
+
def fn_for name
|
150
|
+
File.join @dir, "#{name}.rb"
|
151
|
+
end
|
152
|
+
|
153
|
+
def log m
|
154
|
+
info("hook: " + m)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
@@ -0,0 +1,158 @@
|
|
1
|
+
module Redwood
|
2
|
+
|
3
|
+
class HookManager
|
4
|
+
class HookContext
|
5
|
+
def initialize name
|
6
|
+
@__say_id = nil
|
7
|
+
@__name = name
|
8
|
+
<<<<<<< HEAD:lib/sup/hook.rb
|
9
|
+
@__cache = {}
|
10
|
+
=======
|
11
|
+
@__locals = {}
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_writer :__locals
|
15
|
+
def method_missing m, *a
|
16
|
+
case @__locals[m]
|
17
|
+
when Proc
|
18
|
+
@__locals[m] = @__locals[m].call(*a) # only call the proc once
|
19
|
+
when nil
|
20
|
+
super
|
21
|
+
else
|
22
|
+
@__locals[m]
|
23
|
+
end
|
24
|
+
>>>>>>> custom-search-hook:lib/sup/hook.rb
|
25
|
+
end
|
26
|
+
|
27
|
+
def say s
|
28
|
+
if BufferManager.instantiated?
|
29
|
+
@__say_id = BufferManager.say s, @__say_id
|
30
|
+
BufferManager.draw_screen
|
31
|
+
else
|
32
|
+
log s
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def log s
|
37
|
+
info "hook[#@__name]: #{s}"
|
38
|
+
end
|
39
|
+
|
40
|
+
def ask_yes_or_no q
|
41
|
+
if BufferManager.instantiated?
|
42
|
+
BufferManager.ask_yes_or_no q
|
43
|
+
else
|
44
|
+
print q
|
45
|
+
gets.chomp.downcase == 'y'
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def get tag
|
50
|
+
HookManager.tags[tag]
|
51
|
+
end
|
52
|
+
|
53
|
+
def set tag, value
|
54
|
+
HookManager.tags[tag] = value
|
55
|
+
end
|
56
|
+
|
57
|
+
def __run __hook, __filename, __locals
|
58
|
+
__binding = binding
|
59
|
+
__lprocs, __lvars = __locals.partition { |k, v| v.is_a?(Proc) }
|
60
|
+
eval __lvars.map { |k, v| "#{k} = __locals[#{k.inspect}];" }.join, __binding
|
61
|
+
## we also support closures for delays evaluation. unfortunately
|
62
|
+
## we have to do this via method calls, so you don't get all the
|
63
|
+
## semantics of a regular variable. not ideal.
|
64
|
+
__lprocs.each do |k, v|
|
65
|
+
self.class.instance_eval do
|
66
|
+
define_method k do
|
67
|
+
@__cache[k] ||= v.call
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
ret = eval __hook, __binding, __filename
|
72
|
+
BufferManager.clear @__say_id if @__say_id
|
73
|
+
@__cache = {}
|
74
|
+
ret
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
include Singleton
|
79
|
+
|
80
|
+
def initialize dir
|
81
|
+
@dir = dir
|
82
|
+
@hooks = {}
|
83
|
+
@descs = {}
|
84
|
+
@contexts = {}
|
85
|
+
@tags = {}
|
86
|
+
|
87
|
+
Dir.mkdir dir unless File.exists? dir
|
88
|
+
end
|
89
|
+
|
90
|
+
attr_reader :tags
|
91
|
+
|
92
|
+
def run name, locals={}
|
93
|
+
hook = hook_for(name) or return
|
94
|
+
context = @contexts[hook] ||= HookContext.new(name)
|
95
|
+
|
96
|
+
result = nil
|
97
|
+
begin
|
98
|
+
result = context.__run hook, fn_for(name), locals
|
99
|
+
rescue Exception => e
|
100
|
+
log "error running hook: #{e.message}"
|
101
|
+
log e.backtrace.join("\n")
|
102
|
+
@hooks[name] = nil # disable it
|
103
|
+
BufferManager.flash "Error running hook: #{e.message}" if BufferManager.instantiated?
|
104
|
+
end
|
105
|
+
result
|
106
|
+
end
|
107
|
+
|
108
|
+
def register name, desc
|
109
|
+
@descs[name] = desc
|
110
|
+
end
|
111
|
+
|
112
|
+
def print_hooks f=$stdout
|
113
|
+
puts <<EOS
|
114
|
+
Have #{@descs.size} registered hooks:
|
115
|
+
|
116
|
+
EOS
|
117
|
+
|
118
|
+
@descs.sort.each do |name, desc|
|
119
|
+
f.puts <<EOS
|
120
|
+
#{name}
|
121
|
+
#{"-" * name.length}
|
122
|
+
File: #{fn_for name}
|
123
|
+
#{desc}
|
124
|
+
EOS
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def enabled? name; !hook_for(name).nil? end
|
129
|
+
|
130
|
+
def clear; @hooks.clear; end
|
131
|
+
|
132
|
+
private
|
133
|
+
|
134
|
+
def hook_for name
|
135
|
+
unless @hooks.member? name
|
136
|
+
@hooks[name] = begin
|
137
|
+
returning IO.read(fn_for(name)) do
|
138
|
+
debug "read '#{name}' from #{fn_for(name)}"
|
139
|
+
end
|
140
|
+
rescue SystemCallError => e
|
141
|
+
#debug "disabled hook for '#{name}': #{e.message}"
|
142
|
+
nil
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
@hooks[name]
|
147
|
+
end
|
148
|
+
|
149
|
+
def fn_for name
|
150
|
+
File.join @dir, "#{name}.rb"
|
151
|
+
end
|
152
|
+
|
153
|
+
def log m
|
154
|
+
info("hook: " + m)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|