redcar 0.3.4.3 → 0.3.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (196) hide show
  1. data/CHANGES +45 -0
  2. data/README.md +2 -1
  3. data/ROADMAP.md +0 -1
  4. data/Rakefile +10 -4
  5. data/bin/redcar +2 -2
  6. data/lib/openssl/build.properties +7 -0
  7. data/lib/plugin_manager/lib/plugin_manager.rb +10 -0
  8. data/lib/plugin_manager/lib/plugin_manager/plugin_definition.rb +1 -13
  9. data/lib/redcar.rb +12 -8
  10. data/lib/redcar/installer.rb +16 -15
  11. data/lib/redcar/ruby_extensions.rb +146 -1
  12. data/lib/redcar/runner.rb +16 -7
  13. data/lib/redcar/usage.rb +4 -7
  14. data/lib/redcar_quick_start.rb +5 -5
  15. data/lib/regex_replace.rb +0 -7
  16. data/plugins/application/features/step_definitions/command_steps.rb +5 -0
  17. data/plugins/application/features/step_definitions/dialog_steps.rb +5 -0
  18. data/plugins/application/features/step_definitions/filter_list_dialog_steps.rb +38 -0
  19. data/plugins/application/features/step_definitions/window_steps.rb +1 -1
  20. data/plugins/application/features/support/env.rb +44 -8
  21. data/plugins/application/lib/application.rb +32 -33
  22. data/plugins/application/lib/application/command.rb +32 -2
  23. data/plugins/application/lib/application/command/executor.rb +2 -12
  24. data/plugins/application/lib/application/dialog.rb +14 -14
  25. data/plugins/application/lib/application/event_spewer.rb +32 -0
  26. data/plugins/application/lib/application/menu.rb +5 -5
  27. data/plugins/application/lib/application/menu/builder.rb +5 -0
  28. data/plugins/application/lib/application/menu/lazy_menu.rb +24 -0
  29. data/plugins/application/lib/application/notebook.rb +4 -3
  30. data/plugins/application/lib/application/tab.rb +6 -2
  31. data/plugins/application/lib/application/window.rb +8 -4
  32. data/plugins/application/spec/application/menu/builder_spec.rb +17 -1
  33. data/plugins/application/spec/application/notebook_spec.rb +1 -1
  34. data/plugins/application_swt/build.xml +74 -0
  35. data/plugins/application_swt/lib/application_swt.rb +79 -0
  36. data/plugins/application_swt/lib/application_swt/cucumber_patches.rb +6 -1
  37. data/plugins/application_swt/lib/application_swt/dialog_adapter.rb +25 -17
  38. data/plugins/application_swt/lib/application_swt/dialogs/filter_list_dialog_controller.rb +50 -12
  39. data/plugins/application_swt/lib/application_swt/html_tab.rb +20 -0
  40. data/plugins/application_swt/lib/application_swt/menu.rb +26 -2
  41. data/plugins/application_swt/lib/application_swt/notebook.rb +10 -12
  42. data/plugins/application_swt/lib/application_swt/window.rb +11 -11
  43. data/plugins/application_swt/src/com/redcareditor/application_swt/CocoaUIEnhancer.java +313 -0
  44. data/plugins/auto_completer/lib/auto_completer.rb +74 -67
  45. data/plugins/auto_completer/lib/auto_completer/current_document_completion_source.rb +19 -0
  46. data/plugins/auto_completer/lib/auto_completer/document_controller.rb +2 -2
  47. data/plugins/auto_completer/lib/auto_completer/word_list.rb +8 -1
  48. data/plugins/auto_indenter/features/ruby_style_indentation.feature +24 -0
  49. data/plugins/auto_indenter/features/step_definitions/indentation_steps.rb +6 -0
  50. data/plugins/auto_indenter/features/support/env.rb +2 -0
  51. data/plugins/auto_indenter/lib/auto_indenter.rb +86 -0
  52. data/plugins/auto_indenter/lib/auto_indenter/analyzer.rb +91 -0
  53. data/plugins/auto_indenter/lib/auto_indenter/commands.rb +34 -0
  54. data/plugins/auto_indenter/lib/auto_indenter/document_controller.rb +67 -12
  55. data/plugins/auto_indenter/lib/auto_indenter/rules.rb +41 -0
  56. data/plugins/auto_indenter/spec/auto_indenter/analyzer_spec.rb +151 -0
  57. data/plugins/auto_indenter/spec/spec_helper.rb +5 -0
  58. data/plugins/auto_pairer/lib/auto_pairer.rb +1 -0
  59. data/plugins/auto_pairer/lib/auto_pairer/document_controller.rb +43 -42
  60. data/plugins/auto_pairer/lib/auto_pairer/pairs_for_scope.rb +1 -5
  61. data/plugins/core/lib/core.rb +12 -1
  62. data/plugins/core/lib/core/observable.rb +7 -7
  63. data/plugins/core/lib/core/persistent_cache.rb +14 -2
  64. data/plugins/core/lib/core/plugin.rb +7 -0
  65. data/plugins/core/lib/core/resource.rb +78 -0
  66. data/plugins/core/lib/core/task.rb +62 -0
  67. data/plugins/core/lib/core/task_queue.rb +72 -0
  68. data/plugins/core/spec/core/resource_spec.rb +124 -0
  69. data/plugins/core/spec/core/task_queue_spec.rb +202 -0
  70. data/plugins/core/spec/spec_helper.rb +23 -1
  71. data/plugins/declarations/TODO +3 -0
  72. data/plugins/declarations/lib/declarations.rb +144 -0
  73. data/plugins/declarations/lib/declarations/completion_source.rb +22 -0
  74. data/plugins/declarations/lib/declarations/file.rb +68 -0
  75. data/plugins/declarations/lib/declarations/parser.rb +94 -0
  76. data/plugins/declarations/lib/declarations/select_tag_dialog.rb +44 -0
  77. data/plugins/declarations/plugin.rb +7 -0
  78. data/plugins/declarations/spec/declarations/file_spec.rb +62 -0
  79. data/plugins/declarations/spec/fixtures/federalist.rb +15 -0
  80. data/plugins/declarations/spec/spec_helper.rb +4 -0
  81. data/plugins/edit_view/features/indentation_commands.feature +40 -0
  82. data/plugins/edit_view/features/line_delimiter.feature +40 -0
  83. data/plugins/edit_view/features/step_definitions/editing_steps.rb +16 -4
  84. data/plugins/edit_view/features/step_definitions/notebook_steps.rb +1 -1
  85. data/plugins/edit_view/features/step_definitions/tab_steps.rb +1 -1
  86. data/plugins/edit_view/features/step_definitions/window_steps.rb +5 -1
  87. data/plugins/edit_view/features/support/env.rb +3 -5
  88. data/plugins/edit_view/features/undo_and_redo.feature +21 -0
  89. data/plugins/edit_view/lib/edit_view.rb +57 -4
  90. data/plugins/edit_view/lib/edit_view/actions/arrow_keys.rb +19 -3
  91. data/plugins/edit_view/lib/edit_view/document.rb +46 -11
  92. data/plugins/edit_view/lib/edit_view/document/indentation.rb +35 -0
  93. data/plugins/edit_view/lib/edit_view/modified_tabs_checker.rb +35 -0
  94. data/plugins/edit_view/lib/edit_view/tab_settings.rb +13 -3
  95. data/plugins/edit_view/spec/edit_view/document/indentation_spec.rb +112 -0
  96. data/plugins/edit_view/spec/edit_view/document_spec.rb +22 -0
  97. data/plugins/edit_view/spec/spec_helper.rb +1 -0
  98. data/plugins/edit_view_swt/lib/edit_view_swt.rb +59 -7
  99. data/plugins/edit_view_swt/lib/edit_view_swt/document.rb +3 -3
  100. data/plugins/edit_view_swt/lib/edit_view_swt/word_movement.rb +2 -2
  101. data/plugins/edit_view_swt/vendor/java-mateview.rb +3 -2
  102. data/plugins/encryption/encryption.rb +13 -6
  103. data/plugins/execute_current_tab/lib/execute_current_tab.rb +25 -15
  104. data/plugins/html_view/assets/redcar.css +32 -1
  105. data/plugins/html_view/lib/html_view.rb +23 -3
  106. data/plugins/html_view/lib/html_view/html_tab.rb +4 -0
  107. data/plugins/my_plugin/lib/my_plugin.rb +4 -12
  108. data/plugins/plugin_manager_ui/lib/plugin_manager_ui.rb +1 -0
  109. data/plugins/plugin_manager_ui/views/index.html.erb +30 -37
  110. data/plugins/project/features/find_file.feature +75 -0
  111. data/plugins/project/features/open_and_save_files.feature +7 -7
  112. data/plugins/project/features/open_directory_tree.feature +11 -3
  113. data/plugins/project/features/refresh_directory_tree.feature +7 -1
  114. data/plugins/project/features/step_definitions/directory_steps.rb +11 -1
  115. data/plugins/project/features/step_definitions/file_steps.rb +10 -0
  116. data/plugins/project/features/support/env.rb +6 -1
  117. data/plugins/project/features/watch_for_modified_files.feature +79 -0
  118. data/plugins/project/lib/project.rb +72 -306
  119. data/plugins/project/lib/project/commands.rb +128 -0
  120. data/plugins/project/lib/project/dir_mirror.rb +5 -1
  121. data/plugins/project/lib/project/drb_service.rb +21 -31
  122. data/plugins/project/lib/project/file_list.rb +76 -0
  123. data/plugins/project/lib/project/file_mirror.rb +13 -1
  124. data/plugins/project/lib/project/find_file_dialog.rb +22 -52
  125. data/plugins/project/lib/project/manager.rb +210 -0
  126. data/plugins/project/lib/project/recent_directories.rb +16 -3
  127. data/plugins/project/plugin.rb +1 -1
  128. data/plugins/project/spec/fixtures/myproject/README +2 -0
  129. data/plugins/project/spec/fixtures/myproject/lib/foo_lib.rb +1 -0
  130. data/plugins/project/spec/fixtures/myproject/spec/foo_spec.rb +1 -0
  131. data/plugins/project/{features → spec}/fixtures/winter.txt +0 -0
  132. data/plugins/project/spec/project/dir_mirror_spec.rb +1 -12
  133. data/plugins/project/spec/project/file_list_spec.rb +140 -0
  134. data/plugins/project/spec/spec_helper.rb +20 -0
  135. data/plugins/redcar/plugin.rb +1 -0
  136. data/plugins/redcar/redcar.rb +254 -84
  137. data/plugins/redcar_debug/lib/redcar_debug.rb +58 -11
  138. data/plugins/redcar_debug/vendor/jruby-prof/README +46 -0
  139. data/plugins/redcar_debug/vendor/jruby-prof/Rakefile +36 -0
  140. data/plugins/redcar_debug/vendor/jruby-prof/build.xml +31 -0
  141. data/plugins/redcar_debug/vendor/jruby-prof/example/call_tree.html +22677 -0
  142. data/plugins/redcar_debug/vendor/jruby-prof/example/call_tree.txt +589 -0
  143. data/plugins/redcar_debug/vendor/jruby-prof/example/flat.txt +28 -0
  144. data/plugins/redcar_debug/vendor/jruby-prof/example/graph.html +1670 -0
  145. data/plugins/redcar_debug/vendor/jruby-prof/example/graph.txt +125 -0
  146. data/plugins/redcar_debug/vendor/jruby-prof/example/pidigits.rb +92 -0
  147. data/plugins/redcar_debug/vendor/jruby-prof/example/test.rb +28 -0
  148. data/plugins/redcar_debug/vendor/jruby-prof/example/test2.rb +29 -0
  149. data/plugins/redcar_debug/vendor/jruby-prof/example/test_exception.rb +28 -0
  150. data/plugins/redcar_debug/vendor/jruby-prof/example/test_overhead.rb +43 -0
  151. data/plugins/redcar_debug/vendor/jruby-prof/lib/jruby-prof.rb +66 -0
  152. data/plugins/redcar_debug/vendor/jruby-prof/lib/jruby-prof/abstract_printer.rb +21 -0
  153. data/plugins/redcar_debug/vendor/jruby-prof/lib/jruby-prof/flat_text_printer.rb +35 -0
  154. data/plugins/redcar_debug/vendor/jruby-prof/lib/jruby-prof/graph_html_printer.rb +123 -0
  155. data/plugins/redcar_debug/vendor/jruby-prof/lib/jruby-prof/graph_text_printer.rb +45 -0
  156. data/plugins/redcar_debug/vendor/jruby-prof/lib/jruby-prof/invocation_set.rb +34 -0
  157. data/plugins/redcar_debug/vendor/jruby-prof/lib/jruby-prof/method.rb +107 -0
  158. data/plugins/redcar_debug/vendor/jruby-prof/lib/jruby-prof/profile_invocation.rb +43 -0
  159. data/plugins/redcar_debug/vendor/jruby-prof/lib/jruby-prof/simple_tree_printer.rb +27 -0
  160. data/plugins/redcar_debug/vendor/jruby-prof/lib/jruby-prof/tree_html_printer.rb +144 -0
  161. data/plugins/redcar_debug/vendor/jruby-prof/src/org/jruby/prof/Invocation.java +14 -0
  162. data/plugins/redcar_debug/vendor/jruby-prof/src/org/jruby/prof/JRubyProf.java +94 -0
  163. data/plugins/redcar_debug/vendor/jruby-prof/src/org/jruby/prof/ProfEventHook.java +49 -0
  164. data/plugins/redcar_debug/vendor/jruby-prof/templates/graph_row.html.erb +18 -0
  165. data/plugins/redcar_debug/vendor/jruby-prof/test/basic_test.rb +291 -0
  166. data/plugins/redcar_debug/views/history.html.erb +33 -0
  167. data/plugins/redcar_debug/views/index.html.erb +33 -0
  168. data/plugins/repl/lib/repl/internal_mirror.rb +3 -15
  169. data/plugins/repl/spec/repl/internal_mirror_spec.rb +2 -2
  170. data/plugins/snippets/lib/snippets.rb +0 -1
  171. data/plugins/snippets/lib/snippets/document_controller.rb +7 -1
  172. data/plugins/task_manager/lib/task_manager.rb +28 -0
  173. data/plugins/task_manager/plugin.rb +11 -0
  174. data/plugins/task_manager/views/index.html.erb +67 -0
  175. data/plugins/textmate/lib/textmate.rb +17 -21
  176. data/plugins/textmate/lib/textmate/plist.rb +1 -2
  177. data/plugins/textmate/lib/textmate/preference.rb +5 -1
  178. data/plugins/textmate/lib/textmate/snippet.rb +6 -1
  179. data/plugins/tree_view_swt/lib/tree_view_swt.rb +0 -6
  180. data/textmate/Bundles/Cucumber.tmbundle/Preferences/Comments.tmPreferences +1 -1
  181. data/textmate/Bundles/Cucumber.tmbundle/Preferences/next_Cucumber_Plain_Text_Feature_Completions.tmPreferences +30 -0
  182. data/textmate/Bundles/Cucumber.tmbundle/Preferences/next_Symbol_list___Scenario.tmPreferences +19 -0
  183. data/textmate/Bundles/Cucumber.tmbundle/Syntaxes/next_Cucumber_Plain_Text_Feature.tmLanguage +221 -0
  184. data/textmate/Bundles/Cucumber.tmbundle/Syntaxes/next_Cucumber_Steps.tmLanguage +424 -0
  185. data/textmate/Bundles/Cucumber.tmbundle/Syntaxes/plaintext_template.erb +19 -77
  186. data/textmate/Bundles/Cucumber.tmbundle/info.plist +1 -20
  187. data/textmate/Bundles/Perl.tmbundle/Syntaxes/Perl.plist +1 -1
  188. data/textmate/Themes/Emacs Strict.tmTheme +241 -0
  189. data/textmate/Themes/IR_White.tmTheme +792 -0
  190. data/textmate/Themes/Monokai.tmTheme +291 -0
  191. data/textmate/Themes/WhysPoignant.tmTheme +191 -0
  192. metadata +92 -7
  193. data/plugins/application/features/main_window.feature +0 -8
  194. data/plugins/project/lib/project/project_command.rb +0 -5
  195. data/textmate/Bundles/Cucumber.tmbundle/Snippets/Scenario.tmSnippet +0 -22
  196. data/textmate/Bundles/Cucumber.tmbundle/Snippets/Story.tmSnippet +0 -25
