ruby-lsp 0.4.2 → 0.4.3
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/README.md +28 -35
- data/VERSION +1 -1
- data/lib/rubocop/cop/ruby_lsp/use_language_server_aliases.rb +62 -0
- data/lib/ruby_lsp/document.rb +13 -4
- data/lib/ruby_lsp/executor.rb +20 -12
- data/lib/ruby_lsp/requests/base_request.rb +4 -4
- data/lib/ruby_lsp/requests/code_actions.rb +5 -4
- data/lib/ruby_lsp/requests/diagnostics.rb +3 -3
- data/lib/ruby_lsp/requests/document_highlight.rb +3 -3
- data/lib/ruby_lsp/requests/document_link.rb +7 -7
- data/lib/ruby_lsp/requests/document_symbol.rb +13 -10
- data/lib/ruby_lsp/requests/folding_ranges.rb +13 -9
- data/lib/ruby_lsp/requests/formatting.rb +5 -4
- data/lib/ruby_lsp/requests/hover.rb +7 -6
- data/lib/ruby_lsp/requests/inlay_hints.rb +5 -4
- data/lib/ruby_lsp/requests/path_completion.rb +9 -3
- data/lib/ruby_lsp/requests/selection_ranges.rb +3 -3
- data/lib/ruby_lsp/requests/semantic_highlighting.rb +29 -15
- data/lib/ruby_lsp/requests/support/highlight_target.rb +5 -4
- data/lib/ruby_lsp/requests/support/rails_document_client.rb +7 -6
- data/lib/ruby_lsp/requests/support/selection_range.rb +1 -1
- data/lib/ruby_lsp/requests/support/semantic_token_encoder.rb +2 -2
- data/lib/ruby_lsp/requests/support/sorbet.rb +5 -15
- data/lib/ruby_lsp/requests/support/syntax_tree_formatting_runner.rb +39 -0
- data/lib/ruby_lsp/server.rb +4 -1
- data/lib/ruby_lsp/store.rb +7 -7
- metadata +7 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f7bf79fd6cdc704c8f874f58985f0e72ac034c76bb70a68166654185f6f00cf1
|
4
|
+
data.tar.gz: '083edc726c05ffb6e5e3ae63d480b17fa0f7161ee62349665cc57e309acd5598'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f6192daf27dfd82dbb505f5184eebd66308690ce10ead4d4cedc4d9c6667be882a8b9de4c87e66eb88ff43e896307be24bbcc6506b0544b496e1bcb3c9804498
|
7
|
+
data.tar.gz: bb68928d9a72b3b2873509bf915f753a202a520187bf5f55da1870d552e0ba0917a7d21ea70d20853ac60aa614f7d85d117d7291ec9c0778cab80e4561a7aba0
|
data/README.md
CHANGED
@@ -1,57 +1,50 @@
|
|
1
|
-

