rtext 0.8.2 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- 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)
|