rucoa 0.5.1 → 0.6.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/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
|

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