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.
- data/CHANGES +21 -0
- data/data/share/apps/ruber/ruberui.rc +3 -1
- data/lib/ruber/application/application.rb +22 -23
- data/lib/ruber/application/plugin.yaml +7 -2
- data/lib/ruber/{projects → application}/project_files_list.rb +0 -0
- data/lib/ruber/{projects → application}/project_files_widget.rb +0 -0
- data/lib/ruber/application/ui/project_files_rule_chooser_widget.rb +74 -0
- data/lib/ruber/{projects → application}/ui/project_files_rule_chooser_widget.ui +0 -0
- data/lib/ruber/application/ui/project_files_widget.rb +117 -0
- data/lib/ruber/{projects → application}/ui/project_files_widget.ui +0 -0
- data/lib/ruber/component_manager.rb +14 -9
- data/lib/ruber/editor/document.rb +35 -5
- data/lib/ruber/kde_sugar.rb +16 -0
- data/lib/ruber/main_window/choose_plugins_dlg.rb +7 -4
- data/lib/ruber/main_window/main_window.rb +131 -193
- data/lib/ruber/main_window/main_window_actions.rb +157 -58
- data/lib/ruber/main_window/main_window_internal.rb +145 -54
- data/lib/ruber/main_window/open_file_in_project_dlg.rb +4 -4
- data/lib/ruber/main_window/plugin.yaml +3 -6
- data/lib/ruber/main_window/ui/workspace_settings_widget.rb +2 -2
- data/lib/ruber/main_window/workspace.rb +62 -32
- data/lib/ruber/output_widget.rb +20 -16
- data/lib/ruber/pane.rb +11 -5
- data/lib/ruber/project.rb +27 -12
- data/lib/ruber/projects/ui/project_files_rule_chooser_widget.rb +2 -2
- data/lib/ruber/projects/ui/project_files_widget.rb +2 -2
- data/lib/ruber/utils.rb +37 -4
- data/lib/ruber/version.rb +1 -1
- data/lib/ruber/world/document_factory.rb +121 -0
- data/lib/ruber/world/document_list.rb +396 -0
- data/lib/ruber/world/environment.rb +470 -0
- data/lib/ruber/{main_window → world}/hint_solver.rb +1 -1
- data/lib/ruber/world/plugin.yaml +11 -0
- data/lib/ruber/world/project_factory.rb +131 -0
- data/lib/ruber/world/project_list.rb +265 -0
- data/lib/ruber/world/ui/workspace_settings_widget.rb +51 -0
- data/lib/ruber/{main_window → world}/ui/workspace_settings_widget.ui +0 -0
- data/lib/ruber/world/world.rb +307 -0
- data/plugins/auto_end/auto_end.rb +135 -9
- data/plugins/autosave/autosave.rb +4 -4
- data/plugins/find_in_files/find_in_files.rb +5 -5
- data/plugins/find_in_files/find_in_files_widgets.rb +1 -1
- data/plugins/project_browser/project_browser.rb +4 -4
- data/plugins/rake/rake.rb +4 -4
- data/plugins/rake/rake_extension.rb +1 -1
- data/plugins/rspec/rspec.rb +4 -4
- data/plugins/rspec/ruber_rspec_formatter.rb +2 -2
- data/plugins/ruby_development/ruby_development.rb +3 -3
- data/plugins/ruby_runner/ruby_runner.rb +2 -2
- data/plugins/state/plugin.yaml +6 -8
- data/plugins/state/state.rb +201 -391
- data/plugins/state/ui/config_widget.rb +5 -5
- data/plugins/state/ui/config_widget.ui +3 -3
- data/plugins/syntax_checker/syntax_checker.rb +4 -0
- data/spec/annotation_model_spec.rb +1 -1
- data/spec/auto_end_spec.rb +98 -47
- data/spec/component_manager_spec.rb +80 -21
- data/spec/document_factory_spec.rb +115 -0
- data/spec/document_list_spec.rb +560 -450
- data/spec/document_spec.rb +143 -55
- data/spec/editor_view_spec.rb +2 -2
- data/spec/environment_spec.rb +1900 -0
- data/spec/hint_solver_spec.rb +5 -5
- data/spec/kde_sugar_spec.rb +16 -0
- data/spec/output_widget_spec.rb +177 -51
- data/spec/pane_spec.rb +29 -5
- data/spec/plugin_spec.rb +1 -1
- data/spec/project_factory_spec.rb +104 -0
- data/spec/project_list_spec.rb +352 -447
- data/spec/project_spec.rb +34 -33
- data/spec/qt_sugar_spec.rb +2 -2
- data/spec/state_spec.rb +508 -811
- data/spec/utils_spec.rb +149 -98
- data/spec/workspace_spec.rb +120 -9
- data/spec/world_spec.rb +1219 -0
- metadata +23 -14
- data/lib/ruber/documents/document_list.rb +0 -412
- data/lib/ruber/documents/plugin.yaml +0 -4
- data/lib/ruber/main_window/view_manager.rb +0 -431
- data/lib/ruber/projects/plugin.yaml +0 -11
- data/lib/ruber/projects/project_list.rb +0 -314
File without changes
|
@@ -0,0 +1,307 @@
|
|
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/plugin_like'
|
22
|
+
require 'ruber/world/document_factory'
|
23
|
+
require 'ruber/world/project_factory'
|
24
|
+
require 'ruber/world/environment'
|
25
|
+
require 'ruber/world/project_list'
|
26
|
+
require 'ruber/world/document_list'
|
27
|
+
require_relative 'ui/workspace_settings_widget'
|
28
|
+
|
29
|
+
module Ruber
|
30
|
+
|
31
|
+
module World
|
32
|
+
|
33
|
+
class World < Qt::Object
|
34
|
+
|
35
|
+
=begin rdoc
|
36
|
+
Exception raised from {Ruber::World::World#new_project} when the given file already
|
37
|
+
exists
|
38
|
+
=end
|
39
|
+
class ExistingProjectFileError < StandardError
|
40
|
+
end
|
41
|
+
|
42
|
+
include PluginLike
|
43
|
+
|
44
|
+
attr_reader :default_environment
|
45
|
+
|
46
|
+
attr_reader :active_environment
|
47
|
+
|
48
|
+
attr_reader :active_document
|
49
|
+
|
50
|
+
signals 'active_environment_changed(QObject*)'
|
51
|
+
|
52
|
+
signals 'active_environment_changed_2(QObject*, QObject*)'
|
53
|
+
|
54
|
+
signals 'active_project_changed(QObject*)'
|
55
|
+
|
56
|
+
signals 'active_project_changed_2(QObject*, QObject*)'
|
57
|
+
|
58
|
+
signals 'document_created(QObject*)'
|
59
|
+
|
60
|
+
signals 'project_created(QObject*)'
|
61
|
+
|
62
|
+
signals 'closing_project(QObject*)'
|
63
|
+
|
64
|
+
signals 'closing_document(QObject*)'
|
65
|
+
|
66
|
+
signals 'active_document_changed(QObject*)'
|
67
|
+
|
68
|
+
signals 'active_editor_changed(QWidget*)'
|
69
|
+
|
70
|
+
|
71
|
+
=begin rdoc
|
72
|
+
@param [ComponentManager] manager the component manager (unused)
|
73
|
+
@param [PluginSpecification] psf the plugin specification object associated with
|
74
|
+
the component
|
75
|
+
=end
|
76
|
+
def initialize _, psf
|
77
|
+
super Ruber[:app]
|
78
|
+
@documents = MutableDocumentList.new []
|
79
|
+
@projects = MutableProjectList.new []
|
80
|
+
@environments = {}
|
81
|
+
initialize_plugin psf
|
82
|
+
@active_environment = nil
|
83
|
+
@active_document = nil
|
84
|
+
@document_factory = DocumentFactory.new self
|
85
|
+
connect @document_factory, SIGNAL('document_created(QObject*)'), self, SLOT('slot_document_created(QObject*)')
|
86
|
+
@project_factory = ProjectFactory.new self
|
87
|
+
connect @project_factory, SIGNAL('project_created(QObject*)'), self, SLOT('slot_project_created(QObject*)')
|
88
|
+
@default_environment = Environment.new(nil, self)
|
89
|
+
add_environment @default_environment, nil
|
90
|
+
end
|
91
|
+
|
92
|
+
def environment prj
|
93
|
+
@environments[prj]
|
94
|
+
# unless env
|
95
|
+
# env = Environment.new(prj)
|
96
|
+
# connect env, SIGNAL('closing(QObject*)'), self, SLOT('environment_closing(QObject*)')
|
97
|
+
# connect env, SIGNAL('active_editor_changed(QWidget*)'), self, SLOT('slot_active_editor_changed(QWidget*)')
|
98
|
+
# @environments[prj] = env
|
99
|
+
# end
|
100
|
+
end
|
101
|
+
|
102
|
+
def active_environment= env
|
103
|
+
return if @active_environment == env
|
104
|
+
old = @active_environment
|
105
|
+
old.deactivate if old
|
106
|
+
@active_environment = env
|
107
|
+
emit active_environment_changed(env)
|
108
|
+
emit active_environment_changed_2(env, old)
|
109
|
+
@active_environment.activate if @active_environment
|
110
|
+
end
|
111
|
+
|
112
|
+
def environments
|
113
|
+
@environments.values
|
114
|
+
end
|
115
|
+
|
116
|
+
def each_environment
|
117
|
+
if block_given?
|
118
|
+
@environments.each_value{|e| yield e}
|
119
|
+
self
|
120
|
+
else to_enum(:each_environment)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def active_project= prj
|
125
|
+
old = @active_environment.project if @active_environment
|
126
|
+
return old if old == prj
|
127
|
+
old.deactivate if old
|
128
|
+
self.active_environment = @environments[prj]
|
129
|
+
emit active_project_changed prj
|
130
|
+
emit active_project_changed_2 prj, old
|
131
|
+
prj.activate if prj
|
132
|
+
end
|
133
|
+
|
134
|
+
def active_project
|
135
|
+
@active_environment.project if @active_environment
|
136
|
+
end
|
137
|
+
|
138
|
+
def projects
|
139
|
+
ProjectList.new @environments.keys.compact
|
140
|
+
end
|
141
|
+
|
142
|
+
def each_project
|
143
|
+
if block_given?
|
144
|
+
@environments.each_key{|prj| yield prj if prj}
|
145
|
+
self
|
146
|
+
else self.to_enum(:each_project)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
=begin rdoc
|
151
|
+
Creates a new document
|
152
|
+
@return [Document] the new document. It will be a child of *self*
|
153
|
+
=end
|
154
|
+
def new_document
|
155
|
+
doc = @document_factory.document nil, self
|
156
|
+
doc
|
157
|
+
end
|
158
|
+
|
159
|
+
=begin rdoc
|
160
|
+
The document associated with the given file or URL
|
161
|
+
|
162
|
+
If a document for the given file or URL already exists, that document will be
|
163
|
+
returned, otherwise a new one will be created.
|
164
|
+
|
165
|
+
@param [String,KDE::Url] file the absolute name or the URL of the
|
166
|
+
file to retrieve the document for
|
167
|
+
@return [Document,nil] a document associated with _file_ and having *self* as parent.
|
168
|
+
If _file_ represents a local file and that file doesn't exist, *nil* is returned
|
169
|
+
=end
|
170
|
+
def document file
|
171
|
+
@document_factory.document file, self
|
172
|
+
end
|
173
|
+
|
174
|
+
def documents
|
175
|
+
DocumentList.new @documents
|
176
|
+
end
|
177
|
+
|
178
|
+
def each_document
|
179
|
+
if block_given?
|
180
|
+
@documents.each{|doc| yield doc}
|
181
|
+
self
|
182
|
+
else self.to_enum :each_document
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
=begin rdoc
|
187
|
+
Creates a new project
|
188
|
+
@param [String] file the absolute path of the project file
|
189
|
+
@param [String] name the name of the project
|
190
|
+
@return [Project] a new project having _file_ as project file and _name_ as project
|
191
|
+
name
|
192
|
+
@raise [ExistingProjectFileError] if a file called _file_ already exists (regardless
|
193
|
+
of whether it's a valid project file or not)
|
194
|
+
=end
|
195
|
+
def new_project file, name
|
196
|
+
raise ExistingProjectFileError, "#{file} already exists" if File.exist?(file)
|
197
|
+
@project_factory.project file, name
|
198
|
+
end
|
199
|
+
|
200
|
+
=begin rdoc
|
201
|
+
Retrieves the project associated with a given project file
|
202
|
+
|
203
|
+
If a project associated with the project file _file_ already exists, that project
|
204
|
+
is returned. Otherwise, a new project object is created.
|
205
|
+
|
206
|
+
@param [String] file the absolute path of the project file. Note that this file
|
207
|
+
*must* already exist and be a valid project file
|
208
|
+
@return [Project] a project associated with _file_
|
209
|
+
@raise [AbstractProject::InvalidProjectFile] if the project file is not a valid
|
210
|
+
project file
|
211
|
+
=end
|
212
|
+
def project file
|
213
|
+
@project_factory.project file
|
214
|
+
end
|
215
|
+
|
216
|
+
def close_all what, save_behaviour = :save
|
217
|
+
close_docs = (what == :all || what == :documents)
|
218
|
+
close_prjs = (what == :all || what == :projects)
|
219
|
+
save = save_behaviour == :save
|
220
|
+
@projects.dup.each{|prj| prj.close save} if close_prjs
|
221
|
+
@documents.dup.each{|doc| doc.close save} if close_docs
|
222
|
+
end
|
223
|
+
|
224
|
+
def save_settings
|
225
|
+
@documents.each{|doc| doc.save_settings}
|
226
|
+
@projects.each{|prj| prj.save}
|
227
|
+
end
|
228
|
+
|
229
|
+
def query_close
|
230
|
+
@documents.each{|doc| return false unless doc.own_project.query_close}
|
231
|
+
return false unless Ruber[:main_window].save_documents @documents.to_a
|
232
|
+
@projects.each{|prj| return false unless prj.query_close}
|
233
|
+
true
|
234
|
+
end
|
235
|
+
|
236
|
+
private
|
237
|
+
|
238
|
+
def add_environment env, prj
|
239
|
+
@environments[prj] = env
|
240
|
+
connect env, SIGNAL('closing(QObject*)'), self, SLOT('environment_closing(QObject*)')
|
241
|
+
connect env, SIGNAL('active_editor_changed(QWidget*)'), self, SLOT('slot_active_editor_changed(QWidget*)')
|
242
|
+
end
|
243
|
+
|
244
|
+
def environment_closing env
|
245
|
+
@environments.delete env.project
|
246
|
+
self.active_environment = nil if @active_environment == env
|
247
|
+
end
|
248
|
+
slots 'environment_closing(QObject*)'
|
249
|
+
|
250
|
+
def slot_document_created doc
|
251
|
+
@documents.add doc
|
252
|
+
connect doc, SIGNAL('closing(QObject*)'), self, SLOT('slot_document_closing(QObject*)')
|
253
|
+
emit document_created(doc)
|
254
|
+
end
|
255
|
+
slots 'slot_document_created(QObject*)'
|
256
|
+
|
257
|
+
def slot_project_created prj
|
258
|
+
@projects.add prj
|
259
|
+
connect prj, SIGNAL('closing(QObject*)'), self, SLOT('slot_closing_project(QObject*)')
|
260
|
+
add_environment prj.extension(:environment), prj
|
261
|
+
emit project_created(prj)
|
262
|
+
end
|
263
|
+
slots 'slot_project_created(QObject*)'
|
264
|
+
|
265
|
+
def slot_document_closing doc
|
266
|
+
emit closing_document(doc)
|
267
|
+
@documents.remove doc
|
268
|
+
end
|
269
|
+
slots 'slot_document_closing(QObject*)'
|
270
|
+
|
271
|
+
def slot_closing_project prj
|
272
|
+
emit closing_project(prj)
|
273
|
+
@projects.remove prj
|
274
|
+
end
|
275
|
+
slots 'slot_closing_project(QObject*)'
|
276
|
+
|
277
|
+
def load_settings
|
278
|
+
tabs_closable = Ruber[:config][:workspace, :close_buttons]
|
279
|
+
@environments.each_value{|e| e.tab_widget.tabs_closable = tabs_closable}
|
280
|
+
end
|
281
|
+
slots :load_settings
|
282
|
+
|
283
|
+
def slot_active_editor_changed editor
|
284
|
+
doc = editor ? editor.document : nil
|
285
|
+
if doc != @active_document
|
286
|
+
@active_document = doc
|
287
|
+
emit active_document_changed(@active_document)
|
288
|
+
end
|
289
|
+
emit active_editor_changed(editor)
|
290
|
+
end
|
291
|
+
slots 'slot_active_editor_changed(QWidget*)'
|
292
|
+
|
293
|
+
end
|
294
|
+
|
295
|
+
class WorkspaceSettingsWidget < Qt::Widget
|
296
|
+
|
297
|
+
def initialize parent = nil
|
298
|
+
super
|
299
|
+
@ui = Ui::WorkspaceSettingsWidgetBase.new
|
300
|
+
@ui.setup_ui self
|
301
|
+
end
|
302
|
+
|
303
|
+
end
|
304
|
+
|
305
|
+
end
|
306
|
+
|
307
|
+
end
|
@@ -20,32 +20,113 @@
|
|
20
20
|
|
21
21
|
module Ruber
|
22
22
|
|
23
|
+
=begin rdoc
|
24
|
+
Plugin which automatically inserts an @end@ keyword after the user presses Enter
|
25
|
+
after a line starting a construct which requires it.
|
26
|
+
|
27
|
+
The algorithm used to find out whether an end should be inserted after the current
|
28
|
+
line is very simple: the line is checked against several possible regexps. The @end@
|
29
|
+
is inserted if any of the regexps matches.
|
30
|
+
|
31
|
+
The above algorithm has the limitation of not being able to tell whether the line
|
32
|
+
is inside a multiline string or a block comment, and can thus lead to spurious @end@s
|
33
|
+
being added.
|
34
|
+
|
35
|
+
Another problem with the way the plugin works now is that it has no way to know
|
36
|
+
whether a given keyword already has its closing @end@. To try to lessen this issue,
|
37
|
+
before inserting an @end@, this plugin checks the indentation of the following line,
|
38
|
+
comparing it to the indentation of the line where Enter has been pressed. If the
|
39
|
+
former is greater than the latter, it assumes that the user is editing an already-existing
|
40
|
+
construct and doesn't insert the @end@.
|
41
|
+
|
42
|
+
@note This plugin does nothing unless the text is inserted in the document while
|
43
|
+
one of the views associated with it has focus
|
44
|
+
=end
|
23
45
|
module AutoEnd
|
24
46
|
|
47
|
+
=begin rdoc
|
48
|
+
Extension object for the Auto End plugin
|
49
|
+
|
50
|
+
The procedure of inserting an @end@ is split in two parts, performed in separate
|
51
|
+
moments:
|
52
|
+
# finding out whether the current line needs an end inserted after it. This is
|
53
|
+
done in response to the {Document#text_inserted} signal
|
54
|
+
# inserting the text. This is done in response to the {Document#text_changed} signal
|
55
|
+
|
56
|
+
The reason for this two-step behaviour is that {Document#text_inserted} is emitted
|
57
|
+
multiple times in case of a Paste operation. Thus, inserting the @end@ keywords
|
58
|
+
in it would cause them to be added in the middle of the pasted text, which is
|
59
|
+
wrong. What we do instead is to analyze each line in response to {Document#text_inserted},
|
60
|
+
storing the line position and the text to insert if appropriate, overwriting any
|
61
|
+
other information so that only the last position is recorded. When all text has
|
62
|
+
been processed, the document emits the {Document#text_changed} signal and, in response
|
63
|
+
to this we insert the end keyword (if appropriate).
|
64
|
+
=end
|
25
65
|
class Extension < Qt::Object
|
26
66
|
|
27
67
|
include Ruber::Extension
|
28
68
|
|
69
|
+
=begin rdoc
|
70
|
+
Contains the information about the next insertion to do
|
71
|
+
|
72
|
+
@attr [Integer] line_number the number of the line where the insertion should be done
|
73
|
+
@attr [String] lines the text to insert
|
74
|
+
@attr [Array(Integer,Integer)] final_position the position to move after the insertion
|
75
|
+
The first element is the line number, relative to the insertion line (for example,
|
76
|
+
a value of 1 means to move the cursor to the line after the insertion line, while
|
77
|
+
a value of -1 means to move it to the line before). The second element is the
|
78
|
+
column number. If negative, it's counted from the end of the line
|
79
|
+
=end
|
29
80
|
Insertion = Struct.new :line_number, :lines, :final_position
|
30
81
|
|
82
|
+
=begin rdoc
|
83
|
+
The regexp fragment which matches an identifier. In theory, this should
|
84
|
+
just be @\w+@. However, from ruby 1.9.2, @\w@ only matches ASCII characters, while
|
85
|
+
identifiers can also contain unicode characters. To allow for this, the @\p{Word}@
|
86
|
+
character class is used from ruby 1.9.2 onward, while @\w@ is used for previous
|
87
|
+
versions
|
88
|
+
=end
|
31
89
|
IDENTIFIER_PATTERN = RUBY_VERSION >= '1.9.2' ? '\p{Word}+' : '\w+'
|
32
90
|
|
91
|
+
=begin rdoc
|
92
|
+
The regexp fragment which matches a multiple identifier (that is, an identifier
|
93
|
+
maybe followed by several other identifiers separated by @::@)
|
94
|
+
=end
|
33
95
|
MULTI_ID_PATTERN = "#{IDENTIFIER_PATTERN}(?:::#{IDENTIFIER_PATTERN})*"
|
34
96
|
|
97
|
+
=begin rdoc
|
98
|
+
The patterns used to find out whether an @end@ keyword should be inserted after
|
99
|
+
a line.
|
100
|
+
|
101
|
+
Each entry is itself an array with three elements:
|
102
|
+
* the regexp to match agains the line
|
103
|
+
* the text to insert if the regexp match
|
104
|
+
* an array with two elements, representing the position where the cursor should be
|
105
|
+
moved to after the insertion, as described in {Insertion#final_position}
|
106
|
+
=end
|
35
107
|
PATTERNS = [
|
36
108
|
[/^\s*if\s/, "\nend", [0, -1]],
|
37
109
|
[/=\s*if\s/, "\nend", [0, -1]],
|
110
|
+
[/^\s*unless\s/, "\nend", [0, -1]],
|
111
|
+
[/=\s*unless\s/, "\nend", [0, -1]],
|
38
112
|
[/\bdo\s*$/, "\nend", [0, -1]],
|
39
113
|
[/\bdo\s+\|/, "\nend", [0, -1]],
|
40
114
|
[/^\s*def\s/, "\nend", [0, -1]],
|
41
115
|
[/^class\s+#{IDENTIFIER_PATTERN}\s*$/, "\nend", [0, -1]],
|
42
116
|
[/^class\s+#{MULTI_ID_PATTERN}\s*<{1,2}\s*#{MULTI_ID_PATTERN}\s*$/, "\nend", [0, -1]],
|
43
117
|
[/^\s*module\s+#{MULTI_ID_PATTERN}\s*$/, "\nend", [0,-1]],
|
44
|
-
[
|
118
|
+
[/^\s*while\s/, "\nend", [0,-1]],
|
119
|
+
[/^\s*until\s/, "\nend", [0,-1]],
|
120
|
+
# [/^=begin(\s|$)/, "\n=end", [0, -1]],
|
45
121
|
[/^\s*begin\s/, "\nend", [0, -1]],
|
46
|
-
[
|
122
|
+
[/(^=\s+|.=\s*)begin\s/, "\nend", [0, -1]],
|
123
|
+
[/^\s*for\s+#{IDENTIFIER_PATTERN}\s+in.+$/, "\nend", [0,-1]],
|
124
|
+
[/=\s*for\s+#{IDENTIFIER_PATTERN}\s+in.+$/, "\nend", [0,-1]]
|
47
125
|
]
|
48
126
|
|
127
|
+
=begin rdoc
|
128
|
+
@param [DocumentProject] prj the project associated with the document
|
129
|
+
=end
|
49
130
|
def initialize prj
|
50
131
|
super
|
51
132
|
@doc = prj.document
|
@@ -53,6 +134,20 @@ module Ruber
|
|
53
134
|
connect_slots
|
54
135
|
end
|
55
136
|
|
137
|
+
private
|
138
|
+
=begin rdoc
|
139
|
+
Slot called when some text is inserted
|
140
|
+
|
141
|
+
If one of the recognized patterns match the current line, memorizes an {Insertion}
|
142
|
+
object pointing to the current line and using the parameters associated with the
|
143
|
+
matching pattern.
|
144
|
+
|
145
|
+
If the inserted text doesn't end in a newline, nothing is done.
|
146
|
+
|
147
|
+
If the current line doesn't match any pattern, the currently memorized insertion
|
148
|
+
position (if any) is forgotten
|
149
|
+
@param [KTextEditor::Range] the range corresponding to the inserted text
|
150
|
+
=end
|
56
151
|
def text_inserted range
|
57
152
|
text = @doc.text range
|
58
153
|
return unless text.end_with? "\n"
|
@@ -66,9 +161,20 @@ module Ruber
|
|
66
161
|
@insertion = Insertion.new range.end.line, pattern[1], pattern[2]
|
67
162
|
end
|
68
163
|
end
|
164
|
+
nil
|
69
165
|
end
|
70
166
|
slots 'text_inserted(KTextEditor::Range)'
|
71
167
|
|
168
|
+
=begin rdoc
|
169
|
+
Slot called in response to the {Document#text_changed} signal
|
170
|
+
|
171
|
+
If there's an insertion position memorized, inserts the corresponding text after
|
172
|
+
the current line, then moves the cursor to the position stored with the insertion
|
173
|
+
object.
|
174
|
+
|
175
|
+
The current insertion is forgotten.
|
176
|
+
@return [nil]
|
177
|
+
=end
|
72
178
|
def text_changed
|
73
179
|
if @insertion
|
74
180
|
insert_text KTextEditor::Cursor.new(@insertion.line_number, 0),
|
@@ -78,22 +184,46 @@ module Ruber
|
|
78
184
|
end
|
79
185
|
slots :text_changed
|
80
186
|
|
187
|
+
=begin rdoc
|
188
|
+
Override of {Extension#remove_from_project}
|
189
|
+
@return [nil]
|
190
|
+
=end
|
81
191
|
def remove_from_project
|
82
192
|
disconnect_slots
|
83
193
|
end
|
84
194
|
|
85
|
-
|
86
|
-
|
195
|
+
=begin rdoc
|
196
|
+
Makes connections to the document's signals
|
197
|
+
@return [nil]
|
198
|
+
=end
|
87
199
|
def connect_slots
|
88
200
|
connect @doc, SIGNAL('text_inserted(KTextEditor::Range, QObject*)'), self, SLOT('text_inserted(KTextEditor::Range)')
|
89
201
|
connect @doc, SIGNAL('text_changed(QObject*)'), self, SLOT(:text_changed)
|
202
|
+
nil
|
90
203
|
end
|
91
204
|
|
205
|
+
=begin rdoc
|
206
|
+
Disconnects connections to the document's signals
|
207
|
+
@return [nil]
|
208
|
+
=end
|
92
209
|
def disconnect_slots
|
93
210
|
disconnect @doc, SIGNAL('text_inserted(KTextEditor::Range, QObject*)'), self, SLOT('text_inserted(KTextEditor::Range)')
|
94
211
|
disconnect @doc, SIGNAL('text_changed(QObject*)'), self, SLOT(:text_changed)
|
95
212
|
end
|
96
213
|
|
214
|
+
=begin rdoc
|
215
|
+
Inserts text at the given position and moves the cursor to the specified position
|
216
|
+
|
217
|
+
To avoid the possibility of infinite recursion, before inserting text {#disconnect_slots}
|
218
|
+
is called. After the text has been inserted {#connect_slots} is called.
|
219
|
+
|
220
|
+
@note nothing is done unless the active view (according to {Document#active_view})
|
221
|
+
is associated with the document
|
222
|
+
@param [KTextEditor::Cursor] insert_pos the position where the text should be inserted
|
223
|
+
@param [String] lines the text to insert
|
224
|
+
@param [Array(Integer,Integer)] dest the position to move the cursor to, relative
|
225
|
+
to the insertion position, as described in {Insertion#final_position}
|
226
|
+
=end
|
97
227
|
def insert_text insert_pos, lines, dest
|
98
228
|
view = @doc.active_view
|
99
229
|
return unless view
|
@@ -103,7 +233,7 @@ module Ruber
|
|
103
233
|
@doc.insert_text insert_pos, lines
|
104
234
|
final_pos = KTextEditor::Cursor.new insert_pos.line + lines.size - 1,
|
105
235
|
lines[-1].size
|
106
|
-
|
236
|
+
view.execute_action 'tools_align'
|
107
237
|
dest_line = insert_pos.line+dest[0]
|
108
238
|
dest_col = dest[1]
|
109
239
|
dest_col += @doc.line_length(dest_line) + 1 if dest_col < 0
|
@@ -111,10 +241,6 @@ module Ruber
|
|
111
241
|
connect_slots
|
112
242
|
end
|
113
243
|
|
114
|
-
def do_indentation view
|
115
|
-
view.execute_action 'tools_align'
|
116
|
-
end
|
117
|
-
|
118
244
|
end
|
119
245
|
|
120
246
|
end
|