redcar 0.3.4.3 → 0.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
@@ -12,6 +12,14 @@ Feature: Open directory tree
12
12
  When I open a directory
13
13
  Then I should see "core,application,tree" in the tree
14
14
 
15
-
16
-
17
-
15
+ Scenario: Title of window reflects open project
16
+ Given I will choose "plugins/project/spec/fixtures/myproject" from the "open_directory" dialog
17
+ When I open a directory
18
+ Then the window should have title "myproject"
19
+
20
+ Scenario: Title of window returns to "Redcar" if directory is closed
21
+ Given I will choose "plugins/project/spec/fixtures/myproject" from the "open_directory" dialog
22
+ When I open a directory
23
+ Then the window should have title "myproject"
24
+ When I close the directory
25
+ Then the window should have title "Redcar"
@@ -24,7 +24,7 @@ Feature: Refresh directory tree
24
24
  And I should not see "testyfile.txt" in the tree
25
25
  When I touch the file "./testyfile.txt"
26
26
  When I open a new window
27
- And I focus the window "Redcar" through the gui
27
+ And I focus the window "redcar" through the gui
28
28
  Then I should see "bin,config,lib,plugins,testyfile.txt" in the tree
29
29
 
30
30
  Scenario: Refreshing the tree leaves rows expanded as they were before
@@ -35,3 +35,9 @@ Feature: Refresh directory tree
35
35
  And I refresh the directory tree
36
36
  Then I should see "bin,config,lib,freebase2,plugins" in the tree
37
37
 
38
+ Scenario: Tree is moved
39
+ Given I will choose "plugins/project/spec/fixtures/myproject" from the "open_directory" dialog
40
+ When I open a directory
41
+ And I move the myproject fixture away
42
+ And I refresh the directory tree
43
+ Then I should not see "lib" in the tree
@@ -3,6 +3,16 @@ When /I open a directory/ do
3
3
  Redcar::Project::DirectoryOpenCommand.new.run
4
4
  end
5
5
 
6
+ When /I close the directory/ do
7
+ Redcar::Project::DirectoryCloseCommand.new.run
8
+ end
9
+
6
10
  When /^I refresh the directory tree$/ do
7
- Redcar::Project.refresh_tree(Redcar.app.focussed_window)
11
+ Redcar::Project::Manager.focussed_project.refresh
8
12
  end
13
+
14
+ When /^I move the myproject fixture away$/ do
15
+ FileUtils.mv("plugins/project/spec/fixtures/myproject",
16
+ "plugins/project/spec/fixtures/myproject.bak")
17
+ @put_myproject_fixture_back = true
18
+ end
@@ -20,6 +20,10 @@ When /^I touch the file "([^\"]*)"$/ do |fn|
20
20
  add_test_file(fn)
21
21
  end
22
22
 
23
+ When /^I put "([^\"]*)" into the file "([^\"]*)"$/ do |contents, path|
24
+ File.open(path, "w") {|fout| fout.print contents }
25
+ end
26
+
23
27
  When /^I save the tab as$/ do
24
28
  Redcar::Project::FileSaveAsCommand.new.run
25
29
  end
@@ -28,6 +32,12 @@ Then /^the file "([^\"]*)" should contain "([^\"]*)"$/ do |arg1, arg2|
28
32
  File.read(arg1).should == arg2
29
33
  end
30
34
 
35
+ When /^I put a lot of lines into the file "([^\"]*)"$/ do |file|
36
+ File.open(file, "w") do |f|
37
+ 200.times { |i| f.puts (i*20).to_s }
38
+ end
39
+ end
40
+
31
41
  def add_test_file(fn)
32
42
  (@test_files ||= []) << File.expand_path(fn)
33
43
  end
@@ -1,7 +1,12 @@
1
1
  RequireSupportFiles File.dirname(__FILE__) + "/../../../edit_view/features/"
2
2
 
3
3
  def reset_project_fixtures
4
- fixtures_path = File.expand_path(File.dirname(__FILE__) + "/../fixtures")
4
+ if @put_myproject_fixture_back
5
+ @put_myproject_fixture_back = nil
6
+ FileUtils.mv("plugins/project/spec/fixtures/myproject.bak",
7
+ "plugins/project/spec/fixtures/myproject")
8
+ end
9
+ fixtures_path = File.expand_path(File.dirname(__FILE__) + "/../../spec/fixtures")
5
10
  File.open(fixtures_path + "/winter.txt", "w") {|f| f.print "Wintersmith" }
6
11
  FileUtils.rm_rf(fixtures_path + "/winter2.txt")
