rucoa 0.5.1 → 0.7.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/data/definitions_ruby_3_1 +0 -0
- data/lib/rucoa/cli.rb +3 -2
- data/lib/rucoa/configuration.rb +69 -16
- data/lib/rucoa/handler_concerns/diagnostics_publishable.rb +14 -2
- data/lib/rucoa/handlers/initialize_handler.rb +7 -0
- data/lib/rucoa/handlers/initialized_handler.rb +1 -1
- data/lib/rucoa/handlers/text_document_completion_handler.rb +223 -0
- data/lib/rucoa/handlers/text_document_did_close_handler.rb +20 -0
- data/lib/rucoa/handlers/text_document_formatting_handler.rb +2 -2
- data/lib/rucoa/handlers/text_document_hover_handler.rb +76 -0
- data/lib/rucoa/handlers/text_document_range_formatting_handler.rb +2 -2
- data/lib/rucoa/handlers.rb +3 -0
- data/lib/rucoa/node_inspector.rb +13 -1
- data/lib/rucoa/position.rb +12 -1
- data/lib/rucoa/{definition_builders/rbs_constant_definition_builder.rb → rbs/constant_definition_mapper.rb} +4 -8
- data/lib/rucoa/{definition_builders/rbs_method_definition_builder.rb → rbs/method_definition_mapper.rb} +4 -7
- data/lib/rucoa/rbs/ruby_definitions_loader.rb +78 -0
- data/lib/rucoa/rbs.rb +9 -0
- data/lib/rucoa/rubocop/autocorrector.rb +40 -0
- data/lib/rucoa/rubocop/configuration_checker.rb +44 -0
- data/lib/rucoa/rubocop/investigator.rb +50 -0
- data/lib/rucoa/rubocop.rb +9 -0
- data/lib/rucoa/server.rb +45 -12
- data/lib/rucoa/source.rb +6 -1
- data/lib/rucoa/version.rb +1 -1
- data/lib/rucoa/{definition_builders/yard_method_definition_builder.rb → yard/definition_mapper.rb} +20 -21
- data/lib/rucoa/yard/definitions_loader.rb +62 -0
- data/lib/rucoa/yard.rb +8 -0
- data/lib/rucoa.rb +3 -7
- metadata +16 -12
- data/lib/rucoa/definition_builders.rb +0 -9
- data/lib/rucoa/rbs_document_loader.rb +0 -43
- data/lib/rucoa/rubocop_autocorrector.rb +0 -38
- data/lib/rucoa/rubocop_configuration_checker.rb +0 -42
- data/lib/rucoa/rubocop_investigator.rb +0 -48
- data/lib/rucoa/yard_glob_document_loader.rb +0 -47
- data/lib/rucoa/yard_string_document_loader.rb +0 -70
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 48f65475f89a895b8fa3429ddcb5a10738c78e2181a0a0f41a8fe14ec8a2fd17
|
4
|
+
data.tar.gz: b94bffab0ae35cf83ee0ae5146f41b583abcea4b4192eabcdc8acbcedf3418b4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1693536178207fc2740ede4806a8803f140477b312c143e7ad0284875c1685244a09fa33dcd6208e993f4d0acb87284391a605a27e09d8479c71f556cf951d7f
|
7
|
+
data.tar.gz: d4458ea8223b032e5df2680bfa4f8ed2f939f2971a19db327306a3c6fb6a9a6b3810ffd8ed56346b6e7defb36b916e9054bcb71d031f2494c30b0d6f216995eb
|
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/data/definitions_ruby_3_1
CHANGED
Binary file
|
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
|
@@ -16,6 +16,18 @@ module Rucoa
|
|
16
16
|
)
|
17
17
|
end
|
18
18
|
|
19
|
+
# @param uri [String]
|
20
|
+
# @return [void]
|
21
|
+
def clear_diagnostics_on(uri)
|
22
|
+
write(
|
23
|
+
method: 'textDocument/publishDiagnostics',
|
24
|
+
params: {
|
25
|
+
diagnostics: [],
|
26
|
+
uri: uri
|
27
|
+
}
|
28
|
+
)
|
29
|
+
end
|
30
|
+
|
19
31
|
# @param uri [String]
|
20
32
|
# @return [void]
|
21
33
|
def publish_diagnostics_on(uri)
|
@@ -48,7 +60,7 @@ module Rucoa
|
|
48
60
|
|
49
61
|
# @return [Array<Hash>]
|
50
62
|
def call
|
51
|
-
return [] unless
|
63
|
+
return [] unless Rubocop::ConfigurationChecker.call
|
52
64
|
|
53
65
|
offenses.map do |offense|
|
54
66
|
OffenseToDiagnosticMapper.call(
|
@@ -63,7 +75,7 @@ module Rucoa
|
|
63
75
|
|
64
76
|
# @return [Array<RuboCop::Cop::Offense>]
|
65
77
|
def offenses
|
66
|
-
|
78
|
+
Rubocop::Investigator.call(source: @source)
|
67
79
|
end
|
68
80
|
|
69
81
|
class OffenseToDiagnosticMapper
|
@@ -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,223 @@
|
|
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(
|
212
|
+
case node
|
213
|
+
when Nodes::SendNode
|
214
|
+
node.location.selector
|
215
|
+
else
|
216
|
+
node.location.expression
|
217
|
+
end
|
218
|
+
)
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Rucoa
|
4
|
+
module Handlers
|
5
|
+
class TextDocumentDidCloseHandler < Base
|
6
|
+
include HandlerConcerns::DiagnosticsPublishable
|
7
|
+
|
8
|
+
def call
|
9
|
+
clear_diagnostics_on(uri)
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
# @return [String]
|
15
|
+
def uri
|
16
|
+
request.dig('params', 'textDocument', 'uri')
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -13,7 +13,7 @@ module Rucoa
|
|
13
13
|
def formattable?
|
14
14
|
configuration.enables_formatting? &&
|
15
15
|
source &&
|
16
|
-
|
16
|
+
Rubocop::ConfigurationChecker.call
|
17
17
|
end
|
18
18
|
|
19
19
|
# @return [Array<Hash>]
|
@@ -43,7 +43,7 @@ module Rucoa
|
|
43
43
|
|
44
44
|
# @return [String]
|
45
45
|
def new_text
|
46
|
-
|
46
|
+
Rubocop::Autocorrector.call(source: source)
|
47
47
|
end
|
48
48
|
|
49
49
|
# @return [Hash]
|
@@ -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
|
@@ -25,7 +25,7 @@ module Rucoa
|
|
25
25
|
def formattable?
|
26
26
|
configuration.enables_formatting? &&
|
27
27
|
source &&
|
28
|
-
|
28
|
+
Rubocop::ConfigurationChecker.call
|
29
29
|
end
|
30
30
|
|
31
31
|
# @return [Rucoa::Source]
|
@@ -59,7 +59,7 @@ module Rucoa
|
|
59
59
|
|
60
60
|
# @return [Array<RuboCop::Cop::Offense>]
|
61
61
|
def offenses
|
62
|
-
|
62
|
+
Rubocop::Investigator.call(source: source)
|
63
63
|
end
|
64
64
|
|
65
65
|
# @return [Array(Rucoa::Range, String)]
|
data/lib/rucoa/handlers.rb
CHANGED
@@ -8,10 +8,13 @@ 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'
|
13
|
+
autoload :TextDocumentDidCloseHandler, 'rucoa/handlers/text_document_did_close_handler'
|
12
14
|
autoload :TextDocumentDidOpenHandler, 'rucoa/handlers/text_document_did_open_handler'
|
13
15
|
autoload :TextDocumentDocumentSymbolHandler, 'rucoa/handlers/text_document_document_symbol_handler'
|
14
16
|
autoload :TextDocumentFormattingHandler, 'rucoa/handlers/text_document_formatting_handler'
|
17
|
+
autoload :TextDocumentHoverHandler, 'rucoa/handlers/text_document_hover_handler'
|
15
18
|
autoload :TextDocumentRangeFormattingHandler, 'rucoa/handlers/text_document_range_formatting_handler'
|
16
19
|
autoload :TextDocumentSelectionRangeHandler, 'rucoa/handlers/text_document_selection_range_handler'
|
17
20
|
autoload :TextDocumentSignatureHelpHandler, 'rucoa/handlers/text_document_signature_help_handler'
|
data/lib/rucoa/node_inspector.rb
CHANGED
@@ -80,7 +80,19 @@ module Rucoa
|
|
80
80
|
[
|
81
81
|
type,
|
82
82
|
@node.name
|
83
|
-
].join(
|
83
|
+
].join(method_kind_symbol)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# @return [String, nil]
|
88
|
+
def method_kind_symbol
|
89
|
+
return unless @node.is_a?(Nodes::SendNode)
|
90
|
+
|
91
|
+
case @node.receiver
|
92
|
+
when Nodes::ConstNode
|
93
|
+
'.'
|
94
|
+
else
|
95
|
+
'#'
|
84
96
|
end
|
85
97
|
end
|
86
98
|
|