ruby-lsp 0.4.2 → 0.4.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
![Build Status](https://github.com/Shopify/ruby-lsp/workflows/CI/badge.svg)
|
1
|
+
[![Build Status](https://github.com/Shopify/ruby-lsp/workflows/CI/badge.svg)](https://github.com/Shopify/ruby-lsp/actions/workflows/ci.yml)
|
2
|
+
[![Ruby LSP extension](https://img.shields.io/badge/VS%20Code-Ruby%20LSP-success?logo=visual-studio-code)](https://marketplace.visualstudio.com/items?itemName=Shopify.ruby-lsp)
|
3
|
+
[![Ruby DX Slack](https://img.shields.io/badge/Slack-Ruby%20DX-success?logo=slack)](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
|