data/lib/redcar/runner.rb CHANGED
@@ -16,17 +16,26 @@ module Redcar
16
16
  puts "\nCan't find jruby jar at #{jruby_complete}, did you run 'redcar install' ?"
17
17
  exit 1
18
18
  end
19
- args = []
20
- if false
21
- command = "jruby #{java_args} \"#{bin}\" #{ARGV.join(' ')}"
22
- else
23
- ENV['RUBYOPT'] = nil # disable other native args
24
- command = "java #{java_args} -Xmx500m -Xss1024k -Djruby.memory.max=500m -Djruby.stack.max=1024k -cp \"#{jruby_complete}\" org.jruby.Main \"#{bin}\" #{ARGV.join(' ')} --no-sub-jruby"
25
- end
19
+ ENV['RUBYOPT'] = nil # disable other native args
20
+ command = "java #{java_args} -Xmx500m -Xss1024k -Djruby.memory.max=500m -Djruby.stack.max=1024k -cp \"#{jruby_complete}\" org.jruby.Main #{"--debug" if debug_mode?} \"#{bin}\" #{cleaned_args} --no-sub-jruby"
26
21
  puts command
27
22
  exec(command)
28
23
  end
29
24
 
25
+ def cleaned_args
26
+ ARGV.map do |arg|
27
+ if arg =~ /--(.+)=(.+)/
28
+ "--" + $1 + "=\"" + $2 + "\""
29
+ else
30
+ arg
31
+ end
32
+ end.join(' ')
33
+ end
34
+
35
+ def debug_mode?
36
+ ARGV.include?("--debug")
37
+ end
38
+
30
39
  def java_args
