]> git.cworth.org Git - sup/blob - lib/sup/modes/console-mode.rb
e2a69d9389b9da8fbeca40aa79aff22c5c00c4ba
[sup] / lib / sup / modes / console-mode.rb
1 require 'pp'
2
3 module Redwood
4
5 class Console
6   def initialize mode
7     @mode = mode
8   end
9
10   def query(query)
11     Enumerable::Enumerator.new(Index, :each_message, Index.parse_query(query))
12   end
13
14   def add_labels(query, *labels)
15     query(query).each { |m| m.labels += labels; m.save Index }
16   end
17
18   def remove_labels(query, *labels)
19     query(query).each { |m| m.labels -= labels; m.save Index }
20   end
21
22   def xapian; Index.instance.instance_variable_get :@xapian; end
23   def ferret; Index.instance.instance_variable_get :@index; end
24
25   ## files that won't cause problems when reloaded
26   ## TODO expand this list / convert to blacklist
27   RELOAD_WHITELIST = %w(sup/xapian_index.rb sup/modes/console-mode.rb)
28
29   def reload
30     old_verbose = $VERBOSE
31     $VERBOSE = nil
32     old_features = $".dup
33     begin
34       fs = $".grep(/^sup\//)
35       fs.reject! { |f| not RELOAD_WHITELIST.member? f }
36       fs.each { |f| $".delete f }
37       fs.each do |f|
38         @mode << "reloading #{f}\n"
39         begin
40           require f
41         rescue LoadError => e
42           raise unless e.message =~ /no such file to load/
43         end
44       end
45     rescue Exception
46       $".clear
47       $".concat old_features
48       raise
49     ensure
50       $VERBOSE = old_verbose
51     end
52     true
53   end
54
55   def clear_hooks
56     HookManager.clear
57     nil
58   end
59 end
60
61 class ConsoleMode < LogMode
62   register_keymap do |k|
63     k.add :run, "Restart evaluation", 'e'
64   end
65
66   def initialize
67     super
68     @console = Console.new self
69     @binding = @console.instance_eval { binding }
70     self << <<EOS
71 Sup #{VERSION} console.
72 Available commands: #{(@console.methods - Object.methods) * ", "}
73 Ctrl-g stops evaluation; 'e' restarts it.
74
75 EOS
76   end
77
78   def execute cmd
79     begin
80       self << ">> #{cmd}\n"
81       ret = eval cmd, @binding
82       self << "=> #{ret.pretty_inspect}\n"
83     rescue Exception
84       self << "#{$!.class}: #{$!.message}\n"
85       clean_backtrace = []
86       $!.backtrace.each { |l| break if l =~ /console-mode/; clean_backtrace << l }
87       clean_backtrace.each { |l| self << "#{l}\n" }
88     end
89   end
90
91   def prompt
92     BufferManager.ask :console, "eval: "
93   end
94
95   def run
96     while true
97       cmd = prompt or return
98       execute cmd
99     end
100   end
101 end
102
103 end