ruber 0.0.8 → 0.0.9

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 (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