31
40
  if Config::CONFIG["host_os"] =~ /darwin/
32
41
  "-XstartOnFirstThread"
data/lib/redcar/usage.rb CHANGED
@@ -16,19 +16,16 @@ module Redcar
16
16
 
17
17
  def help_requested
18
18
  if ARGV.include?("-h") or ARGV.include?("--help")
19
+ puts
20
+ puts "Usage: redcar [OPTIONS] [FILE|DIR]*"
19
21
  puts
20
22
  puts " --font=FONT Choose font"
21
23
  puts " --font-size=SIZE Choose font point size"
22
24
  puts " --theme=THEME Choose Textmate theme"
23
25
  puts "--multiple-instance Don't attempt to run from an existing instance"
24
26
  puts " --verbose Set $VERBOSE to true"
25
- puts " filename1, filename2, dirname1, dirname2 ..."
26
- puts
27
- puts
28
- puts "To download jars:"
29
- puts
30
- puts " $ [sudo] redcar install"
31
- puts
27
+ puts " --debug JRuby debugging mode: activates the profiling commands in the Debug menu"
28
+ puts ""
32
29
  #puts "To associate with right click in windows explorer:"
33
30
  #puts
34
31
  #puts " C:> redcar --associate_with_any_right_click"
@@ -1,21 +1,21 @@
1
1
  require 'socket'