7
12
  end
@@ -0,0 +1,79 @@
1
+ Feature: Watch for modified files
2
+ If an open file has changed on disc since the last time the user looked at it,
3
+ then reload the contents. Alert the user if they have made modifications.
4
+
5
+ Background:
6
+ Given I will choose "plugins/project/spec/fixtures/winter.txt" from the "open_file" dialog
7
+ When I open a file
8
+
9
+ Scenario: Without modifications
10
+ Then there should be one edit tab
11
+ And I should see "Wintersmith" in the edit tab
12
+ When I open a new edit tab
13
+ And I wait "2" seconds
14
+ And I put "Summer" into the file "plugins/project/spec/fixtures/winter.txt"
15
+ And I close the focussed tab
16
+ Then I should see "Summer" in the edit tab
17
+
18
+ Scenario: With modifications, reloading from disc
19
+ Then there should be one edit tab
20
+ And I should see "Wintersmith" in the edit tab
21
+ And I replace the contents with "FOFOOF"
22
+ When I open a new edit tab
23
+ And I wait "2" seconds
24
+ And I put "Summer" into the file "plugins/project/spec/fixtures/winter.txt"
25
+ Given I will choose "yes" from the "message_box" dialog
26
+ And I close the focussed tab
27
+ Then I should see "Summer" in the edit tab
28
+
29
+ Scenario: With modifications, keeping modified version
30
+ Then there should be one edit tab
31
+ And I should see "Wintersmith" in the edit tab
32
+ And I replace the contents with "Newton"
33
+ When I open a new edit tab
34
+ And I wait "2" seconds
35
+ And I put "Summer" into the file "plugins/project/spec/fixtures/winter.txt"
36
+ Given I will choose "no" from the "message_box" dialog
37
+ And I close the focussed tab
38
+ Then I should see "Newton" in the edit tab
39
+
40
+ Scenario: With modifications, keeping modified version, twice
41
+ Then there should be one edit tab
42
+ And I should see "Wintersmith" in the edit tab
43
+ And I replace the contents with "Newton"
44
+ When I open a new edit tab
45
+ And I wait "2" seconds
46
+ And I put "Summer" into the file "plugins/project/spec/fixtures/winter.txt"
47
+ Given I will choose "no" from the "message_box" dialog
48
+ And I close the focussed tab
49
+ Then I should see "Newton" in the edit tab
50
+ When I open a new edit tab
51
+ Then I should not see a "message_box" dialog for the rest of the feature
52
+ And I close the focussed tab
53
+
54
+ Scenario: Keep in the same position in the file when reloading
55
+ Given I close the focussed tab
56
+ And I put a lot of lines into the file "plugins/project/spec/fixtures/winter.txt"
57
+ When I open a file
58
+ And I move to line 100
59
+ Then there should be one edit tab
60
+ When I open a new edit tab
61
+ And I wait "2" seconds
62
+ And I put a lot of lines into the file "plugins/project/spec/fixtures/winter.txt"
63
+ And I close the focussed tab
64
+ Then the cursor should be on line 100
65
+
66
+ Scenario: Move to the top if the line you were on is no longer there
67
+ Given I close the focussed tab
68
+ And I put a lot of lines into the file "plugins/project/spec/fixtures/winter.txt"
69
+ When I open a file
70
+ And I move to line 100
71
+ Then there should be one edit tab
72
+ When I open a new edit tab
73
+ And I wait "2" seconds
74
+ And I put "Summer" into the file "plugins/project/spec/fixtures/winter.txt"
75
+ And I close the focussed tab
76
+ Then the cursor should be on line 0
77
+
78
+
79
+
@@ -1,360 +1,126 @@
1
1
  require 'drb/drb'
2
2
 
3
- require "project/project_command"
4
- require "project/file_mirror"
5
- require "project/find_file_dialog"
3
+ require "project/commands"
6
4
  require "project/dir_mirror"
7
5
  require "project/dir_controller"
8
6
  require "project/drb_service"
7
+ require "project/file_list"
8
+ require "project/file_mirror"
9
+ require "project/find_file_dialog"
10
+ require "project/manager"
9
11
  require "project/recent_directories"
10
12
 
11
13
  module Redcar
12
14
  class Project
13
15
  RECENT_FILES_LENGTH = 20