|
1
|
+
[](https://github.com/Shopify/ruby-lsp/actions/workflows/ci.yml)
|
2
|
+
[](https://marketplace.visualstudio.com/items?itemName=Shopify.ruby-lsp)
|
3
|
+
[](https://join.slack.com/t/ruby-dx/shared_invite/zt-1s6f4y15t-v9jedZ9YUPQLM91TEJ4Gew)
|
2
4
|
|
3
|
-
# Ruby LSP
|
4
|
-
|
5
|
-
This gem is an implementation of the [language server protocol specification](https://microsoft.github.io/language-server-protocol/) for Ruby, used to improve editor features.
|
6
|
-
|
7
|
-
# Overview
|
8
|
-
|
9
|
-
The intention of Ruby LSP is to provide a fast, robust and feature-rich coding environment for Ruby developers.
|
10
|
-
|
11
|
-
It's part of a [wider Shopify goal](https://github.com/Shopify/vscode-shopify-ruby) to provide a state-of-the-art experience to Ruby developers using modern standards for cross-editor features, documentation and debugging.
|
12
5
|
|
13
|
-
|
14
|
-
|
15
|
-
* Syntax highlighting
|
16
|
-
* Linting and formatting
|
17
|
-
* Code folding
|
18
|
-
* Selection ranges
|
19
|
-
|
20
|
-
It does not perform typechecking, so its features are implemented on a best-effort basis, aiming to be as accurate as possible.
|
21
|
-
|
22
|
-
Planned future features include:
|
6
|
+
# Ruby LSP
|
23
7
|
|
24
|
-
|
25
|
-
|
8
|
+
The Ruby LSP is an implementation of the [language server protocol](https://microsoft.github.io/language-server-protocol/)
|
9
|
+
for Ruby, used to improve rich features in editors. It is a part of a wider goal to provide a state-of-the-art
|
10
|
+
experience to Ruby developers using modern standards for cross-editor features, documentation and debugging.
|
26
11
|
|
27
|
-
|
12
|
+
Want to discuss Ruby developer experience? Consider joining the public
|
13
|
+
[Ruby DX Slack workspace](https://join.slack.com/t/ruby-dx/shared_invite/zt-1s6f4y15t-v9jedZ9YUPQLM91TEJ4Gew).
|
28
14
|
|
29
|
-
|
15
|
+
## Usage
|
30
16
|
|
31
|
-
|
32
|
-
* Solargraph can be used as a globally installed gem, but Ruby LSP must be added to the Gemfile or gemspec if using RuboCop. (There are pros and cons to each approach)
|
17
|
+
### With VS Code
|
33
18
|
|
34
|
-
|
19
|
+
If using VS Code, all you have to do is install the [Ruby LSP extension](https://github.com/Shopify/vscode-ruby-lsp) to
|
20
|
+
get the extra features in the editor. Do not install this gem manually.
|
35
21
|
|
36
|
-
|
22
|
+
### With other editors
|
37
23
|
|
38
|
-
|
24
|
+
See [editors](https://github.com/Shopify/ruby-lsp/blob/main/EDITORS.md) for community instructions on setting up the
|
25
|
+
Ruby LSP.
|
39
26
|
|
40
|
-
|
27
|
+
The gem can be installed by doing
|
28
|
+
```shell
|
29
|
+
gem install ruby-lsp
|
30
|
+
```
|
41
31
|
|
32
|
+
If you decide to add the gem to the bundle, it is not necessary to require it.
|
42
33
|
```ruby
|
43
34
|
group :development do
|
44
35
|
gem "ruby-lsp", require: false
|
45
36
|
end
|
46
37
|
```
|
47
38
|
|
48
|
-
|
49
|
-
in the editor. See [editors](https://github.com/Shopify/ruby-lsp/blob/main/EDITORS.md) for community instructions on
|
50
|
-
setting up the Ruby LSP in different editors.
|
39
|
+
### Documentation
|
51
40
|
|
52
41
|
See the [documentation](https://shopify.github.io/ruby-lsp) for more in-depth details about the
|
53
42
|
[supported features](https://shopify.github.io/ruby-lsp/RubyLsp/Requests.html).
|
54
43
|
|
44
|
+
## Learn More
|
45
|
+
|
46
|
+
* [RubyConf 2022: Improving the development experience with language servers](https://www.youtube.com/watch?v=kEfXPTm1aCI) ([Vinicius Stock](https://github.com/vinistock))
|
47
|
+
|
55
48
|
## Contributing
|
56
49
|
|
57
50
|
Bug reports and pull requests are welcome on GitHub at https://github.com/Shopify/ruby-lsp.
|
@@ -113,7 +106,7 @@ To add a new expectations test runner for a new request handler:
|
|
113
106
|
* Tests with expectations will be checked with `assert_expectations`
|
114
107
|
* Tests without expectations will be ran against your new $HANDLER to check that nothing breaks
|
115
108
|
|
116
|
-
|
109
|
+
### Debugging
|
117
110
|
|
118
111
|
### Debugging Tests
|
119
112
|
|
@@ -135,7 +128,7 @@ To add a new expectations test runner for a new request handler:
|
|
135
128
|
7. [`ruby-lsp`] Use commands like `b <file>:<line>` or `b Class#method` to set breakpoints and type `c` to continue the process.
|
136
129
|
8. In your `Extension Development Host` project (e.g. [`Tapioca`](https://github.com/Shopify/tapioca)), trigger the request that will hit the breakpoint.
|
137
130
|
|
138
|
-
|
131
|
+
### Spell Checking
|
139
132
|
|
140
133
|
VS Code users will be prompted to enable the [Code Spell Checker](https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker) extension.
|
141
134
|
By default this will be enabled for all workspaces, but you can choose to selectively enable or disable it per workspace.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.4.
|
1
|
+
0.4.3
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "rubocop"
|
5
|
+
require "sorbet-runtime"
|
6
|
+
|
7
|
+
module RuboCop
|
8
|
+
module Cop
|
9
|
+
module RubyLsp
|
10
|
+
# Prefer using `Interface`, `Transport` and `Constant` aliases
|
11
|
+
# within the `RubyLsp` module, without having to prefix with
|
12
|
+
# `LanguageServer::Protocol`
|
13
|
+
#
|
14
|
+
# @example
|
15
|
+
# # bad
|
16
|
+
# module RubyLsp
|
17
|
+
# class FoldingRanges
|
18
|
+
# sig { override.returns(T.all(T::Array[LanguageServer::Protocol::Interface::FoldingRange], Object)) }
|
19
|
+
# def run; end
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# # good
|
23
|
+
# module RubyLsp
|
24
|
+
# class FoldingRanges
|
25
|
+
# sig { override.returns(T.all(T::Array[Interface::FoldingRange], Object)) }
|
26
|
+
# def run; end
|
27
|
+
# end
|
28
|
+
# end
|
29
|
+
class UseLanguageServerAliases < RuboCop::Cop::Base
|
30
|
+
extend RuboCop::Cop::AutoCorrector
|
31
|
+
|
32
|
+
ALIASED_CONSTANTS = T.let([:Interface, :Transport, :Constant].freeze, T::Array[Symbol])
|
33
|
+
|
34
|
+
MSG = "Use constant alias `%{constant}`."
|
35
|
+
|
36
|
+
def_node_search :ruby_lsp_modules, <<~PATTERN
|
37
|
+
(module (const nil? :RubyLsp) ...)
|
38
|
+
PATTERN
|
39
|
+
|
40
|
+
def_node_search :lsp_constant_usages, <<~PATTERN
|
41
|
+
(const (const (const nil? :LanguageServer) :Protocol) {:Interface | :Transport | :Constant})
|
42
|
+
PATTERN
|
43
|
+
|
44
|
+
def on_new_investigation
|
45
|
+
return if processed_source.blank?
|
46
|
+
|
47
|
+
ruby_lsp_modules(processed_source.ast).each do |ruby_lsp_mod|
|
48
|
+
lsp_constant_usages(ruby_lsp_mod).each do |node|
|
49
|
+
lsp_const = node.children.last
|
50
|
+
|
51
|
+
next unless ALIASED_CONSTANTS.include?(lsp_const)
|
52
|
+
|
53
|
+
add_offense(node, message: format(MSG, constant: lsp_const)) do |corrector|
|
54
|
+
corrector.replace(node, lsp_const)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
data/lib/ruby_lsp/document.rb
CHANGED
@@ -15,11 +15,19 @@ module RubyLsp
|
|
15
15
|
sig { returns(String) }
|
16
16
|
attr_reader :source
|
17
17
|
|
18
|
-
sig {
|
19
|
-
|
18
|
+
sig { returns(Integer) }
|
19
|
+
attr_reader :version
|
20
|
+
|
21
|
+
sig { returns(String) }
|
22
|
+
attr_reader :uri
|
23
|
+
|
24
|
+
sig { params(source: String, version: Integer, uri: String, encoding: String).void }
|
25
|
+
def initialize(source:, version:, uri:, encoding: "utf-8")
|
20
26
|
@cache = T.let({}, T::Hash[Symbol, T.untyped])
|
21
27
|
@encoding = T.let(encoding, String)
|
22
28
|
@source = T.let(source, String)
|
29
|
+
@version = T.let(version, Integer)
|
30
|
+
@uri = T.let(uri, String)
|
23
31
|
@unparsed_edits = T.let([], T::Array[EditShape])
|
24
32
|
@syntax_error = T.let(false, T::Boolean)
|
25
33
|
@tree = T.let(SyntaxTree.parse(@source), T.nilable(SyntaxTree::Node))
|
@@ -48,8 +56,8 @@ module RubyLsp
|
|
48
56
|
result
|
49
57
|
end
|
50
58
|
|
51
|
-
sig { params(edits: T::Array[EditShape]).void }
|
52
|
-
def push_edits(edits)
|
59
|
+
sig { params(edits: T::Array[EditShape], version: Integer).void }
|
60
|
+
def push_edits(edits, version:)
|
53
61
|
edits.each do |edit|
|
54
62
|
range = edit[:range]
|
55
63
|
scanner = create_scanner
|
@@ -60,6 +68,7 @@ module RubyLsp
|
|
60
68
|
@source[start_position...end_position] = edit[:text]
|
61
69
|
end
|
62
70
|
|
71
|
+
@version = version
|
63
72
|
@unparsed_edits.concat(edits)
|
64
73
|
@cache.clear
|
65
74
|
end
|
data/lib/ruby_lsp/executor.rb
CHANGED
@@ -41,7 +41,11 @@ module RubyLsp
|
|
41
41
|
warn("Ruby LSP is ready")
|
42
42
|
VOID
|
43
43
|
when "textDocument/didOpen"
|
44
|
-
text_document_did_open(
|
44
|
+
text_document_did_open(
|
45
|
+
uri,
|
46
|
+
request.dig(:params, :textDocument, :text),
|
47
|
+
request.dig(:params, :textDocument, :version),
|
48
|
+
)
|
45
49
|
when "textDocument/didClose"
|
46
50
|
@notifications << Notification.new(
|
47
51
|
message: "textDocument/publishDiagnostics",
|
@@ -50,7 +54,11 @@ module RubyLsp
|
|
50
54
|
|
51
55
|
text_document_did_close(uri)
|
52
56
|
when "textDocument/didChange"
|
53
|
-
text_document_did_change(
|
57
|
+
text_document_did_change(
|
58
|
+
uri,
|
59
|
+
request.dig(:params, :contentChanges),
|
60
|
+
request.dig(:params, :textDocument, :version),
|
61
|
+
)
|
54
62
|
when "textDocument/foldingRange"
|
55
63
|
folding_range(uri)
|
56
64
|
when "textDocument/documentLink"
|
@@ -138,7 +146,7 @@ module RubyLsp
|
|
138
146
|
sig { params(uri: String).returns(T::Array[Interface::DocumentLink]) }
|
139
147
|
def document_link(uri)
|
140
148
|
@store.cache_fetch(uri, :document_link) do |document|
|
141
|
-
RubyLsp::Requests::DocumentLink.new(
|
149
|
+
RubyLsp::Requests::DocumentLink.new(document).run
|
142
150
|
end
|
143
151
|
end
|
144
152
|
|
@@ -149,15 +157,15 @@ module RubyLsp
|
|
149
157
|
end
|
150
158
|
end
|
151
159
|
|
152
|
-
sig { params(uri: String, content_changes: T::Array[Document::EditShape]).returns(Object) }
|
153
|
-
def text_document_did_change(uri, content_changes)
|
154
|
-
@store.push_edits(uri, content_changes)
|
160
|
+
sig { params(uri: String, content_changes: T::Array[Document::EditShape], version: Integer).returns(Object) }
|
161
|
+
def text_document_did_change(uri, content_changes, version)
|
162
|
+
@store.push_edits(uri: uri, edits: content_changes, version: version)
|
155
163
|
VOID
|
156
164
|
end
|
157
165
|
|
158
|
-
sig { params(uri: String, text: String).returns(Object) }
|
159
|
-
def text_document_did_open(uri, text)
|
160
|
-
@store.set(uri, text)
|
166
|
+
sig { params(uri: String, text: String, version: Integer).returns(Object) }
|
167
|
+
def text_document_did_open(uri, text, version)
|
168
|
+
@store.set(uri: uri, source: text, version: version)
|
161
169
|
VOID
|
162
170
|
end
|
163
171
|
|
@@ -207,7 +215,7 @@ module RubyLsp
|
|
207
215
|
|
208
216
|
sig { params(uri: String).returns(T.nilable(T::Array[Interface::TextEdit])) }
|
209
217
|
def formatting(uri)
|
210
|
-
Requests::Formatting.new(
|
218
|
+
Requests::Formatting.new(@store.get(uri), formatter: @store.formatter).run
|
211
219
|
end
|
212
220
|
|
213
221
|
sig do
|
@@ -250,7 +258,7 @@ module RubyLsp
|
|
250
258
|
def code_action(uri, range, context)
|
251
259
|
document = @store.get(uri)
|
252
260
|
|
253
|
-
Requests::CodeActions.new(
|
261
|
+
Requests::CodeActions.new(document, range, context).run
|
254
262
|
end
|
255
263
|
|
256
264
|
sig { params(params: T::Hash[Symbol, T.untyped]).returns(Interface::CodeAction) }
|
@@ -286,7 +294,7 @@ module RubyLsp
|
|
286
294
|
sig { params(uri: String).returns(T.nilable(Interface::FullDocumentDiagnosticReport)) }
|
287
295
|
def diagnostic(uri)
|
288
296
|
response = @store.cache_fetch(uri, :diagnostics) do |document|
|
289
|
-
Requests::Diagnostics.new(
|
297
|
+
Requests::Diagnostics.new(document).run
|
290
298
|
end
|
291
299
|
|
292
300
|
Interface::FullDocumentDiagnosticReport.new(kind: "full", items: response.map(&:to_lsp_diagnostic)) if response
|
@@ -36,16 +36,16 @@ module RubyLsp
|
|
36
36
|
nodes.each { |node| visit(node) }
|
37
37
|
end
|
38
38
|
|
39
|
-
sig { params(node: SyntaxTree::Node).returns(
|
39
|
+
sig { params(node: SyntaxTree::Node).returns(Interface::Range) }
|
40
40
|
def range_from_syntax_tree_node(node)
|
41
41
|
loc = node.location
|
42
42
|
|
43
|
-
|
44
|
-
start:
|
43
|
+
Interface::Range.new(
|
44
|
+
start: Interface::Position.new(
|
45
45
|
line: loc.start_line - 1,
|
46
46
|
character: loc.start_column,
|
47
47
|
),
|
48
|
-
end:
|
48
|
+
end: Interface::Position.new(line: loc.end_line - 1, character: loc.end_column),
|
49
49
|
)
|
50
50
|
end
|
51
51
|
|
@@ -21,16 +21,15 @@ module RubyLsp
|
|
21
21
|
|
22
22
|
sig do
|
23
23
|
params(
|
24
|
-
uri: String,
|
25
24
|
document: Document,
|
26
25
|
range: Document::RangeShape,
|
27
26
|
context: T::Hash[Symbol, T.untyped],
|
28
27
|
).void
|
29
28
|
end
|
30
|
-
def initialize(
|
29
|
+
def initialize(document, range, context)
|
31
30
|
super(document)
|
32
31
|
|
33
|
-
@uri = uri
|
32
|
+
@uri = T.let(document.uri, String)
|
34
33
|
@range = range
|
35
34
|
@context = context
|
36
35
|
end
|
@@ -49,7 +48,9 @@ module RubyLsp
|
|
49
48
|
code_action if diagnostic.dig(:data, :correctable) && cover?(range)
|
50
49
|
end
|
51
50
|
|
52
|
-
|
51
|
+
# Only add refactor actions if there's a non empty selection in the editor
|
52
|
+
code_actions << refactor_code_action(@range, @uri) unless @range.dig(:start) == @range.dig(:end)
|
53
|
+
code_actions
|
53
54
|
end
|
54
55
|
|
55
56
|
private
|
@@ -21,11 +21,11 @@ module RubyLsp
|
|
21
21
|
class Diagnostics < BaseRequest
|
22
22
|
extend T::Sig
|
23
23
|
|
24
|
-
sig { params(
|
25
|
-
def initialize(
|
24
|
+
sig { params(document: Document).void }
|
25
|
+
def initialize(document)
|
26
26
|
super(document)
|
27
27
|
|
28
|
-
@uri = uri
|
28
|
+
@uri = T.let(document.uri, String)
|
29
29
|
end
|
30
30
|
|
31
31
|
sig { override.returns(T.nilable(T.all(T::Array[Support::RuboCopDiagnostic], Object))) }
|
@@ -29,14 +29,14 @@ module RubyLsp
|
|
29
29
|
def initialize(document, position)
|
30
30
|
super(document)
|
31
31
|
|
32
|
-
@highlights = T.let([], T::Array[
|
32
|
+
@highlights = T.let([], T::Array[Interface::DocumentHighlight])
|
33
33
|
return unless document.parsed?
|
34
34
|
|
35
35
|
position = document.create_scanner.find_char_position(position)
|
36
36
|
@target = T.let(find(T.must(document.tree), position), T.nilable(Support::HighlightTarget))
|
37
37
|
end
|
38
38
|
|
39
|
-
sig { override.returns(T.all(T::Array[
|
39
|
+
sig { override.returns(T.all(T::Array[Interface::DocumentHighlight], Object)) }
|
40
40
|
def run
|
41
41
|
# no @target means the target is not highlightable
|
42
42
|
visit(@document.tree) if @document.parsed? && @target
|
@@ -90,7 +90,7 @@ module RubyLsp
|
|
90
90
|
sig { params(match: Support::HighlightTarget::HighlightMatch).void }
|
91
91
|
def add_highlight(match)
|
92
92
|
range = range_from_syntax_tree_node(match.node)
|
93
|
-
@highlights <<
|
93
|
+
@highlights << Interface::DocumentHighlight.new(range: range, kind: match.type)
|
94
94
|
end
|
95
95
|
end
|
96
96
|
end
|
@@ -69,18 +69,18 @@ module RubyLsp
|
|
69
69
|
end
|
70
70
|
end
|
71
71
|
|
72
|
-
sig { params(
|
73
|
-
def initialize(
|
72
|
+
sig { params(document: Document).void }
|
73
|
+
def initialize(document)
|
74
74
|
super(document)
|
75
75
|
|
76
76
|
# Match the version based on the version in the RBI file name. Notice that the `@` symbol is sanitized to `%40`
|
77
77
|
# in the URI
|
78
|
-
version_match = /(?<=%40)[\d.]+(?=\.rbi$)/.match(uri)
|
78
|
+
version_match = /(?<=%40)[\d.]+(?=\.rbi$)/.match(document.uri)
|
79
79
|
@gem_version = T.let(version_match && version_match[0], T.nilable(String))
|
80
|
-
@links = T.let([], T::Array[
|
80
|
+
@links = T.let([], T::Array[Interface::DocumentLink])
|
81
81
|
end
|
82
82
|
|
83
|
-
sig { override.returns(T.all(T::Array[
|
83
|
+
sig { override.returns(T.all(T::Array[Interface::DocumentLink], Object)) }
|
84
84
|
def run
|
85
85
|
visit(@document.tree) if @document.parsed?
|
86
86
|
@links
|
@@ -91,12 +91,12 @@ module RubyLsp
|
|
91
91
|
match = node.value.match(%r{source://.*#\d+$})
|
92
92
|
return unless match
|
93
93
|
|
94
|
-
uri = T.cast(URI(match[0]), URI::Source)
|
94
|
+
uri = T.cast(URI(T.must(match[0])), URI::Source)
|
95
95
|
gem_version = T.must(resolve_version(uri))
|
96
96
|
file_path = self.class.gem_paths.dig(uri.gem_name, gem_version, uri.path)
|
97
97
|
return if file_path.nil?
|
98
98
|
|
99
|
-
@links <<
|
99
|
+
@links << Interface::DocumentLink.new(
|
100
100
|
range: range_from_syntax_tree_node(node),
|
101
101
|
target: "file://#{file_path}##{uri.line_number}",
|
102
102
|
tooltip: "Jump to #{file_path}##{uri.line_number}",
|
@@ -66,12 +66,12 @@ module RubyLsp
|
|
66
66
|
class SymbolHierarchyRoot
|
67
67
|
extend T::Sig
|
68
68
|
|
69
|
-
sig { returns(T::Array[
|
69
|
+
sig { returns(T::Array[Interface::DocumentSymbol]) }
|
70
70
|
attr_reader :children
|
71
71
|
|
72
72
|
sig { void }
|
73
73
|
def initialize
|
74
|
-
@children = T.let([], T::Array[
|
74
|
+
@children = T.let([], T::Array[Interface::DocumentSymbol])
|
75
75
|
end
|
76
76
|
end
|
77
77
|
|
@@ -82,11 +82,11 @@ module RubyLsp
|
|
82
82
|
@root = T.let(SymbolHierarchyRoot.new, SymbolHierarchyRoot)
|
83
83
|
@stack = T.let(
|
84
84
|
[@root],
|
85
|
-
T::Array[T.any(SymbolHierarchyRoot,
|
85
|
+
T::Array[T.any(SymbolHierarchyRoot, Interface::DocumentSymbol)],
|
86
86
|
)
|
87
87
|
end
|
88
88
|
|
89
|
-
sig { override.returns(T.all(T::Array[
|
89
|
+
sig { override.returns(T.all(T::Array[Interface::DocumentSymbol], Object)) }
|
90
90
|
def run
|
91
91
|
visit(@document.tree) if @document.parsed?
|
92
92
|
@root.children
|
@@ -134,7 +134,9 @@ module RubyLsp
|
|
134
134
|
|
135
135
|
sig { override.params(node: SyntaxTree::DefNode).void }
|
136
136
|
def visit_def(node)
|
137
|
-
|
137
|
+
target = node.target
|
138
|
+
|
139
|
+
if target.is_a?(SyntaxTree::VarRef) && target.value.is_a?(SyntaxTree::Kw) && target.value.value == "self"
|
138
140
|
name = "self.#{node.name.value}"
|
139
141
|
kind = :method
|
140
142
|
else
|
@@ -180,7 +182,8 @@ module RubyLsp
|
|
180
182
|
|
181
183
|
sig { override.params(node: SyntaxTree::VarField).void }
|
182
184
|
def visit_var_field(node)
|
183
|
-
|
185
|
+
value = node.value
|
186
|
+
kind = case value
|
184
187
|
when SyntaxTree::Const
|
185
188
|
:constant
|
186
189
|
when SyntaxTree::CVar, SyntaxTree::IVar
|
@@ -190,10 +193,10 @@ module RubyLsp
|
|
190
193
|
end
|
191
194
|
|
192
195
|
create_document_symbol(
|
193
|
-
name:
|
196
|
+
name: value.value,
|
194
197
|
kind: kind,
|
195
198
|
range_node: node,
|
196
|
-
selection_range_node:
|
199
|
+
selection_range_node: value,
|
197
200
|
)
|
198
201
|
end
|
199
202
|
|
@@ -205,10 +208,10 @@ module RubyLsp
|
|
205
208
|
kind: Symbol,
|
206
209
|
range_node: SyntaxTree::Node,
|
207
210
|
selection_range_node: SyntaxTree::Node,
|
208
|
-
).returns(
|
211
|
+
).returns(Interface::DocumentSymbol)
|
209
212
|
end
|
210
213
|
def create_document_symbol(name:, kind:, range_node:, selection_range_node:)
|
211
|
-
symbol =
|
214
|
+
symbol = Interface::DocumentSymbol.new(
|
212
215
|
name: name,
|
213
216
|
kind: SYMBOL_KIND[kind],
|
214
217
|
range: range_from_syntax_tree_node(range_node),
|
@@ -63,11 +63,11 @@ module RubyLsp
|
|
63
63
|
def initialize(document)
|
64
64
|
super
|
65
65
|
|
66
|
-
@ranges = T.let([], T::Array[
|
66
|
+
@ranges = T.let([], T::Array[Interface::FoldingRange])
|
67
67
|
@partial_range = T.let(nil, T.nilable(PartialRange))
|
68
68
|
end
|
69
69
|
|
70
|
-
sig { override.returns(T.all(T::Array[
|
70
|
+
sig { override.returns(T.all(T::Array[Interface::FoldingRange], Object)) }
|
71
71
|
def run
|
72
72
|
if @document.parsed?
|
73
73
|
visit(@document.tree)
|
@@ -161,9 +161,9 @@ module RubyLsp
|
|
161
161
|
node.is_a?(SyntaxTree::Comment) && @end_line + 1 != node.location.start_line - 1
|
162
162
|
end
|
163
163
|
|
164
|
-
sig { returns(
|
164
|
+
sig { returns(Interface::FoldingRange) }
|
165
165
|
def to_range
|
166
|
-
|
166
|
+
Interface::FoldingRange.new(
|
167
167
|
start_line: @start_line,
|
168
168
|
end_line: @end_line,
|
169
169
|
kind: @kind,
|
@@ -220,7 +220,8 @@ module RubyLsp
|
|
220
220
|
|
221
221
|
sig { params(node: T.any(SyntaxTree::CallNode, SyntaxTree::CommandCall)).void }
|
222
222
|
def add_call_range(node)
|
223
|
-
receiver = T.let(node.receiver, SyntaxTree::Node)
|
223
|
+
receiver = T.let(node.receiver, T.nilable(SyntaxTree::Node))
|
224
|
+
|
224
225
|
loop do
|
225
226
|
case receiver
|
226
227
|
when SyntaxTree::CallNode
|
@@ -255,9 +256,10 @@ module RubyLsp
|
|
255
256
|
def add_def_range(node)
|
256
257
|
# For an endless method with no arguments, `node.params` returns `nil` for Ruby 3.0, but a `Syntax::Params`
|
257
258
|
# for Ruby 3.1
|
258
|
-
|
259
|
+
params = node.params
|
260
|
+
return unless params
|
259
261
|
|
260
|
-
params_location =
|
262
|
+
params_location = params.location
|
261
263
|
|
262
264
|
if params_location.start_line < params_location.end_line
|
263
265
|
add_lines_range(params_location.end_line, node.location.end_line - 1)
|
@@ -276,7 +278,9 @@ module RubyLsp
|
|
276
278
|
|
277
279
|
sig { params(node: SyntaxTree::Node, statements: SyntaxTree::Statements).void }
|
278
280
|
def add_statements_range(node, statements)
|
279
|
-
|
281
|
+
return if statements.empty?
|
282
|
+
|
283
|
+
add_lines_range(node.location.start_line, T.must(statements.body.last).location.end_line)
|
280
284
|
end
|
281
285
|
|
282
286
|
sig { params(node: SyntaxTree::StringConcat).void }
|
@@ -291,7 +295,7 @@ module RubyLsp
|
|
291
295
|
def add_lines_range(start_line, end_line)
|
292
296
|
return if start_line >= end_line
|
293
297
|
|
294
|
-
@ranges <<
|
298
|
+
@ranges << Interface::FoldingRange.new(
|
295
299
|
start_line: start_line - 1,
|
296
300
|
end_line: end_line - 1,
|
297
301
|
kind: "region",
|
@@ -2,6 +2,7 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require "ruby_lsp/requests/support/rubocop_formatting_runner"
|
5
|
+
require "ruby_lsp/requests/support/syntax_tree_formatting_runner"
|
5
6
|
|
6
7
|
module RubyLsp
|
7
8
|
module Requests
|
@@ -26,11 +27,11 @@ module RubyLsp
|
|
26
27
|
|
27
28
|
extend T::Sig
|
28
29
|
|
29
|
-
sig { params(
|
30
|
-
def initialize(
|
30
|
+
sig { params(document: Document, formatter: String).void }
|
31
|
+
def initialize(document, formatter: "auto")
|
31
32
|
super(document)
|
32
33
|
|
33
|
-
@uri = uri
|
34
|
+
@uri = T.let(document.uri, String)
|
34
35
|
@formatter = T.let(
|
35
36
|
if formatter == "auto"
|
36
37
|
defined?(Support::RuboCopFormattingRunner) ? "rubocop" : "syntax_tree"
|
@@ -73,7 +74,7 @@ module RubyLsp
|
|
73
74
|
when "rubocop"
|
74
75
|
Support::RuboCopFormattingRunner.instance.run(@uri, @document)
|
75
76
|
when "syntax_tree"
|
76
|
-
|
77
|
+
Support::SyntaxTreeFormattingRunner.instance.run(@uri, @document)
|
77
78
|
else
|
78
79
|
raise InvalidFormatter, "Unknown formatter: #{@formatter}"
|
79
80
|
end
|
@@ -36,7 +36,7 @@ module RubyLsp
|
|
36
36
|
@position = T.let(document.create_scanner.find_char_position(position), Integer)
|
37
37
|
end
|
38
38
|
|
39
|
-
sig { override.returns(T.nilable(
|
39
|
+
sig { override.returns(T.nilable(Interface::Hover)) }
|
40
40
|
def run
|
41
41
|
return unless @document.parsed?
|
42
42
|
|
@@ -48,9 +48,10 @@ module RubyLsp
|
|
48
48
|
message = target.message
|
49
49
|
generate_rails_document_link_hover(message.value, message)
|
50
50
|
when SyntaxTree::CallNode
|
51
|
-
|
51
|
+
message = target.message
|
52
|
+
return if message.is_a?(Symbol)
|
52
53
|
|
53
|
-
generate_rails_document_link_hover(
|
54
|
+
generate_rails_document_link_hover(message.value, message)
|
54
55
|
when SyntaxTree::ConstPathRef
|
55
56
|
constant_name = full_constant_name(target)
|
56
57
|
generate_rails_document_link_hover(constant_name, target)
|
@@ -60,18 +61,18 @@ module RubyLsp
|
|
60
61
|
private
|
61
62
|
|
62
63
|
sig do
|
63
|
-
params(name: String, node: SyntaxTree::Node).returns(T.nilable(
|
64
|
+
params(name: String, node: SyntaxTree::Node).returns(T.nilable(Interface::Hover))
|
64
65
|
end
|
65
66
|
def generate_rails_document_link_hover(name, node)
|
66
67
|
urls = Support::RailsDocumentClient.generate_rails_document_urls(name)
|
67
68
|
|
68
69
|
return if urls.empty?
|
69
70
|
|
70
|
-
contents =
|
71
|
+
contents = Interface::MarkupContent.new(
|
71
72
|
kind: "markdown",
|
72
73
|
value: urls.join("\n\n"),
|
73
74
|
)
|
74
|
-
|
75
|
+
Interface::Hover.new(
|
75
76
|
range: range_from_syntax_tree_node(node),
|
76
77
|
contents: contents,
|
77
78
|
)
|
@@ -25,11 +25,11 @@ module RubyLsp
|
|
25
25
|
def initialize(document, range)
|
26
26
|
super(document)
|
27
27
|
|
28
|
-
@hints = T.let([], T::Array[
|
28
|
+
@hints = T.let([], T::Array[Interface::InlayHint])
|
29
29
|
@range = range
|
30
30
|
end
|
31
31
|
|
32
|
-
sig { override.returns(T.all(T::Array[
|
32
|
+
sig { override.returns(T.all(T::Array[Interface::InlayHint], Object)) }
|
33
33
|
def run
|
34
34
|
visit(@document.tree) if @document.parsed?
|
35
35
|
@hints
|
@@ -37,12 +37,13 @@ module RubyLsp
|
|
37
37
|
|
38
38
|
sig { override.params(node: SyntaxTree::Rescue).void }
|
39
39
|
def visit_rescue(node)
|
40
|
-
|
40
|
+
exception = node.exception
|
41
|
+
return unless exception.nil? || exception.exceptions.nil?
|
41
42
|
|
42
43
|
loc = node.location
|
43
44
|
return unless visible?(node, @range)
|
44
45
|
|
45
|
-
@hints <<
|
46
|
+
@hints << Interface::InlayHint.new(
|
46
47
|
position: { line: loc.start_line - 1, character: loc.start_column + RESCUE_STRING_LENGTH },
|
47
48
|
label: "StandardError",
|
48
49
|
padding_left: true,
|
@@ -63,13 +63,19 @@ module RubyLsp
|
|
63
63
|
|
64
64
|
case matched
|
65
65
|
when SyntaxTree::Command, SyntaxTree::CallNode, SyntaxTree::CommandCall
|
66
|
-
|
66
|
+
message = matched.message
|
67
|
+
return if message.is_a?(Symbol)
|
68
|
+
return unless message.value == "require"
|
67
69
|
|
68
70
|
args = matched.arguments
|
69
71
|
args = args.arguments if args.is_a?(SyntaxTree::ArgParen)
|
72
|
+
return if args.nil? || args.is_a?(SyntaxTree::ArgsForward)
|
70
73
|
|
71
|
-
|
72
|
-
return unless
|
74
|
+
argument = args.parts.first
|
75
|
+
return unless argument.is_a?(SyntaxTree::StringLiteral)
|
76
|
+
|
77
|
+
path_node = argument.parts.first
|
78
|
+
return unless path_node.is_a?(SyntaxTree::TStringContent)
|
73
79
|
return unless (path_node.location.start_char..path_node.location.end_char).cover?(position)
|
74
80
|
|
75
81
|
path_node
|
@@ -100,12 +100,12 @@ module RubyLsp
|
|
100
100
|
end
|
101
101
|
def create_selection_range(location, parent = nil)
|
102
102
|
RubyLsp::Requests::Support::SelectionRange.new(
|
103
|
-
range:
|
104
|
-
start:
|
103
|
+
range: Interface::Range.new(
|
104
|
+
start: Interface::Position.new(
|
105
105
|
line: location.start_line - 1,
|
106
106
|
character: location.start_column,
|
107
107
|
),
|
108
|
-
end:
|
108
|
+
end: Interface::Position.new(
|
109
109
|
line: location.end_line - 1,
|
110
110
|
character: location.end_column,
|
111
111
|
),
|
@@ -122,7 +122,7 @@ module RubyLsp
|
|
122
122
|
sig do
|
123
123
|
override.returns(
|
124
124
|
T.any(
|
125
|
-
|
125
|
+
Interface::SemanticTokens,
|
126
126
|
T.all(T::Array[SemanticToken], Object),
|
127
127
|
),
|
128
128
|
)
|
@@ -143,7 +143,7 @@ module RubyLsp
|
|
143
143
|
visit(node.receiver)
|
144
144
|
|
145
145
|
message = node.message
|
146
|
-
if message
|
146
|
+
if !message.is_a?(Symbol) && !special_method?(message.value)
|
147
147
|
type = Support::Sorbet.annotation?(node) ? :type : :method
|
148
148
|
|
149
149
|
add_token(message.location, type)
|
@@ -168,7 +168,8 @@ module RubyLsp
|
|
168
168
|
return super unless visible?(node, @range)
|
169
169
|
|
170
170
|
visit(node.receiver)
|
171
|
-
|
171
|
+
message = node.message
|
172
|
+
add_token(message.location, :method) unless message.is_a?(Symbol)
|
172
173
|
visit(node.arguments)
|
173
174
|
visit(node.block)
|
174
175
|
end
|
@@ -205,7 +206,7 @@ module RubyLsp
|
|
205
206
|
def visit_params(node)
|
206
207
|
return super unless visible?(node, @range)
|
207
208
|
|
208
|
-
node.keywords.each do |keyword
|
209
|
+
node.keywords.each do |keyword, *|
|
209
210
|
location = keyword.location
|
210
211
|
add_token(location_without_colon(location), :parameter)
|
211
212
|
end
|
@@ -215,7 +216,7 @@ module RubyLsp
|
|
215
216
|
end
|
216
217
|
|
217
218
|
rest = node.keyword_rest
|
218
|
-
if rest && !rest.is_a?(SyntaxTree::ArgsForward)
|
219
|
+
if rest && !rest.is_a?(SyntaxTree::ArgsForward) && !rest.is_a?(Symbol)
|
219
220
|
name = rest.name
|
220
221
|
add_token(name.location, :parameter) if name
|
221
222
|
end
|
@@ -238,9 +239,14 @@ module RubyLsp
|
|
238
239
|
|
239
240
|
value = node.value
|
240
241
|
|
241
|
-
|
242
|
+
case value
|
243
|
+
when SyntaxTree::Ident
|
242
244
|
type = type_for_local(value)
|
243
245
|
add_token(value.location, type)
|
246
|
+
when Symbol
|
247
|
+
# do nothing
|
248
|
+
else
|
249
|
+
visit(value)
|
244
250
|
end
|
245
251
|
|
246
252
|
super
|
@@ -256,6 +262,8 @@ module RubyLsp
|
|
256
262
|
when SyntaxTree::Ident
|
257
263
|
type = type_for_local(value)
|
258
264
|
add_token(value.location, type)
|
265
|
+
when Symbol
|
266
|
+
# do nothing
|
259
267
|
else
|
260
268
|
visit(value)
|
261
269
|
end
|
@@ -305,18 +313,21 @@ module RubyLsp
|
|
305
313
|
return unless node.operator == :=~
|
306
314
|
|
307
315
|
left = node.left
|
316
|
+
# The regexp needs to be on the left hand side of the =~ for local variable capture
|
317
|
+
return unless left.is_a?(SyntaxTree::RegexpLiteral)
|
318
|
+
|
308
319
|
parts = left.parts
|
320
|
+
return unless parts.one?
|
309
321
|
|
310
|
-
|
311
|
-
|
322
|
+
content = parts.first
|
323
|
+
return unless content.is_a?(SyntaxTree::TStringContent)
|
312
324
|
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
325
|
+
# For each capture name we find in the regexp, look for a local in the current_scope
|
326
|
+
Regexp.new(content.value, Regexp::FIXEDENCODING).names.each do |name|
|
327
|
+
local = current_scope.find_local(name)
|
328
|
+
next unless local
|
317
329
|
|
318
|
-
|
319
|
-
end
|
330
|
+
local.definitions.each { |definition| add_token(definition, :variable) }
|
320
331
|
end
|
321
332
|
end
|
322
333
|
|
@@ -325,7 +336,10 @@ module RubyLsp
|
|
325
336
|
return super unless visible?(node, @range)
|
326
337
|
|
327
338
|
add_token(node.constant.location, :class, [:declaration])
|
328
|
-
|
339
|
+
|
340
|
+
superclass = node.superclass
|
341
|
+
add_token(superclass.location, :class) if superclass
|
342
|
+
|
329
343
|
visit(node.bodystmt)
|
330
344
|
end
|
331
345
|
|
@@ -7,8 +7,8 @@ module RubyLsp
|
|
7
7
|
class HighlightTarget
|
8
8
|
extend T::Sig
|
9
9
|
|
10
|
-
READ =
|
11
|
-
WRITE =
|
10
|
+
READ = Constant::DocumentHighlightKind::READ
|
11
|
+
WRITE = Constant::DocumentHighlightKind::WRITE
|
12
12
|
|
13
13
|
class HighlightMatch
|
14
14
|
extend T::Sig
|
@@ -84,10 +84,11 @@ module RubyLsp
|
|
84
84
|
SyntaxTree::KwRestParam, SyntaxTree::BlockArg
|
85
85
|
node.name&.value
|
86
86
|
when SyntaxTree::VarField, SyntaxTree::VarRef, SyntaxTree::VCall
|
87
|
-
node.value
|
87
|
+
value = node.value
|
88
|
+
value.value unless value.nil? || value.is_a?(Symbol)
|
88
89
|
when SyntaxTree::CallNode, SyntaxTree::Command, SyntaxTree::CommandCall
|
89
90
|
message = node.message
|
90
|
-
message
|
91
|
+
message.value unless message.is_a?(Symbol)
|
91
92
|
when SyntaxTree::ClassDeclaration, SyntaxTree::ModuleDeclaration
|
92
93
|
node.constant.constant.value
|
93
94
|
end
|
@@ -67,12 +67,13 @@ module RubyLsp
|
|
67
67
|
return unless RAILTIES_VERSION
|
68
68
|
|
69
69
|
warn("Fetching Rails Documents...")
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
70
|
+
|
71
|
+
response = Net::HTTP.get_response(URI("#{RAILS_DOC_HOST}/v#{RAILTIES_VERSION}/js/search_index.js"))
|
72
|
+
|
73
|
+
if response.code == "302"
|
74
|
+
# If the version's doc is not found, e.g. Rails main, it'll be redirected
|
75
|
+
# In this case, we just fetch the latest doc
|
76
|
+
response = Net::HTTP.get_response(URI("#{RAILS_DOC_HOST}/js/search_index.js"))
|
76
77
|
end
|
77
78
|
|
78
79
|
if response.code == "200"
|
@@ -4,7 +4,7 @@
|
|
4
4
|
module RubyLsp
|
5
5
|
module Requests
|
6
6
|
module Support
|
7
|
-
class SelectionRange <
|
7
|
+
class SelectionRange < Interface::SelectionRange
|
8
8
|
extend T::Sig
|
9
9
|
|
10
10
|
sig { params(position: Document::PositionShape).returns(T::Boolean) }
|
@@ -16,7 +16,7 @@ module RubyLsp
|
|
16
16
|
sig do
|
17
17
|
params(
|
18
18
|
tokens: T::Array[SemanticHighlighting::SemanticToken],
|
19
|
-
).returns(
|
19
|
+
).returns(Interface::SemanticTokens)
|
20
20
|
end
|
21
21
|
def encode(tokens)
|
22
22
|
delta = tokens
|
@@ -27,7 +27,7 @@ module RubyLsp
|
|
27
27
|
compute_delta(token)
|
28
28
|
end
|
29
29
|
|
30
|
-
|
30
|
+
Interface::SemanticTokens.new(data: delta)
|
31
31
|
end
|
32
32
|
|
33
33
|
# The delta array is computed according to the LSP specification:
|
@@ -63,7 +63,8 @@ module RubyLsp
|
|
63
63
|
when SyntaxTree::VCall
|
64
64
|
ANNOTATIONS[node.value.value]
|
65
65
|
when SyntaxTree::CallNode
|
66
|
-
|
66
|
+
message = node.message
|
67
|
+
ANNOTATIONS[message.value] unless message.is_a?(Symbol)
|
67
68
|
else
|
68
69
|
T.absurd(node)
|
69
70
|
end
|
@@ -84,21 +85,10 @@ module RubyLsp
|
|
84
85
|
end
|
85
86
|
|
86
87
|
sig do
|
87
|
-
params(node: T.nilable(T.
|
88
|
-
SyntaxTree::VarRef,
|
89
|
-
SyntaxTree::CallNode,
|
90
|
-
SyntaxTree::VCall,
|
91
|
-
SyntaxTree::Ident,
|
92
|
-
SyntaxTree::Backtick,
|
93
|
-
SyntaxTree::Const,
|
94
|
-
SyntaxTree::Op,
|
95
|
-
Symbol,
|
96
|
-
))).returns(T.nilable(String))
|
88
|
+
params(node: T.nilable(SyntaxTree::Node)).returns(T.nilable(String))
|
97
89
|
end
|
98
90
|
def node_name(node)
|
99
91
|
case node
|
100
|
-
when NilClass
|
101
|
-
nil
|
102
92
|
when SyntaxTree::VarRef
|
103
93
|
node.value.value
|
104
94
|
when SyntaxTree::CallNode
|
@@ -107,8 +97,8 @@ module RubyLsp
|
|
107
97
|
node_name(node.value)
|
108
98
|
when SyntaxTree::Ident, SyntaxTree::Backtick, SyntaxTree::Const, SyntaxTree::Op
|
109
99
|
node.value
|
110
|
-
when
|
111
|
-
|
100
|
+
when NilClass, SyntaxTree::Node
|
101
|
+
nil
|
112
102
|
else
|
113
103
|
T.absurd(node)
|
114
104
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "syntax_tree/cli"
|
5
|
+
require "singleton"
|
6
|
+
|
7
|
+
module RubyLsp
|
8
|
+
module Requests
|
9
|
+
module Support
|
10
|
+
# :nodoc:
|
11
|
+
class SyntaxTreeFormattingRunner
|
12
|
+
extend T::Sig
|
13
|
+
include Singleton
|
14
|
+
|
15
|
+
sig { void }
|
16
|
+
def initialize
|
17
|
+
@options =
|
18
|
+
T.let(
|
19
|
+
begin
|
20
|
+
opts = SyntaxTree::CLI::Options.new
|
21
|
+
opts.parse(SyntaxTree::CLI::ConfigFile.new.arguments)
|
22
|
+
opts
|
23
|
+
end,
|
24
|
+
SyntaxTree::CLI::Options,
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
28
|
+
sig { params(_uri: String, document: Document).returns(T.nilable(String)) }
|
29
|
+
def run(_uri, document)
|
30
|
+
SyntaxTree.format(
|
31
|
+
document.source,
|
32
|
+
@options.print_width,
|
33
|
+
options: @options.formatter_options,
|
34
|
+
)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/ruby_lsp/server.rb
CHANGED
@@ -2,9 +2,11 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
module RubyLsp
|
5
|
+
# rubocop:disable RubyLsp/UseLanguageServerAliases
|
5
6
|
Interface = LanguageServer::Protocol::Interface
|
6
7
|
Constant = LanguageServer::Protocol::Constant
|
7
8
|
Transport = LanguageServer::Protocol::Transport
|
9
|
+
# rubocop:enable RubyLsp/UseLanguageServerAliases
|
8
10
|
|
9
11
|
class Server
|
10
12
|
extend T::Sig
|
@@ -33,7 +35,8 @@ module RubyLsp
|
|
33
35
|
# fall under the else branch which just pushes requests to the queue
|
34
36
|
@reader.read do |request|
|
35
37
|
case request[:method]
|
36
|
-
when "initialize", "initialized", "textDocument/didOpen", "textDocument/didClose", "textDocument/didChange"
|
38
|
+
when "initialize", "initialized", "textDocument/didOpen", "textDocument/didClose", "textDocument/didChange",
|
39
|
+
"textDocument/formatting", "textDocument/onTypeFormatting", "codeAction/resolve"
|
37
40
|
result = Executor.new(@store).execute(request)
|
38
41
|
finalize_request(result, request)
|
39
42
|
when "$/cancelRequest"
|
data/lib/ruby_lsp/store.rb
CHANGED
@@ -27,19 +27,19 @@ module RubyLsp
|
|
27
27
|
document = @state[uri]
|
28
28
|
return document unless document.nil?
|
29
29
|
|
30
|
-
set(uri, File.binread(CGI.unescape(URI.parse(uri).path)))
|
30
|
+
set(uri: uri, source: File.binread(CGI.unescape(URI.parse(uri).path)), version: 0)
|
31
31
|
T.must(@state[uri])
|
32
32
|
end
|
33
33
|
|
34
|
-
sig { params(uri: String,
|
35
|
-
def set(uri
|
36
|
-
document = Document.new(
|
34
|
+
sig { params(uri: String, source: String, version: Integer).void }
|
35
|
+
def set(uri:, source:, version:)
|
36
|
+
document = Document.new(source: source, version: version, uri: uri, encoding: @encoding)
|
37
37
|
@state[uri] = document
|
38
38
|
end
|
39
39
|
|
40
|
-
sig { params(uri: String, edits: T::Array[Document::EditShape]).void }
|
41
|
-
def push_edits(uri
|
42
|
-
T.must(@state[uri]).push_edits(edits)
|
40
|
+
sig { params(uri: String, edits: T::Array[Document::EditShape], version: Integer).void }
|
41
|
+
def push_edits(uri:, edits:, version:)
|
42
|
+
T.must(@state[uri]).push_edits(edits, version: version)
|
43
43
|
end
|
44
44
|
|
45
45
|
sig { void }
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-lsp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shopify
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-03-
|
11
|
+
date: 2023-03-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: language_server-protocol
|
@@ -44,7 +44,7 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: 6.
|
47
|
+
version: 6.1.1
|
48
48
|
- - "<"
|
49
49
|
- !ruby/object:Gem::Version
|
50
50
|
version: '7'
|
@@ -54,7 +54,7 @@ dependencies:
|
|
54
54
|
requirements:
|
55
55
|
- - ">="
|
56
56
|
- !ruby/object:Gem::Version
|
57
|
-
version: 6.
|
57
|
+
version: 6.1.1
|
58
58
|
- - "<"
|
59
59
|
- !ruby/object:Gem::Version
|
60
60
|
version: '7'
|
@@ -70,6 +70,7 @@ files:
|
|
70
70
|
- README.md
|
71
71
|
- VERSION
|
72
72
|
- exe/ruby-lsp
|
73
|
+
- lib/rubocop/cop/ruby_lsp/use_language_server_aliases.rb
|
73
74
|
- lib/ruby-lsp.rb
|
74
75
|
- lib/ruby_lsp/document.rb
|
75
76
|
- lib/ruby_lsp/executor.rb
|
@@ -102,6 +103,7 @@ files:
|
|
102
103
|
- lib/ruby_lsp/requests/support/semantic_token_encoder.rb
|
103
104
|
- lib/ruby_lsp/requests/support/sorbet.rb
|
104
105
|
- lib/ruby_lsp/requests/support/source_uri.rb
|
106
|
+
- lib/ruby_lsp/requests/support/syntax_tree_formatting_runner.rb
|
105
107
|
- lib/ruby_lsp/server.rb
|
106
108
|
- lib/ruby_lsp/store.rb
|
107
109
|
- lib/ruby_lsp/utils.rb
|
@@ -125,7 +127,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
125
127
|
- !ruby/object:Gem::Version
|
126
128
|
version: '0'
|
127
129
|
requirements: []
|
128
|
-
rubygems_version: 3.
|
130
|
+
rubygems_version: 3.4.9
|
129
131
|
signing_key:
|
130
132
|
specification_version: 4
|
131
133
|
summary: An opinionated language server for Ruby
|