2
2
 
3
3
  module Redcar
4
-
5
- # attempt to load via drb if available
4
+ DRB_PORT = 10021
5
+
6
6
  def self.try_to_load_via_drb
7
7
  return if ARGV.find{|arg| arg == "--multiple-instance" || arg == '--help' || arg == '-h'}
8
- port = 9999
9
8
  begin
10
9
  begin
11
- TCPSocket.new('127.0.0.1', port).close
10
+ TCPSocket.new('127.0.0.1', DRB_PORT).close
12
11
  rescue Errno::ECONNREFUSED
13
12
  # no other instance is currently running...
14
13
  return
15
14
  end
16
15
  puts 'attempting to start via running instance' if $VERBOSE
16
+
17
17
  require 'drb' # late require to avoid loadup time
18
- drb = DRbObject.new(nil, "druby://127.0.0.1:#{port}")
18
+ drb = DRbObject.new(nil, "druby://127.0.0.1:#{DRB_PORT}")
19
19
 
20
20
  if ARGV.any?
21
21
  ARGV.each do |arg|
data/lib/regex_replace.rb CHANGED
@@ -1,11 +1,4 @@
1
1
 
2
- begin
3
- require 'rubygems'
4
- require 'oniguruma'
5
- rescue LoadError
6
-
7
- end
8
-
9
2
  class RegexReplace