14
-
15
- # this will restore open files unless other files or dirs were passed
16
- # as command line parameters
17
- def self.start
18
- restore_last_session unless handle_startup_arguments
19
- init_current_files_hooks
20
- init_window_closed_hooks
21
- init_drb_listener
22
- end
23
-
24
- def self.init_window_closed_hooks
25
- Redcar.app.add_listener(:window_about_to_close) do |win|
26
- self.save_file_list win
27
- end
28
- end
29
-
30
- def self.init_drb_listener
31
- return if ARGV.include?("--multiple-instance")
32
- @drb_service = DrbService.new
33
- end
34
-
35
- def self.storage
36
- @storage ||= Plugin::Storage.new('project_plugin')
37
- end
38
-
39
- def self.sensitivities
40
- [ @open_project_sensitivity =
41
- Sensitivity.new(:open_project, Redcar.app, false, [:focussed_window]) do
42
- if win = Redcar.app.focussed_window
43
- win.treebook.trees.detect {|t| t.tree_mirror.is_a?(DirMirror) }
44
- end
45
- end
46
- ]
47
- end
48
-
49
- class << self
50
- attr_reader :open_project_sensitivity
51
- end
52
16
 
53
- def self.filter_path
54
- if Redcar.app.focussed_notebook_tab
55
- if mirror = EditView.focussed_document_mirror and mirror.is_a?(FileMirror)
56
- dir = File.dirname(mirror.path)
57
- return dir
58
- end
59
- end
60
- Project.storage['last_dir'] || File.expand_path(Dir.pwd)
61
- end
62
-
63
- def self.window_trees
64
- @window_trees ||= {}
65
- end
66
-
67
- def self.open_tree(win, tree)
68
- if window_trees[win]
69
- old_tree = window_trees[win]
70
- set_tree(win, tree)
71
- win.treebook.remove_tree(old_tree)
72
- else
73
- set_tree(win, tree)
74
- end
75
- Project.open_project_sensitivity.recompute
76
- end
77
-
78
- # Close the Directory Tree for the given window, if there
79
- # is one.
80
- def self.close_tree(win)
81
- win.treebook.remove_tree(window_trees[win])
82
- Project.open_project_sensitivity.recompute
83
- end
84
-
85
- # Refresh the DirMirror Tree for the given Window, if
86
- # there is one.
87
- def self.refresh_tree(win)
88
- if tree = window_trees[win]
89
- tree.refresh
90
- end
91
- end
92
-
93
- # Finds an EditTab with a mirror for the given path.
94
- #
95
- # @param [String] path the path of the file being edited
96
- # @return [EditTab, nil] the EditTab that is editing it, or nil
97
- def self.open_file_tab(path)
98
- path = File.expand_path(path)
99
- all_tabs = Redcar.app.windows.map {|win| win.notebooks}.flatten.map {|nb| nb.tabs }.flatten
100
- all_tabs.find do |t|
101
- t.is_a?(Redcar::EditTab) and
102
- t.edit_view.document.mirror and
103
- t.edit_view.document.mirror.is_a?(FileMirror) and
104
- File.expand_path(t.edit_view.document.mirror.path) == path
105
- end
106
- end
107
-
108
- # Opens a new EditTab with a FileMirror for the given path.
109
- #
110
- # @path [String] path the path of the file to be edited
111
- # @param [Window] win the Window to open the File in
112
- def self.open_file(path, win = Redcar.app.focussed_window)
113
- win ||= Redcar.app.new_window # in case there's not one open
114
- tab = win.new_tab(Redcar::EditTab)
115
- mirror = FileMirror.new(path)
116
- tab.edit_view.document.mirror = mirror
117
- tab.edit_view.reset_undo
118
- tab.focus
17
+ def self.window_projects
18
+ @window_projects ||= {}
119
19
  end
120
20
 
121
- # Opens a new Tree with a DirMirror and DirController for the given
122
- # path.
123
- #
124
- # @param [String] path the path of the directory to view
125
- # @param [Window] win the Window to open the Tree in
126
- def self.open_dir(path, win = Redcar.app.focussed_window)
21
+ attr_reader :window, :tree, :path
22
+
23
+ def initialize(path)
127
24
  path = File.expand_path(path)
128
25
  if !File.directory?(path)
129
26
  raise 'Not a directory: ' + path
130
27
  end
131
- win ||= Redcar.app.new_window # case none open
132
- tree = Tree.new(Project::DirMirror.new(path),
133
- Project::DirController.new)
134
- Project.open_tree(win, tree)
135
- # adds the directory path to the RecentDirectories plugin
136
- RecentDirectories.store_path(path)
137
- storage['last_open_dir'] = path
28
+ @path = path
29
+ @tree = Tree.new(Project::DirMirror.new(path),
30
+ Project::DirController.new)
31
+ @window = nil
32
+ file_list_resource.compute
138
33
  end
