]> git.cworth.org Git - sup/blob - lib/sup/hook.rb
remove out-of-date comments about the hook system
[sup] / lib / sup / hook.rb
1 module Redwood
2
3 class HookManager
4   class HookContext
5     def initialize name
6       @__say_id = nil
7       @__name = name
8       @__locals = {}
9     end
10
11     attr_writer :__locals
12     def method_missing m, *a
13       case @__locals[m]
14       when Proc
15         @__locals[m] = @__locals[m].call(*a) # only call the proc once
16       when nil
17         super
18       else
19         @__locals[m]
20       end
21     end
22
23     def say s
24       if BufferManager.instantiated?
25         @__say_id = BufferManager.say s, @__say_id
26         BufferManager.draw_screen
27       else
28         log s
29       end
30     end
31
32     def log s
33       Redwood::log "hook[#@__name]: #{s}"
34     end
35
36     def ask_yes_or_no q
37       if BufferManager.instantiated?
38         BufferManager.ask_yes_or_no q
39       else
40         print q
41         gets.chomp.downcase == 'y'
42       end
43     end
44
45     def get tag
46       HookManager.tags[tag]
47     end
48
49     def set tag, value
50       HookManager.tags[tag] = value
51     end
52
53     def __binding 
54       binding
55     end
56
57     def __cleanup
58       BufferManager.clear @__say_id if @__say_id
59     end
60   end
61
62   include Singleton
63
64   def initialize dir
65     @dir = dir
66     @hooks = {}
67     @descs = {}
68     @contexts = {}
69     @tags = {}
70
71     Dir.mkdir dir unless File.exists? dir
72
73     self.class.i_am_the_instance self
74   end
75
76   attr_reader :tags
77
78   def run name, locals={}
79     hook = hook_for(name) or return
80     context = @contexts[hook] ||= HookContext.new(name)
81     context.__locals = locals
82
83     result = nil
84     begin
85       result = context.instance_eval @hooks[name], fn_for(name)
86     rescue Exception => e
87       log "error running hook: #{e.message}"
88       log e.backtrace.join("\n")
89       @hooks[name] = nil # disable it
90       BufferManager.flash "Error running hook: #{e.message}" if BufferManager.instantiated?
91     end
92     context.__cleanup
93     result
94   end
95
96   def register name, desc
97     @descs[name] = desc
98   end
99
100   def print_hooks f=$stdout
101 puts <<EOS
102 Have #{@descs.size} registered hooks:
103
104 EOS
105
106     @descs.sort.each do |name, desc|
107       f.puts <<EOS
108 #{name}
109 #{"-" * name.length}
110 File: #{fn_for name}
111 #{desc}
112 EOS
113     end
114   end
115
116   def enabled? name; !hook_for(name).nil? end
117
118 private
119
120   def hook_for name
121     unless @hooks.member? name
122       @hooks[name] =
123         begin
124           returning IO.read(fn_for(name)) do
125             log "read '#{name}' from #{fn_for(name)}"
126           end
127         rescue SystemCallError => e
128           #log "disabled hook for '#{name}': #{e.message}"
129           nil
130         end
131     end
132
133     @hooks[name]
134   end
135
136   def fn_for name
137     File.join @dir, "#{name}.rb"
138   end
139
140   def log m
141     Redwood::log("hook: " + m)
142   end
143 end
144
145 end