10
3
  COND_RE = /\(
11
4
  \?(\d+):
@@ -0,0 +1,5 @@
1
+
2
+ When /^I run the command ([^\s]+)$/ do |command_name|
3
+ command_class = eval(command_name)
4
+ command_class.new.run
5
+ end
@@ -3,3 +3,8 @@ Given /^I will choose "([^\"]*)" from the "([^\"]*)" dialog$/ do |path, type|
3
3
  Redcar.gui.register_dialog_adapter(FakeDialogAdapter.new)
4
4
  Redcar.gui.dialog_adapter.set(type.to_sym, path)
5
5
  end
6
+
7
+ Then /^I should not see a "([^\"]*)" dialog for the rest of the feature/ do |type|
8
+ Redcar.gui.register_dialog_adapter(FakeDialogAdapter.new)
9
+ Redcar.gui.dialog_adapter.set(type.to_sym, :raise_error)
10
+ end
@@ -0,0 +1,38 @@
1
+
2
+ def filter_dialog
3
+ dialog(Redcar::ApplicationSWT::FilterListDialogController::FilterListDialog)
4
+ end
5
+
6
+ def filter_dialog_items
7
+ filter_dialog.list.get_items.to_a
8
+ end
9
+
10
+ Then /^there should be a filter dialog open$/ do
11
+ filter_dialog.should_not be_nil
12
+ end
13
+
14
+ Then /^there should be no filter dialog open$/ do
15
+ filter_dialog.should be_nil
16
+ end
17
+
18
+ When /^I set the filter to "(.*)"$/ do |text|
19
+ filter_dialog.text.set_text(text)
20
+ end
21
+
22
+ When /^I select in the filter dialog$/ do
23
+ filter_dialog.controller.selected
24
+ end
25
+
26
+ When /^I wait "(.*)" seconds?$/ do |time|
27
+ Cucumber::Ast::StepInvocation.wait_time = time.to_f
28
+ end
29
+
30
+ Then /^the filter dialog should have (no|\d+) entr(?:y|ies)$/ do |num|
31
+ num = (num == "no" ? 0 : num.to_i)
32
+ filter_dialog_items.length.should == num
33
+ end
34
+
35
+ Then /^I should see "(.*)" at (\d+) the filter dialog$/ do |text, pos|
36
+ pos = pos.to_i
37
+ filter_dialog_items[pos].should == text
38
+ end
@@ -1,4 +1,4 @@
1
1
 
2
2
  Then /^the window should have title "([^\"]*)"$/ do |expected_title|
3
- first_shell.get_text.should == expected_title
3
+ active_shell.get_text.should == expected_title
4
4
  end
@@ -10,8 +10,22 @@ module SwtHelper
10
10
  Redcar::ApplicationSWT.display.get_shells.to_a.first
11
11
  end
12
12
 
13
+ def active_shell
14
+ Redcar::ApplicationSWT.display.get_active_shell
15
+ end
16
+
17
+ def dialog(type)
18
+ dialogs.detect {|d| d.is_a?(type) }
19
+ end
20
+
21
+ def dialogs
22
+ Redcar::ApplicationSWT.display.get_shells.to_a.map do |s|
23
+ Redcar::ApplicationSWT.shell_dialogs[s]
24
+ end.compact
25
+ end
26
+
13
27
  def sash_form
14
- first_shell.getChildren.to_a.first
28
+ active_shell.getChildren.to_a.first
15
29
  end
16
30
 
17
31
  def tree_book
@@ -45,21 +59,40 @@ class FakeDialogAdapter
45
59
  end
46
60
 
47
61
  def open_file(*args)
48
- @responses[:open_file]
62
+ check_for_raise(@responses[:open_file])
49
63
  end
50
64
 
51
65
  def open_directory(*args)
52
- @responses[:open_directory]
66
+ check_for_raise(@responses[:open_directory])
53
67
  end
54
68
 
55
69
  def save_file(*args)
56
- @responses[:save_file]
70
+ check_for_raise(@responses[:save_file])
71
+ end
72
+
73
+ def message_box(*args)
74
+ check_for_raise(@responses[:message_box].to_sym)
75
+ end
76
+
77
+ def check_for_raise(result)
78
+ if result == :raise_error
79
+ raise "did not expect dialog"
80
+ end
81
+ result
82
+ end
83
+
84
+ def available_message_box_button_combos
85
+ Redcar::ApplicationSWT::DialogAdapter.new.available_message_box_button_combos
57
86
  end
58
87
  end
59
88
 
60
89
  World(SwtHelper)
61
90
 
62
91
  def close_everything
92
+ Redcar.app.task_queue.cancel_all
93
+ Redcar::ApplicationSWT.sync_exec do
94
+ dialogs.each {|d| d.controller.model.close }
95
+ end
63
96
  Redcar.app.windows.each do |win|
64
97
  while tree = win.treebook.trees.first
65
98
  Redcar::ApplicationSWT.sync_exec do
@@ -84,19 +117,22 @@ def close_everything
84
117
  Redcar.app.windows.last.close
85
118
  end
86
119
  end
120
+ Redcar::ApplicationSWT.sync_exec do
121
+ Redcar.app.windows.first.title = Redcar::Window::DEFAULT_TITLE
122
+ end
87
123
  end
88
124
 
89
125
  Before do
90
126
  close_everything
127
+ Redcar::ApplicationSWT::FilterListDialogController.test_mode = true
91
128
  end
92
129
 
93
130
  After do
94
131
  close_everything
95
132
  end
96
133
 
97
-
98
-
99
-
100
-
134
+ at_exit {
135
+ FileUtils.rm_rf(Redcar::Plugin::Storage.storage_dir)
136
+ }
101
137
 
102
138
 
@@ -8,10 +8,12 @@ require 'application/clipboard'
8
8
  require 'application/command'
9
9
  require 'application/dialog'
10
10
  require 'application/dialogs/filter_list_dialog'
11
+ require 'application/event_spewer'
11
12
  require 'application/keymap'
12
13
  require 'application/keymap/builder'
13
14
  require 'application/menu'
14
15
  require 'application/menu/item'
16
+ require 'application/menu/lazy_menu'
15
17
  require 'application/menu/builder'
16
18
  require 'application/notebook'
17
19
  require 'application/speedbar'
@@ -66,7 +68,7 @@ module Redcar
66
68
  ]