139
34
 
140
- # A list of files previously opened in this session for a given directory path
141
- #
142
- # @param [String] path a directory path
143
- # @return [Array<String>] an array of paths
144
- def self.recent_files_for(path)
145
- (@recent_files ||= Hash.new {|h,k| h[k] = [] })[path]
35
+ def inspect
36
+ "<Project #{path}>"
146
37
  end
147
38
 
148
- # The directory path of the currently focussed project, or nil if
149
- # there is no directory open in the focussed window.
150
- #
151
- # @return [String, nil]
152
- def self.focussed_project_path
153
- if tree = focussed_project_tree
154
- tree.tree_mirror.path
39
+ def open(win)
40
+ @window = win
41
+ if current_project = Project.window_projects[window]
42
+ current_project.close
155
43
  end
44
+ window.treebook.add_tree(@tree)
45
+ window.title = File.basename(@tree.tree_mirror.path)
46
+ Manager.open_project_sensitivity.recompute
47
+ RecentDirectories.store_path(path)
48
+ Manager.storage['last_open_dir'] = path
49
+ Project.window_projects[window] = self
156
50
  end
157
51
 
158
- # The Tree object for the currently focussed project tree, or nil
159
- # if there is no directory open in the focussed window.
160
- def self.focussed_project_tree
161
- Redcar.app.focussed_window.treebook.trees.detect {|t| t.tree_mirror.is_a?(Project::DirMirror)}
162
- end
163
-
164
- private
165
-
166
- # restores the directory/files in the last open window
167
- def self.restore_last_session
168
- if path = storage['last_open_dir']
169
- open_dir(path)
170
- end
171
-
172
- if files = Project.storage['files_open_last_session']
173
- files.each do |path|
174
- open_file(path)
175
- end
176
- end
177
- end
178
-
179
- # saves away a list of the currently open files in
180
- # @param [win]
181
- def self.save_file_list(win)
182
- # create a list of open files
183
- file_list = []
184
- win.notebooks[0].tabs.each do |tab|
185
- if tab.document && tab.document.path
186
- file_list << tab.document.path
187
- end
188
- end
189
- Project.storage['files_open_last_session'] = file_list
52
+ def close
53
+ window.treebook.remove_tree(@tree)
54
+ Project.window_projects.delete(window)
55
+ window.title = Window::DEFAULT_TITLE
56
+ Manager.open_project_sensitivity.recompute
190
57
  end
191
58
 
192
- # handles files and/or dirs passed as command line arguments
193
- def self.handle_startup_arguments
194
- if ARGV
195
- args = ARGV.dup
196
- dir_args = args.select {|path| File.directory?(path) }
197
- args -= dir_args
198
- file_args = args.select {|path| !path.start_with?('--') }
199
-
200
- dir_args.each {|path| open_dir(path) }
201
- file_args.each {|path| open_file(path) }
202
- return (dir_args.any? or file_args.any?)
203
- end
59
+ # Refresh the DirMirror Tree for the given Window, if
60
+ # there is one.
61
+ def refresh
62
+ @tree.refresh
63
+ file_list_resource.compute
204
64
  end
205
65
 
206
- # Attaches a new listener to tab focus change events, so we can
207
- # keep the current_files list.
208
- def self.init_current_files_hooks
209
- Redcar.app.add_listener(:tab_focussed) do |tab|
210
- if tab and tab.document_mirror.respond_to?(:path)
211
- add_to_recent_files_for(Project.focussed_project_path, tab.document_mirror.path)
212
- end
213
- end
214
- attach_app_listeners
66
+ def contains_path?(path)
67
+ File.expand_path(path) =~ /^#{@path}/
215
68
  end
216
69
 
217
- def self.attach_app_listeners
218
- Redcar.app.add_listener(:lost_focus) do
219
- FindFileDialog.clear
220
- end
221
-
222
- Redcar.app.add_listener(:focussed) do
223
- window_trees.values.each {|tree| tree.refresh }
224
- end
70
+ # A list of files previously opened in this session for this project
71
+ #
72
+ # @return [Array<String>] an array of paths
73
+ def recent_files
74
+ @recent_files ||= []
225
75
  end
226
76
 
227
- def self.add_to_recent_files_for(directory_path, new_file)
228
- new_file = File.expand_path(new_file)
229
- if recent_files_for(directory_path).include?(new_file)
230
- recent_files_for(directory_path).delete(new_file)
77
+ def add_to_recent_files(new_file)
78
+ new_file = File.expand_path(new_file)
79
+ if recent_files.include?(new_file)
80
+ recent_files.delete(new_file)
231
81
  end
