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
@@ -0,0 +1,202 @@
1
+
2
+ require 'java'
3
+
4
+ require File.join(File.dirname(__FILE__), *%w".. spec_helper")
5
+
6
+ TaskQueue = Redcar::TaskQueue
7
+ Task = Redcar::Task
8
+
9
+ describe TaskQueue do
10
+ before do
11
+ $started_tasks = []
12
+ @q = TaskQueue.new
13
+ end
14
+
15
+ after do
16
+ @q.stop
17
+ end
18
+
19
+ describe "running tasks" do
20
+ it "should accept tasks and call them" do
21
+ @q.submit(QuickTask.new(101)).get
22
+ $started_tasks.should == [101]
23
+ end
24
+
25
+ it "should call tasks in order" do
26
+ @q.submit(QuickTask.new(101))
27
+ @q.submit(QuickTask.new(102))
28
+ @q.submit(QuickTask.new(103)).get
29
+ $started_tasks.should == [101, 102, 103]
30
+ end
31
+
32
+ it "should return the result of the Task execute method" do
33
+ @q.submit(QuickTask.new(103)).get.should == :hiho
34
+ end
35
+ end
36
+
37
+ describe "cancelling tasks" do
38
+ before do
39
+ $wait_task_finish = false
40
+ end
41
+
42
+ class WaitTask < QuickTask
43
+ def execute
44
+ super
45
+ 1 until $wait_task_finish
46
+ end
47
+ end
48
+
49
+ it "can be cancelled" do
50
+ @q.submit(QuickTask.new(101))
51
+ @q.submit(WaitTask.new(102))
52
+ @q.submit(task = QuickTask.new(103))
53
+ task.cancel
54
+ $wait_task_finish = true
55
+ sleep 0.1
56
+ $started_tasks.should == [101, 102]
57
+ @q.pending.should be_empty
58
+ task.should be_cancelled
59
+ end
60
+
61
+ it "can cancel all pending tasks" do
62
+ @q.submit(WaitTask.new(102))
63
+ @q.submit(task1 = QuickTask.new(103))
64
+ @q.submit(task2 = QuickTask.new(104))
65
+ 1 until $started_tasks.include?(102)
66
+ @q.cancel_all
67
+ $wait_task_finish = true
68
+ $started_tasks.should == [102]
69
+ end
70
+ end
71
+
72
+ describe "information" do
73
+ describe "about pending tasks" do
74
+ it "should tell you about tasks that have not been started yet" do
75
+ @q.submit(t1 = BlockingTask.new(:a))
76
+ @q.submit(t2 = BlockingTask.new(:b))
77
+ @q.pending.include?(t2).should be_true
78
+ end
79
+
80
+ it "should not include in process tasks" do
81
+ @q.submit(t1 = BlockingTask.new(:a))
82
+ @q.submit(t2 = BlockingTask.new(:b))
83
+ 1 until $started_tasks.include?(:a)
84
+ @q.pending.include?(t1).should be_false
85
+ end
86
+
87
+ it "should not include completed tasks" do
88
+ @q.submit(t1 = QuickTask.new(:a))
89
+ @q.submit(t2 = BlockingTask.new(:b))
90
+ 1 until $started_tasks.include?(:b)
91
+ @q.pending.include?(t1).should be_false
92
+ end
93
+
94
+ it "should tell you when it was enqueued" do
95
+ @q.submit(t1 = QuickTask.new(:a))
96
+ t1.enqueue_time.should be_an_instance_of(Time)
97
+ end
98
+
99
+ it "should tell you it is pending" do
100
+ @q.submit(t1 = BlockingTask.new(:a))
101
+ @q.submit(t2 = BlockingTask.new(:b))
102
+ 1 until $started_tasks.include?(:a)
103
+ t2.should be_pending
104
+ t2.should_not be_completed
105
+ t2.should_not be_in_process
106
+ end
107
+ end
108
+
109
+ describe "in process tasks" do
110
+ it "should tell you which task is in process" do
111
+ @q.submit(t1 = BlockingTask.new(:a))
112
+ 1 until $started_tasks.include?(:a)
113
+ @q.in_process.should == t1
114
+ end
115
+
116
+ it "should tell you when it was started" do
117
+ @q.submit(t1 = BlockingTask.new(:a))
118
+ 1 until $started_tasks.include?(:a)
119
+ t1.start_time.should be_an_instance_of(Time)
120
+ end
121
+
122
+ it "should tell you they are in process" do
123
+ @q.submit(t1 = BlockingTask.new(:a))
124
+ 1 until $started_tasks.include?(:a)
125
+ t1.should be_in_process
126
+ t1.should_not be_pending
127
+ t1.should_not be_completed
128
+ end
129
+ end
130
+
131
+ describe "completed tasks" do
132
+ it "should tell you which tasks have completed" do
133
+ @q.submit(t1 = QuickTask.new(:a))
134
+ @q.submit(t2 = BlockingTask.new(:b))
135
+ 1 until $started_tasks.include?(:b)
136
+ @q.completed.include?(t1).should be_true
137
+ end
138
+
139
+ it "should not include in process tasks" do
140
+ @q.submit(t1 = QuickTask.new(:a))
141
+ @q.submit(t2 = BlockingTask.new(:b))
142
+ 1 until $started_tasks.include?(:b)
143
+ @q.completed.include?(t2).should be_false
144
+ end
145
+
146
+ it "should not include in pending tasks" do
147
+ @q.submit(t1 = QuickTask.new(:a))
148
+ @q.submit(t2 = BlockingTask.new(:b))
149
+ @q.submit(t3 = BlockingTask.new(:c))
150
+ 1 until $started_tasks.include?(:b)
151
+ @q.completed.include?(t3).should be_false
152
+ end
153
+
154
+ it "should tell you when it was completed" do
155
+ @q.submit(t1 = QuickTask.new(:a))
156
+ @q.submit(t2 = BlockingTask.new(:b))
157
+ 1 until $started_tasks.include?(:b)
158
+ t1.completed_time.should be_an_instance_of(Time)
159
+ end
160
+
161
+ it "should tell you they are completed" do
162
+ @q.submit(t1 = QuickTask.new(:a))
163
+ @q.submit(t2 = BlockingTask.new(:b))
164
+ 1 until $started_tasks.include?(:b)
165
+ t1.should be_completed
166
+ t1.should_not be_pending
167
+ t1.should_not be_in_process
168
+ end
169
+ end
170
+ end
171
+
172
+ describe "errored tasks" do
173
+ class ErrorTask < QuickTask
174
+ def execute
175
+ $started_tasks << @id
176
+ raise 'error'
177
+ end
178
+ end
179
+
180
+ it "should be in completed task list" do
181
+ @q.submit(t1 = ErrorTask.new(:a))
182
+ @q.submit(t2 = BlockingTask.new(:b))
183
+ 1 until $started_tasks.include?(:b)
184
+ @q.completed.should == [t1]
185
+ end
186
+
187
+ it "should have the error" do
188
+ @q.submit(t1 = ErrorTask.new(:a))
189
+ @q.submit(t2 = BlockingTask.new(:b))
190
+ 1 until $started_tasks.include?(:b)
191
+ @q.completed.first.error.should be_an_instance_of(RuntimeError)
192
+ end
193
+ end
194
+ end
195
+
196
+
197
+
198
+
199
+
200
+
201
+
202
+
@@ -2,4 +2,26 @@ $:.push File.join(File.dirname(__FILE__), '..', '..', '..', 'lib')
2
2
 
