redcar 0.9.2 → 0.10
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 +34 -4
- data/Rakefile +2 -1
- data/lib/redcar.rb +3 -3
- data/lib/redcar/installer.rb +2 -3
- data/plugins/application/features/step_definitions/dialog_steps.rb +7 -0
- data/plugins/application/features/step_definitions/key_steps.rb +18 -0
- data/plugins/application/features/step_definitions/menu_steps.rb +5 -6
- data/plugins/application/features/step_definitions/speedbar_steps.rb +29 -9
- data/plugins/application/features/step_definitions/tree_steps.rb +13 -0
- data/plugins/application/features/support/env.rb +39 -5
- data/plugins/application/features/support/fake_event.rb +12 -0
- data/plugins/application/lib/application.rb +5 -6
- data/plugins/application/lib/application/dialog.rb +53 -10
- data/plugins/application/lib/application/dialogs/modeless_list_dialog.rb +85 -0
- data/plugins/application/lib/application/keymap.rb +10 -8
- data/plugins/application/lib/application/menu.rb +38 -16
- data/plugins/application/lib/application/treebook.rb +30 -0
- data/plugins/application/lib/application/window.rb +20 -2
- data/plugins/application/spec/application/command/executor_spec.rb +1 -0
- data/plugins/application/spec/application/menu_spec.rb +26 -26
- data/plugins/application/spec/application/treebook_spec.rb +6 -6
- data/plugins/application/spec/spec_helper.rb +10 -1
- data/plugins/application_swt/lib/application_swt.rb +25 -3
- data/plugins/application_swt/lib/application_swt/dialog_adapter.rb +48 -27
- data/plugins/application_swt/lib/application_swt/dialogs/filter_list_dialog_controller.rb +22 -11
- data/plugins/application_swt/lib/application_swt/dialogs/modeless_dialog.rb +113 -0
- data/plugins/application_swt/lib/application_swt/dialogs/modeless_html_dialog.rb +85 -0
- data/plugins/application_swt/lib/application_swt/dialogs/modeless_list_dialog_controller.rb +143 -0
- data/plugins/application_swt/lib/application_swt/gradient.rb +61 -0
- data/plugins/application_swt/lib/application_swt/menu/binding_translator.rb +4 -4
- data/plugins/application_swt/lib/application_swt/notebook.rb +5 -8
- data/plugins/application_swt/lib/application_swt/speedbar.rb +1 -0
- data/plugins/application_swt/lib/application_swt/treebook.rb +6 -8
- data/plugins/application_swt/lib/application_swt/window.rb +85 -57
- data/plugins/application_swt/lib/swt/graphics_utils.rb +23 -0
- data/plugins/application_swt/lib/swt/vtab_folder.rb +7 -0
- data/plugins/application_swt/lib/swt/vtab_label.rb +1 -1
- data/plugins/application_swt/spec/application_swt/gradient_spec.rb +142 -0
- data/plugins/auto_completer/lib/auto_completer.rb +10 -42
- data/plugins/auto_completer/lib/auto_completer/list_dialog.rb +21 -0
- data/plugins/clojure/lib/clojure.rb +33 -0
- data/plugins/{repl/lib/repl/clojure_mirror.rb → clojure/lib/clojure/repl_mirror.rb} +16 -20
- data/plugins/clojure/plugin.rb +9 -0
- data/plugins/{repl/spec/repl/clojure_mirror_spec.rb → clojure/spec/clojure/repl_mirror_spec.rb} +12 -13
- data/plugins/clojure/spec/spec_helper.rb +5 -0
- data/plugins/{repl → clojure}/vendor/Wrapper.clj +0 -0
- data/plugins/{repl → clojure}/vendor/dummy +0 -0
- data/plugins/{repl → clojure}/vendor/enclojure-wrapper.jar +0 -0
- data/plugins/connection_manager/lib/connection_manager.rb +13 -13
- data/plugins/declarations/lib/declarations.rb +17 -6
- data/plugins/document_search/features/find.feature +389 -0
- data/plugins/document_search/features/find_and_replace.feature +723 -0
- data/plugins/document_search/features/replace.feature +69 -62
- data/plugins/document_search/lib/document_search.rb +81 -64
- data/plugins/document_search/lib/document_search/commands.rb +258 -0
- data/plugins/document_search/lib/document_search/find_and_replace_speedbar.rb +142 -0
- data/plugins/document_search/lib/document_search/find_speedbar.rb +102 -0
- data/plugins/document_search/lib/document_search/query_options.rb +45 -0
- data/plugins/edit_view/features/case_change.feature +9 -5
- data/plugins/edit_view/features/step_definitions/editing_steps.rb +19 -0
- data/plugins/edit_view/lib/edit_view.rb +15 -12
- data/plugins/edit_view/lib/edit_view/actions/arrow_keys.rb +12 -2
- data/plugins/edit_view/lib/edit_view/commands/text_conversion_commands.rb +1 -1
- data/plugins/edit_view/lib/edit_view/document.rb +129 -99
- data/plugins/edit_view_swt/lib/edit_view_swt.rb +33 -15
- data/plugins/encryption/encryption.rb +2 -0
- data/plugins/find-in-project/lib/find_in_project.rb +3 -5
- data/plugins/find-in-project/lib/find_in_project/views/index.html.erb +2 -0
- data/plugins/groovy/features/step_definitions/groovy_steps.rb +2 -2
- data/plugins/groovy/features/syntax_check_groovy.feature +3 -3
- data/plugins/groovy/lib/groovy.rb +38 -0
- data/plugins/groovy/lib/groovy/commands.rb +10 -0
- data/plugins/{repl/lib/repl/groovy_mirror.rb → groovy/lib/groovy/repl_mirror.rb} +33 -13
- data/plugins/groovy/lib/{syntax_check/groovy.rb → groovy/syntax_checker.rb} +13 -8
- data/plugins/groovy/plugin.rb +5 -4
- data/plugins/{repl/spec/repl/groovy_mirror_spec.rb → groovy/spec/groovy/repl_mirror_spec.rb} +14 -13
- data/plugins/groovy/spec/spec_helper.rb +5 -0
- data/plugins/html_view/assets/json2.js +476 -0
- data/plugins/html_view/lib/html_view.rb +1 -0
- data/plugins/java/features/fixtures/test.java +0 -0
- data/plugins/java/features/support/env.rb +27 -0
- data/plugins/java/features/syntax_check_java.feature +86 -0
- data/plugins/java/lib/syntax_check/java.rb +86 -0
- data/plugins/java/plugin.rb +7 -0
- data/plugins/javascript/features/fixtures/test2.js +5 -0
- data/plugins/javascript/features/step_definitions/javascript_steps.rb +16 -0
- data/plugins/javascript/features/support/env.rb +14 -0
- data/plugins/javascript/features/syntax_check_javascript.feature +46 -3
- data/plugins/javascript/lib/syntax_check/javascript.rb +15 -9
- data/plugins/line_tools/features/trim_line.feature +49 -0
- data/plugins/line_tools/lib/line_tools.rb +5 -1
- data/plugins/mirah/README +7 -0
- data/plugins/mirah/features/fixtures/test.mirah +2 -0
- data/plugins/mirah/features/syntax_check_mirah.feature +46 -0
- data/plugins/mirah/lib/mirah.rb +43 -0
- data/plugins/mirah/lib/mirah/my_error_handler.rb +22 -0
- data/plugins/mirah/lib/mirah/repl_mirror.rb +50 -0
- data/plugins/mirah/lib/mirah/syntax_checker.rb +38 -0
- data/plugins/mirah/plugin.rb +8 -0
- data/plugins/mirah/spec/mirah/repl_mirror_spec.rb +188 -0
- data/plugins/mirah/spec/spec_helper.rb +5 -0
- data/plugins/mirah/vendor/mirah-parser.jar +0 -0
- data/plugins/pair_highlighter/lib/pair_highlighter/document_controller.rb +24 -23
- data/plugins/plugin_manager_ui/lib/plugin_manager_ui.rb +10 -1
- data/plugins/plugin_manager_ui/views/index.html.erb +2 -0
- data/plugins/project/features/find_file.feature +40 -16
- data/plugins/project/features/highlight_focussed_tab.feature +16 -10
- data/plugins/project/features/step_definitions/find_file_steps.rb +11 -0
- data/plugins/project/features/step_definitions/project_tree_steps.rb +5 -1
- data/plugins/project/features/support/env.rb +5 -0
- data/plugins/project/lib/project/commands.rb +8 -1
- data/plugins/project/lib/project/dir_controller.rb +4 -1
- data/plugins/project/lib/project/find_file_dialog.rb +16 -12
- data/plugins/project/lib/project/manager.rb +30 -1
- data/plugins/project_search/vendor/lucene/CHANGELOG +147 -0
- data/plugins/project_search/vendor/lucene/CONTRIBUTORS +17 -0
- data/plugins/project_search/vendor/lucene/Gemfile +9 -0
- data/plugins/project_search/vendor/lucene/Gemfile.lock +33 -0
- data/plugins/project_search/vendor/lucene/LICENSE +19 -0
- data/plugins/project_search/vendor/lucene/README.rdoc +283 -0
- data/plugins/project_search/vendor/lucene/Rakefile +35 -0
- data/plugins/project_search/vendor/lucene/examples/active_model/serializers.rb +25 -0
- data/plugins/project_search/vendor/lucene/examples/active_model/validation.rb +26 -0
- data/plugins/project_search/vendor/lucene/examples/admin/Rakefile +4 -0
- data/plugins/project_search/vendor/lucene/examples/admin/admin.rb +29 -0
- data/plugins/project_search/vendor/lucene/examples/admin/public/jquery.js +4376 -0
- data/plugins/project_search/vendor/lucene/examples/admin/public/neo4j.css +153 -0
- data/plugins/project_search/vendor/lucene/examples/admin/public/neo_admin.js +18 -0
- data/plugins/project_search/vendor/lucene/examples/admin/spec/admin_spec.rb +26 -0
- data/plugins/project_search/vendor/lucene/examples/admin/views/index.erb +21 -0
- data/plugins/project_search/vendor/lucene/examples/filetree/README.rdoc +9 -0
- data/plugins/project_search/vendor/lucene/examples/filetree/app.rb +7 -0
- data/plugins/project_search/vendor/lucene/examples/filetree/batch.props +5 -0
- data/plugins/project_search/vendor/lucene/examples/filetree/features/step_definitions/add_steps.rb +121 -0
- data/plugins/project_search/vendor/lucene/examples/filetree/features/support/env.rb +30 -0
- data/plugins/project_search/vendor/lucene/examples/filetree/features/support/rspec_helper.rb +50 -0
- data/plugins/project_search/vendor/lucene/examples/filetree/features/treesizes.feature +19 -0
- data/plugins/project_search/vendor/lucene/examples/imdb/1_create_neo_db.rb +66 -0
- data/plugins/project_search/vendor/lucene/examples/imdb/2_index_db.rb +23 -0
- data/plugins/project_search/vendor/lucene/examples/imdb/README +12 -0
- data/plugins/project_search/vendor/lucene/examples/imdb/find_actors.rb +56 -0
- data/plugins/project_search/vendor/lucene/examples/imdb/install.sh +12 -0
- data/plugins/project_search/vendor/lucene/examples/imdb/model.rb +37 -0
- data/plugins/project_search/vendor/lucene/examples/railway/README +111 -0
- data/plugins/project_search/vendor/lucene/examples/railway/railnet-app.rb +31 -0
- data/plugins/project_search/vendor/lucene/examples/railway/railnet-data.rb +42 -0
- data/plugins/project_search/vendor/lucene/examples/rest/example.rb +41 -0
- data/plugins/project_search/vendor/lucene/examples/you_might_know/YouMightKnow.java +60 -0
- data/plugins/project_search/vendor/lucene/examples/you_might_know/all_simple_paths.rb +34 -0
- data/plugins/project_search/vendor/lucene/examples/you_might_know/nodes.rb +34 -0
- data/plugins/project_search/vendor/lucene/examples/you_might_know/you_might_know.rb +50 -0
- data/plugins/project_search/vendor/lucene/lib/lucene.rb +15 -0
- data/plugins/project_search/vendor/lucene/lib/lucene/config.rb +145 -0
- data/plugins/project_search/vendor/lucene/lib/lucene/document.rb +96 -0
- data/plugins/project_search/vendor/lucene/lib/lucene/field_info.rb +144 -0
- data/plugins/project_search/vendor/lucene/lib/lucene/hits.rb +54 -0
- data/plugins/project_search/vendor/lucene/lib/lucene/index.rb +267 -0
- data/plugins/project_search/vendor/lucene/lib/lucene/index_info.rb +146 -0
- data/plugins/project_search/vendor/lucene/lib/lucene/index_searcher.rb +157 -0
- data/plugins/project_search/vendor/lucene/lib/lucene/jars.rb +5 -0
- data/plugins/project_search/vendor/lucene/lib/lucene/query_dsl.rb +135 -0
- data/plugins/project_search/vendor/lucene/lib/lucene/transaction.rb +117 -0
- data/plugins/project_search/vendor/lucene/lib/lucene/version.rb +3 -0
- data/plugins/project_search/vendor/lucene/lucene.gemspec +23 -0
- data/plugins/project_search/vendor/lucene/spec/lucene/document_spec.rb +32 -0
- data/plugins/project_search/vendor/lucene/spec/lucene/field_info_spec.rb +70 -0
- data/plugins/project_search/vendor/lucene/spec/lucene/index_info_spec.rb +76 -0
- data/plugins/project_search/vendor/lucene/spec/lucene/index_spec.rb +643 -0
- data/plugins/project_search/vendor/lucene/spec/lucene/query_dsl_spec.rb +142 -0
- data/plugins/project_search/vendor/lucene/spec/lucene/sort_spec.rb +101 -0
- data/plugins/project_search/vendor/lucene/spec/lucene/spec_helper.rb +10 -0
- data/plugins/project_search/vendor/lucene/spec/lucene/transaction_spec.rb +118 -0
- data/plugins/redcar/features/alter_font_size.feature +25 -0
- data/plugins/redcar/features/step_definitions/font_steps.rb +34 -0
- data/plugins/redcar/redcar.rb +256 -43
- data/plugins/repl/features/command_editing.feature +55 -0
- data/plugins/repl/features/command_history.feature +75 -0
- data/plugins/repl/features/step_definitions/repl_steps.rb +17 -1
- data/plugins/repl/features/support/env.rb +24 -0
- data/plugins/repl/features/support/fake_repl.rb +16 -0
- data/plugins/repl/lib/repl.rb +17 -74
- data/plugins/repl/lib/repl/repl_command.rb +20 -0
- data/plugins/repl/lib/repl/repl_mirror.rb +168 -22
- data/plugins/repl/lib/repl/repl_tab.rb +131 -6
- data/plugins/repl/plugin.rb +1 -1
- data/plugins/repl/spec/repl/repl_mirror_spec.rb +72 -0
- data/plugins/repl/spec/spec_helper.rb +1 -1
- data/plugins/repl_swt/lib/repl_swt.rb +7 -0
- data/plugins/repl_swt/lib/repl_swt/key_listener.rb +43 -0
- data/plugins/repl_swt/plugin.rb +8 -0
- data/plugins/ruby/lib/ruby.rb +35 -0
- data/plugins/{repl/lib/repl/ruby_mirror.rb → ruby/lib/ruby/repl_mirror.rb} +12 -12
- data/plugins/ruby/lib/{syntax_check/ruby.rb → ruby/syntax_checker.rb} +3 -3
- data/plugins/ruby/plugin.rb +5 -4
- data/plugins/{repl/spec/repl/ruby_mirror_spec.rb → ruby/spec/ruby/repl_mirror_spec.rb} +38 -29
- data/plugins/ruby/spec/spec_helper.rb +5 -0
- data/plugins/runnables/lib/runnables.rb +2 -0
- data/plugins/runnables/lib/runnables/command_output_controller.rb +5 -0
- data/plugins/runnables/lib/runnables/output_processor.rb +14 -3
- data/plugins/runnables/views/command_output.html.erb +3 -2
- data/plugins/scm/lib/scm.rb +4 -2
- data/plugins/scm/lib/scm/diff_mirror.rb +6 -6
- data/plugins/scm_git/lib/scm_git.rb +136 -107
- data/plugins/scm_git/lib/scm_git/change.rb +28 -19
- data/plugins/snippets/lib/snippets/explorer.rb +2 -2
- data/plugins/swt/lib/swt/full_swt.rb +1 -0
- data/plugins/syntax_check/features/step_definitions/syntax_check_steps.rb +4 -0
- data/plugins/syntax_check/features/support/env.rb +3 -0
- data/plugins/syntax_check/lib/syntax_check.rb +71 -5
- data/plugins/syntax_check/lib/syntax_check/annotation.rb +61 -0
- data/plugins/test_runner/lib/test_runner.rb +39 -0
- data/plugins/test_runner/lib/test_runner/rspec_runner.rb +20 -0
- data/plugins/test_runner/lib/test_runner/run_test_command.rb +63 -0
- data/plugins/test_runner/lib/test_runner/runnable_test_runner.rb +26 -0
- data/plugins/test_runner/plugin.rb +8 -0
- data/plugins/test_runner/spec/run_test_command_spec.rb +51 -0
- data/plugins/test_runner/spec/spec_helper.rb +5 -0
- data/plugins/textmate/lib/textmate.rb +12 -2
- data/plugins/textmate/vendor/redcar-bundles/Bundles/HTML.tmbundle/Syntaxes/HTML.plist +0 -2
- data/plugins/textmate/vendor/redcar-bundles/Bundles/Mirah.tmbundle/Syntaxes/Mirah.plist +22 -0
- data/plugins/textmate/vendor/redcar-bundles/Bundles/Mirah.tmbundle/info.plist +12 -0
- data/plugins/textmate/vendor/redcar-bundles/Bundles/Ruby.tmbundle/Syntaxes/Ruby.plist +2 -0
- data/plugins/todo_list/lib/todo_list.rb +7 -0
- data/plugins/todo_list/lib/todo_list/todo_controller.rb +3 -1
- data/plugins/tree/lib/tree.rb +4 -0
- data/plugins/tree_view_swt/lib/tree_view_swt.rb +5 -0
- data/plugins/web_bookmarks/lib/web_bookmarks.rb +10 -0
- metadata +137 -22
- data/plugins/document_search/features/search.feature +0 -163
- data/plugins/document_search/lib/document_search/replace_all_command.rb +0 -27
- data/plugins/document_search/lib/document_search/replace_command.rb +0 -38
- data/plugins/document_search/lib/document_search/replace_next_command.rb +0 -27
- data/plugins/document_search/lib/document_search/search_and_replace.rb +0 -81
- data/plugins/ruby/README +0 -6
|
@@ -8,73 +8,71 @@ Feature: Replace in file
|
|
|
8
8
|
Scenario: Open replace speedbar
|
|
9
9
|
When I replace the contents with "Foo\nBar\nBaz"
|
|
10
10
|
And I move the cursor to 0
|
|
11
|
-
And I run the command DocumentSearch::
|
|
12
|
-
Then the DocumentSearch::
|
|
11
|
+
And I run the command DocumentSearch::FindAndReplaceSpeedbarCommand
|
|
12
|
+
Then the DocumentSearch::FindAndReplaceSpeedbar speedbar should be open
|
|
13
13
|
|
|
14
14
|
Scenario: Replace next occurrence on the same line
|
|
15
15
|
When I replace the contents with "Foo\nBar Rab Rab\nBaz"
|
|
16
16
|
And I move the cursor to 4
|
|
17
|
-
And I run the command DocumentSearch::
|
|
18
|
-
And I type "Rab" into the "
|
|
17
|
+
And I run the command DocumentSearch::FindAndReplaceSpeedbarCommand
|
|
18
|
+
And I type "Rab" into the "Find" field in the speedbar
|
|
19
19
|
And I type "RABBIT" into the "Replace" field in the speedbar
|
|
20
|
-
And I press "Replace" in the speedbar
|
|
20
|
+
And I press "Replace && Find" in the speedbar
|
|
21
21
|
Then the contents should be "Foo\nBar RABBIT Rab\nBaz"
|
|
22
|
-
And the selected text should be "
|
|
23
|
-
And the selection range should be from
|
|
22
|
+
And the selected text should be "Rab"
|
|
23
|
+
And the selection range should be from 15 to 18
|
|
24
24
|
|
|
25
25
|
Scenario: Replace next occurrence on the same line twice
|
|
26
26
|
When I replace the contents with "Foo\nBar Rab Rab\nBaz"
|
|
27
27
|
And I move the cursor to 4
|
|
28
|
-
And I run the command DocumentSearch::
|
|
29
|
-
And I type "Rab" into the "
|
|
28
|
+
And I run the command DocumentSearch::FindAndReplaceSpeedbarCommand
|
|
29
|
+
And I type "Rab" into the "Find" field in the speedbar
|
|
30
30
|
And I type "RAB" into the "Replace" field in the speedbar
|
|
31
|
-
And I press "Replace" in the speedbar
|
|
32
|
-
And I press "Replace" in the speedbar
|
|
31
|
+
And I press "Replace && Find" in the speedbar
|
|
32
|
+
And I press "Replace && Find" in the speedbar
|
|
33
33
|
Then the contents should be "Foo\nBar RAB RAB\nBaz"
|
|
34
34
|
And the selected text should be "RAB"
|
|
35
|
-
And the selection range should be from
|
|
35
|
+
And the selection range should be from 8 to 11
|
|
36
36
|
|
|
37
37
|
Scenario: Replace next occurrence
|
|
38
38
|
When I replace the contents with "Foo\nBar\nBaz\nBar\nQux"
|
|
39
39
|
And I move the cursor to 0
|
|
40
|
-
And I run the command DocumentSearch::
|
|
41
|
-
And I type "Bar" into the "
|
|
40
|
+
And I run the command DocumentSearch::FindAndReplaceSpeedbarCommand
|
|
41
|
+
And I type "Bar" into the "Find" field in the speedbar
|
|
42
42
|
And I type "Rab" into the "Replace" field in the speedbar
|
|
43
|
-
And I press "Replace" in the speedbar
|
|
43
|
+
And I press "Replace && Find" in the speedbar
|
|
44
44
|
Then the contents should be "Foo\nRab\nBaz\nBar\nQux"
|
|
45
|
-
And the selected text should be "
|
|
46
|
-
And the selection should be on line
|
|
45
|
+
And the selected text should be "Bar"
|
|
46
|
+
And the selection should be on line 3
|
|
47
47
|
|
|
48
48
|
Scenario: Replace next occurrence twice
|
|
49
49
|
When I replace the contents with "Foo\nBar\nBaz\nBar\nQux"
|
|
50
50
|
And I move the cursor to 0
|
|
51
|
-
And I run the command DocumentSearch::
|
|
52
|
-
And I type "Bar" into the "
|
|
51
|
+
And I run the command DocumentSearch::FindAndReplaceSpeedbarCommand
|
|
52
|
+
And I type "Bar" into the "Find" field in the speedbar
|
|
53
53
|
And I type "Rab" into the "Replace" field in the speedbar
|
|
54
|
-
And I press "Replace" in the speedbar
|
|
54
|
+
And I press "Replace && Find" in the speedbar
|
|
55
55
|
Then the contents should be "Foo\nRab\nBaz\nBar\nQux"
|
|
56
|
-
When I press "Replace" in the speedbar
|
|
56
|
+
When I press "Replace && Find" in the speedbar
|
|
57
57
|
Then the contents should be "Foo\nRab\nBaz\nRab\nQux"
|
|
58
|
-
And
|
|
59
|
-
And the selection should be on line 3
|
|
58
|
+
And there should not be any text selected
|
|
60
59
|
|
|
61
60
|
Scenario: Replace next occurrence wraps
|
|
62
61
|
When I replace the contents with "Foo\nBar\nBaz"
|
|
63
62
|
And I move the cursor to 8
|
|
64
|
-
And I run the command DocumentSearch::
|
|
65
|
-
And I type "Bar" into the "
|
|
63
|
+
And I run the command DocumentSearch::FindAndReplaceSpeedbarCommand
|
|
64
|
+
And I type "Bar" into the "Find" field in the speedbar
|
|
66
65
|
And I type "Rab" into the "Replace" field in the speedbar
|
|
67
|
-
When I press "Replace" in the speedbar
|
|
66
|
+
When I press "Replace && Find" in the speedbar
|
|
68
67
|
Then the contents should be "Foo\nRab\nBaz"
|
|
69
|
-
And
|
|
68
|
+
And there should not be any text selected
|
|
70
69
|
|
|
71
70
|
Scenario: Replace all replaces one
|
|
72
71
|
When I replace the contents with "Foo\nBar\nBaz"
|
|
73
72
|
And I move the cursor to 0
|
|
74
|
-
And I run the command DocumentSearch::
|
|
75
|
-
And I type "Bar" into the "
|
|
73
|
+
And I run the command DocumentSearch::FindAndReplaceSpeedbarCommand
|
|
74
|
+
And I type "Bar" into the "Find" field in the speedbar
|
|
76
75
|
And I type "Rab" into the "Replace" field in the speedbar
|
|
77
|
-
Then I should see a message box containing "Replaced 1 occurrence"
|
|
78
76
|
When I press "Replace All" in the speedbar
|
|
79
77
|
Then the contents should be "Foo\nRab\nBaz"
|
|
80
78
|
And the selected text should be "Rab"
|
|
@@ -83,10 +81,9 @@ Feature: Replace in file
|
|
|
83
81
|
Scenario: Replace all replaces two
|
|
84
82
|
When I replace the contents with "Foo\nBar\nBaz\nBar\nQux"
|
|
85
83
|
And I move the cursor to 0
|
|
86
|
-
And I run the command DocumentSearch::
|
|
87
|
-
And I type "Bar" into the "
|
|
84
|
+
And I run the command DocumentSearch::FindAndReplaceSpeedbarCommand
|
|
85
|
+
And I type "Bar" into the "Find" field in the speedbar
|
|
88
86
|
And I type "Rab" into the "Replace" field in the speedbar
|
|
89
|
-
Then I should see a message box containing "Replaced 2 occurrences"
|
|
90
87
|
When I press "Replace All" in the speedbar
|
|
91
88
|
Then the contents should be "Foo\nRab\nBaz\nRab\nQux"
|
|
92
89
|
And the selected text should be "Rab"
|
|
@@ -94,69 +91,79 @@ Feature: Replace in file
|
|
|
94
91
|
|
|
95
92
|
Scenario: Replace all replaces two on the same line
|
|
96
93
|
When I replace the contents with "abcabc"
|
|
97
|
-
And I run the command DocumentSearch::
|
|
98
|
-
And I type "bc" into the "
|
|
94
|
+
And I run the command DocumentSearch::FindAndReplaceSpeedbarCommand
|
|
95
|
+
And I type "bc" into the "Find" field in the speedbar
|
|
99
96
|
And I type "xx" into the "Replace" field in the speedbar
|
|
100
|
-
Then I should see a message box containing "Replaced 2 occurrences"
|
|
101
97
|
When I press "Replace All" in the speedbar
|
|
102
98
|
Then the contents should be "axxaxx"
|
|
103
99
|
|
|
104
100
|
Scenario: Replace all replaces overlapping occurences on the same line
|
|
105
101
|
When I replace the contents with "deedeedeed"
|
|
106
|
-
And I run the command DocumentSearch::
|
|
107
|
-
And I type "deed" into the "
|
|
102
|
+
And I run the command DocumentSearch::FindAndReplaceSpeedbarCommand
|
|
103
|
+
And I type "deed" into the "Find" field in the speedbar
|
|
108
104
|
And I type "misdeed" into the "Replace" field in the speedbar
|
|
109
|
-
Then I should see a message box containing "Replaced 2 occurrences"
|
|
110
105
|
When I press "Replace All" in the speedbar
|
|
111
106
|
Then the contents should be "misdeedeemisdeed"
|
|
112
107
|
|
|
108
|
+
Scenario: Replace all is a single undo action
|
|
109
|
+
When I replace the contents with "abcabc"
|
|
110
|
+
And I run the command DocumentSearch::FindAndReplaceSpeedbarCommand
|
|
111
|
+
And I type "bc" into the "Find" field in the speedbar
|
|
112
|
+
And I type "xx" into the "Replace" field in the speedbar
|
|
113
|
+
When I press "Replace All" in the speedbar
|
|
114
|
+
Then the contents should be "axxaxx"
|
|
115
|
+
When I undo
|
|
116
|
+
Then the contents should be "abcabc"
|
|
117
|
+
|
|
113
118
|
Scenario: Replace next occurrence test bug
|
|
114
119
|
When I replace the contents with "the\n* Speedbars have access to the properties of the widgets in them."
|
|
115
120
|
And I move the cursor to 0
|
|
116
|
-
And I run the command DocumentSearch::
|
|
117
|
-
And I type "the" into the "
|
|
121
|
+
And I run the command DocumentSearch::FindAndReplaceSpeedbarCommand
|
|
122
|
+
And I type "the" into the "Find" field in the speedbar
|
|
118
123
|
And I type "THE" into the "Replace" field in the speedbar
|
|
119
|
-
And I press "Replace" in the speedbar
|
|
124
|
+
And I press "Replace && Find" in the speedbar
|
|
120
125
|
Then the contents should be "THE\n* Speedbars have access to the properties of the widgets in them."
|
|
121
|
-
And the selection range should be from 0 to 3
|
|
122
|
-
And I press "Replace" in the speedbar
|
|
123
|
-
Then the contents should be "THE\n* Speedbars have access to THE properties of the widgets in them."
|
|
124
126
|
And the selection range should be from 31 to 34
|
|
125
|
-
And I press "Replace" in the speedbar
|
|
126
|
-
Then the contents should be "THE\n* Speedbars have access to THE properties of
|
|
127
|
+
And I press "Replace && Find" in the speedbar
|
|
128
|
+
Then the contents should be "THE\n* Speedbars have access to THE properties of the widgets in them."
|
|
127
129
|
And the selection range should be from 49 to 52
|
|
128
|
-
And I press "Replace" in the speedbar
|
|
129
|
-
Then the contents should be "THE\n* Speedbars have access to THE properties of THE widgets in
|
|
130
|
+
And I press "Replace && Find" in the speedbar
|
|
131
|
+
Then the contents should be "THE\n* Speedbars have access to THE properties of THE widgets in them."
|
|
130
132
|
And the selection range should be from 64 to 67
|
|
133
|
+
And I press "Replace && Find" in the speedbar
|
|
134
|
+
Then the contents should be "THE\n* Speedbars have access to THE properties of THE widgets in THEm."
|
|
135
|
+
And the selected text should be "THE"
|
|
136
|
+
And the selection should be on line 0
|
|
131
137
|
|
|
132
138
|
Scenario: Replace regex with back-references
|
|
133
139
|
When I replace the contents with "Curry chicken"
|
|
134
140
|
And I move the cursor to 0
|
|
135
|
-
And I run the command DocumentSearch::
|
|
136
|
-
And I
|
|
141
|
+
And I run the command DocumentSearch::FindAndReplaceSpeedbarCommand
|
|
142
|
+
And I choose "Regex" in the "query_type" field in the speedbar
|
|
143
|
+
And I type "(\w+) chicken" into the "Find" field in the speedbar
|
|
137
144
|
And I type "\1 beef" into the "Replace" field in the speedbar
|
|
138
|
-
And I press "Replace" in the speedbar
|
|
145
|
+
And I press "Replace && Find" in the speedbar
|
|
139
146
|
Then the contents should be "Curry beef"
|
|
140
147
|
|
|
141
148
|
Scenario: Replace should move past the current replacement if the query is a substring of the replacement
|
|
142
149
|
When I replace the contents with "foo\nfoo\nfoo"
|
|
143
150
|
And I move the cursor to 0
|
|
144
|
-
And I run the command DocumentSearch::
|
|
145
|
-
And I type "foo" into the "
|
|
151
|
+
And I run the command DocumentSearch::FindAndReplaceSpeedbarCommand
|
|
152
|
+
And I type "foo" into the "Find" field in the speedbar
|
|
146
153
|
And I type "foobar" into the "Replace" field in the speedbar
|
|
147
|
-
And I press "Replace" in the speedbar
|
|
148
|
-
And I press "Replace" in the speedbar
|
|
149
|
-
And I press "Replace" in the speedbar
|
|
154
|
+
And I press "Replace && Find" in the speedbar
|
|
155
|
+
And I press "Replace && Find" in the speedbar
|
|
156
|
+
And I press "Replace && Find" in the speedbar
|
|
150
157
|
Then the contents should be "foobar\nfoobar\nfoobar"
|
|
151
|
-
And the
|
|
158
|
+
And the selected text should be "foo"
|
|
159
|
+
And the selection should be on line 0
|
|
152
160
|
|
|
153
161
|
Scenario: The Search-and-Replace Speedbar should get initialized with the currently selected text
|
|
154
162
|
When I replace the contents with "Foo\nBar\nFoo"
|
|
155
163
|
And I select from 4 to 7
|
|
156
|
-
When I run the command DocumentSearch::
|
|
157
|
-
Then the "
|
|
164
|
+
When I run the command DocumentSearch::FindAndReplaceSpeedbarCommand
|
|
165
|
+
Then the "Find" field in the speedbar should have text "Bar"
|
|
158
166
|
When I type "Foo" into the "Replace" field in the speedbar
|
|
159
|
-
And I press "Replace" in the speedbar
|
|
167
|
+
And I press "Replace && Find" in the speedbar
|
|
160
168
|
Then the contents should be "Foo\nFoo\nFoo"
|
|
161
169
|
|
|
162
|
-
|
|
@@ -1,103 +1,113 @@
|
|
|
1
1
|
require 'strscan'
|
|
2
|
-
require "document_search/
|
|
3
|
-
require "document_search/
|
|
4
|
-
require "document_search/
|
|
5
|
-
require "document_search/
|
|
2
|
+
require "document_search/query_options"
|
|
3
|
+
require "document_search/commands"
|
|
4
|
+
require "document_search/find_speedbar"
|
|
5
|
+
require "document_search/find_and_replace_speedbar"
|
|
6
6
|
|
|
7
7
|
module DocumentSearch
|
|
8
8
|
def self.menus
|
|
9
9
|
Redcar::Menu::Builder.build do
|
|
10
10
|
sub_menu "Edit" do
|
|
11
|
-
sub_menu "
|
|
12
|
-
item "
|
|
13
|
-
item "
|
|
14
|
-
|
|
11
|
+
sub_menu "Find", :priority => 50 do
|
|
12
|
+
item "Incremental Search", FindMenuCommand
|
|
13
|
+
item "Find...", FindAndReplaceSpeedbarCommand
|
|
14
|
+
separator
|
|
15
|
+
item "Find Next", FindNextMenuCommand
|
|
16
|
+
item "Find Previous", FindPreviousMenuCommand
|
|
17
|
+
item "Replace and Find", ReplaceAndFindMenuCommand
|
|
18
|
+
separator
|
|
19
|
+
item "Use Selection for Find", UseSelectionForFindMenuCommand
|
|
20
|
+
item "Use Selection for Replace", UseSelectionForReplaceMenuCommand
|
|
15
21
|
end
|
|
16
22
|
separator
|
|
17
23
|
end
|
|
18
24
|
end
|
|
19
25
|
end
|
|
20
26
|
|
|
21
|
-
def self.
|
|
22
|
-
Redcar::
|
|
23
|
-
|
|
24
|
-
|
|
27
|
+
def self.keymaps
|
|
28
|
+
osx = Redcar::Keymap.build("main", :osx) do
|
|
29
|
+
link "Ctrl+S", DocumentSearch::FindMenuCommand
|
|
30
|
+
link "Cmd+F", DocumentSearch::FindAndReplaceSpeedbarCommand
|
|
31
|
+
link "Cmd+G", DocumentSearch::FindNextMenuCommand
|
|
32
|
+
link "Cmd+Shift+G", DocumentSearch::FindPreviousMenuCommand
|
|
33
|
+
link "Cmd+Alt+F", DocumentSearch::ReplaceAndFindMenuCommand
|
|
34
|
+
link "Cmd+E", DocumentSearch::UseSelectionForFindMenuCommand
|
|
35
|
+
link "Cmd+Shift+E", DocumentSearch::UseSelectionForReplaceMenuCommand
|
|
25
36
|
end
|
|
26
|
-
end
|
|
27
37
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
38
|
+
linwin = Redcar::Keymap.build("main", [:linux, :windows]) do
|
|
39
|
+
link "Alt+S", DocumentSearch::FindMenuCommand
|
|
40
|
+
link "Ctrl+F", DocumentSearch::FindAndReplaceSpeedbarCommand
|
|
41
|
+
link "Ctrl+G", DocumentSearch::FindNextMenuCommand
|
|
42
|
+
link "Ctrl+Shift+G", DocumentSearch::FindPreviousMenuCommand
|
|
43
|
+
link "Ctrl+E", DocumentSearch::UseSelectionForFindMenuCommand
|
|
44
|
+
link "Alt+E", DocumentSearch::UseSelectionForReplaceMenuCommand
|
|
33
45
|
end
|
|
34
46
|
|
|
35
|
-
|
|
47
|
+
[linwin, osx]
|
|
48
|
+
end
|
|
36
49
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
self.match_case.value = SearchSpeedbar.previous_match_case
|
|
42
|
-
self.query.edit_view.document.select_all
|
|
50
|
+
def self.toolbars
|
|
51
|
+
Redcar::ToolBar::Builder.build do
|
|
52
|
+
item "Find", :command => DocumentSearch::FindMenuCommand, :icon => File.join(Redcar::ICONS_DIRECTORY, "magnifier.png"), :barname => :edit
|
|
53
|
+
item "Find Next", :command => DocumentSearch::FindNextMenuCommand, :icon => File.join(Redcar::ICONS_DIRECTORY, "magnifier--arrow.png"), :barname => :edit
|
|
43
54
|
end
|
|
55
|
+
end
|
|
44
56
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
57
|
+
class FindMenuCommand < Redcar::EditTabCommand
|
|
58
|
+
def execute
|
|
59
|
+
@speedbar = FindSpeedbar.new
|
|
60
|
+
if doc.selection?
|
|
61
|
+
@speedbar.initial_query = doc.selected_text
|
|
62
|
+
end
|
|
63
|
+
win.open_speedbar(@speedbar)
|
|
51
64
|
end
|
|
65
|
+
end
|
|
52
66
|
|
|
53
|
-
|
|
54
|
-
|
|
67
|
+
class FindAndReplaceSpeedbarCommand < Redcar::EditTabCommand
|
|
68
|
+
def execute
|
|
69
|
+
@speedbar = FindAndReplaceSpeedbar.new
|
|
70
|
+
if doc.selection?
|
|
71
|
+
@speedbar.initial_query = doc.selected_text
|
|
72
|
+
end
|
|
73
|
+
win.open_speedbar(@speedbar)
|
|
55
74
|
end
|
|
75
|
+
end
|
|
56
76
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
SearchSpeedbar.previous_is_regex = is_regex.value
|
|
61
|
-
success = SearchSpeedbar.repeat_query
|
|
77
|
+
class FindNextMenuCommand < Redcar::EditTabCommand
|
|
78
|
+
def execute
|
|
79
|
+
FindSpeedbar.find_next
|
|
62
80
|
end
|
|
81
|
+
end
|
|
63
82
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
current_query = Regexp.escape(current_query)
|
|
68
|
-
end
|
|
69
|
-
cmd = FindNextRegex.new(Regexp.new(current_query, !@previous_match_case), true)
|
|
70
|
-
cmd.run_in_focussed_tab_edit_view
|
|
83
|
+
class FindPreviousMenuCommand < Redcar::EditTabCommand
|
|
84
|
+
def execute
|
|
85
|
+
FindSpeedbar.find_previous
|
|
71
86
|
end
|
|
72
87
|
end
|
|
73
88
|
|
|
74
|
-
class
|
|
75
|
-
|
|
89
|
+
class ReplaceAndFindMenuCommand < Redcar::EditTabCommand
|
|
76
90
|
def execute
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
win.open_speedbar(@speedbar)
|
|
91
|
+
FindAndReplaceSpeedbar.replace_and_find(
|
|
92
|
+
FindSpeedbar.previous_query,
|
|
93
|
+
FindAndReplaceSpeedbar.previous_replace,
|
|
94
|
+
FindSpeedbar.previous_options)
|
|
82
95
|
end
|
|
83
96
|
end
|
|
84
97
|
|
|
85
|
-
class
|
|
98
|
+
class UseSelectionForFindMenuCommand < Redcar::EditTabCommand
|
|
86
99
|
def execute
|
|
87
|
-
|
|
100
|
+
FindSpeedbar.use_selection_for_find(doc, win.speedbar)
|
|
88
101
|
end
|
|
89
102
|
end
|
|
90
103
|
|
|
91
|
-
class
|
|
104
|
+
class UseSelectionForReplaceMenuCommand < Redcar::EditTabCommand
|
|
92
105
|
def execute
|
|
93
|
-
|
|
94
|
-
if doc.selection?
|
|
95
|
-
@speedbar.initial_query = doc.selected_text
|
|
96
|
-
end
|
|
97
|
-
win.open_speedbar(@speedbar)
|
|
106
|
+
FindAndReplaceSpeedbar.use_selection_for_replace(doc, win.speedbar)
|
|
98
107
|
end
|
|
99
108
|
end
|
|
100
109
|
|
|
110
|
+
# TODO(yozhipozhi): Figure out if this is still needed.
|
|
101
111
|
class FindNextRegex < Redcar::DocumentCommand
|
|
102
112
|
def initialize(re, wrap=nil)
|
|
103
113
|
@re = re
|
|
@@ -110,8 +120,8 @@ module DocumentSearch
|
|
|
110
120
|
|
|
111
121
|
def execute
|
|
112
122
|
position = doc.cursor_offset
|
|
113
|
-
sc
|
|
114
|
-
sc.pos
|
|
123
|
+
sc = StringScanner.new(doc.get_all_text)
|
|
124
|
+
sc.pos = position
|
|
115
125
|
sc.scan_until(@re)
|
|
116
126
|
|
|
117
127
|
if @wrap and !sc.matched?
|
|
@@ -123,12 +133,19 @@ module DocumentSearch
|
|
|
123
133
|
if sc.matched?
|
|
124
134
|
endoff = sc.pos
|
|
125
135
|
startoff = sc.pos - sc.matched_size
|
|
136
|
+
line = doc.line_at_offset(startoff)
|
|
137
|
+
lineoff = startoff - doc.offset_at_line(line)
|
|
138
|
+
if lineoff < doc.smallest_visible_horizontal_index
|
|
139
|
+
horiz = lineoff
|
|
140
|
+
else
|
|
141
|
+
horiz = endoff - doc.offset_at_line(line)
|
|
142
|
+
end
|
|
126
143
|
doc.set_selection_range(sc.pos, sc.pos - sc.matched_size)
|
|
127
|
-
doc.scroll_to_line(
|
|
144
|
+
doc.scroll_to_line(line)
|
|
145
|
+
doc.scroll_to_horizontal_offset(horiz) if horiz
|
|
128
146
|
return true
|
|
129
147
|
end
|
|
130
148
|
false
|
|
131
149
|
end
|
|
132
150
|
end
|
|
133
|
-
|
|
134
151
|
end
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
module DocumentSearch
|
|
2
|
+
# Utilities for extended search commands.
|
|
3
|
+
module FindCommandMixin
|
|
4
|
+
### QUERY PATTERNS ###
|
|
5
|
+
|
|
6
|
+
# An instance of a search type method: Regular expression
|
|
7
|
+
def query_regex(query, options)
|
|
8
|
+
Regexp.new(query, !options.match_case)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# An instance of a search type method: Plain text search
|
|
12
|
+
def query_plain(query, options)
|
|
13
|
+
query_regex(Regexp.escape(query), options)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# An instance of a search type method: Glob text search
|
|
17
|
+
# Converts a glob pattern (* or ?) into a regex pattern
|
|
18
|
+
def query_glob(query, options)
|
|
19
|
+
# convert the glob pattern to a regex pattern
|
|
20
|
+
new_query = ""
|
|
21
|
+
query.each_char do |c|
|
|
22
|
+
case c
|
|
23
|
+
when "*"
|
|
24
|
+
new_query << ".*"
|
|
25
|
+
when "?"
|
|
26
|
+
new_query << "."
|
|
27
|
+
else
|
|
28
|
+
new_query << Regexp.escape(c)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
query_regex(new_query, options)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
### SELECTION ###
|
|
35
|
+
|
|
36
|
+
# Selects the first match of query, starting from the start_pos.
|
|
37
|
+
def select_next_match(doc, start_pos, query, wrap_around)
|
|
38
|
+
scanner = StringScanner.new(doc.get_all_text)
|
|
39
|
+
scanner.pos = start_pos
|
|
40
|
+
if not scanner.scan_until(query)
|
|
41
|
+
if not wrap_around
|
|
42
|
+
return false
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
scanner.reset
|
|
46
|
+
if not scanner.scan_until(query)
|
|
47
|
+
return false
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
selection_pos = scanner.pos - scanner.matched_size
|
|
52
|
+
select_range(selection_pos, scanner.pos)
|
|
53
|
+
true
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Selects the match that first precedes the search position.
|
|
57
|
+
#
|
|
58
|
+
# The current implementation is brain-dead, but works: the document is scanned from the start
|
|
59
|
+
# up to the search position, retaining the most recent match. Many smarter, but more
|
|
60
|
+
# complicated strategies are possible; the best would be full reversal of the query regex, but
|
|
61
|
+
# that obviously has a lot of tricky aspects to it.
|
|
62
|
+
def select_previous_match(doc, search_pos, query, wrap_around)
|
|
63
|
+
previous_match = nil
|
|
64
|
+
scanner = StringScanner.new(doc.get_all_text)
|
|
65
|
+
scanner.pos = 0
|
|
66
|
+
while scanner.scan_until(query)
|
|
67
|
+
start_pos = scanner.pos - scanner.matched_size
|
|
68
|
+
if start_pos < search_pos
|
|
69
|
+
previous_match = [start_pos, scanner.pos]
|
|
70
|
+
elsif previous_match
|
|
71
|
+
select_range(*previous_match)
|
|
72
|
+
return true
|
|
73
|
+
elsif not wrap_around
|
|
74
|
+
return false
|
|
75
|
+
else
|
|
76
|
+
break
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Find the last match in the document.
|
|
81
|
+
while scanner.scan_until(query)
|
|
82
|
+
start_pos = scanner.pos - scanner.matched_size
|
|
83
|
+
previous_match = [start_pos, scanner.pos]
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
if previous_match
|
|
87
|
+
select_range(*previous_match)
|
|
88
|
+
return true
|
|
89
|
+
else
|
|
90
|
+
return false
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Replaces the current selection, if it matches the query completely.
|
|
95
|
+
def replace_selection_if_match(doc, start_pos, query, replace)
|
|
96
|
+
scanner = StringScanner.new(doc.selected_text)
|
|
97
|
+
scanner.check(query)
|
|
98
|
+
if (not scanner.matched?) || (scanner.matched_size != doc.selected_text.length)
|
|
99
|
+
return 0
|
|
100
|
+
end
|
|
101
|
+
matched_text = doc.get_range(start_pos, scanner.matched_size)
|
|
102
|
+
replacement_text = matched_text.gsub(query, replace)
|
|
103
|
+
doc.replace(start_pos, scanner.matched_size, replacement_text)
|
|
104
|
+
replacement_text.length
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Selects the specified range and scrolls to the start.
|
|
108
|
+
def select_range(start, stop)
|
|
109
|
+
line = doc.line_at_offset(start)
|
|
110
|
+
lineoff = start - doc.offset_at_line(line)
|
|
111
|
+
if lineoff < doc.smallest_visible_horizontal_index
|
|
112
|
+
horiz = lineoff
|
|
113
|
+
else
|
|
114
|
+
horiz = stop - doc.offset_at_line(line)
|
|
115
|
+
end
|
|
116
|
+
doc.set_selection_range(start, stop)
|
|
117
|
+
doc.scroll_to_line(line)
|
|
118
|
+
doc.scroll_to_horizontal_offset(horiz) if horiz
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
# Base class for find commands.
|
|
124
|
+
class FindCommandBase < Redcar::DocumentCommand
|
|
125
|
+
include FindCommandMixin
|
|
126
|
+
|
|
127
|
+
attr_reader :query
|
|
128
|
+
|
|
129
|
+
# description here
|
|
130
|
+
def initialize(query, options)
|
|
131
|
+
@options = options
|
|
132
|
+
@query = send(options.query_type, query, options)
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
# Finds the next match after the current location.
|
|
138
|
+
class FindIncrementalCommand < FindCommandBase
|
|
139
|
+
def execute
|
|
140
|
+
offsets = [doc.cursor_offset, doc.selection_offset]
|
|
141
|
+
start_pos = offsets.min
|
|
142
|
+
if select_next_match(doc, start_pos, query, @options.wrap_around)
|
|
143
|
+
true
|
|
144
|
+
else
|
|
145
|
+
# Clear selection as visual feedback that search failed.
|
|
146
|
+
doc.set_selection_range(start_pos, start_pos)
|
|
147
|
+
false
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
# Finds the next match after the current location.
|
|
154
|
+
class FindNextCommand < FindCommandBase
|
|
155
|
+
def execute
|
|
156
|
+
offsets = [doc.cursor_offset, doc.selection_offset]
|
|
157
|
+
start_pos = offsets.max
|
|
158
|
+
if select_next_match(doc, start_pos, query, @options.wrap_around)
|
|
159
|
+
true
|
|
160
|
+
else
|
|
161
|
+
# Clear selection as visual feedback that search failed.
|
|
162
|
+
doc.set_selection_range(start_pos, start_pos)
|
|
163
|
+
false
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
# Finds the previous match before the current location.
|
|
170
|
+
class FindPreviousCommand < FindCommandBase
|
|
171
|
+
def execute
|
|
172
|
+
offsets = [doc.cursor_offset, doc.selection_offset]
|
|
173
|
+
start_pos = offsets.min
|
|
174
|
+
if select_previous_match(doc, start_pos, query, @options.wrap_around)
|
|
175
|
+
true
|
|
176
|
+
else
|
|
177
|
+
# Clear selection as visual feedback that search failed.
|
|
178
|
+
doc.set_selection_range(start_pos, start_pos)
|
|
179
|
+
false
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
# Base class for replace commands.
|
|
186
|
+
class ReplaceCommandBase < Redcar::DocumentCommand
|
|
187
|
+
include FindCommandMixin
|
|
188
|
+
|
|
189
|
+
attr_reader :query, :replace
|
|
190
|
+
|
|
191
|
+
# description here
|
|
192
|
+
def initialize(query, replace, options)
|
|
193
|
+
@options = options
|
|
194
|
+
@query = send(options.query_type, query, options)
|
|
195
|
+
@replace = replace
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
# Replaces the currently selected text, if it matches the search criteria, then finds and
|
|
201
|
+
# selects the next match in the document.
|
|
202
|
+
#
|
|
203
|
+
# This command maintains the invariant that no text is replaced without first being selected, so
|
|
204
|
+
# the user always knows exactly what change is about to be made. A ramification of this policy
|
|
205
|
+
# is that, if no text is selected beforehand, or the selected text does not match the query,
|
|
206
|
+
# then "replace" portion of "replace and find" is essentially skipped, so that two button
|
|
207
|
+
# presses are required.
|
|
208
|
+
class ReplaceAndFindCommand < ReplaceCommandBase
|
|
209
|
+
def execute
|
|
210
|
+
offsets = [doc.cursor_offset, doc.selection_offset]
|
|
211
|
+
start_pos = offsets.min
|
|
212
|
+
if doc.selected_text.length > 0
|
|
213
|
+
chars_replaced = replace_selection_if_match(doc, start_pos, query, replace)
|
|
214
|
+
if chars_replaced > 0
|
|
215
|
+
start_pos += chars_replaced
|
|
216
|
+
else
|
|
217
|
+
start_pos = offsets.max
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
if select_next_match(doc, start_pos, query, @options.wrap_around)
|
|
221
|
+
true
|
|
222
|
+
else
|
|
223
|
+
# Clear selection as visual feedback that search failed.
|
|
224
|
+
doc.set_selection_range(start_pos, start_pos)
|
|
225
|
+
false
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
# Replaces all query matches.
|
|
232
|
+
class ReplaceAllCommand < ReplaceCommandBase
|
|
233
|
+
def execute
|
|
234
|
+
startoff, endoff = nil
|
|
235
|
+
text = doc.get_all_text
|
|
236
|
+
count = 0
|
|
237
|
+
sc = StringScanner.new(text)
|
|
238
|
+
while sc.scan_until(query)
|
|
239
|
+
count += 1
|
|
240
|
+
|
|
241
|
+
startoff = sc.pos - sc.matched_size
|
|
242
|
+
replacement_text = text.slice(startoff, sc.matched_size).gsub(query, replace)
|
|
243
|
+
endoff = startoff + replacement_text.length
|
|
244
|
+
|
|
245
|
+
text[startoff...sc.pos] = replacement_text
|
|
246
|
+
sc.string = text
|
|
247
|
+
sc.pos = startoff + replacement_text.length
|
|
248
|
+
end
|
|
249
|
+
if count > 0
|
|
250
|
+
doc.text = text
|
|
251
|
+
select_range(startoff + replacement_text.length, startoff)
|
|
252
|
+
true
|
|
253
|
+
else
|
|
254
|
+
false
|
|
255
|
+
end
|
|
256
|
+
end
|
|
257
|
+
end
|
|
258
|
+
end
|