ruber 0.0.8 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. data/CHANGES +21 -0
  2. data/data/share/apps/ruber/ruberui.rc +3 -1
  3. data/lib/ruber/application/application.rb +22 -23
  4. data/lib/ruber/application/plugin.yaml +7 -2
  5. data/lib/ruber/{projects → application}/project_files_list.rb +0 -0
  6. data/lib/ruber/{projects → application}/project_files_widget.rb +0 -0
  7. data/lib/ruber/application/ui/project_files_rule_chooser_widget.rb +74 -0
  8. data/lib/ruber/{projects → application}/ui/project_files_rule_chooser_widget.ui +0 -0
  9. data/lib/ruber/application/ui/project_files_widget.rb +117 -0
  10. data/lib/ruber/{projects → application}/ui/project_files_widget.ui +0 -0
  11. data/lib/ruber/component_manager.rb +14 -9
  12. data/lib/ruber/editor/document.rb +35 -5
  13. data/lib/ruber/kde_sugar.rb +16 -0
  14. data/lib/ruber/main_window/choose_plugins_dlg.rb +7 -4
  15. data/lib/ruber/main_window/main_window.rb +131 -193
  16. data/lib/ruber/main_window/main_window_actions.rb +157 -58
  17. data/lib/ruber/main_window/main_window_internal.rb +145 -54
  18. data/lib/ruber/main_window/open_file_in_project_dlg.rb +4 -4
  19. data/lib/ruber/main_window/plugin.yaml +3 -6
  20. data/lib/ruber/main_window/ui/workspace_settings_widget.rb +2 -2
  21. data/lib/ruber/main_window/workspace.rb +62 -32
  22. data/lib/ruber/output_widget.rb +20 -16
  23. data/lib/ruber/pane.rb +11 -5
  24. data/lib/ruber/project.rb +27 -12
  25. data/lib/ruber/projects/ui/project_files_rule_chooser_widget.rb +2 -2
  26. data/lib/ruber/projects/ui/project_files_widget.rb +2 -2
  27. data/lib/ruber/utils.rb +37 -4
  28. data/lib/ruber/version.rb +1 -1
  29. data/lib/ruber/world/document_factory.rb +121 -0
  30. data/lib/ruber/world/document_list.rb +396 -0
  31. data/lib/ruber/world/environment.rb +470 -0
  32. data/lib/ruber/{main_window → world}/hint_solver.rb +1 -1
  33. data/lib/ruber/world/plugin.yaml +11 -0
  34. data/lib/ruber/world/project_factory.rb +131 -0
  35. data/lib/ruber/world/project_list.rb +265 -0
  36. data/lib/ruber/world/ui/workspace_settings_widget.rb +51 -0
  37. data/lib/ruber/{main_window → world}/ui/workspace_settings_widget.ui +0 -0
  38. data/lib/ruber/world/world.rb +307 -0
  39. data/plugins/auto_end/auto_end.rb +135 -9
  40. data/plugins/autosave/autosave.rb +4 -4
  41. data/plugins/find_in_files/find_in_files.rb +5 -5
  42. data/plugins/find_in_files/find_in_files_widgets.rb +1 -1
  43. data/plugins/project_browser/project_browser.rb +4 -4
  44. data/plugins/rake/rake.rb +4 -4
  45. data/plugins/rake/rake_extension.rb +1 -1
  46. data/plugins/rspec/rspec.rb +4 -4
  47. data/plugins/rspec/ruber_rspec_formatter.rb +2 -2
  48. data/plugins/ruby_development/ruby_development.rb +3 -3
  49. data/plugins/ruby_runner/ruby_runner.rb +2 -2
  50. data/plugins/state/plugin.yaml +6 -8
  51. data/plugins/state/state.rb +201 -391
  52. data/plugins/state/ui/config_widget.rb +5 -5
  53. data/plugins/state/ui/config_widget.ui +3 -3
  54. data/plugins/syntax_checker/syntax_checker.rb +4 -0
  55. data/spec/annotation_model_spec.rb +1 -1
  56. data/spec/auto_end_spec.rb +98 -47
  57. data/spec/component_manager_spec.rb +80 -21
  58. data/spec/document_factory_spec.rb +115 -0
  59. data/spec/document_list_spec.rb +560 -450
  60. data/spec/document_spec.rb +143 -55
  61. data/spec/editor_view_spec.rb +2 -2
  62. data/spec/environment_spec.rb +1900 -0
  63. data/spec/hint_solver_spec.rb +5 -5
  64. data/spec/kde_sugar_spec.rb +16 -0
  65. data/spec/output_widget_spec.rb +177 -51
  66. data/spec/pane_spec.rb +29 -5
  67. data/spec/plugin_spec.rb +1 -1
  68. data/spec/project_factory_spec.rb +104 -0
  69. data/spec/project_list_spec.rb +352 -447
  70. data/spec/project_spec.rb +34 -33
  71. data/spec/qt_sugar_spec.rb +2 -2
  72. data/spec/state_spec.rb +508 -811
  73. data/spec/utils_spec.rb +149 -98
  74. data/spec/workspace_spec.rb +120 -9
  75. data/spec/world_spec.rb +1219 -0
  76. metadata +23 -14
  77. data/lib/ruber/documents/document_list.rb +0 -412
  78. data/lib/ruber/documents/plugin.yaml +0 -4
  79. data/lib/ruber/main_window/view_manager.rb +0 -431
  80. data/lib/ruber/projects/plugin.yaml +0 -11
  81. data/lib/ruber/projects/project_list.rb +0 -314