67
69
  end
68
70
 
69
- attr_reader :clipboard, :keymap, :menu, :history
71
+ attr_reader :clipboard, :keymap, :menu, :history, :task_queue
70
72
 
71
73
  # Create an application instance with a Redcar::Clipboard and a Redcar::History.
72
74
  def initialize
@@ -74,10 +76,18 @@ module Redcar
74
76
  @window_handlers = Hash.new {|h,k| h[k] = []}
75
77
  create_clipboard
76
78
  create_history
79
+ @event_spewer = EventSpewer.new
80
+ @task_queue = TaskQueue.new
77
81
  end
78
82
 
79
- # Immediately halts the gui event loop.
83
+ def events
84
+ @event_spewer
85
+ end
86
+
87
+ # Immediately stop the gui event loop.
88
+ # (You should probably be running QuitCommand instead.)
80
89
  def quit
90
+ @task_queue.stop
81
91
  Redcar.gui.stop
82
92
  end
83
93
 
@@ -90,15 +100,15 @@ module Redcar
90
100
 
91
101
  # Create a new Application::Window, and the controller for it.
92
102
  def new_window
103
+ s = Time.now
93
104
  new_window = Window.new
94
105
  windows << new_window
95
106
  notify_listeners(:new_window, new_window)
96
107
  attach_window_listeners(new_window)