3
3
  require 'redcar'
4
4
  Redcar.environment = :test
5
- Redcar.load
5
+ Redcar.load
6
+
7
+ class QuickTask < Redcar::Task
8
+ def initialize(id=nil)
9
+ @id = id
10
+ end
11
+
12
+ def execute
13
+ $started_tasks << @id
14
+ :hiho
15
+ end
16
+
17
+ def inspect
18
+ "<#{self.class} #{@id}>"
19
+ end
20
+ end
21
+
22
+ class BlockingTask < QuickTask
23
+ def execute
24
+ $started_tasks << @id
25
+ loop { break if java.lang.Thread.interrupted }
26
+ end
27
+ end
@@ -0,0 +1,3 @@
1
+ * automagicaly match word under cursor
2
+ * automagically update tags file (watchr / gtags)
3
+ * automagically create tags file? (when shift+ctrl+T pressed first time)
@@ -0,0 +1,144 @@
1
+
2
+ require 'declarations/completion_source'
3
+ require 'declarations/file'
4
+ require 'declarations/parser'
5
+ require 'declarations/select_tag_dialog'
6
+ require 'tempfile'
7
+
8
+ module Redcar
9
+ class Declarations
10
+ def self.menus
11
+ Menu::Builder.build do
12
+ sub_menu "Project" do
13
+ item "Go to declaration", Declarations::GoToTagCommand
14
+ end
15
+ end
16
+ end
17
+
18
+ def self.keymaps
19
+ linwin = Keymap.build("main", [:linux, :windows]) do
20
+ link "Ctrl+G", Declarations::GoToTagCommand
21
+ end
22
+
23
+ osx = Keymap.build("main", :osx) do
24
+ link "Cmd+G", Declarations::GoToTagCommand
25
+ end
26
+
27
+ [linwin, osx]
28
+ end
29
+
30
+ def self.autocompletion_source_types
31
+ [] #[Declarations::CompletionSource]
32
+ end
33
+
34
+ def self.file_path(project)
35
+ ::File.join(project.path, 'tags')
36
+ end
37
+
38
+ class ProjectRefresh < Task
39
+ def initialize(project)
40
+ @file_list = project.file_list
41
+ @project = project
42
+ end
43
+
44
+ def description
45
+ "#{@project.path}: reparse files for declarations"
46
+ end
47
+
48
+ def execute
49
+ file = Declarations::File.new(Declarations.file_path(@project))
50
+ file.update_files(@file_list)
51
+ file.dump
52
+ Declarations.clear_tags_for_path(file.path)
53
+ end
54
+ end
55
+
56
+ def self.project_refresh_task_type
57
+ ProjectRefresh
58
+ end
59
+
60
+ def self.tags_for_path(path)
61
+ @tags_for_path ||= {}
62
+ @tags_for_path[path] ||= begin
63
+ tags = {}
64
+ ::File.read(path).each_line do |line|
65
+ key, file, *match = line.split("\t")
66
+ if [key, file, match].all? { |el| !el.nil? && !el.empty? }
67
+ tags[key] ||= []
68
+ tags[key] << { :file => file, :match => match.join("\t").chomp }
69
+ end
70
+ end
71
+ tags
72
+ rescue Errno::ENOENT
73
+ {}
74
+ end
75
+ end
76
+
77
+ def self.clear_tags_for_path(path)
78
+ @tags_for_path ||= {}
79
+ @tags_for_path.delete(path)
80
+ end
81
+
82
+ def self.go_to_definition(match)
83
+ path = match[:file]
84
+ Project::Manager.open_file(path)
85
+ regexp = Regexp.new(Regexp.escape(match[:match]))
86
+ Redcar::Top::FindNextRegex.new(regexp, true).run
87
+ end
88
+
89
+ class GoToTagCommand < EditTabCommand
90
+
91
+ def execute
92
+ if doc.selection?
93
+ handle_tag(doc.selected_text)
94
+ else
95
+ line = doc.get_line(doc.cursor_line)
96
+ left = doc.cursor_line_offset - 1
97
+ right = doc.cursor_line_offset
98
+ left_range = 0
99
+ right_range = 0
100
+ offset = doc.cursor_offset
101
+
102
+ until left == -1 || AutoCompleter::WORD_CHARACTERS !~ (line[left].chr)
103
+ left -= 1
104
+ left_range -= 1
105
+ end
106
+ until right == line.length || AutoCompleter::WORD_CHARACTERS !~ (line[right].chr)
107
+ right += 1
108
+ right_range += 1
109
+ end
110
+ handle_tag(doc.get_slice(doc.cursor_offset+left_range, doc.cursor_offset+right_range))
111
+ end
112
+ end
113
+
114
+ def handle_tag(token = '')
115
+ tags_path = Declarations.file_path(Project::Manager.focussed_project)
116
+ unless ::File.exist?(tags_path)
117
+ Application::Dialog.message_box("The declarations file 'tags' has not been generated yet.")
118
+ return
119
+ end
120
+ matches = find_tag(tags_path, token)
121
+ case matches.size
122
+ when 0
123
+ Application::Dialog.message_box("There is no declaration for '#{token}' in the 'tags' file.")
124
+ when 1
125
+ Redcar::Declarations.go_to_definition(matches.first)
126
+ else
127
+ open_select_tag_dialog(matches)
128
+ end
129
+ end
130
+
131
+ def find_tag(tags_path, tag)
132
+ Declarations.tags_for_path(tags_path)[tag] || []
133
+ end
134
+
135
+ def open_select_tag_dialog(matches)
136
+ Declarations::SelectTagDialog.new(matches).open
137
+ end
138
+
139
+ def log(message)
140
+ puts("==> Ctags: #{message}")
141
+ end
142
+ end
143
+ end
144
+ end
@@ -0,0 +1,22 @@
1
+ module Redcar
2
+ class Declarations
3
+ class CompletionSource
4
+ def initialize(_, project)
5
+ @project = project
6
+ end
7
+
8
+ def alternatives(prefix)
9
+ if @project
10
+ word_list = AutoCompleter::WordList.new
11
+ tags = Declarations.tags_for_path(Declarations.file_path(@project))
12
+ tags.keys.each do |tag|
13
+ if tag[0..(prefix.length-1)] == prefix
14
+ word_list.add_word(tag, 10000)
15
+ end
16
+ end
17
+ word_list
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,68 @@
1
+
2
+ module Redcar
3
+ class Declarations
4
+ class File
5
+ attr_reader :tags, :path
6
+ attr_accessor :last_updated
7
+
8
+ def initialize(path)
9
+ @path = path
10
+ @tags = []
11
+ load
12
+ end
13
+
14
+ def load
15
+ @tags = []
16
+ @last_updated = Time.at(0)
17
+ if ::File.exist?(path)
18
+ first_line = true
19
+ ::File.read(path).each_line do |line|
20
+ if first_line
21
+ first_line = false
22
+ @last_updated = Time.at(line.chomp.to_i)
23
+ end
24
+ key, path, *match = line.split("\t")
25
+ if [key, path, match].all? { |el| !el.nil? && !el.empty? }
26
+ @tags << [key, path, match.join("\t").chomp]
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ def update_files(file_list)
33
+ changed_files = file_list.changed_since(last_updated)
34
+ changed_files.delete(@path)
35
+ @tags = @tags.select do |_, path, _|
36
+ file_list.contains?(path) and !changed_files[path]
37
+ end
38
+ add_tags_for_paths(changed_files.keys)
39
+ @last_updated = Time.now
40
+ end
41
+
42
+ def add_tags_for_paths(add_paths)
43
+ parser = Declarations::Parser.new
44
+ parser.parse(add_paths)
45
+ add_tags(parser.tags)
46
+ end
47
+
48
+ def add_tags(tags)
49
+ @tags += tags
50
+ end
51
+
52
+ def dump
53
+ @tags.sort!
54
+ tags_file_path = nil
55
+ Tempfile.open('tags') do |tags_file|
56
+ tags_file.puts(@last_updated.to_i.to_s)
57
+ @tags.each do |id, path, declaration|
58
+ tags_file.puts "#{id}\t#{path}\t#{declaration}"
59
+ end
60
+ tags_file.flush
61
+ tags_file_path = tags_file.path
62
+ end
63
+ FileUtils.cp(tags_file_path, path)
64
+ FileUtils.rm(tags_file_path)
65
+ end
66
+ end
67
+ end
68
+ end