@@ -1,5 +1,5 @@
1
1
  module Ruber
2
2
 
3
- VERSION = '0.0.8'
3
+ VERSION = '0.0.9'
4
4
 
5
5
  end
@@ -0,0 +1,121 @@
1
+ =begin
2
+ Copyright (C) 2011 by Stefano Crocco
3
+ stefano.crocco@alice.it
4
+
5
+ This program is free software; you can redistribute it andor modify
6
+ it under the terms of the GNU General Public License as published by
7
+ the Free Software Foundation; either version 2 of the License, or
8
+ (at your option) any later version.
9
+
10
+ This program is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ GNU General Public License for more details.
14
+
15
+ You should have received a copy of the GNU General Public License
16
+ along with this program; if not, write to the
17
+ Free Software Foundation, Inc.,
18
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
+ =end
20
+
21
+ require 'ruber/editor/document'
22
+
23
+ module Ruber
24
+
25
+ module World
26
+
27
+ =begin rdoc
28
+ Factory class to create documents
29
+
30
+ It ensures that at all times there's only a single document associated with a
31
+ given file.
32
+
33
+ @note in the documentation, whenever a file name is mentioned, it can be replaced
34
+ by a @KDE::Url@.
35
+ =end
36
+ class DocumentFactory < Qt::Object
37
+
38
+ signals 'document_created(QObject*)'
39
+
40
+ =begin rdoc
41
+ @param [Qt::Object,nil] parent the parent object
42
+ =end
43
+ def initialize parent = nil
44
+ super
45
+ @documents = {}
46
+ end
47
+
48
+ =begin rdoc
49
+ Returns a document, creating it if needed
50
+
51
+ If a file name is specified, a document for that file will be returned.
52
+ If a document for that file name already exists, it will be returned. Otherwise, a new
53
+ document will be created.
54
+
55
+ If no file or URL is given, a new document (not associated with a file) is returned.
56
+ @param [String,KDE::Url,nil] file if not nil, the absolute name or the URL of the
57
+ file to retrieve the document for. If *nil*, a new document not associated with
58
+ any file will be created
59
+ @param [Qt::Object,nil] parent the object the document should be child of. If *nil*,
60
+ the document will be parentless
61
+ @return [Document,nil] a document associated with _file_ or a new document not
62
+ associated with a file if _file_ is *nil*. If _file_ represents a local file
63
+ and that file doesn't exist, *nil* is returned
64
+ =end
65
+ def document file, parent = nil
66
+ if file
67
+ url = KDE::Url.new file
68
+ return if url.local_file? and !File.exist?(url.path)
69
+ doc = @documents[url]
70
+ doc || create_document(file, parent)
71
+ else create_document nil, parent
72
+ end
73
+ end
74
+
75
+ private
76
+
77
+ =begin rdoc
78
+ Slot called whenever a document is closed
79
+
80
+ It ensures that the document is removed from the internal document list
81
+ @param [Document] doc the document being closed
82
+ =end
83
+ def document_closed doc
84
+ @documents.delete doc.url
85
+ end
86
+ slots 'document_closed(QObject*)'
87
+
88
+ =begin rdoc
89
+ Slot called whenever a document's URL changes
90
+
91
+ It updates the internal list of documents
92
+ @param [Document] doc the document whose URL has changed
93
+ =end
94
+ def document_url_changed doc
95
+ @documents.reject!{|k, v| v == doc}
96
+ @documents[doc.url] = doc
97
+ end
98
+ slots 'document_url_changed(QObject*)'
99
+
100
+ =begin rdoc
101
+ Creates a new document
102
+
103
+ After creating the document, makes all the necessary signal-slot connections with
104
+ it and adds it to the internal document list if needed
105
+ @param (see Ruber::World::DocumentFactory#document)
106
+ @return [Ruber::Document] the new document
107
+ =end
108
+ def create_document file, parent
109
+ doc = Document.new file, parent
110
+ @documents[doc.url] = doc if file
111
+ connect doc, SIGNAL('closing(QObject*)'), self, SLOT('document_closed(QObject*)')
112
+ connect doc, SIGNAL('document_url_changed(QObject*)'), self, SLOT('document_url_changed(QObject*)')
113
+ emit document_created(doc)
114
+ doc
115
+ end
116
+
117
+ end
118
+
119
+ end
120
+
121
+ end
@@ -0,0 +1,396 @@
1
+ =begin
2
+ Copyright (C) 2011 by Stefano Crocco
3
+ stefano.crocco@alice.it
4
+
5
+ This program is free software; you can redistribute it andor modify
6
+ it under the terms of the GNU General Public License as published by
7
+ the Free Software Foundation; either version 2 of the License, or
8
+ (at your option) any later version.
9
+
10
+ This program is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ GNU General Public License for more details.
14
+
15
+ You should have received a copy of the GNU General Public License
16
+ along with this program; if not, write to the
17
+ Free Software Foundation, Inc.,
18
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
+ =end
20
+
21
+ module Ruber
22
+
23
+ module World
24
+
25
+ =begin rdoc
26
+ A list of documents
27
+
28
+ It's an immutable @Enumerable@ class with some convenience methods for dealing
29
+ with documents.
30
+
31
+ The documents in the list are set in the constructor and can't be changed later.
32
+ =end
33
+ class DocumentList
34
+
35
+ include Enumerable
36
+
37
+ =begin rdoc
38
+ @param [Array<Document>, DocumentList] docs the documents to insert in the
39
+ list when created. If it's a {DocumentList}, changes to _docs_ will be
40
+ reflected by the newly created object. This won't happen if _docs_ is an array
41
+ =end
42
+ def initialize docs = []
43
+ @documents = docs.is_a?(DocumentList) ? docs.document_array : docs.dup
44
+ end
45
+
46
+ =begin rdoc
47
+ Iterates on the documents
48
+
49
+ @overload each{|doc| }
50
+ Calls the block once for each document in the list, in insertion order
51
+ @yieldparam [Ruber::Document] doc the documents in the list
52
+ @return [DocumentList] *self*
53
+ @overload each
54
+ @return [Enumerator] an enumerator which iterates on the documents
55
+ @return [DocumentList,Enumerator]
56
+ =end
57
+ def each &blk
58
+ if block_given?
59
+ @documents.each &blk
60
+ self
61
+ else self.to_enum
62
+ end
63
+ end
64
+
65
+ =begin rdoc
66
+ @return [Integer] the number of documents in the list
67
+ =end
68
+ def size
69
+ @documents.size
70
+ end
71
+
72
+ =begin rdoc
73
+ Whether or not the list is empty
74
+ @return [Boolean] *true* if the list is empty and *false* otherwise
75
+ =end
76
+ def empty?
77
+ @documents.empty?
78
+ end
79
+
80
+ =begin rdoc
81
+ Element access
82
+ @overload [] idx
83
+ Returns the document at a given position
84
+ @param [Integer] idx the index of the document to return. If negative, elements
85
+ are counted from the end of the list
86
+ @return [Document,nil] the document at position _idx_ or *nil* if _idx_ is out
87
+ of range
88
+ @overload [] range
89
+ Returns an array containing the documents in the given range of indexes
90
+ @param [Range] range the range of indexes of the documents to return. Negative
91
+ indexes are counted from the end of the list
92
+ @return [Array<Document>,nil] an array containing the documents corresponding
93
+ to the given range. Indexes which are out of range are ignored. If the whole
94
+ range is out of range, *nil* is returned
95
+ @overload [] url
96
+ Returns the document associated with the given URL
97
+ @param [KDE::Url] url the url to retrieve the document for
98
+ @return [Document,nil] the document associated with the given url or *nil*
99
+ if the list contains no document associated with the url. If the list contains
100
+ more than one document associated with the url, the first of them is returned
101
+ @overload [] file
102
+ Returns the document associated with the given file
103
+ @param [String] fike the *absolute* path of the file
104
+ @return [Document,nil] the document associated with the given file or *nil*
105
+ if the list contains no document associated with the file. If the list contains
106
+ more than one document associated with the file, the first of them is returned
107
+ @overload [] name
108
+ Returns the document with the given document name
109
+ @param [String] name the document name. It must not start with a slash (@/@)
110
+ @return [Document,nil] the document with the given document name or *nil*
111
+ if the list contains no document with that name. If the list contains
112
+ more than one document with that name, the first of them is returned
113
+ @return [Document,Array<Document>,nil]
114
+ =end
115
+ def [] arg
116
+ case arg
117
+ when Integer, Range then @documents[arg]
118
+ when KDE::Url then @documents.find{|doc| doc.url == arg}
119
+ when String
120
+ if arg.start_with? '/'
121
+ @documents.find do |doc|
122
+ doc.url.local_file? and doc.path == arg
123
+ end
124
+ else @documents.find{|doc| doc.document_name == arg}
125
+ end
126
+ end
127
+ end
128
+
129
+ =begin rdoc
130
+ The document associated with a given file
131
+ @param [String] file the absolute path of the file
132
+ @return [Document,nil] the document associated with the given file or *nil* if
133
+ there's no document associated with it in the list. If there is more than one
134
+ document associated with the file, the first one will be returned
135
+ @raise [ArgumentError] if the file name is not an absolute path (i.e., it doesn't
136
+ start with a @/@)
137
+ =end
138
+ def document_for_file file
139
+ raise ArgumentError, "#{file} is not an absolute path" unless file.start_with?('/')
140
+ @documents.find{|doc| doc.url.local_file? && doc.path == file}
141
+ end
142
+
143
+ =begin rdoc
144
+ Whether or not the list contains a document associated with a given file
145
+ @param (see DocumentList#document_for_file)
146
+ @return [Boolean] *true* if the list contains a document associated with _file_ and *false*
147
+ otherwise
148
+ @raise (see DocumentList#document_for_file)
149
+ =end
150
+ def document_for_file? file
151
+ document_for_file(file).to_bool
152
+ end
153
+
154
+ =begin rdoc
155
+ The document associated with a given URL
156
+ @param [KDE::Url, String] url the URL associated with the file. If it is a string,
157
+ it must be in a format suitable to be passed to @KDE::Url.new@
158
+ @return [Document,nil] the document associated with the given url or *nil* if
159
+ there's no document associated with it in the list. If there is more than one
160
+ document associated with the URL, the first one will be returned
161
+ =end
162
+ def document_for_url url
163
+ @documents.find{|doc| doc.url == url}
164
+ end
165
+
166
+ =begin rdoc
167
+ Whether or not the list contains a document associated with a given URL
168
+ @param (see DocumentList#document_for_url)
169
+ @return [Boolean] *true* if the list contains a document associated with _url_ and *false*
170
+ otherwise
171
+ =end
172
+ def document_for_url? url
173
+ document_for_url(url).to_bool
174
+ end
175
+
176
+ =begin rdoc
177
+ The document with a given @document_name@
178
+ @param [String] name the name of the document
179
+ @return [Document,nil] the document with the given document name or *nil* if
180
+ there's no document with that name. If there is more than one
181
+ document with the given document name, the first one will be returned
182
+ =end
183
+ def document_with_name name
184
+ @documents.find{|doc| doc.document_name == name}
185
+ end
186
+
187
+ =begin rdoc
188
+ Whether or not the list contains a document with a given document name
189
+ @param (see DocumentList#document_with_name)
190
+ @return [Boolean] *true* if the list contains a document with the given document
191
+ name and *false* otherwise
192
+ =end
193
+ def document_with_name? name
194
+ document_with_name(name).to_bool
195
+ end
196
+
197
+ =begin rdoc
198
+ A list of the documents having a file associated with them
199
+
200
+ According to the _which_ argument, this method can return all the documents in
201
+ the list which have a file associated with them, only those which have a _local_
202
+ file associated with them or only those which have a _remote_ file associated with
203
+ them.
204
+
205
+ @param [Symbol] which the kind of files which can be associated with the documents.
206
+ It can be: @:local@ to return only documents associated with local files, @:remote@
207
+ to return only documents associated with remote files or @:any@ to return documents
208
+ associated with either @:local@ or @:remote@ files
209
+ @return [Array<Document>] a list of the documents associated with a file, according
210
+ with the restrictions posed by _which_.
211
+ =end
212
+ def documents_with_file which = :any
213
+ case which
214
+ when :local then @documents.select{|doc| doc.url.local_file?}
215
+ when :remote then @documents.select{|doc| doc.url.remote_file?}
216
+ when :any then @documents.select{|doc| doc.has_file?}
217
+ end
218
+ end
219
+
220
+ =begin rdoc
221
+ Comparison operator
222
+
223
+ @param [Object] other the object to compare *self* with
224
+ @return [Boolean] *true* if _other_ is either an @Array@ or a {DocumentList}
225
+ containing the same elements as *self* in the same order and *false* otherwise
226
+ =end
227
+ def == other
228
+ case other
229
+ when DocumentList
230
+ @documents == other.instance_variable_get(:@documents)
231
+ when Array then @documents == other
232
+ else false
233
+ end
234
+ end
235
+
236
+ =begin rdoc
237
+ Comparison operator used by Hash
238
+
239
+ @param [Object] other the object to compare *self* with
240
+ @return [Boolean] *true* if _other_ is a {DocumentList} containing the
241
+ same elements as *self* in the same order and *false* otherwise
242
+ =end
243
+ def eql? other
244
+ if other.is_a? DocumentList
245
+ @documents == other.instance_variable_get(:@documents)
246
+ else false
247
+ end
248
+ end
249
+
250
+ =begin rdoc
251
+ Override of @Object#hash@
252
+
253
+ @return [Integer] the hash value for *self*
254
+ =end
255
+ def hash
256
+ @documents.hash
257
+ end
258
+
259
+ protected
260
+
261
+ =begin rdoc
262
+ @return [Array<Document>] the internal array used to keep trace of the documents
263
+ =end
264
+ def document_array
265
+ @documents
266
+ end
267
+
268
+ end
269
+
270
+ =begin rdoc
271
+ A {DocumentList} which allows to change the contents of the list.
272
+ =end
273
+ class MutableDocumentList < DocumentList
274
+
275
+ =begin rdoc
276
+ @param [Array<Document>, DocumentList] docs the documents to insert in the
277
+ list when created. Further changes to _docs_ won't change the new instance and
278
+ vice versa
279
+ =end
280
+ def initialize docs = []
281
+ docs = docs.document_array if docs.is_a? DocumentList
282
+ @documents = docs.dup
283
+ end
284
+
285
+ =begin rdoc
286
+ Override of @Object#dup@
287
+ @return [MutableDocumentList] a duplicate of *self*
288
+ =end
289
+ def dup
290
+ self.class.new self
291
+ end
292
+
293
+ =begin rdoc
294
+ Override of @Object#clone@
295
+ @return [MutableDocumentList] a duplicate of *self*
296
+ =end
297
+ def clone
298
+ res = self.class.new self
299
+ if frozen?
300
+ res.freeze
301
+ res.document_array.freeze
302
+ end
303
+ res
304
+ end
305
+
306
+
307
+ =begin rdoc
308
+ Adds documents to the list
309
+
310
+ @param [Array<Document,Array<Document>>] docs the documents to add. If it contains
311
+ nested arrays, they'll be flattened
312
+ @return [MutableDocumentList] *self*
313
+ @note this method doesn't check for duplicate documents. While having multiple
314
+ copies of the same document shouldn't cause troubles, it's better to avoid them.
315
+ To do so, either check beforehand that _docs_ contains no duplicates and no
316
+ document already in the list, or use {#uniq!} afterwards
317
+ =end
318
+ def add *docs
319
+ docs.flatten!
320
+ @documents.insert -1, *docs
321
+ self
322
+ end
323
+
324
+ =begin rdoc
325
+ Adds the contents of another array or {MutableDocumentList} to the list
326
+
327
+ The documents from the other list will be added at the end of this list.
328
+
329
+ @param [Array<Document>, DocumentList] other the list whose contents should
330
+ be added to this list contents
331
+ @param [Boolean] remove_duplicates if *true*, after adding the contents of _other_
332
+ to the list, {#uniq!} will be called to ensure there are no duplicates. If *false*,
333
+ {#uniq!} won't be called
334
+ @return [MutableDocumentList] *self*
335
+ =end
336
+ def merge! other, remove_duplicates = true
337
+ if other.is_a? DocumentList
338
+ @documents.concat other.document_array
339
+ else @documents.concat other
340
+ end
341
+ uniq! if remove_duplicates
342
+ self
343
+ end
344
+
345
+ =begin rdoc
346
+ Removes a document from the list
347
+
348
+ If the given document isn't in the list, nothing is done
349
+
350
+ @param [Document] doc the document to remove
351
+ @return [Document,nil] the removed document or *nil* if no document was removed
352
+ =end
353
+ def remove doc
354
+ @documents.delete doc
355
+ end
356
+
357
+ =begin rdoc
358
+ Removes all the elements from the list
359
+
360
+ @return [MutableDocumentList] *self*
361
+ =end
362
+ def clear
363
+ @documents.clear
364
+ self
365
+ end
366
+
367
+ =begin rdoc
368
+ Removes from the list all documents for which the block returns true
369
+
370
+ @yieldparam [Document] doc the documents in the list
371
+ @yieldreturn [Boolean] *true* for documents which should be removed from the list
372
+ and *false* otherwise
373
+ @return [MutableDocumentList] *self*
374
+ =end
375
+ def delete_if &blk
376
+ @documents.delete_if &blk
377
+ self
378
+ end
379
+
380
+ =begin rdoc
381
+ Ensures that the list doesn't contain duplicates
382
+
383
+ After calling this method, the list won't contain the same document in multiple
384
+ places
385
+ @return [MutableDocumentList] *self*
386
+ =end
387
+ def uniq!
388
+ @documents.uniq!
389
+ self
390
+ end
391
+
392
+ end
393
+
394
+ end
395
+
396
+ end