lib/sup/modes/console_mode.rb (2793B) - raw
1 require 'pp'
2
3 require "sup/service/label_service"
4
5 module Redwood
6
7 class Console
8 def initialize mode
9 @mode = mode
10 @label_service = LabelService.new
11 end
12
13 def query(query)
14 Index.instance.enum_for :each_message, Index.parse_query(query)
15 end
16
17 def add_labels(query, *labels)
18 count = @label_service.add_labels(query, *labels)
19 print_buffer_dirty_msg count
20 end
21
22 def remove_labels(query, *labels)
23 count = @label_service.remove_labels(query, *labels)
24 print_buffer_dirty_msg count
25 end
26
27 def print_buffer_dirty_msg msg_count
28 puts "Scanned #{msg_count} messages."
29 puts "You might want to refresh open buffers with `@` key."
30 end
31 private :print_buffer_dirty_msg
32
33 def xapian; Index.instance.instance_variable_get :@xapian; end
34
35 def loglevel; Redwood::Logger.level; end
36 def set_loglevel(level); Redwood::Logger.level = level; end
37
38 def special_methods; public_methods - Object.methods end
39
40 def puts x; @mode << "#{x.to_s.rstrip}\n" end
41 def p x; puts x.inspect end
42
43 ## files that won't cause problems when reloaded
44 ## TODO expand this list / convert to blacklist
45 RELOAD_WHITELIST = %w(sup/index.rb sup/modes/console-mode.rb)
46
47 def reload
48 old_verbose = $VERBOSE
49 $VERBOSE = nil
50 old_features = $".dup
51 begin
52 fs = $".grep(/^sup\//)
53 fs.reject! { |f| not RELOAD_WHITELIST.member? f }
54 fs.each { |f| $".delete f }
55 fs.each do |f|
56 @mode << "reloading #{f}\n"
57 begin
58 require f
59 rescue LoadError => e
60 raise unless e.message =~ /no such file to load/
61 end
62 end
63 rescue Exception
64 $".clear
65 $".concat old_features
66 raise
67 ensure
68 $VERBOSE = old_verbose
69 end
70 true
71 end
72
73 def clear_hooks
74 HookManager.clear
75 nil
76 end
77 end
78
79 class ConsoleMode < LogMode
80 register_keymap do |k|
81 k.add :run, "Restart evaluation", 'e'
82 end
83
84 def initialize
85 super "console"
86 @console = Console.new self
87 @binding = @console.instance_eval { binding }
88 end
89
90 def execute cmd
91 begin
92 self << ">> #{cmd}\n"
93 ret = eval cmd, @binding
94 self << "=> #{ret.pretty_inspect}\n"
95 rescue Exception
96 self << "#{$!.class}: #{$!.message}\n"
97 clean_backtrace = []
98 $!.backtrace.each { |l| break if l =~ /console-mode/; clean_backtrace << l }
99 clean_backtrace.each { |l| self << "#{l}\n" }
100 end
101 end
102
103 def prompt
104 BufferManager.ask :console, ">> "
105 end
106
107 def run
108 self << <<EOS
109 Sup v#{VERSION} console session started.
110 Available extra commands: #{(@console.special_methods) * ", "}
111 Ctrl-G stops evaluation; 'e' restarts it.
112
113 EOS
114 while true
115 if(cmd = prompt)
116 execute cmd
117 else
118 self << "Console session ended."
119 break
120 end
121 end
122 end
123 end
124
125 end