]> git.cworth.org Git - sup/blob - lib/sup/modes/console-mode.rb
Merge branch 'master' into next
[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   def special_methods; methods - Object.methods end
25
26   ## files that won't cause problems when reloaded
27   ## TODO expand this list / convert to blacklist
28   RELOAD_WHITELIST = %w(sup/xapian_index.rb sup/modes/console-mode.rb)
29
30   def reload
31     old_verbose = $VERBOSE
32     $VERBOSE = nil
33     old_features = $".dup
34     begin
35       fs = $".grep(/^sup\//)
36       fs.reject! { |f| not RELOAD_WHITELIST.member? f }
37       fs.each { |f| $".delete f }
38       fs.each do |f|
39         @mode << "reloading #{f}\n"
40         begin
41           require f
42         rescue LoadError => e
43           raise unless e.message =~ /no such file to load/
44         end
45       end
46     rescue Exception
47       $".clear
48       $".concat old_features
49       raise
50     ensure
51       $VERBOSE = old_verbose
52     end
53     true
54   end
55
56   def clear_hooks
57     HookManager.clear
58     nil
59   end
60 end
61
62 class ConsoleMode < LogMode
63   register_keymap do |k|
64     k.add :run, "Restart evaluation", 'e'
65   end
66
67   def initialize
68     super "console"
69     @console = Console.new self
70     @binding = @console.instance_eval { binding }
71   end
72
73   def execute cmd
74     begin
75       self << ">> #{cmd}\n"
76       ret = eval cmd, @binding
77       self << "=> #{ret.pretty_inspect}\n"
78     rescue Exception
79       self << "#{$!.class}: #{$!.message}\n"
80       clean_backtrace = []
81       $!.backtrace.each { |l| break if l =~ /console-mode/; clean_backtrace << l }
82       clean_backtrace.each { |l| self << "#{l}\n" }
83     end
84   end
85
86   def prompt
87     BufferManager.ask :console, ">> "
88   end
89
90   def run
91     self << <<EOS
92 Sup v#{VERSION} console session started.
93 Available extra commands: #{(@console.special_methods) * ", "}
94 Ctrl-G stops evaluation; 'e' restarts it.
95
96 EOS
97     while true
98       if(cmd = prompt)
99         execute cmd
100       else
101         self << "Console session ended."
102         break
103       end
104     end
105   end
106 end
107
108 end