97
- new_window.menu = load_menu
98
- new_window.keymap = main_keymap
99
108
  new_window.refresh_menu
100
109
  new_window.show
101
110
  set_focussed_window(new_window)
111
+ #puts "App#new_window took #{Time.now - s}s"
102
112
  new_window
103
113
  end
104
114
 
@@ -118,13 +128,6 @@ module Redcar
118
128
  @window_handlers[window].each {|h| window.remove_listener(h) }
119
129
 
120
130
  @window_handlers.delete(window)
121
- if windows.length == 0 and [:linux, :windows].include?(Redcar.platform)
122
- if Application.storage['stay_resident_after_last_window_closed'] && !(ARGV.include?("--multiple-instance"))
123
- puts 'continuing to run to wait for incoming drb connections later'
124
- else
125
- quit
126
- end
127
- end
128
131
  end
129
132
 
130
133
  def self.storage
@@ -175,49 +178,46 @@ module Redcar
175
178
 
176
179
  # Redraw the main menu, reloading all the Menus and Keymaps from the plugins.
177
180
  def refresh_menu!
178
- windows.each do |window|
179
- window.menu = load_menu
180
- window.keymap = main_keymap
181
- window.refresh_menu
182
- end
181
+ @main_menu = nil
182
+ @main_keymap = nil
183
+ windows.each {|window| window.refresh_menu }
184
+ controller.refresh_menu
183
185
  end
184
186
 
185
187
  # Generate the main menu by combining menus from all plugins.
186
188
  #
187
189
  # @return [Redcar::Menu]
188
- def load_menu
189
- menu = Menu.new
190
- Redcar.plugin_manager.loaded_plugins.each do |plugin|
191
- if plugin.object.respond_to?(:menus)
192
- menu.merge(plugin.object.menus)
190
+ def main_menu
191
+ @main_menu ||= begin
192
+ menu = Menu.new
193
+ Redcar.plugin_manager.objects_implementing(:menus).each do |object|
194
+ menu.merge(object.menus)
193
195
  end
