ruby-lsp 0.0.4 → 0.2.1
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/.rubocop.yml +11 -1
- data/CHANGELOG.md +35 -0
- data/Gemfile +4 -3
- data/Gemfile.lock +26 -24
- data/README.md +3 -2
- data/Rakefile +8 -1
- data/VERSION +1 -1
- data/bin/console +19 -0
- data/exe/ruby-lsp +1 -3
- data/lib/ruby_lsp/document.rb +17 -4
- data/lib/ruby_lsp/handler.rb +54 -141
- data/lib/{internal.rb → ruby_lsp/internal.rb} +4 -2
- data/lib/ruby_lsp/requests/base_request.rb +9 -7
- data/lib/ruby_lsp/requests/code_actions.rb +20 -9
- data/lib/ruby_lsp/requests/diagnostics.rb +25 -8
- data/lib/ruby_lsp/requests/document_highlight.rb +32 -32
- data/lib/ruby_lsp/requests/document_symbol.rb +59 -10
- data/lib/ruby_lsp/requests/folding_ranges.rb +73 -34
- data/lib/ruby_lsp/requests/formatting.rb +25 -15
- data/lib/ruby_lsp/requests/selection_ranges.rb +18 -5
- data/lib/ruby_lsp/requests/semantic_highlighting.rb +179 -36
- data/lib/ruby_lsp/requests/support/highlight_target.rb +87 -0
- data/lib/ruby_lsp/requests/support/rubocop_diagnostic.rb +16 -4
- data/lib/ruby_lsp/requests/support/rubocop_diagnostics_runner.rb +61 -0
- data/lib/ruby_lsp/requests/support/rubocop_formatting_runner.rb +50 -0
- data/lib/ruby_lsp/requests/support/selection_range.rb +4 -1
- data/lib/ruby_lsp/requests/support/semantic_token_encoder.rb +13 -3
- data/lib/ruby_lsp/requests/support/syntax_error_diagnostic.rb +6 -1
- data/lib/ruby_lsp/requests.rb +13 -2
- data/lib/ruby_lsp/server.rb +160 -0
- data/lib/ruby_lsp/store.rb +17 -9
- data/rakelib/check_docs.rake +30 -5
- data/ruby-lsp.gemspec +6 -5
- data/sorbet/tapioca/require.rb +1 -1
- metadata +14 -26
- data/lib/ruby_lsp/cli.rb +0 -88
- data/lib/ruby_lsp/requests/rubocop_request.rb +0 -50
- data/shipit.production.yml +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d067270389ee6b02bb03fb6363e272b6808e7c3d27d77354442801d09a617149
|
4
|
+
data.tar.gz: 74e7cd206a790a8c139969f5167ab3d38686f78646c619488153fd8ab139892e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8d65637f892541a79fde71e3f523dfc37c887ec4892315ffe58b450718c8fa6e2a342036c394c28f5a94da0a1348948a104609881109c5621488b9d23a581bc1
|
7
|
+
data.tar.gz: 1d25dbac214c23c2af2bd991d4c57bdae9dce488ac886cc700d7ab10a7e3b4a0e72ddc2c1d4be459b332e9cdfac69588d42eac11ff78023d365e0d5ef6701f78
|
data/.rubocop.yml
CHANGED
@@ -25,6 +25,16 @@ Sorbet/FalseSigil:
|
|
25
25
|
Sorbet/TrueSigil:
|
26
26
|
Enabled: true
|
27
27
|
Include:
|
28
|
-
- "
|
28
|
+
- "test/**/*.rb"
|
29
29
|
Exclude:
|
30
30
|
- "**/*.rake"
|
31
|
+
- "lib/**/*.rb"
|
32
|
+
|
33
|
+
Sorbet/StrictSigil:
|
34
|
+
Enabled: true
|
35
|
+
Include:
|
36
|
+
- "lib/**/*.rb"
|
37
|
+
Exclude:
|
38
|
+
- "**/*.rake"
|
39
|
+
- "test/**/*.rb"
|
40
|
+
- "lib/ruby-lsp.rb"
|
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,41 @@ Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how
|
|
6
6
|
|
7
7
|
## [Unreleased]
|
8
8
|
|
9
|
+
## [0.2.1]
|
10
|
+
|
11
|
+
- Implement the exit lifecycle request (https://github.com/Shopify/ruby-lsp/pull/198)
|
12
|
+
- Remove the Sorbet runtime from the gem's default load path (https://github.com/Shopify/ruby-lsp/pull/214)
|
13
|
+
- Return nil if the document is already formatted (https://github.com/Shopify/ruby-lsp/pull/216)
|
14
|
+
- Handle nameless keyword rest parameters in semantic highlighting (https://github.com/Shopify/ruby-lsp/pull/222)
|
15
|
+
- Display a warning on invalid RuboCop configuration (https://github.com/Shopify/ruby-lsp/pull/226)
|
16
|
+
- Centralize request handling logic in server.rb (https://github.com/Shopify/ruby-lsp/pull/221)
|
17
|
+
- Fix folding ranges for chained invocations involving an FCall (https://github.com/Shopify/ruby-lsp/pull/223)
|
18
|
+
- Fix handling of argument fowarding in semantic highlighting (https://github.com/Shopify/ruby-lsp/pull/228)
|
19
|
+
- Recover from initial syntax errors when opening documents (https://github.com/Shopify/ruby-lsp/pull/224)
|
20
|
+
- Highlight occurrences and definitions in document highlight (https://github.com/Shopify/ruby-lsp/pull/187)
|
21
|
+
|
22
|
+
## [0.2.0]
|
23
|
+
|
24
|
+
- Add semantic token for keyword and keyword rest params (https://github.com/Shopify/ruby-lsp/pull/142)
|
25
|
+
- Return error responses on exceptions (https://github.com/Shopify/ruby-lsp/pull/160)
|
26
|
+
- Sanitize home directory for telemetry (https://github.com/Shopify/ruby-lsp/pull/171)
|
27
|
+
- Avoid adding semantic tokens for special methods (https://github.com/Shopify/ruby-lsp/pull/162)
|
28
|
+
- Properly respect excluded files in RuboCop requests (https://github.com/Shopify/ruby-lsp/pull/173)
|
29
|
+
- Clear diagnostics when closing files (https://github.com/Shopify/ruby-lsp/pull/174)
|
30
|
+
- Avoid pushing ranges for single line partial ranges (https://github.com/Shopify/ruby-lsp/pull/185)
|
31
|
+
- Change folding ranges to include closing tokens (https://github.com/Shopify/ruby-lsp/pull/181)
|
32
|
+
- Remove RuboCop dependency and fallback to SyntaxTree formatting (https://github.com/Shopify/ruby-lsp/pull/184)
|
33
|
+
|
34
|
+
## [0.1.0]
|
35
|
+
|
36
|
+
- Implement token modifiers in SemanticTokenEncoder ([#112](https://github.com/Shopify/ruby-lsp/pull/112))
|
37
|
+
- Add semantic token for name in a method definition ([#133](https://github.com/Shopify/ruby-lsp/pull/133))
|
38
|
+
- Add semantic highighting for def endless and singleton method names ([#134](https://github.com/Shopify/ruby-lsp/pull/134))
|
39
|
+
- Add semantic token for keyword self ([#137](https://github.com/Shopify/ruby-lsp/pull/137))
|
40
|
+
- Add semantic token for constants ([#138](https://github.com/Shopify/ruby-lsp/pull/138))
|
41
|
+
- Improve error handling + fix formatting hanging issue ([#149](https://github.com/Shopify/ruby-lsp/pull/149))
|
42
|
+
- Set the minimum syntax_tree version to 2.4 ([#151](https://github.com/Shopify/ruby-lsp/pull/151))
|
43
|
+
|
9
44
|
## [0.0.4]
|
10
45
|
|
11
46
|
- Add basic document highlight (https://github.com/Shopify/ruby-lsp/pull/91)
|
data/Gemfile
CHANGED
@@ -5,11 +5,12 @@ source "https://rubygems.org"
|
|
5
5
|
gemspec
|
6
6
|
|
7
7
|
gem "debug", "~> 1.5", require: false
|
8
|
-
gem "minitest", "~> 5.
|
8
|
+
gem "minitest", "~> 5.16"
|
9
9
|
gem "minitest-reporters", "~> 1.5"
|
10
10
|
gem "rake", "~> 13.0"
|
11
|
-
gem "rubocop
|
12
|
-
gem "rubocop-
|
11
|
+
gem "rubocop", ">= 1.0.0"
|
12
|
+
gem "rubocop-shopify", "~> 2.8", require: false
|
13
|
+
gem "rubocop-minitest", "~> 0.20.1", require: false
|
13
14
|
gem "rubocop-rake", "~> 0.6.0", require: false
|
14
15
|
gem "rubocop-sorbet", "~> 0.6", require: false
|
15
16
|
gem "sorbet-static-and-runtime"
|
data/Gemfile.lock
CHANGED
@@ -1,11 +1,10 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
ruby-lsp (0.
|
4
|
+
ruby-lsp (0.2.1)
|
5
5
|
language_server-protocol
|
6
|
-
rubocop (>= 1.0)
|
7
6
|
sorbet-runtime
|
8
|
-
syntax_tree (>= 2.
|
7
|
+
syntax_tree (>= 2.4)
|
9
8
|
|
10
9
|
GEM
|
11
10
|
remote: https://rubygems.org/
|
@@ -21,9 +20,10 @@ GEM
|
|
21
20
|
io-console (0.5.11)
|
22
21
|
irb (1.4.1)
|
23
22
|
reline (>= 0.3.0)
|
23
|
+
json (2.6.2)
|
24
24
|
language_server-protocol (3.16.0.3)
|
25
25
|
method_source (1.0.0)
|
26
|
-
minitest (5.
|
26
|
+
minitest (5.16.2)
|
27
27
|
minitest-reporters (1.5.0)
|
28
28
|
ansi
|
29
29
|
builder
|
@@ -38,7 +38,7 @@ GEM
|
|
38
38
|
method_source (~> 1.0)
|
39
39
|
rainbow (3.1.1)
|
40
40
|
rake (13.0.6)
|
41
|
-
rbi (0.0.
|
41
|
+
rbi (0.0.15)
|
42
42
|
ast
|
43
43
|
parser (>= 2.6.4.0)
|
44
44
|
sorbet-runtime (>= 0.5.9204)
|
@@ -47,7 +47,8 @@ GEM
|
|
47
47
|
reline (0.3.1)
|
48
48
|
io-console (~> 0.5)
|
49
49
|
rexml (3.2.5)
|
50
|
-
rubocop (1.
|
50
|
+
rubocop (1.31.1)
|
51
|
+
json (~> 2.3)
|
51
52
|
parallel (~> 1.10)
|
52
53
|
parser (>= 3.1.0.0)
|
53
54
|
rainbow (>= 2.2.2, < 4.0)
|
@@ -58,30 +59,30 @@ GEM
|
|
58
59
|
unicode-display_width (>= 1.4.0, < 3.0)
|
59
60
|
rubocop-ast (1.18.0)
|
60
61
|
parser (>= 3.1.1.0)
|
61
|
-
rubocop-minitest (0.20.
|
62
|
+
rubocop-minitest (0.20.1)
|
62
63
|
rubocop (>= 0.90, < 2.0)
|
63
64
|
rubocop-rake (0.6.0)
|
64
65
|
rubocop (~> 1.0)
|
65
|
-
rubocop-shopify (2.
|
66
|
-
rubocop (~> 1.
|
67
|
-
rubocop-sorbet (0.6.
|
66
|
+
rubocop-shopify (2.8.0)
|
67
|
+
rubocop (~> 1.31)
|
68
|
+
rubocop-sorbet (0.6.11)
|
68
69
|
rubocop (>= 0.90.0)
|
69
70
|
ruby-progressbar (1.11.0)
|
70
|
-
sorbet (0.5.
|
71
|
-
sorbet-static (= 0.5.
|
72
|
-
sorbet-runtime (0.5.
|
73
|
-
sorbet-static (0.5.
|
74
|
-
sorbet-static (0.5.
|
75
|
-
sorbet-static-and-runtime (0.5.
|
76
|
-
sorbet (= 0.5.
|
77
|
-
sorbet-runtime (= 0.5.
|
71
|
+
sorbet (0.5.10139)
|
72
|
+
sorbet-static (= 0.5.10139)
|
73
|
+
sorbet-runtime (0.5.10139)
|
74
|
+
sorbet-static (0.5.10139-universal-darwin-21)
|
75
|
+
sorbet-static (0.5.10139-x86_64-linux)
|
76
|
+
sorbet-static-and-runtime (0.5.10139)
|
77
|
+
sorbet (= 0.5.10139)
|
78
|
+
sorbet-runtime (= 0.5.10139)
|
78
79
|
spoom (1.1.11)
|
79
80
|
sorbet (>= 0.5.9204)
|
80
81
|
sorbet-runtime (>= 0.5.9204)
|
81
82
|
thor (>= 0.19.2)
|
82
|
-
syntax_tree (2.
|
83
|
+
syntax_tree (2.8.0)
|
83
84
|
prettier_print
|
84
|
-
tapioca (0.8.
|
85
|
+
tapioca (0.8.3)
|
85
86
|
bundler (>= 1.17.3)
|
86
87
|
parallel (>= 1.21.0)
|
87
88
|
pry (>= 0.12.2)
|
@@ -91,7 +92,7 @@ GEM
|
|
91
92
|
thor (>= 1.2.0)
|
92
93
|
yard-sorbet
|
93
94
|
thor (1.2.1)
|
94
|
-
unicode-display_width (2.
|
95
|
+
unicode-display_width (2.2.0)
|
95
96
|
unparser (0.6.5)
|
96
97
|
diff-lcs (~> 1.3)
|
97
98
|
parser (>= 3.1.0)
|
@@ -108,12 +109,13 @@ PLATFORMS
|
|
108
109
|
|
109
110
|
DEPENDENCIES
|
110
111
|
debug (~> 1.5)
|
111
|
-
minitest (~> 5.
|
112
|
+
minitest (~> 5.16)
|
112
113
|
minitest-reporters (~> 1.5)
|
113
114
|
rake (~> 13.0)
|
114
|
-
rubocop
|
115
|
+
rubocop (>= 1.0.0)
|
116
|
+
rubocop-minitest (~> 0.20.1)
|
115
117
|
rubocop-rake (~> 0.6.0)
|
116
|
-
rubocop-shopify (~> 2.
|
118
|
+
rubocop-shopify (~> 2.8)
|
117
119
|
rubocop-sorbet (~> 0.6)
|
118
120
|
ruby-lsp!
|
119
121
|
sorbet-static-and-runtime
|
data/README.md
CHANGED
@@ -17,7 +17,8 @@ end
|
|
17
17
|
If using VS Code, install the [Ruby LSP plugin](https://github.com/Shopify/vscode-ruby-lsp) to get the extra features in
|
18
18
|
the editor.
|
19
19
|
|
20
|
-
See the [documentation](https://shopify.github.io/ruby-lsp) for
|
20
|
+
See the [documentation](https://shopify.github.io/ruby-lsp) for
|
21
|
+
[supported features](https://shopify.github.io/ruby-lsp/RubyLsp/Requests.html).
|
21
22
|
|
22
23
|
## Contributing
|
23
24
|
|
@@ -50,7 +51,7 @@ To add a new expectations test runner for a new request handler:
|
|
50
51
|
require "expectations/expectations_test_runner"
|
51
52
|
|
52
53
|
class $HANDLERExpectationsTest < ExpectationsTestRunner
|
53
|
-
|
54
|
+
expectations_tests RubyLsp::Requests::$HANDLER, "$EXPECTATIONS_DIR"
|
54
55
|
end
|
55
56
|
```
|
56
57
|
|
data/Rakefile
CHANGED
@@ -11,7 +11,14 @@ Rake::TestTask.new(:test) do |t|
|
|
11
11
|
end
|
12
12
|
|
13
13
|
YARD::Rake::YardocTask.new do |t|
|
14
|
-
t.options = [
|
14
|
+
t.options = [
|
15
|
+
"--markup",
|
16
|
+
"markdown",
|
17
|
+
"--output-dir",
|
18
|
+
"docs",
|
19
|
+
"--asset",
|
20
|
+
"misc",
|
21
|
+
]
|
15
22
|
end
|
16
23
|
|
17
24
|
require "rubocop/rake_task"
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.1
|
data/bin/console
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# typed: strict
|
3
|
+
# frozen_string_literal: true
|
4
|
+
|
5
|
+
require "bundler/setup"
|
6
|
+
require_relative "../lib/ruby_lsp/internal"
|
7
|
+
require "irb"
|
8
|
+
|
9
|
+
extend T::Sig
|
10
|
+
|
11
|
+
sig { params(source: String).returns(RubyLsp::Document) }
|
12
|
+
def new_doc(source)
|
13
|
+
RubyLsp::Document.new(source)
|
14
|
+
end
|
15
|
+
|
16
|
+
@source = T.let(File.read(File.expand_path("../lib/ruby_lsp/handler.rb", __dir__)), String)
|
17
|
+
@document = T.let(new_doc(@source), RubyLsp::Document)
|
18
|
+
|
19
|
+
IRB.start(__FILE__)
|
data/exe/ruby-lsp
CHANGED
data/lib/ruby_lsp/document.rb
CHANGED
@@ -9,7 +9,7 @@ module RubyLsp
|
|
9
9
|
RangeShape = T.type_alias { { start: PositionShape, end: PositionShape } }
|
10
10
|
EditShape = T.type_alias { { range: RangeShape, text: String } }
|
11
11
|
|
12
|
-
sig { returns(SyntaxTree::Node) }
|
12
|
+
sig { returns(T.nilable(SyntaxTree::Node)) }
|
13
13
|
attr_reader :tree
|
14
14
|
|
15
15
|
sig { returns(String) }
|
@@ -20,11 +20,13 @@ module RubyLsp
|
|
20
20
|
|
21
21
|
sig { params(source: String).void }
|
22
22
|
def initialize(source)
|
23
|
-
@tree = T.let(SyntaxTree.parse(source), SyntaxTree::Node)
|
24
23
|
@cache = T.let({}, T::Hash[Symbol, T.untyped])
|
25
24
|
@syntax_error_edits = T.let([], T::Array[EditShape])
|
26
|
-
@source = source
|
25
|
+
@source = T.let(source, String)
|
27
26
|
@parsable_source = T.let(source.dup, String)
|
27
|
+
@tree = T.let(SyntaxTree.parse(@source), T.nilable(SyntaxTree::Node))
|
28
|
+
rescue SyntaxTree::Parser::ParseError
|
29
|
+
# Do not raise if we failed to parse
|
28
30
|
end
|
29
31
|
|
30
32
|
sig { params(other: Document).returns(T::Boolean) }
|
@@ -32,7 +34,13 @@ module RubyLsp
|
|
32
34
|
@source == other.source
|
33
35
|
end
|
34
36
|
|
35
|
-
sig
|
37
|
+
sig do
|
38
|
+
type_parameters(:T)
|
39
|
+
.params(
|
40
|
+
request_name: Symbol,
|
41
|
+
block: T.proc.params(document: Document).returns(T.type_parameter(:T))
|
42
|
+
).returns(T.type_parameter(:T))
|
43
|
+
end
|
36
44
|
def cache_fetch(request_name, &block)
|
37
45
|
cached = @cache[request_name]
|
38
46
|
return cached if cached
|
@@ -61,6 +69,11 @@ module RubyLsp
|
|
61
69
|
@syntax_error_edits.any?
|
62
70
|
end
|
63
71
|
|
72
|
+
sig { returns(T::Boolean) }
|
73
|
+
def parsed?
|
74
|
+
!@tree.nil?
|
75
|
+
end
|
76
|
+
|
64
77
|
private
|
65
78
|
|
66
79
|
sig { params(edits: T::Array[EditShape]).void }
|
data/lib/ruby_lsp/handler.rb
CHANGED
@@ -6,17 +6,24 @@ require "ruby_lsp/store"
|
|
6
6
|
require "benchmark"
|
7
7
|
|
8
8
|
module RubyLsp
|
9
|
+
Interface = LanguageServer::Protocol::Interface
|
10
|
+
Constant = LanguageServer::Protocol::Constant
|
11
|
+
Transport = LanguageServer::Protocol::Transport
|
12
|
+
|
9
13
|
class Handler
|
10
14
|
extend T::Sig
|
11
15
|
VOID = T.let(Object.new.freeze, Object)
|
12
16
|
|
17
|
+
sig { params(blk: T.proc.bind(Handler).params(arg0: T.untyped).void).void }
|
18
|
+
def self.start(&blk)
|
19
|
+
handler = new
|
20
|
+
handler.instance_exec(&blk)
|
21
|
+
handler.start
|
22
|
+
end
|
23
|
+
|
13
24
|
sig { returns(Store) }
|
14
25
|
attr_reader :store
|
15
26
|
|
16
|
-
Interface = LanguageServer::Protocol::Interface
|
17
|
-
Constant = LanguageServer::Protocol::Constant
|
18
|
-
Transport = LanguageServer::Protocol::Transport
|
19
|
-
|
20
27
|
sig { void }
|
21
28
|
def initialize
|
22
29
|
@writer = T.let(Transport::Stdio::Writer.new, Transport::Stdio::Writer)
|
@@ -28,14 +35,7 @@ module RubyLsp
|
|
28
35
|
sig { void }
|
29
36
|
def start
|
30
37
|
$stderr.puts "Starting Ruby LSP..."
|
31
|
-
@reader.read
|
32
|
-
with_telemetry(request) { handle(request) }
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
sig { params(blk: T.proc.bind(Handler).params(arg0: T.untyped).void).void }
|
37
|
-
def config(&blk)
|
38
|
-
instance_exec(&blk)
|
38
|
+
@reader.read { |request| handle(request) }
|
39
39
|
end
|
40
40
|
|
41
41
|
private
|
@@ -52,11 +52,32 @@ module RubyLsp
|
|
52
52
|
|
53
53
|
sig { params(request: T::Hash[Symbol, T.untyped]).void }
|
54
54
|
def handle(request)
|
55
|
+
result = T.let(nil, T.untyped)
|
56
|
+
error = T.let(nil, T.nilable(StandardError))
|
55
57
|
handler = @handlers[request[:method]]
|
56
|
-
return unless handler
|
57
58
|
|
58
|
-
|
59
|
-
|
59
|
+
request_time = Benchmark.realtime do
|
60
|
+
if handler
|
61
|
+
begin
|
62
|
+
result = handler.call(request)
|
63
|
+
rescue StandardError => e
|
64
|
+
error = e
|
65
|
+
end
|
66
|
+
|
67
|
+
if error
|
68
|
+
@writer.write(
|
69
|
+
{
|
70
|
+
id: request[:id],
|
71
|
+
error: { code: Constant::ErrorCodes::INTERNAL_ERROR, message: error.inspect, data: request.to_json },
|
72
|
+
}
|
73
|
+
)
|
74
|
+
elsif result != VOID
|
75
|
+
@writer.write(id: request[:id], result: result)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
@writer.write(method: "telemetry/event", params: telemetry_params(request, request_time, error))
|
60
81
|
end
|
61
82
|
|
62
83
|
sig { void }
|
@@ -65,106 +86,14 @@ module RubyLsp
|
|
65
86
|
store.clear
|
66
87
|
end
|
67
88
|
|
68
|
-
sig { params(enabled_features: T::Array[String]).returns(Interface::InitializeResult) }
|
69
|
-
def respond_with_capabilities(enabled_features)
|
70
|
-
document_symbol_provider = if enabled_features.include?("documentSymbols")
|
71
|
-
Interface::DocumentSymbolClientCapabilities.new(
|
72
|
-
hierarchical_document_symbol_support: true,
|
73
|
-
symbol_kind: {
|
74
|
-
value_set: Requests::DocumentSymbol::SYMBOL_KIND.values,
|
75
|
-
}
|
76
|
-
)
|
77
|
-
end
|
78
|
-
|
79
|
-
folding_ranges_provider = if enabled_features.include?("foldingRanges")
|
80
|
-
Interface::FoldingRangeClientCapabilities.new(line_folding_only: true)
|
81
|
-
end
|
82
|
-
|
83
|
-
semantic_tokens_provider = if enabled_features.include?("semanticHighlighting")
|
84
|
-
Interface::SemanticTokensRegistrationOptions.new(
|
85
|
-
document_selector: { scheme: "file", language: "ruby" },
|
86
|
-
legend: Interface::SemanticTokensLegend.new(
|
87
|
-
token_types: Requests::SemanticHighlighting::TOKEN_TYPES,
|
88
|
-
token_modifiers: Requests::SemanticHighlighting::TOKEN_MODIFIERS.keys
|
89
|
-
),
|
90
|
-
range: false,
|
91
|
-
full: {
|
92
|
-
delta: true,
|
93
|
-
}
|
94
|
-
)
|
95
|
-
end
|
96
|
-
|
97
|
-
Interface::InitializeResult.new(
|
98
|
-
capabilities: Interface::ServerCapabilities.new(
|
99
|
-
text_document_sync: Interface::TextDocumentSyncOptions.new(
|
100
|
-
change: Constant::TextDocumentSyncKind::INCREMENTAL,
|
101
|
-
open_close: true,
|
102
|
-
),
|
103
|
-
selection_range_provider: enabled_features.include?("selectionRanges"),
|
104
|
-
document_symbol_provider: document_symbol_provider,
|
105
|
-
folding_range_provider: folding_ranges_provider,
|
106
|
-
semantic_tokens_provider: semantic_tokens_provider,
|
107
|
-
document_formatting_provider: enabled_features.include?("formatting"),
|
108
|
-
document_highlight_provider: enabled_features.include?("documentHighlights"),
|
109
|
-
code_action_provider: enabled_features.include?("codeActions")
|
110
|
-
)
|
111
|
-
)
|
112
|
-
end
|
113
|
-
|
114
|
-
sig { params(uri: String).returns(T::Array[LanguageServer::Protocol::Interface::DocumentSymbol]) }
|
115
|
-
def respond_with_document_symbol(uri)
|
116
|
-
store.cache_fetch(uri, :document_symbol) do |document|
|
117
|
-
RubyLsp::Requests::DocumentSymbol.run(document)
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
sig { params(uri: String).returns(T::Array[LanguageServer::Protocol::Interface::FoldingRange]) }
|
122
|
-
def respond_with_folding_ranges(uri)
|
123
|
-
store.cache_fetch(uri, :folding_ranges) do |document|
|
124
|
-
Requests::FoldingRanges.run(document)
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
|
-
sig do
|
129
|
-
params(
|
130
|
-
uri: String,
|
131
|
-
positions: T::Array[Document::PositionShape]
|
132
|
-
).returns(T::Array[RubyLsp::Requests::Support::SelectionRange])
|
133
|
-
end
|
134
|
-
def respond_with_selection_ranges(uri, positions)
|
135
|
-
ranges = store.cache_fetch(uri, :selection_ranges) do |document|
|
136
|
-
Requests::SelectionRanges.run(document)
|
137
|
-
end
|
138
|
-
|
139
|
-
# Per the selection range request spec (https://microsoft.github.io/language-server-protocol/specification#textDocument_selectionRange),
|
140
|
-
# every position in the positions array should have an element at the same index in the response
|
141
|
-
# array. For positions without a valid selection range, the corresponding element in the response
|
142
|
-
# array will be nil.
|
143
|
-
positions.map do |position|
|
144
|
-
ranges.find do |range|
|
145
|
-
range.cover?(position)
|
146
|
-
end
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
|
-
sig { params(uri: String).returns(LanguageServer::Protocol::Interface::SemanticTokens) }
|
151
|
-
def respond_with_semantic_highlighting(uri)
|
152
|
-
store.cache_fetch(uri, :semantic_highlighting) do |document|
|
153
|
-
Requests::SemanticHighlighting.new(document, encoder: Requests::Support::SemanticTokenEncoder.new).run
|
154
|
-
end
|
155
|
-
end
|
156
|
-
|
157
|
-
sig { params(uri: String).returns(T::Array[LanguageServer::Protocol::Interface::TextEdit]) }
|
158
|
-
def respond_with_formatting(uri)
|
159
|
-
Requests::Formatting.run(uri, store.get(uri))
|
160
|
-
end
|
161
|
-
|
162
89
|
sig { params(uri: String).void }
|
163
90
|
def send_diagnostics(uri)
|
164
91
|
response = store.cache_fetch(uri, :diagnostics) do |document|
|
165
|
-
Requests::Diagnostics.
|
92
|
+
Requests::Diagnostics.new(uri, document).run
|
166
93
|
end
|
167
94
|
|
95
|
+
return if response.nil?
|
96
|
+
|
168
97
|
@writer.write(
|
169
98
|
method: "textDocument/publishDiagnostics",
|
170
99
|
params: Interface::PublishDiagnosticsParams.new(
|
@@ -172,40 +101,24 @@ module RubyLsp
|
|
172
101
|
diagnostics: response.map(&:to_lsp_diagnostic)
|
173
102
|
)
|
174
103
|
)
|
104
|
+
rescue RuboCop::ValidationError => e
|
105
|
+
show_message(Constant::MessageType::ERROR, "Error in RuboCop configuration file: #{e.message}")
|
175
106
|
end
|
176
107
|
|
177
|
-
sig
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
end
|
184
|
-
end
|
185
|
-
|
186
|
-
sig do
|
187
|
-
params(
|
188
|
-
uri: String,
|
189
|
-
position: Document::PositionShape
|
190
|
-
).returns(T::Array[LanguageServer::Protocol::Interface::DocumentHighlight])
|
191
|
-
end
|
192
|
-
def respond_with_document_highlight(uri, position)
|
193
|
-
Requests::DocumentHighlight.run(store.get(uri), position)
|
108
|
+
sig { params(uri: String).void }
|
109
|
+
def clear_diagnostics(uri)
|
110
|
+
@writer.write(
|
111
|
+
method: "textDocument/publishDiagnostics",
|
112
|
+
params: Interface::PublishDiagnosticsParams.new(uri: uri, diagnostics: [])
|
113
|
+
)
|
194
114
|
end
|
195
115
|
|
196
|
-
sig { params(
|
197
|
-
def
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
result = block.call
|
203
|
-
rescue StandardError => e
|
204
|
-
error = e
|
205
|
-
end
|
206
|
-
|
207
|
-
@writer.write(method: "telemetry/event", params: telemetry_params(request, request_time, error))
|
208
|
-
result
|
116
|
+
sig { params(type: Integer, message: String).void }
|
117
|
+
def show_message(type, message)
|
118
|
+
@writer.write(
|
119
|
+
method: "window/showMessage",
|
120
|
+
params: Interface::ShowMessageParams.new(type: type, message: message)
|
121
|
+
)
|
209
122
|
end
|
210
123
|
|
211
124
|
sig do
|
@@ -229,7 +142,7 @@ module RubyLsp
|
|
229
142
|
params[:errorMessage] = error.message
|
230
143
|
end
|
231
144
|
|
232
|
-
params[:uri] = uri if uri
|
145
|
+
params[:uri] = uri.sub(%r{.*://#{Dir.home}}, "~") if uri
|
233
146
|
params
|
234
147
|
end
|
235
148
|
end
|
@@ -1,24 +1,26 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
module RubyLsp
|
5
5
|
module Requests
|
6
6
|
# :nodoc:
|
7
7
|
class BaseRequest < SyntaxTree::Visitor
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
extend T::Sig
|
9
|
+
extend T::Helpers
|
10
|
+
|
11
|
+
abstract!
|
11
12
|
|
13
|
+
sig { params(document: Document).void }
|
12
14
|
def initialize(document)
|
13
15
|
@document = document
|
14
16
|
|
15
17
|
super()
|
16
18
|
end
|
17
19
|
|
18
|
-
|
19
|
-
|
20
|
-
end
|
20
|
+
sig { abstract.returns(Object) }
|
21
|
+
def run; end
|
21
22
|
|
23
|
+
sig { params(node: SyntaxTree::Node).returns(LanguageServer::Protocol::Interface::Range) }
|
22
24
|
def range_from_syntax_tree_node(node)
|
23
25
|
loc = node.location
|
24
26
|
|
@@ -1,8 +1,10 @@
|
|
1
|
-
# typed:
|
1
|
+
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
module RubyLsp
|
5
5
|
module Requests
|
6
|
+
# 
|
7
|
+
#
|
6
8
|
# The [code actions](https://microsoft.github.io/language-server-protocol/specification#textDocument_codeAction)
|
7
9
|
# request informs the editor of RuboCop quick fixes that can be applied. These are accesible by hovering over a
|
8
10
|
# specific diagnostic.
|
@@ -14,23 +16,32 @@ module RubyLsp
|
|
14
16
|
# puts "Hello" # --> code action: quick fix indentation
|
15
17
|
# end
|
16
18
|
# ```
|
17
|
-
class CodeActions
|
18
|
-
|
19
|
-
new(uri, document, range).run
|
20
|
-
end
|
19
|
+
class CodeActions < BaseRequest
|
20
|
+
extend T::Sig
|
21
21
|
|
22
|
+
sig do
|
23
|
+
params(
|
24
|
+
uri: String,
|
25
|
+
document: Document,
|
26
|
+
range: T::Range[Integer]
|
27
|
+
).void
|
28
|
+
end
|
22
29
|
def initialize(uri, document, range)
|
23
|
-
|
30
|
+
super(document)
|
31
|
+
|
24
32
|
@uri = uri
|
25
33
|
@range = range
|
26
34
|
end
|
27
35
|
|
36
|
+
sig { override.returns(T.all(T::Array[LanguageServer::Protocol::Interface::CodeAction], Object)) }
|
28
37
|
def run
|
29
|
-
diagnostics = Diagnostics.
|
30
|
-
corrections = diagnostics.select
|
38
|
+
diagnostics = Diagnostics.new(@uri, @document).run
|
39
|
+
corrections = diagnostics.select do |diagnostic|
|
40
|
+
diagnostic.correctable? && T.cast(diagnostic, Support::RuboCopDiagnostic).in_range?(@range)
|
41
|
+
end
|
31
42
|
return [] if corrections.empty?
|
32
43
|
|
33
|
-
corrections.map!(&:to_lsp_code_action)
|
44
|
+
T.cast(corrections, T::Array[Support::RuboCopDiagnostic]).map!(&:to_lsp_code_action)
|
34
45
|
end
|
35
46
|
end
|
36
47
|
end
|