rtext 0.8.2 → 0.9.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG +9 -0
- data/RText_Protocol +46 -3
- data/Rakefile +2 -2
- data/lib/rtext/context_builder.rb +49 -8
- data/lib/rtext/default_completer.rb +70 -25
- data/lib/rtext/default_service_provider.rb +3 -3
- data/lib/rtext/instantiator.rb +2 -6
- data/lib/rtext/language.rb +5 -5
- data/lib/rtext/serializer.rb +1 -1
- data/lib/rtext/service.rb +12 -5
- data/lib/rtext/tokenizer.rb +1 -1
- data/test/completer_test.rb +16 -15
- data/test/context_builder_test.rb +6 -5
- data/test/frontend/context_test.rb +3 -2
- data/test/instantiator_test.rb +34 -36
- data/test/integration/backend.out +15 -12
- data/test/integration/frontend.log +0 -444
- data/test/integration/test.rb +7 -5
- data/test/link_detector_test.rb +3 -2
- data/test/message_helper_test.rb +10 -11
- data/test/serializer_test.rb +22 -2
- data/test/tokenizer_test.rb +3 -2
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e9e6e9cf51849833ea57ae6f44b6e1b56bc715af
|
4
|
+
data.tar.gz: c63bf26429dee687a2ae1e07e63626a461a493f9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ebe766d35ad7ccb86a7ada1cd5344cf4463fb3318ff2cf40613294e462542b63b464e150f747abe33af2193c94fd747cf6a776c64dcdb0f7535aff55cc37e01d
|
7
|
+
data.tar.gz: 7d576b493c98b55ff22a50e0bda0ed928adb765b032f7bf83fc10edc52e3e26e6067fce2aa6e6ae03b9d24358d7c7c964388030439599c057902130491721f5a
|
data/CHANGELOG
CHANGED
@@ -87,3 +87,12 @@
|
|
87
87
|
* Fixed frontend content extraction to support line breaks with backslash
|
88
88
|
* Fixed frontend content extraction, joining of broken lines
|
89
89
|
|
90
|
+
=0.8.2
|
91
|
+
|
92
|
+
* Fixed serializer negative decimal quotation
|
93
|
+
* Added Object attribute test case
|
94
|
+
|
95
|
+
=0.9.0
|
96
|
+
|
97
|
+
* Added protocol versioning support
|
98
|
+
* Added completion options for square brackets and curly braces
|
data/RText_Protocol
CHANGED
@@ -4,6 +4,10 @@ RText frontend and backend pass messages containing JSON objects.
|
|
4
4
|
Normally the frontend invokes a backend command by means of a request message and the
|
5
5
|
backend will eventually reply with a response message.
|
6
6
|
|
7
|
+
== Versioning
|
8
|
+
|
9
|
+
RText protocol supports versioning mechanism with a single version natural number.
|
10
|
+
The actual version of the protocol is 1.
|
7
11
|
|
8
12
|
== Encoding
|
9
13
|
|
@@ -25,8 +29,8 @@ In addition, the character "%" is escaped in the same way, i.e. "%" will always
|
|
25
29
|
|
26
30
|
Example:
|
27
31
|
|
28
|
-
The word "
|
29
|
-
"%dcbung" (the "
|
32
|
+
The word "Übung" (german: exercise), encoded in ISO-8859-1 would result in the string:
|
33
|
+
"%dcbung" (the "Ü" Umlaut has a byte value of 0xdc is ISO-8859-1).
|
30
34
|
|
31
35
|
|
32
36
|
== Request Messages
|
@@ -34,9 +38,12 @@ The word "
|
|
34
38
|
Each request message contains a field ``command`` and a field ``invocation_id``.
|
35
39
|
The command field holds the name of the command to be invoked as a string.
|
36
40
|
The invocation id field holds an identifier which will be repeated by the backend's response.
|
41
|
+
The "version" field was introduced in version 1. It is optional for protocol version 0 requests,
|
42
|
+
but mandatory for newer versions.
|
37
43
|
|
38
44
|
{
|
39
45
|
"type": "request",
|
46
|
+
"version": <protocol_version [integer]>,
|
40
47
|
"command": <command>,
|
41
48
|
"invocation_id": <invocation_id>
|
42
49
|
...
|
@@ -65,6 +72,16 @@ There are a number of error message which may be sent in response to a request m
|
|
65
72
|
"invocation_id": <invocation_id>,
|
66
73
|
"command": <unknown command [string]>
|
67
74
|
}
|
75
|
+
|
76
|
+
=== Unsupported Protocol Version Error
|
77
|
+
|
78
|
+
Introduced in version 1.
|
79
|
+
|
80
|
+
{
|
81
|
+
"type": "unsupported_version",
|
82
|
+
"invocation_id": <invocation_id>,
|
83
|
+
"version": <supported version [integer]>
|
84
|
+
}
|
68
85
|
|
69
86
|
== Progress Information
|
70
87
|
|
@@ -90,6 +107,25 @@ The message field may carry information about the currently ongoing subtask.
|
|
90
107
|
For each command, the layout of the request and response messages will be given below.
|
91
108
|
Note that the invocation id field is present in every request and response but is omitted for brevity.
|
92
109
|
|
110
|
+
=== Backend version request
|
111
|
+
|
112
|
+
Introduced in version 1.
|
113
|
+
|
114
|
+
This command requests the backend to disclose its supported protocol version.
|
115
|
+
|
116
|
+
{
|
117
|
+
"type": "request",
|
118
|
+
"command": "version"
|
119
|
+
}
|
120
|
+
|
121
|
+
The backend responds with a version information.
|
122
|
+
|
123
|
+
{
|
124
|
+
"type": "response",
|
125
|
+
"version": <version [integer]>
|
126
|
+
}
|
127
|
+
|
128
|
+
The backend supporting protocool version 0 only responds with an 'Unknown Command Error'.
|
93
129
|
|
94
130
|
=== Load Model
|
95
131
|
|
@@ -141,7 +177,14 @@ build the set of context lines in the frontend. Column number start at 1.
|
|
141
177
|
}
|
142
178
|
|
143
179
|
The backend replies with a list of completion options.
|
144
|
-
The field ``insert`` holds the text to be inserted if the completion option is chosen.
|
180
|
+
The field ``insert`` holds the text to be inserted if the completion option is chosen. This text
|
181
|
+
may contains placeholders for cursor position. An editor may use them to assist a user in
|
182
|
+
filling additional completion fields.
|
183
|
+
Each placeholder must start and end with a vertical bar character (``|``) and can contain up to
|
184
|
+
three optional parts separated by an additional vertical bar character: ordering number, name and
|
185
|
+
description of this cursor position. E.g.: ``||``, ``|1|name|Entity name|``, ``|||New value|``.
|
186
|
+
Placeholders with the same name must be considered as the same value repeated in different
|
187
|
+
positions.
|
145
188
|
The field ``display`` contains the string which should be displayed to the user in some kind of
|
146
189
|
completion option menu. An optional description field may provide more information about a
|
147
190
|
particular option.
|
data/Rakefile
CHANGED
@@ -8,14 +8,14 @@ DocFiles = [
|
|
8
8
|
|
9
9
|
RTextGemSpec = Gem::Specification.new do |s|
|
10
10
|
s.name = %q{rtext}
|
11
|
-
s.version = "0.
|
11
|
+
s.version = "0.9.0"
|
12
12
|
s.date = Time.now.strftime("%Y-%m-%d")
|
13
13
|
s.summary = %q{Ruby Textual Modelling}
|
14
14
|
s.email = %q{martin dot thiede at gmx de}
|
15
15
|
s.homepage = %q{http://ruby-gen.org}
|
16
16
|
s.description = %q{RText can be used to derive textual languages from an RGen metamodel with very little effort.}
|
17
17
|
s.authors = ["Martin Thiede"]
|
18
|
-
s.add_dependency('rgen', '>= 0.
|
18
|
+
s.add_dependency('rgen', '>= 0.8.2')
|
19
19
|
gemfiles = Rake::FileList.new
|
20
20
|
gemfiles.include("{lib,test}/**/*")
|
21
21
|
gemfiles.include(DocFiles)
|
@@ -26,7 +26,8 @@ module RText
|
|
26
26
|
#
|
27
27
|
module ContextBuilder
|
28
28
|
|
29
|
-
|
29
|
+
PositionContext = Struct.new(:in_array, :in_block, :after_label, :after_comma, :before_brace, :before_bracket)
|
30
|
+
Context = Struct.new(:element, :feature, :prefix, :problem, :position, :line_indent, :indent)
|
30
31
|
|
31
32
|
class << self
|
32
33
|
include RText::Tokenizer
|
@@ -50,13 +51,37 @@ module ContextBuilder
|
|
50
51
|
else
|
51
52
|
feature = nil
|
52
53
|
end
|
53
|
-
|
54
|
+
context_info.position.after_label = after_label
|
55
|
+
Context.new(element, feature, context_info.prefix, context_info.problem, context_info.position,
|
56
|
+
get_line_indent(context_lines.last), get_indent(context_lines))
|
54
57
|
else
|
55
|
-
|
58
|
+
context_info.position.after_label = false
|
59
|
+
Context.new(nil, nil, context_info.prefix, context_info.problem, context_info.position,
|
60
|
+
get_line_indent(context_lines.last), get_indent(context_lines))
|
56
61
|
end
|
57
62
|
end
|
58
63
|
|
59
64
|
private
|
65
|
+
|
66
|
+
def get_line_indent(line)
|
67
|
+
return '' unless line
|
68
|
+
match = line.match(/^\s+/)
|
69
|
+
if match.nil?
|
70
|
+
''
|
71
|
+
else
|
72
|
+
match[0]
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# Compute indent from context lines
|
77
|
+
def get_indent(context_lines)
|
78
|
+
cl = context_lines.dup
|
79
|
+
while true
|
80
|
+
return ' ' if cl.size < 2 # default indentation is 2 spaces
|
81
|
+
indent = get_line_indent(cl.last)[get_line_indent(cl.delete_at(-2)).size..-1]
|
82
|
+
return indent unless indent.nil? || indent.empty?
|
83
|
+
end
|
84
|
+
end
|
60
85
|
|
61
86
|
def instantiate_context_element(language, context_info)
|
62
87
|
root_elements = []
|
@@ -72,7 +97,7 @@ module ContextBuilder
|
|
72
97
|
end
|
73
98
|
|
74
99
|
def find_leaf_child(element, num_required_children)
|
75
|
-
childs = element.class.ecore.eAllReferences.select{|r| r.containment}.collect{|r|
|
100
|
+
childs = element.class.ecore.eAllReferences.select{|r| r.containment }.collect{|r|
|
76
101
|
element.getGenericAsArray(r.name)}.flatten
|
77
102
|
if num_required_children == 0
|
78
103
|
element
|
@@ -83,7 +108,7 @@ module ContextBuilder
|
|
83
108
|
end
|
84
109
|
end
|
85
110
|
|
86
|
-
ContextInternal = Struct.new(:lines, :num_elements, :role, :prefix, :
|
111
|
+
ContextInternal = Struct.new(:lines, :num_elements, :role, :prefix, :problem, :position)
|
87
112
|
|
88
113
|
# extend +context_lines+ into a set of lines which can be processed by the RText
|
89
114
|
def fix_context(language, context_lines, position_in_line)
|
@@ -95,11 +120,14 @@ module ContextBuilder
|
|
95
120
|
position_in_line ||= context_lines.last.size
|
96
121
|
# cut off last line right of cursor
|
97
122
|
if position_in_line < 1
|
98
|
-
context_lines.pop
|
123
|
+
tail = context_lines.pop
|
99
124
|
context_lines << ""
|
100
125
|
else
|
126
|
+
tail = context_lines.last[position_in_line..-1]
|
101
127
|
context_lines << context_lines.pop[0..position_in_line-1]
|
102
128
|
end
|
129
|
+
before_brace = !tail.nil? && !tail.match(/^\s*\{/).nil?
|
130
|
+
before_bracket = !tail.nil? && !tail.match(/^\s*\[/).nil?
|
103
131
|
problem = nil
|
104
132
|
line = context_lines.last
|
105
133
|
if line =~ /\{\s*$/
|
@@ -110,7 +138,7 @@ module ContextBuilder
|
|
110
138
|
problem = :after_curly
|
111
139
|
end
|
112
140
|
|
113
|
-
num_elements = in_block = in_array = missing_comma = role = prefix = nil
|
141
|
+
num_elements = in_block = in_array = missing_comma = role = prefix = after_comma = nil
|
114
142
|
tokens = tokenize(line, language.reference_regexp)
|
115
143
|
tokens.pop if tokens.last && tokens.last.kind == :newline
|
116
144
|
if tokens.size > 0 && tokens[0].kind == :identifier
|
@@ -124,6 +152,7 @@ module ContextBuilder
|
|
124
152
|
unlabled_index = 0
|
125
153
|
tokens[1..-1].each do |token|
|
126
154
|
break if token.kind == :error
|
155
|
+
after_comma = false
|
127
156
|
if token.kind == "["
|
128
157
|
in_array = true
|
129
158
|
elsif token.kind == "]"
|
@@ -136,6 +165,7 @@ module ContextBuilder
|
|
136
165
|
missing_comma = false
|
137
166
|
role = nil unless in_array
|
138
167
|
unlabled_index += 1 unless in_array
|
168
|
+
after_comma = true
|
139
169
|
end
|
140
170
|
end
|
141
171
|
if ((tokens.size == 1 && line =~ /\s+$/) ||
|
@@ -187,6 +217,16 @@ module ContextBuilder
|
|
187
217
|
if context_lines[-2] =~ /^\s*\w+:\s*$/
|
188
218
|
context_lines[-1] = context_lines.pop
|
189
219
|
end
|
220
|
+
elsif tokens.size == 1 && tokens[0].kind == :label
|
221
|
+
token = tokens[0]
|
222
|
+
role = context_lines.last[token.scol - 1..token.ecol - 2]
|
223
|
+
context_lines << context_lines.pop[0..token.scol - 2]
|
224
|
+
context = fix_context(language, context_lines, context_lines.last.size)
|
225
|
+
context.role = role
|
226
|
+
context.position.in_block = false
|
227
|
+
context.position.before_brace = before_brace
|
228
|
+
context.position.before_bracket = before_bracket
|
229
|
+
return context
|
190
230
|
else
|
191
231
|
# comment, closing brackets, etc.
|
192
232
|
num_elements = 0
|
@@ -210,7 +250,8 @@ module ContextBuilder
|
|
210
250
|
end
|
211
251
|
end
|
212
252
|
problem = :missing_comma if !problem && missing_comma
|
213
|
-
ContextInternal.new(context_lines, num_elements, role, prefix,
|
253
|
+
ContextInternal.new(context_lines, num_elements, role, prefix, problem,
|
254
|
+
PositionContext.new(in_array, in_block, false, after_comma, before_brace, before_bracket))
|
214
255
|
end
|
215
256
|
|
216
257
|
def find_role(context_lines)
|
@@ -4,7 +4,33 @@ module RText
|
|
4
4
|
|
5
5
|
class DefaultCompleter
|
6
6
|
|
7
|
-
CompletionOption
|
7
|
+
class CompletionOption
|
8
|
+
|
9
|
+
attr_accessor :insert
|
10
|
+
attr_accessor :display
|
11
|
+
attr_accessor :extra
|
12
|
+
attr_accessor :description
|
13
|
+
|
14
|
+
def self.from_text_extra(text, extra)
|
15
|
+
self.new(text, text + ' ' + extra, nil, extra)
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.for_curly_braces(context)
|
19
|
+
self.new("{\n#{context.line_indent}#{context.indent}||\n#{context.line_indent}}", '{}')
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.for_square_brackets
|
23
|
+
self.new('[ || ]', '[]', '')
|
24
|
+
end
|
25
|
+
|
26
|
+
def initialize(insert, display, description=nil, extra=nil)
|
27
|
+
@insert = insert
|
28
|
+
@display = display
|
29
|
+
@description = description
|
30
|
+
@extra = extra
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
8
34
|
|
9
35
|
# Creates a completer for RText::Language +language+.
|
10
36
|
#
|
@@ -14,23 +40,24 @@ class DefaultCompleter
|
|
14
40
|
|
15
41
|
# Provides completion options
|
16
42
|
#
|
17
|
-
def complete(context)
|
43
|
+
def complete(context, version=0)
|
18
44
|
clazz = context && context.element && context.element.class.ecore
|
19
45
|
if clazz
|
20
|
-
if context.in_block
|
46
|
+
if context.position.in_block
|
21
47
|
block_options(context, clazz)
|
22
48
|
elsif !context.problem
|
23
49
|
result = []
|
24
|
-
if context.feature
|
25
|
-
|
26
|
-
end
|
27
|
-
if !context.after_label
|
28
|
-
add_label_options(context, clazz, result)
|
29
|
-
end
|
50
|
+
add_value_options(context, result, version) if context.feature
|
51
|
+
add_label_options(context, clazz, result, version) unless context.position.after_label
|
30
52
|
result
|
31
53
|
else
|
32
54
|
# missing comma, after curly brace, etc.
|
33
|
-
|
55
|
+
if version > 0 && !context.position.before_brace &&
|
56
|
+
context.element.class.ecore.eAllReferences.any? { |r| r.containment }
|
57
|
+
[CompletionOption.for_curly_braces(context)]
|
58
|
+
else
|
59
|
+
[]
|
60
|
+
end
|
34
61
|
end
|
35
62
|
elsif context
|
36
63
|
root_options
|
@@ -52,7 +79,7 @@ class DefaultCompleter
|
|
52
79
|
# all target types which don't need a label
|
53
80
|
# and all lables which are needed by a potential target type
|
54
81
|
@lang.containments(clazz).each do |r|
|
55
|
-
([r.eType] + r.eType.eAllSubTypes).select{|t|
|
82
|
+
([r.eType] + r.eType.eAllSubTypes).select{|t| t.concrete}.each do |t|
|
56
83
|
if @lang.labeled_containment?(clazz, r) || @lang.containments_by_target_type(clazz, t).size > 1
|
57
84
|
labled_refs << r
|
58
85
|
else
|
@@ -66,14 +93,17 @@ class DefaultCompleter
|
|
66
93
|
class_completion_option(c)
|
67
94
|
end +
|
68
95
|
labled_refs.uniq.collect do |r|
|
69
|
-
CompletionOption.
|
96
|
+
CompletionOption.from_text_extra("#{r.name}:", "<#{r.eType.name}>")
|
70
97
|
end
|
71
98
|
end
|
72
99
|
|
73
|
-
def add_value_options(context, result)
|
100
|
+
def add_value_options(context, result, version)
|
74
101
|
if context.feature.is_a?(RGen::ECore::EAttribute) || !context.feature.containment
|
75
102
|
if context.feature.is_a?(RGen::ECore::EReference)
|
76
103
|
result.concat(reference_options(context))
|
104
|
+
if version > 0 && !context.position.before_bracket && context.feature.upperBound != 1
|
105
|
+
result << CompletionOption.for_square_brackets
|
106
|
+
end
|
77
107
|
elsif context.feature.eType.is_a?(RGen::ECore::EEnum)
|
78
108
|
result.concat(enum_options(context))
|
79
109
|
elsif context.feature.eType.instanceClass == String
|
@@ -88,16 +118,22 @@ class DefaultCompleter
|
|
88
118
|
# no options
|
89
119
|
end
|
90
120
|
else
|
91
|
-
|
121
|
+
if version > 0 && !context.position.before_bracket && context.feature.upperBound != 1
|
122
|
+
result << CompletionOption.for_square_brackets
|
123
|
+
end
|
92
124
|
end
|
93
125
|
end
|
94
126
|
|
95
|
-
def add_label_options(context, clazz, result)
|
127
|
+
def add_label_options(context, clazz, result, version)
|
96
128
|
result.concat(@lang.labled_arguments(clazz).
|
97
129
|
select{|f|
|
98
130
|
!context.element.eIsSet(f.name)}.collect do |f|
|
99
|
-
CompletionOption.
|
100
|
-
|
131
|
+
CompletionOption.from_text_extra("#{f.name}:", "<#{f.eType.name}>")
|
132
|
+
end )
|
133
|
+
if version > 0 && !context.position.after_comma &&
|
134
|
+
context.element.class.ecore.eAllReferences.any? { |r| r.containment } && !context.position.before_brace
|
135
|
+
result << CompletionOption.for_curly_braces(context)
|
136
|
+
end
|
101
137
|
end
|
102
138
|
|
103
139
|
def root_options
|
@@ -118,34 +154,43 @@ class DefaultCompleter
|
|
118
154
|
lname = "\"#{lname.gsub("\\","\\\\\\\\").gsub("\"","\\\"").gsub("\n","\\n").
|
119
155
|
gsub("\r","\\r").gsub("\t","\\t").gsub("\f","\\f").gsub("\b","\\b")}\""
|
120
156
|
end
|
121
|
-
CompletionOption.
|
157
|
+
CompletionOption.from_text_extra("#{lname}", "<#{context.feature.eType.name}>")
|
122
158
|
end
|
123
159
|
end
|
124
160
|
|
125
161
|
def string_options(context)
|
126
162
|
if @lang.unquoted?(context.feature)
|
127
|
-
[ CompletionOption.
|
163
|
+
[ CompletionOption.from_text_extra("#{context.feature.name.gsub(/\W/,"")}", value_description(context)) ]
|
128
164
|
else
|
129
|
-
[ CompletionOption.
|
165
|
+
[ CompletionOption.from_text_extra("\"\"", value_description(context)) ]
|
130
166
|
end
|
131
167
|
end
|
132
168
|
|
169
|
+
def get_default_value_completion(context)
|
170
|
+
return nil unless context.feature.defaultValue
|
171
|
+
CompletionOption.from_text_extra("#{context.feature.defaultValue}", value_description(context))
|
172
|
+
end
|
173
|
+
|
133
174
|
def integer_options(context)
|
134
|
-
|
175
|
+
default_comp = get_default_value_completion(context)
|
176
|
+
return [default_comp] if default_comp
|
177
|
+
(0..0).collect{|i| CompletionOption.from_text_extra("#{i}", value_description(context)) }
|
135
178
|
end
|
136
179
|
|
137
180
|
def float_options(context)
|
138
|
-
|
181
|
+
default_comp = get_default_value_completion(context)
|
182
|
+
return [default_comp] if default_comp
|
183
|
+
(0..0).collect{|i| CompletionOption.from_text_extra("#{i}.0", value_description(context)) }
|
139
184
|
end
|
140
185
|
|
141
186
|
def boolean_options(context)
|
142
|
-
[true, false].collect{|b| CompletionOption.
|
187
|
+
[true, false].collect{|b| CompletionOption.from_text_extra("#{b}", value_description(context)) }
|
143
188
|
end
|
144
189
|
|
145
190
|
private
|
146
191
|
|
147
192
|
def value_description(context)
|
148
|
-
if context.after_label
|
193
|
+
if context.position.after_label
|
149
194
|
"<#{context.feature.eType.name}>"
|
150
195
|
else
|
151
196
|
"[#{context.feature.name}] <#{context.feature.eType.name}>"
|
@@ -154,7 +199,7 @@ class DefaultCompleter
|
|
154
199
|
|
155
200
|
def class_completion_option(eclass)
|
156
201
|
uargs = @lang.unlabled_arguments(eclass).collect{|a| "<#{a.name}>"}.join(", ")
|
157
|
-
CompletionOption.
|
202
|
+
CompletionOption.from_text_extra(@lang.command_by_class(eclass.instanceClass), uargs)
|
158
203
|
end
|
159
204
|
|
160
205
|
end
|
@@ -35,17 +35,17 @@ class DefaultServiceProvider
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
-
def get_completion_options(context)
|
38
|
+
def get_completion_options(context, version=0)
|
39
39
|
completer = RText::DefaultCompleter.new(@lang)
|
40
40
|
class << completer
|
41
41
|
attr_accessor :service_provider
|
42
42
|
def reference_options(context)
|
43
43
|
service_provider.get_reference_completion_options(context).collect {|o|
|
44
|
-
DefaultCompleter::CompletionOption.
|
44
|
+
DefaultCompleter::CompletionOption.from_text_extra(o.identifier, "<#{o.type}>")}
|
45
45
|
end
|
46
46
|
end
|
47
47
|
completer.service_provider = self
|
48
|
-
completer.complete(context)
|
48
|
+
completer.complete(context, version)
|
49
49
|
end
|
50
50
|
|
51
51
|
ReferenceCompletionOption = Struct.new(:identifier, :type)
|