232
- recent_files_for(directory_path).unshift(new_file)
233
- if recent_files_for(directory_path).length > RECENT_FILES_LENGTH
234
- recent_files_for(directory_path).pop
82
+ recent_files << new_file
83
+ if recent_files.length > RECENT_FILES_LENGTH
84
+ recent_files.shift
235
85
  end
236
86
  end
237
87
 
238
- def self.set_tree(win, tree)
239
- window_trees[win] = tree
240
- win.treebook.add_tree(tree)
88
+ def file_list
89
+ @file_list ||= FileList.new(path)
241
90
  end
242
91
 
243
- class FileOpenCommand < Command
244
-
245
- def initialize(path = nil)
246
- @path = path
247
- end
248
-
249
- def execute
250
- path = get_path
251
- if path
252
- if already_open_tab = Project.open_file_tab(path)
253
- already_open_tab.focus
254
- else
255
- Project.open_file(path)
256
- end
257
- end
258
- end
259
-
260
- private
261
-
262
- def get_path
263
- @path || begin
264
- if path = Application::Dialog.open_file(win, :filter_path => Project.filter_path)
265
- Project.storage['last_dir'] = File.dirname(File.expand_path(path))
266
- path
267
- end
268
- end
92
+ def file_list_resource
93
+ @resource ||= Resource.new("refresh file list for #{@path}") do
94
+ file_list.update
95
+ send_refresh_to_plugins
269
96
  end
270
97
  end
271
98
 
272
- class FileSaveCommand < EditTabCommand
273
-
274
- def execute
275
- tab = win.focussed_notebook.focussed_tab
276
- if tab.edit_view.document.mirror
277
- tab.edit_view.document.save!
278
- else
279
- FileSaveAsCommand.new.run
280
- end
281
- end
99
+ def refresh_modified_file(path)
100
+ file_list.update(path)
101
+ @tree.refresh
102
+ send_refresh_to_plugins
282
103
  end
283
-
284
- class FileSaveAsCommand < EditTabCommand
285
104
 
286
- def initialize(path = nil)
287
- @path = path
288
- end
289
-
290
- def execute
291
- tab = win.focussed_notebook.focussed_tab
292
- path = get_path
293
- if path
294
- contents = tab.edit_view.document.to_s
295
- new_mirror = FileMirror.new(path)
296
- new_mirror.commit(contents)
297
- tab.edit_view.document.mirror = new_mirror
298
- Project.refresh_tree(win)
299
- end
300
- end
301
-
302
- private
303
- def get_path
304
- @path || begin
305
- if path = Application::Dialog.save_file(win, :filter_path => Project.filter_path)
306
- Project.storage['last_dir'] = File.dirname(File.expand_path(path))
307
- path
308
- end
309
- end
310
- end
105
+ def all_files
106
+ file_list.all_files
311
107
  end
312
108
 
313
- class DirectoryOpenCommand < Command
314
-
315
- def initialize(path=nil)
316
- @path = path
317
- end
318
-
319
- def execute
320
- if path = get_path
321
- Project.open_dir(path, win)
322
- end
323
- end
324
-
325
- private
326
-
327
- def get_path
328
- @path || begin
329
- if path = Application::Dialog.open_directory(win, :filter_path => Project.filter_path)
330
- Project.storage['last_dir'] = File.dirname(File.expand_path(path))
331
- path
332
- end
333
- end
334
- end
335
- end
336
-
337
- class DirectoryCloseCommand < ProjectCommand
338
-
339
- def execute
340
- Project.close_tree(win)
109
+ def send_refresh_to_plugins
110
+ Redcar.plugin_manager.objects_implementing(:project_refresh_task_type).each do |object|
111
+ Redcar.app.task_queue.submit(object.project_refresh_task_type.new(self))
341
112
  end
342
113
  end
343
114
 
344
- class RefreshDirectoryCommand < ProjectCommand
345
-
346
- def execute
347
- Project.refresh_tree(win)
348
- end
115
+ def lost_application_focus
116
+ @lost_application_focus = true
349
117
  end
350
118
 
351
- class FindFileCommand < ProjectCommand
352
-
353
- def execute
354
- dialog = FindFileDialog.new
355
- dialog.open
119
+ def gained_focus
120
+ if @lost_application_focus
121
+ refresh
356
122
  end
123
+ @lost_application_focus = nil
357
124
  end
358
-
359
125
  end
360
126
  end