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.
- data/CHANGES +45 -0
- data/README.md +2 -1
- data/ROADMAP.md +0 -1
- data/Rakefile +10 -4
- data/bin/redcar +2 -2
- data/lib/openssl/build.properties +7 -0
- data/lib/plugin_manager/lib/plugin_manager.rb +10 -0
- data/lib/plugin_manager/lib/plugin_manager/plugin_definition.rb +1 -13
- data/lib/redcar.rb +12 -8
- data/lib/redcar/installer.rb +16 -15
- data/lib/redcar/ruby_extensions.rb +146 -1
- data/lib/redcar/runner.rb +16 -7
- data/lib/redcar/usage.rb +4 -7
- data/lib/redcar_quick_start.rb +5 -5
- data/lib/regex_replace.rb +0 -7
- data/plugins/application/features/step_definitions/command_steps.rb +5 -0
- data/plugins/application/features/step_definitions/dialog_steps.rb +5 -0
- data/plugins/application/features/step_definitions/filter_list_dialog_steps.rb +38 -0
- data/plugins/application/features/step_definitions/window_steps.rb +1 -1
- data/plugins/application/features/support/env.rb +44 -8
- data/plugins/application/lib/application.rb +32 -33
- data/plugins/application/lib/application/command.rb +32 -2
- data/plugins/application/lib/application/command/executor.rb +2 -12
- data/plugins/application/lib/application/dialog.rb +14 -14
- data/plugins/application/lib/application/event_spewer.rb +32 -0
- data/plugins/application/lib/application/menu.rb +5 -5
- data/plugins/application/lib/application/menu/builder.rb +5 -0
- data/plugins/application/lib/application/menu/lazy_menu.rb +24 -0
- data/plugins/application/lib/application/notebook.rb +4 -3
- data/plugins/application/lib/application/tab.rb +6 -2
- data/plugins/application/lib/application/window.rb +8 -4
- data/plugins/application/spec/application/menu/builder_spec.rb +17 -1
- data/plugins/application/spec/application/notebook_spec.rb +1 -1
- data/plugins/application_swt/build.xml +74 -0
- data/plugins/application_swt/lib/application_swt.rb +79 -0
- data/plugins/application_swt/lib/application_swt/cucumber_patches.rb +6 -1
- data/plugins/application_swt/lib/application_swt/dialog_adapter.rb +25 -17
- data/plugins/application_swt/lib/application_swt/dialogs/filter_list_dialog_controller.rb +50 -12
- data/plugins/application_swt/lib/application_swt/html_tab.rb +20 -0
- data/plugins/application_swt/lib/application_swt/menu.rb +26 -2
- data/plugins/application_swt/lib/application_swt/notebook.rb +10 -12
- data/plugins/application_swt/lib/application_swt/window.rb +11 -11
- data/plugins/application_swt/src/com/redcareditor/application_swt/CocoaUIEnhancer.java +313 -0
- data/plugins/auto_completer/lib/auto_completer.rb +74 -67
- data/plugins/auto_completer/lib/auto_completer/current_document_completion_source.rb +19 -0
- data/plugins/auto_completer/lib/auto_completer/document_controller.rb +2 -2
- data/plugins/auto_completer/lib/auto_completer/word_list.rb +8 -1
- data/plugins/auto_indenter/features/ruby_style_indentation.feature +24 -0
- data/plugins/auto_indenter/features/step_definitions/indentation_steps.rb +6 -0
- data/plugins/auto_indenter/features/support/env.rb +2 -0
- data/plugins/auto_indenter/lib/auto_indenter.rb +86 -0
- data/plugins/auto_indenter/lib/auto_indenter/analyzer.rb +91 -0
- data/plugins/auto_indenter/lib/auto_indenter/commands.rb +34 -0
- data/plugins/auto_indenter/lib/auto_indenter/document_controller.rb +67 -12
- data/plugins/auto_indenter/lib/auto_indenter/rules.rb +41 -0
- data/plugins/auto_indenter/spec/auto_indenter/analyzer_spec.rb +151 -0
- data/plugins/auto_indenter/spec/spec_helper.rb +5 -0
- data/plugins/auto_pairer/lib/auto_pairer.rb +1 -0
- data/plugins/auto_pairer/lib/auto_pairer/document_controller.rb +43 -42
- data/plugins/auto_pairer/lib/auto_pairer/pairs_for_scope.rb +1 -5
- data/plugins/core/lib/core.rb +12 -1
- data/plugins/core/lib/core/observable.rb +7 -7
- data/plugins/core/lib/core/persistent_cache.rb +14 -2
- data/plugins/core/lib/core/plugin.rb +7 -0
- data/plugins/core/lib/core/resource.rb +78 -0
- data/plugins/core/lib/core/task.rb +62 -0
- data/plugins/core/lib/core/task_queue.rb +72 -0
- data/plugins/core/spec/core/resource_spec.rb +124 -0
- data/plugins/core/spec/core/task_queue_spec.rb +202 -0
- data/plugins/core/spec/spec_helper.rb +23 -1
- data/plugins/declarations/TODO +3 -0
- data/plugins/declarations/lib/declarations.rb +144 -0
- data/plugins/declarations/lib/declarations/completion_source.rb +22 -0
- data/plugins/declarations/lib/declarations/file.rb +68 -0
- data/plugins/declarations/lib/declarations/parser.rb +94 -0
- data/plugins/declarations/lib/declarations/select_tag_dialog.rb +44 -0
- data/plugins/declarations/plugin.rb +7 -0
- data/plugins/declarations/spec/declarations/file_spec.rb +62 -0
- data/plugins/declarations/spec/fixtures/federalist.rb +15 -0
- data/plugins/declarations/spec/spec_helper.rb +4 -0
- data/plugins/edit_view/features/indentation_commands.feature +40 -0
- data/plugins/edit_view/features/line_delimiter.feature +40 -0
- data/plugins/edit_view/features/step_definitions/editing_steps.rb +16 -4
- data/plugins/edit_view/features/step_definitions/notebook_steps.rb +1 -1
- data/plugins/edit_view/features/step_definitions/tab_steps.rb +1 -1
- data/plugins/edit_view/features/step_definitions/window_steps.rb +5 -1
- data/plugins/edit_view/features/support/env.rb +3 -5
- data/plugins/edit_view/features/undo_and_redo.feature +21 -0
- data/plugins/edit_view/lib/edit_view.rb +57 -4
- data/plugins/edit_view/lib/edit_view/actions/arrow_keys.rb +19 -3
- data/plugins/edit_view/lib/edit_view/document.rb +46 -11
- data/plugins/edit_view/lib/edit_view/document/indentation.rb +35 -0
- data/plugins/edit_view/lib/edit_view/modified_tabs_checker.rb +35 -0
- data/plugins/edit_view/lib/edit_view/tab_settings.rb +13 -3
- data/plugins/edit_view/spec/edit_view/document/indentation_spec.rb +112 -0
- data/plugins/edit_view/spec/edit_view/document_spec.rb +22 -0
- data/plugins/edit_view/spec/spec_helper.rb +1 -0
- data/plugins/edit_view_swt/lib/edit_view_swt.rb +59 -7
- data/plugins/edit_view_swt/lib/edit_view_swt/document.rb +3 -3
- data/plugins/edit_view_swt/lib/edit_view_swt/word_movement.rb +2 -2
- data/plugins/edit_view_swt/vendor/java-mateview.rb +3 -2
- data/plugins/encryption/encryption.rb +13 -6
- data/plugins/execute_current_tab/lib/execute_current_tab.rb +25 -15
- data/plugins/html_view/assets/redcar.css +32 -1
- data/plugins/html_view/lib/html_view.rb +23 -3
- data/plugins/html_view/lib/html_view/html_tab.rb +4 -0
- data/plugins/my_plugin/lib/my_plugin.rb +4 -12
- data/plugins/plugin_manager_ui/lib/plugin_manager_ui.rb +1 -0
- data/plugins/plugin_manager_ui/views/index.html.erb +30 -37
- data/plugins/project/features/find_file.feature +75 -0
- data/plugins/project/features/open_and_save_files.feature +7 -7
- data/plugins/project/features/open_directory_tree.feature +11 -3
- data/plugins/project/features/refresh_directory_tree.feature +7 -1
- data/plugins/project/features/step_definitions/directory_steps.rb +11 -1
- data/plugins/project/features/step_definitions/file_steps.rb +10 -0
- data/plugins/project/features/support/env.rb +6 -1
- data/plugins/project/features/watch_for_modified_files.feature +79 -0
- data/plugins/project/lib/project.rb +72 -306
- data/plugins/project/lib/project/commands.rb +128 -0
- data/plugins/project/lib/project/dir_mirror.rb +5 -1
- data/plugins/project/lib/project/drb_service.rb +21 -31
- data/plugins/project/lib/project/file_list.rb +76 -0
- data/plugins/project/lib/project/file_mirror.rb +13 -1
- data/plugins/project/lib/project/find_file_dialog.rb +22 -52
- data/plugins/project/lib/project/manager.rb +210 -0
- data/plugins/project/lib/project/recent_directories.rb +16 -3
- data/plugins/project/plugin.rb +1 -1
- data/plugins/project/spec/fixtures/myproject/README +2 -0
- data/plugins/project/spec/fixtures/myproject/lib/foo_lib.rb +1 -0
- data/plugins/project/spec/fixtures/myproject/spec/foo_spec.rb +1 -0
- data/plugins/project/{features → spec}/fixtures/winter.txt +0 -0
- data/plugins/project/spec/project/dir_mirror_spec.rb +1 -12
- data/plugins/project/spec/project/file_list_spec.rb +140 -0
- data/plugins/project/spec/spec_helper.rb +20 -0
- data/plugins/redcar/plugin.rb +1 -0
- data/plugins/redcar/redcar.rb +254 -84
- data/plugins/redcar_debug/lib/redcar_debug.rb +58 -11
- data/plugins/redcar_debug/vendor/jruby-prof/README +46 -0
- data/plugins/redcar_debug/vendor/jruby-prof/Rakefile +36 -0
- data/plugins/redcar_debug/vendor/jruby-prof/build.xml +31 -0
- data/plugins/redcar_debug/vendor/jruby-prof/example/call_tree.html +22677 -0
- data/plugins/redcar_debug/vendor/jruby-prof/example/call_tree.txt +589 -0
- data/plugins/redcar_debug/vendor/jruby-prof/example/flat.txt +28 -0
- data/plugins/redcar_debug/vendor/jruby-prof/example/graph.html +1670 -0
- data/plugins/redcar_debug/vendor/jruby-prof/example/graph.txt +125 -0
- data/plugins/redcar_debug/vendor/jruby-prof/example/pidigits.rb +92 -0
- data/plugins/redcar_debug/vendor/jruby-prof/example/test.rb +28 -0
- data/plugins/redcar_debug/vendor/jruby-prof/example/test2.rb +29 -0
- data/plugins/redcar_debug/vendor/jruby-prof/example/test_exception.rb +28 -0
- data/plugins/redcar_debug/vendor/jruby-prof/example/test_overhead.rb +43 -0
- data/plugins/redcar_debug/vendor/jruby-prof/lib/jruby-prof.rb +66 -0
- data/plugins/redcar_debug/vendor/jruby-prof/lib/jruby-prof/abstract_printer.rb +21 -0
- data/plugins/redcar_debug/vendor/jruby-prof/lib/jruby-prof/flat_text_printer.rb +35 -0
- data/plugins/redcar_debug/vendor/jruby-prof/lib/jruby-prof/graph_html_printer.rb +123 -0
- data/plugins/redcar_debug/vendor/jruby-prof/lib/jruby-prof/graph_text_printer.rb +45 -0
- data/plugins/redcar_debug/vendor/jruby-prof/lib/jruby-prof/invocation_set.rb +34 -0
- data/plugins/redcar_debug/vendor/jruby-prof/lib/jruby-prof/method.rb +107 -0
- data/plugins/redcar_debug/vendor/jruby-prof/lib/jruby-prof/profile_invocation.rb +43 -0
- data/plugins/redcar_debug/vendor/jruby-prof/lib/jruby-prof/simple_tree_printer.rb +27 -0
- data/plugins/redcar_debug/vendor/jruby-prof/lib/jruby-prof/tree_html_printer.rb +144 -0
- data/plugins/redcar_debug/vendor/jruby-prof/src/org/jruby/prof/Invocation.java +14 -0
- data/plugins/redcar_debug/vendor/jruby-prof/src/org/jruby/prof/JRubyProf.java +94 -0
- data/plugins/redcar_debug/vendor/jruby-prof/src/org/jruby/prof/ProfEventHook.java +49 -0
- data/plugins/redcar_debug/vendor/jruby-prof/templates/graph_row.html.erb +18 -0
- data/plugins/redcar_debug/vendor/jruby-prof/test/basic_test.rb +291 -0
- data/plugins/redcar_debug/views/history.html.erb +33 -0
- data/plugins/redcar_debug/views/index.html.erb +33 -0
- data/plugins/repl/lib/repl/internal_mirror.rb +3 -15
- data/plugins/repl/spec/repl/internal_mirror_spec.rb +2 -2
- data/plugins/snippets/lib/snippets.rb +0 -1
- data/plugins/snippets/lib/snippets/document_controller.rb +7 -1
- data/plugins/task_manager/lib/task_manager.rb +28 -0
- data/plugins/task_manager/plugin.rb +11 -0
- data/plugins/task_manager/views/index.html.erb +67 -0
- data/plugins/textmate/lib/textmate.rb +17 -21
- data/plugins/textmate/lib/textmate/plist.rb +1 -2
- data/plugins/textmate/lib/textmate/preference.rb +5 -1
- data/plugins/textmate/lib/textmate/snippet.rb +6 -1
- data/plugins/tree_view_swt/lib/tree_view_swt.rb +0 -6
- data/textmate/Bundles/Cucumber.tmbundle/Preferences/Comments.tmPreferences +1 -1
- data/textmate/Bundles/Cucumber.tmbundle/Preferences/next_Cucumber_Plain_Text_Feature_Completions.tmPreferences +30 -0
- data/textmate/Bundles/Cucumber.tmbundle/Preferences/next_Symbol_list___Scenario.tmPreferences +19 -0
- data/textmate/Bundles/Cucumber.tmbundle/Syntaxes/next_Cucumber_Plain_Text_Feature.tmLanguage +221 -0
- data/textmate/Bundles/Cucumber.tmbundle/Syntaxes/next_Cucumber_Steps.tmLanguage +424 -0
- data/textmate/Bundles/Cucumber.tmbundle/Syntaxes/plaintext_template.erb +19 -77
- data/textmate/Bundles/Cucumber.tmbundle/info.plist +1 -20
- data/textmate/Bundles/Perl.tmbundle/Syntaxes/Perl.plist +1 -1
- data/textmate/Themes/Emacs Strict.tmTheme +241 -0
- data/textmate/Themes/IR_White.tmTheme +792 -0
- data/textmate/Themes/Monokai.tmTheme +291 -0
- data/textmate/Themes/WhysPoignant.tmTheme +191 -0
- metadata +92 -7
- data/plugins/application/features/main_window.feature +0 -8
- data/plugins/project/lib/project/project_command.rb +0 -5
- data/textmate/Bundles/Cucumber.tmbundle/Snippets/Scenario.tmSnippet +0 -22
- 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 "
|
|
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.
|
|
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
|
-
|
|
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/
|
|
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.
|
|
54
|
-
|
|
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
|
-
|
|
122
|
-
|
|
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
|
-
|
|
132
|
-
tree
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
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
|
-
|
|
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
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
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
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
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
|
-
#
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
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
|
-
|
|
207
|
-
|
|
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
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
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
|
|
228
|
-
new_file = File.expand_path(new_file)
|
|
229
|
-
if
|
|
230
|
-
|
|
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
|
-
|
|
233
|
-
if
|
|
234
|
-
|
|
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
|
|
239
|
-
|
|
240
|
-
win.treebook.add_tree(tree)
|
|
88
|
+
def file_list
|
|
89
|
+
@file_list ||= FileList.new(path)
|
|
241
90
|
end
|
|
242
91
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
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
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
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
|
-
|
|
287
|
-
|
|
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
|
-
|
|
314
|
-
|
|
315
|
-
|
|
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
|
-
|
|
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
|
-
|
|
352
|
-
|
|
353
|
-
|
|
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
|