rucoa 0.5.1 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +12 -13
- data/lib/rucoa/cli.rb +3 -2
- data/lib/rucoa/configuration.rb +69 -16
- data/lib/rucoa/handlers/initialize_handler.rb +7 -0
- data/lib/rucoa/handlers/text_document_completion_handler.rb +216 -0
- data/lib/rucoa/handlers/text_document_hover_handler.rb +76 -0
- data/lib/rucoa/handlers.rb +2 -0
- data/lib/rucoa/position.rb +12 -1
- data/lib/rucoa/server.rb +44 -12
- data/lib/rucoa/source.rb +5 -0
- data/lib/rucoa/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f31a0a81d1013267e3bfc0358911e1306e22f0b34f40249604050914da18d8f4
|
4
|
+
data.tar.gz: b999e9fe78ee1dbb0b11662756c84399b474fb8522476429c90becb454fb0fd1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1af0f2fed0d7d7930f69768234263e77707f1f22d80e93392ae126c0cfa72d11b3356de6ba5c6f3476ff7b3f27239c1667ac1c2442e9e12301bdadb0a25fec47
|
7
|
+
data.tar.gz: bdd44ba9cb0284a16589798ec20ee7d9e9bf01989e054108859f3f8286a3f6382a45d84be056dd7a755de8b14d4cf9e28610652489e8e57f9c009b1f81c7f432
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -15,15 +15,6 @@ To install rucoa gem, if your project is managed by bundler, add to your Gemfile
|
|
15
15
|
gem 'rucoa'
|
16
16
|
```
|
17
17
|
|
18
|
-
or in Rails application, we'll recommend you to do like this:
|
19
|
-
|
20
|
-
```ruby
|
21
|
-
# Gemfile
|
22
|
-
group :development do
|
23
|
-
gem 'rucoa', require: false
|
24
|
-
end
|
25
|
-
```
|
26
|
-
|
27
18
|
If bundler is not being used to manage dependencies, simply install the gem:
|
28
19
|
|
29
20
|
```bash
|
@@ -65,14 +56,22 @@ This extension supports the folowiing types of symbols:
|
|
65
56
|
|
66
57
|
![demo](images/document-symbol.gif)
|
67
58
|
|
68
|
-
|
59
|
+
## Experimental features
|
60
|
+
|
61
|
+
### Completion
|
62
|
+
|
63
|
+
Provides completion items for constant names and method names.
|
64
|
+
|
65
|
+
### Hover
|
66
|
+
|
67
|
+
Shows documentation for the symbol under the cursor.
|
68
|
+
|
69
|
+
### Signature help
|
69
70
|
|
70
71
|
Shows method signature help when you start to type method arguments like `"100".to_i(`.
|
71
72
|
|
72
|
-
|
73
|
+
## Coming soon
|
73
74
|
|
74
|
-
- Completion
|
75
|
-
- Documentation
|
76
75
|
- Go to Definition
|
77
76
|
- Highlight
|
78
77
|
- Semantic Tokens
|
data/lib/rucoa/cli.rb
CHANGED
data/lib/rucoa/configuration.rb
CHANGED
@@ -8,62 +8,108 @@ module Rucoa
|
|
8
8
|
|
9
9
|
# @return [void]
|
10
10
|
def disable_code_action
|
11
|
-
|
11
|
+
disable_feature('codeAction')
|
12
|
+
end
|
13
|
+
|
14
|
+
# @return [void]
|
15
|
+
def disable_completion
|
16
|
+
disable_feature('completion')
|
12
17
|
end
|
13
18
|
|
14
19
|
# @return [void]
|
15
20
|
def disable_diagnostics
|
16
|
-
|
21
|
+
disable_feature('diagnostics')
|
17
22
|
end
|
18
23
|
|
19
24
|
# @return [void]
|
20
25
|
def disable_document_symbol
|
21
|
-
|
26
|
+
disable_feature('documentSymbol')
|
22
27
|
end
|
23
28
|
|
24
29
|
# @return [void]
|
25
30
|
def disable_formatting
|
26
|
-
|
31
|
+
disable_feature('formatting')
|
32
|
+
end
|
33
|
+
|
34
|
+
# @return [void]
|
35
|
+
def disable_hover
|
36
|
+
disable_feature('hover')
|
27
37
|
end
|
28
38
|
|
29
39
|
# @return [void]
|
30
40
|
def disable_selection_range
|
31
|
-
|
41
|
+
disable_feature('selectionRange')
|
32
42
|
end
|
33
43
|
|
34
44
|
# @return [void]
|
35
45
|
def disable_signature_help
|
36
|
-
|
46
|
+
disable_feature('signatureHelp')
|
47
|
+
end
|
48
|
+
|
49
|
+
# @return [void]
|
50
|
+
def enable_debug
|
51
|
+
@settings ||= {}
|
52
|
+
@settings['base'] ||= {}
|
53
|
+
@settings['base']['debug'] = true
|
37
54
|
end
|
38
55
|
|
39
56
|
# @return [Boolean]
|
57
|
+
# @example returns false if the configuration is empty
|
58
|
+
# configuration = Rucoa::Configuration.new
|
59
|
+
# expect(configuration).not_to be_enables_debug
|
60
|
+
# @example returns true if the configuration enables debug
|
61
|
+
# configuration = Rucoa::Configuration.new
|
62
|
+
# configuration.update('base' => { 'debug' => true })
|
63
|
+
# expect(configuration).to be_enables_debug
|
64
|
+
def enables_debug?
|
65
|
+
fetch('base', 'debug', default: false)
|
66
|
+
end
|
67
|
+
|
68
|
+
# @return [Boolean]
|
69
|
+
# @example returns true if the configuration is empty
|
70
|
+
# configuration = Rucoa::Configuration.new
|
71
|
+
# expect(configuration).to be_enables_code_action
|
72
|
+
# @example returns false if the configuration disables code action
|
73
|
+
# configuration = Rucoa::Configuration.new
|
74
|
+
# configuration.disable_code_action
|
75
|
+
# expect(configuration).not_to be_enables_code_action
|
40
76
|
def enables_code_action?
|
41
|
-
|
77
|
+
enables_feature?('codeAction')
|
78
|
+
end
|
79
|
+
|
80
|
+
# @return [Boolean]
|
81
|
+
def enables_completion?
|
82
|
+
enables_feature?('completion')
|
42
83
|
end
|
43
84
|
|
44
85
|
# @return [Boolean]
|
45
86
|
def enables_diagnostics?
|
46
|
-
|
87
|
+
enables_feature?('diagnostics')
|
47
88
|
end
|
48
89
|
|
49
90
|
# @return [Boolean]
|
50
91
|
def enables_document_symbol?
|
51
|
-
|
92
|
+
enables_feature?('documentSymbol')
|
52
93
|
end
|
53
94
|
|
54
95
|
# @return [Boolean]
|
55
96
|
def enables_formatting?
|
56
|
-
|
97
|
+
enables_feature?('formatting')
|
98
|
+
end
|
99
|
+
|
100
|
+
# @return [Boolean]
|
101
|
+
def enables_hover?
|
102
|
+
enables_feature?('hover')
|
57
103
|
end
|
58
104
|
|
59
105
|
# @return [Boolean]
|
60
106
|
def enables_selection_range?
|
61
|
-
|
107
|
+
enables_feature?('selectionRange')
|
62
108
|
end
|
63
109
|
|
64
110
|
# @return [Boolean]
|
65
111
|
def enables_signature_help?
|
66
|
-
|
112
|
+
enables_feature?('signatureHelp')
|
67
113
|
end
|
68
114
|
|
69
115
|
# @param settings [Hash]
|
@@ -76,7 +122,7 @@ module Rucoa
|
|
76
122
|
|
77
123
|
# @param feature [String]
|
78
124
|
# @return [void]
|
79
|
-
def
|
125
|
+
def disable_feature(feature)
|
80
126
|
@settings ||= {}
|
81
127
|
@settings['feature'] ||= {}
|
82
128
|
@settings['feature'][feature] ||= {}
|
@@ -85,10 +131,17 @@ module Rucoa
|
|
85
131
|
|
86
132
|
# @param feature [String]
|
87
133
|
# @return [Boolean]
|
88
|
-
def
|
89
|
-
|
134
|
+
def enables_feature?(feature)
|
135
|
+
fetch('feature', feature, 'enable', default: true)
|
136
|
+
end
|
137
|
+
|
138
|
+
# @param keys [Array<String>]
|
139
|
+
# @param default [Object]
|
140
|
+
# @return [Object]
|
141
|
+
def fetch(*keys, default:)
|
142
|
+
value = @settings.dig(*keys)
|
90
143
|
if value.nil?
|
91
|
-
|
144
|
+
default
|
92
145
|
else
|
93
146
|
value
|
94
147
|
end
|
@@ -7,9 +7,16 @@ module Rucoa
|
|
7
7
|
respond(
|
8
8
|
capabilities: {
|
9
9
|
codeActionProvider: true,
|
10
|
+
completionProvider: {
|
11
|
+
resolveProvider: true,
|
12
|
+
triggerCharacters: %w[
|
13
|
+
.
|
14
|
+
]
|
15
|
+
},
|
10
16
|
documentFormattingProvider: true,
|
11
17
|
documentRangeFormattingProvider: true,
|
12
18
|
documentSymbolProvider: true,
|
19
|
+
hoverProvider: true,
|
13
20
|
selectionRangeProvider: true,
|
14
21
|
signatureHelpProvider: {
|
15
22
|
triggerCharacters: %w[
|
@@ -0,0 +1,216 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Rucoa
|
4
|
+
module Handlers
|
5
|
+
class TextDocumentCompletionHandler < Base
|
6
|
+
COMPLETION_ITEM_KIND_FOR_TEXT = 1
|
7
|
+
COMPLETION_ITEM_KIND_FOR_METHOD = 2
|
8
|
+
COMPLETION_ITEM_KIND_FOR_FUNCTION = 3
|
9
|
+
COMPLETION_ITEM_KIND_FOR_CONSTRUCTOR = 4
|
10
|
+
COMPLETION_ITEM_KIND_FOR_FIELD = 5
|
11
|
+
COMPLETION_ITEM_KIND_FOR_VARIABLE = 6
|
12
|
+
COMPLETION_ITEM_KIND_FOR_CLASS = 7
|
13
|
+
COMPLETION_ITEM_KIND_FOR_INTERFACE = 8
|
14
|
+
COMPLETION_ITEM_KIND_FOR_MODULE = 9
|
15
|
+
COMPLETION_ITEM_KIND_FOR_PROPERTY = 10
|
16
|
+
COMPLETION_ITEM_KIND_FOR_UNIT = 11
|
17
|
+
COMPLETION_ITEM_KIND_FOR_VALUE = 12
|
18
|
+
COMPLETION_ITEM_KIND_FOR_ENUM = 13
|
19
|
+
COMPLETION_ITEM_KIND_FOR_KEYWORD = 14
|
20
|
+
COMPLETION_ITEM_KIND_FOR_SNIPPET = 15
|
21
|
+
COMPLETION_ITEM_KIND_FOR_COLOR = 16
|
22
|
+
COMPLETION_ITEM_KIND_FOR_FILE = 17
|
23
|
+
COMPLETION_ITEM_KIND_FOR_REFERENCE = 18
|
24
|
+
COMPLETION_ITEM_KIND_FOR_FOLDER = 19
|
25
|
+
COMPLETION_ITEM_KIND_FOR_ENUM_MEMBER = 20
|
26
|
+
COMPLETION_ITEM_KIND_FOR_CONSTANT = 21
|
27
|
+
COMPLETION_ITEM_KIND_FOR_STRUCT = 22
|
28
|
+
COMPLETION_ITEM_KIND_FOR_EVENT = 23
|
29
|
+
COMPLETION_ITEM_KIND_FOR_OPERATOR = 24
|
30
|
+
COMPLETION_ITEM_KIND_FOR_TYPE_PARAMETER = 25
|
31
|
+
|
32
|
+
EXAMPLE_IDENTIFIER = 'a'
|
33
|
+
private_constant :EXAMPLE_IDENTIFIER
|
34
|
+
|
35
|
+
def call
|
36
|
+
respond(completion_items)
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
# @return [Array<Hash>, nil]
|
42
|
+
def completion_items
|
43
|
+
return unless responsible?
|
44
|
+
|
45
|
+
case node
|
46
|
+
when Nodes::ConstNode
|
47
|
+
completion_items_for_constant
|
48
|
+
when Nodes::SendNode
|
49
|
+
if node.location.dot&.is?('::')
|
50
|
+
completion_items_for_constant
|
51
|
+
else
|
52
|
+
completion_items_for_method
|
53
|
+
end
|
54
|
+
else
|
55
|
+
[]
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# @return [Boolean]
|
60
|
+
def responsible?
|
61
|
+
configuration.enables_completion? &&
|
62
|
+
!source.nil?
|
63
|
+
end
|
64
|
+
|
65
|
+
# @return [Rucoa::Source, nil]
|
66
|
+
def source
|
67
|
+
@source ||= source_store.get(uri)
|
68
|
+
end
|
69
|
+
|
70
|
+
# @return [Rucoa::Position]
|
71
|
+
def position
|
72
|
+
@position ||= Position.from_vscode_position(
|
73
|
+
request.dig('params', 'position')
|
74
|
+
)
|
75
|
+
end
|
76
|
+
|
77
|
+
# @return [String]
|
78
|
+
def uri
|
79
|
+
request.dig('params', 'textDocument', 'uri')
|
80
|
+
end
|
81
|
+
|
82
|
+
# @return [Array<Hash>]
|
83
|
+
def completion_items_for_method
|
84
|
+
completable_method_names.map do |method_name|
|
85
|
+
{
|
86
|
+
kind: COMPLETION_ITEM_KIND_FOR_METHOD,
|
87
|
+
label: method_name,
|
88
|
+
textEdit: {
|
89
|
+
newText: method_name,
|
90
|
+
range: range.to_vscode_range
|
91
|
+
}
|
92
|
+
}
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# @return [Array<Hash>]
|
97
|
+
def completion_items_for_constant
|
98
|
+
completable_constant_names.map do |constant_name|
|
99
|
+
{
|
100
|
+
kind: COMPLETION_ITEM_KIND_FOR_CONSTANT,
|
101
|
+
label: constant_name,
|
102
|
+
textEdit: {
|
103
|
+
newText: constant_name,
|
104
|
+
range: range.to_vscode_range
|
105
|
+
}
|
106
|
+
}
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
# @return [Array<String>]
|
111
|
+
def completable_constant_names
|
112
|
+
referrable_constant_names.select do |constant_name|
|
113
|
+
constant_name.start_with?(completion_head)
|
114
|
+
end.sort
|
115
|
+
end
|
116
|
+
|
117
|
+
# @return [String] e.g. "SE" to `File::SE|`, "ba" to `foo.ba|`
|
118
|
+
def completion_head
|
119
|
+
@completion_head ||=
|
120
|
+
if @repaired
|
121
|
+
''
|
122
|
+
else
|
123
|
+
node.name
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def referrable_constant_names
|
128
|
+
definition_store.constant_definitions_under(constant_namespace).map(&:name).uniq
|
129
|
+
end
|
130
|
+
|
131
|
+
# @return [String] e.g. "Foo::Bar" to `Foo::Bar.baz|`.
|
132
|
+
def constant_namespace
|
133
|
+
node.each_child_node(:const).map(&:name).reverse.join('::')
|
134
|
+
end
|
135
|
+
|
136
|
+
# @return [Array<String>]
|
137
|
+
def completable_method_names
|
138
|
+
callable_method_names.select do |method_name|
|
139
|
+
method_name.start_with?(completion_head)
|
140
|
+
end.sort
|
141
|
+
end
|
142
|
+
|
143
|
+
# @return [Array<String>]
|
144
|
+
def callable_method_names
|
145
|
+
callable_method_definitions.map(&:method_name).uniq
|
146
|
+
end
|
147
|
+
|
148
|
+
# @return [Array<String>]
|
149
|
+
def callable_method_definitions
|
150
|
+
receiver_types.flat_map do |type|
|
151
|
+
definition_store.method_definitions_of(type)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
# @return [Array<String>]
|
156
|
+
def receiver_types
|
157
|
+
NodeInspector.new(
|
158
|
+
definition_store: definition_store,
|
159
|
+
node: node
|
160
|
+
).method_receiver_types
|
161
|
+
end
|
162
|
+
|
163
|
+
# @return [Rucoa::Node, nil]
|
164
|
+
def node
|
165
|
+
@node ||=
|
166
|
+
if source.syntax_error?
|
167
|
+
repair
|
168
|
+
repaired_node
|
169
|
+
else
|
170
|
+
normal_node
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
# @return [Rucoa::Node, nil]
|
175
|
+
def normal_node
|
176
|
+
source.node_at(position)
|
177
|
+
end
|
178
|
+
|
179
|
+
# @return [Rucoa::Node, nil]
|
180
|
+
def repaired_node
|
181
|
+
repaired_source.node_at(position)
|
182
|
+
end
|
183
|
+
|
184
|
+
# @return [void]
|
185
|
+
def repair
|
186
|
+
@repaired = true
|
187
|
+
end
|
188
|
+
|
189
|
+
# @return [String]
|
190
|
+
def repaired_content
|
191
|
+
source.content.dup.insert(
|
192
|
+
position.to_index_of(source.content),
|
193
|
+
EXAMPLE_IDENTIFIER
|
194
|
+
)
|
195
|
+
end
|
196
|
+
|
197
|
+
# @return [Rucoa::Source]
|
198
|
+
def repaired_source
|
199
|
+
Source.new(
|
200
|
+
content: repaired_content,
|
201
|
+
uri: source.uri
|
202
|
+
)
|
203
|
+
end
|
204
|
+
|
205
|
+
# @return [Rucoa::Range]
|
206
|
+
def range
|
207
|
+
@range ||=
|
208
|
+
if @repaired
|
209
|
+
position.to_range
|
210
|
+
else
|
211
|
+
Range.from_parser_range(node.location.expression)
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Rucoa
|
4
|
+
module Handlers
|
5
|
+
class TextDocumentHoverHandler < Base
|
6
|
+
def call
|
7
|
+
respond(hover)
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
# @return [Hash, nil]
|
13
|
+
def hover
|
14
|
+
return unless responsible?
|
15
|
+
|
16
|
+
{
|
17
|
+
contents: contents,
|
18
|
+
range: range.to_vscode_range
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
# @return [Boolean]
|
23
|
+
def responsible?
|
24
|
+
configuration.enables_hover? &&
|
25
|
+
!source.nil? &&
|
26
|
+
!node.nil?
|
27
|
+
end
|
28
|
+
|
29
|
+
# @return [String, nil]
|
30
|
+
def contents
|
31
|
+
method_definition = method_definitions.first
|
32
|
+
return unless method_definition
|
33
|
+
|
34
|
+
[
|
35
|
+
method_definition.signatures.join("\n"),
|
36
|
+
method_definition.description
|
37
|
+
].join("\n\n")
|
38
|
+
end
|
39
|
+
|
40
|
+
# @return [Rucoa::Range]
|
41
|
+
def range
|
42
|
+
Range.from_parser_range(node.location.expression)
|
43
|
+
end
|
44
|
+
|
45
|
+
# @return [Rucoa::Nodes::Base, nil]
|
46
|
+
def node
|
47
|
+
@node ||= source.node_at(position)
|
48
|
+
end
|
49
|
+
|
50
|
+
# @return [Rucoa::Source, nil]
|
51
|
+
def source
|
52
|
+
@source ||= source_store.get(uri)
|
53
|
+
end
|
54
|
+
|
55
|
+
# @return [String]
|
56
|
+
def uri
|
57
|
+
request.dig('params', 'textDocument', 'uri')
|
58
|
+
end
|
59
|
+
|
60
|
+
# @return [Rucoa::Position]
|
61
|
+
def position
|
62
|
+
Position.from_vscode_position(
|
63
|
+
request.dig('params', 'position')
|
64
|
+
)
|
65
|
+
end
|
66
|
+
|
67
|
+
# @return [Array<Rucoa::Definitions::MethodDefinition>]
|
68
|
+
def method_definitions
|
69
|
+
NodeInspector.new(
|
70
|
+
definition_store: definition_store,
|
71
|
+
node: node
|
72
|
+
).method_definitions
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
data/lib/rucoa/handlers.rb
CHANGED
@@ -8,10 +8,12 @@ module Rucoa
|
|
8
8
|
autoload :InitializedHandler, 'rucoa/handlers/initialized_handler'
|
9
9
|
autoload :ShutdownHandler, 'rucoa/handlers/shutdown_handler'
|
10
10
|
autoload :TextDocumentCodeActionHandler, 'rucoa/handlers/text_document_code_action_handler'
|
11
|
+
autoload :TextDocumentCompletionHandler, 'rucoa/handlers/text_document_completion_handler'
|
11
12
|
autoload :TextDocumentDidChangeHandler, 'rucoa/handlers/text_document_did_change_handler'
|
12
13
|
autoload :TextDocumentDidOpenHandler, 'rucoa/handlers/text_document_did_open_handler'
|
13
14
|
autoload :TextDocumentDocumentSymbolHandler, 'rucoa/handlers/text_document_document_symbol_handler'
|
14
15
|
autoload :TextDocumentFormattingHandler, 'rucoa/handlers/text_document_formatting_handler'
|
16
|
+
autoload :TextDocumentHoverHandler, 'rucoa/handlers/text_document_hover_handler'
|
15
17
|
autoload :TextDocumentRangeFormattingHandler, 'rucoa/handlers/text_document_range_formatting_handler'
|
16
18
|
autoload :TextDocumentSelectionRangeHandler, 'rucoa/handlers/text_document_selection_range_handler'
|
17
19
|
autoload :TextDocumentSignatureHelpHandler, 'rucoa/handlers/text_document_signature_help_handler'
|
data/lib/rucoa/position.rb
CHANGED
@@ -21,7 +21,7 @@ module Rucoa
|
|
21
21
|
)
|
22
22
|
end
|
23
23
|
|
24
|
-
# @param hash [Hash{
|
24
|
+
# @param hash [Hash{String => Integer}]
|
25
25
|
# @return [Rucoa::Position]
|
26
26
|
def from_vscode_position(hash)
|
27
27
|
new(
|
@@ -44,6 +44,17 @@ module Rucoa
|
|
44
44
|
@line = line
|
45
45
|
end
|
46
46
|
|
47
|
+
# @param text [String]
|
48
|
+
# @return [Integer]
|
49
|
+
def to_index_of(text)
|
50
|
+
text.each_line.take(@line - 1).sum(&:length) + @column
|
51
|
+
end
|
52
|
+
|
53
|
+
# @return [Rucoa::Range]
|
54
|
+
def to_range
|
55
|
+
Range.new(self, self)
|
56
|
+
end
|
57
|
+
|
47
58
|
# @return [Hash]
|
48
59
|
def to_vscode_position
|
49
60
|
{
|
data/lib/rucoa/server.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'logger'
|
4
|
+
require 'stringio'
|
5
|
+
|
3
6
|
module Rucoa
|
4
7
|
class Server
|
5
8
|
# @return [Hash{String => Class}]
|
@@ -9,10 +12,12 @@ module Rucoa
|
|
9
12
|
'initialized' => Handlers::InitializedHandler,
|
10
13
|
'shutdown' => Handlers::ShutdownHandler,
|
11
14
|
'textDocument/codeAction' => Handlers::TextDocumentCodeActionHandler,
|
15
|
+
'textDocument/completion' => Handlers::TextDocumentCompletionHandler,
|
12
16
|
'textDocument/didChange' => Handlers::TextDocumentDidChangeHandler,
|
13
17
|
'textDocument/didOpen' => Handlers::TextDocumentDidOpenHandler,
|
14
18
|
'textDocument/documentSymbol' => Handlers::TextDocumentDocumentSymbolHandler,
|
15
19
|
'textDocument/formatting' => Handlers::TextDocumentFormattingHandler,
|
20
|
+
'textDocument/hover' => Handlers::TextDocumentHoverHandler,
|
16
21
|
'textDocument/rangeFormatting' => Handlers::TextDocumentRangeFormattingHandler,
|
17
22
|
'textDocument/selectionRange' => Handlers::TextDocumentSelectionRangeHandler,
|
18
23
|
'textDocument/signatureHelp' => Handlers::TextDocumentSignatureHelpHandler,
|
@@ -32,11 +37,18 @@ module Rucoa
|
|
32
37
|
# @return [Rucoa::SourceStore]
|
33
38
|
attr_reader :source_store
|
34
39
|
|
35
|
-
# @param
|
36
|
-
# @param
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
+
# @param io_log [IO]
|
41
|
+
# @param io_in [IO]
|
42
|
+
# @param io_out [IO]
|
43
|
+
def initialize(
|
44
|
+
io_log: ::StringIO.new,
|
45
|
+
io_in: ::StringIO.new,
|
46
|
+
io_out: ::StringIO.new
|
47
|
+
)
|
48
|
+
@logger = ::Logger.new(io_log)
|
49
|
+
@logger.level = ::Logger::DEBUG
|
50
|
+
@reader = MessageReader.new(io_in)
|
51
|
+
@writer = MessageWriter.new(io_out)
|
40
52
|
|
41
53
|
@client_response_handlers = {}
|
42
54
|
@configuration = Configuration.new
|
@@ -50,8 +62,14 @@ module Rucoa
|
|
50
62
|
|
51
63
|
# @return [void]
|
52
64
|
def start
|
53
|
-
@reader.read do |
|
54
|
-
|
65
|
+
@reader.read do |message|
|
66
|
+
debug do
|
67
|
+
{
|
68
|
+
kind: :read,
|
69
|
+
message: message
|
70
|
+
}
|
71
|
+
end
|
72
|
+
handle(message)
|
55
73
|
end
|
56
74
|
end
|
57
75
|
|
@@ -91,6 +109,11 @@ module Rucoa
|
|
91
109
|
end
|
92
110
|
end
|
93
111
|
|
112
|
+
# @yieldparam log [String]
|
113
|
+
def debug(&block)
|
114
|
+
@logger.debug(&block) if configuration.enables_debug?
|
115
|
+
end
|
116
|
+
|
94
117
|
# @param request [Hash]
|
95
118
|
# @return [void]
|
96
119
|
def handle_client_request(request)
|
@@ -115,11 +138,14 @@ module Rucoa
|
|
115
138
|
# @param message [Hash]
|
116
139
|
# @return [void]
|
117
140
|
def write_server_request(message, &block)
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
141
|
+
message = message.merge('id' => @server_request_id)
|
142
|
+
debug do
|
143
|
+
{
|
144
|
+
kind: :write,
|
145
|
+
message: message
|
146
|
+
}
|
147
|
+
end
|
148
|
+
@writer.write(message)
|
123
149
|
@client_response_handlers[@server_request_id] = block
|
124
150
|
@server_request_id += 1
|
125
151
|
end
|
@@ -127,6 +153,12 @@ module Rucoa
|
|
127
153
|
# @param message [Hash]
|
128
154
|
# @return [void]
|
129
155
|
def write_server_response(message)
|
156
|
+
debug do
|
157
|
+
{
|
158
|
+
kind: :write,
|
159
|
+
message: message
|
160
|
+
}
|
161
|
+
end
|
130
162
|
@writer.write(message)
|
131
163
|
end
|
132
164
|
end
|
data/lib/rucoa/source.rb
CHANGED
data/lib/rucoa/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rucoa
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryo Nakamura
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-09-
|
11
|
+
date: 2022-09-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parser
|
@@ -113,10 +113,12 @@ files:
|
|
113
113
|
- lib/rucoa/handlers/initialized_handler.rb
|
114
114
|
- lib/rucoa/handlers/shutdown_handler.rb
|
115
115
|
- lib/rucoa/handlers/text_document_code_action_handler.rb
|
116
|
+
- lib/rucoa/handlers/text_document_completion_handler.rb
|
116
117
|
- lib/rucoa/handlers/text_document_did_change_handler.rb
|
117
118
|
- lib/rucoa/handlers/text_document_did_open_handler.rb
|
118
119
|
- lib/rucoa/handlers/text_document_document_symbol_handler.rb
|
119
120
|
- lib/rucoa/handlers/text_document_formatting_handler.rb
|
121
|
+
- lib/rucoa/handlers/text_document_hover_handler.rb
|
120
122
|
- lib/rucoa/handlers/text_document_range_formatting_handler.rb
|
121
123
|
- lib/rucoa/handlers/text_document_selection_range_handler.rb
|
122
124
|
- lib/rucoa/handlers/text_document_signature_help_handler.rb
|