196
+ menu
194
197
  end
195
- menu
196
198
  end
197
199
 
198
200
  # Generate the main keymap by merging the keymaps from all plugins.
199
201
  #
200
202
  # @return [Redcar::Keymap]
201
203
  def main_keymap
202
- keymap = Keymap.new("main", Redcar.platform)
203
- Redcar.plugin_manager.loaded_plugins.each do |plugin|
204
- if plugin.object.respond_to?(:keymaps)
205
- maps = plugin.object.keymaps
204
+ @main_keymap ||= begin
205
+ keymap = Keymap.new("main", Redcar.platform)
206
+ Redcar.plugin_manager.objects_implementing(:keymaps).each do |object|
207
+ maps = object.keymaps
206
208
  keymaps = maps.select do |map|
207
209
  map.name == "main" and map.platforms.include?(Redcar.platform)
208
210
  end
209
211
  keymap = keymaps.inject(keymap) {|k, nk| k.merge(nk) }
210
212
  end
213
+ keymap
211
214
  end
212
- keymap
213
215
  end
214
216
 
215
217
  # Loads sensitivities from all plugins.
216
218
  def load_sensitivities
217
- Redcar.plugin_manager.loaded_plugins.each do |plugin|
218
- if plugin.object.respond_to?(:sensitivities)
219
- plugin.object.sensitivities
220
- end
219
+ Redcar.plugin_manager.objects_implementing(:sensitivities).each do |object|
220
+ object.sensitivities
221
221
  end
222
222
  end
223
223
 
@@ -226,7 +226,6 @@ module Redcar
226
226
  def lost_application_focus
227
227
  return if @protect_application_focus
228
228
  @application_focus = false
229
- puts "Lost application focus"
230
229
  notify_listeners(:lost_focus, self)
231
230
  end
232
231
 
@@ -235,7 +234,6 @@ module Redcar
235
234
  def gained_application_focus
236
235
  if @application_focus == false
237
236
  @application_focus = true
238
- puts "Gained application focus"
239
237
  notify_listeners(:focussed, self)
240
238
  end
241
239
  end
@@ -262,6 +260,7 @@ module Redcar
262
260
  end
263
261
  h3 = window.add_listener(:focussed) do |win|
264
262
  self.focussed_window = win
263
+ notify_listeners(:window_focussed, win)
265
264
  end
266
265
  h4 = window.add_listener(:new_notebook) do |win|
267
266
  notify_listeners(:notebook_change)
@@ -16,6 +16,36 @@ module Redcar
16
16
  # tab.close if tab
17
17
  # end
18
18
  # end
19
+ #
20
+ # ## Avoiding Memory Leaks (Command instance Lifecycle)
21
+ #
22
+ # When a command is activated, an instance of the Command class will be created.
23
+ # Once the command has been run, the Command instance is put into the Command History,
24
+ # which stores recent commands so they are accessible to e.g. Macros.
25
+ #
26
+ # This means that the command instance will hang around indefinitely, so it is
27
+ # easy to create a memory leak (it is not 'technically' a leak because the Command
28
+ # will be collected eventually, just probably not soon enough.)
29
+ #
30
+ # For example, this command has a memory leak:
31
+ #
32
+ # class MyCommand < Redcar::Command
33
+ # def execute
34
+ # @cache = create_outrageously_large_data_structure
35
+ # do_some_stuff_with_data_structure
36
+ # end
37
+ # end
38
+ #
39
+ # Because the History will store the MyCommand instance, the @cache object will
40
+ # be around for quite a while. Best to get rid of it:
41
+ #
42
+ # class MyCommand < Redcar::Command
43
+ # def execute
44
+ # @cache = create_outrageously_large_data_structure
45
+ # do_some_stuff_with_data_structure
46
+ # @cache = nil
47
+ # end
48
+ # end
19
49
  class Command
20
50
  attr_accessor :error
21
51
 
@@ -56,11 +86,11 @@ module Redcar
56
86
  end
57
87
 
58
88
  def win
59
- env[:win]
89
+ @win || env[:win]
60
90
  end
61
91
 
62
92
  def tab
63
- env[:tab]
93
+ @tab || env[:tab]
64
94
  end
65
95
  end
66
96
  end