ruby-lsp 0.1.0 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +35 -0
  3. data/README.md +2 -1
  4. data/VERSION +1 -1
  5. data/exe/ruby-lsp +1 -3
  6. data/lib/ruby-lsp.rb +2 -2
  7. data/lib/ruby_lsp/document.rb +10 -3
  8. data/lib/ruby_lsp/handler.rb +30 -134
  9. data/lib/ruby_lsp/internal.rb +3 -1
  10. data/lib/ruby_lsp/requests/code_actions.rb +2 -0
  11. data/lib/ruby_lsp/requests/diagnostics.rb +14 -9
  12. data/lib/ruby_lsp/requests/document_highlight.rb +27 -42
  13. data/lib/ruby_lsp/requests/document_link.rb +59 -0
  14. data/lib/ruby_lsp/requests/document_symbol.rb +2 -0
  15. data/lib/ruby_lsp/requests/folding_ranges.rb +26 -21
  16. data/lib/ruby_lsp/requests/formatting.rb +21 -16
  17. data/lib/ruby_lsp/requests/selection_ranges.rb +2 -0
  18. data/lib/ruby_lsp/requests/semantic_highlighting.rb +85 -11
  19. data/lib/ruby_lsp/requests/support/highlight_target.rb +88 -0
  20. data/lib/ruby_lsp/requests/support/rubocop_diagnostic.rb +9 -2
  21. data/lib/ruby_lsp/requests/support/rubocop_diagnostics_runner.rb +61 -0
  22. data/lib/ruby_lsp/requests/support/rubocop_formatting_runner.rb +50 -0
  23. data/lib/ruby_lsp/requests.rb +14 -1
  24. data/lib/ruby_lsp/server.rb +192 -0
  25. data/lib/ruby_lsp/store.rb +12 -5
  26. metadata +10 -87
  27. data/.github/dependabot.yml +0 -11
  28. data/.github/probots.yml +0 -2
  29. data/.github/pull_request_template.md +0 -15
  30. data/.github/workflows/ci.yml +0 -31
  31. data/.github/workflows/publish_docs.yml +0 -32
  32. data/.gitignore +0 -9
  33. data/.rubocop.yml +0 -39
  34. data/.vscode/extensions.json +0 -5
  35. data/.vscode/settings.json +0 -5
  36. data/.vscode/tasks.json +0 -25
  37. data/CODE_OF_CONDUCT.md +0 -78
  38. data/Gemfile +0 -17
  39. data/Gemfile.lock +0 -124
  40. data/Rakefile +0 -21
  41. data/bin/rubocop +0 -29
  42. data/bin/tapioca +0 -29
  43. data/bin/test +0 -9
  44. data/dev.yml +0 -20
  45. data/lib/ruby_lsp/cli.rb +0 -88
  46. data/lib/ruby_lsp/requests/rubocop_request.rb +0 -60
  47. data/rakelib/check_docs.rake +0 -57
  48. data/ruby-lsp.gemspec +0 -26
  49. data/service.yml +0 -2
  50. data/sorbet/config +0 -4
  51. data/sorbet/rbi/.rubocop.yml +0 -8
  52. data/sorbet/rbi/gems/ansi@1.5.0.rbi +0 -338
  53. data/sorbet/rbi/gems/ast@2.4.2.rbi +0 -522
  54. data/sorbet/rbi/gems/builder@3.2.4.rbi +0 -418
  55. data/sorbet/rbi/gems/coderay@1.1.3.rbi +0 -8
  56. data/sorbet/rbi/gems/debug@1.5.0.rbi +0 -1273
  57. data/sorbet/rbi/gems/diff-lcs@1.5.0.rbi +0 -867
  58. data/sorbet/rbi/gems/io-console@0.5.11.rbi +0 -8
  59. data/sorbet/rbi/gems/irb@1.4.1.rbi +0 -376
  60. data/sorbet/rbi/gems/language_server-protocol@3.16.0.3.rbi +0 -7325
  61. data/sorbet/rbi/gems/method_source@1.0.0.rbi +0 -8
  62. data/sorbet/rbi/gems/minitest-reporters@1.5.0.rbi +0 -612
  63. data/sorbet/rbi/gems/minitest@5.15.0.rbi +0 -994
  64. data/sorbet/rbi/gems/parallel@1.22.1.rbi +0 -163
  65. data/sorbet/rbi/gems/parser@3.1.2.0.rbi +0 -3968
  66. data/sorbet/rbi/gems/prettier_print@0.1.0.rbi +0 -734
  67. data/sorbet/rbi/gems/pry@0.14.1.rbi +0 -8
  68. data/sorbet/rbi/gems/rainbow@3.1.1.rbi +0 -227
  69. data/sorbet/rbi/gems/rake@13.0.6.rbi +0 -1853
  70. data/sorbet/rbi/gems/rbi@0.0.14.rbi +0 -2337
  71. data/sorbet/rbi/gems/regexp_parser@2.5.0.rbi +0 -1854
  72. data/sorbet/rbi/gems/reline@0.3.1.rbi +0 -1274
  73. data/sorbet/rbi/gems/rexml@3.2.5.rbi +0 -3852
  74. data/sorbet/rbi/gems/rubocop-ast@1.18.0.rbi +0 -4180
  75. data/sorbet/rbi/gems/rubocop-minitest@0.20.0.rbi +0 -1369
  76. data/sorbet/rbi/gems/rubocop-rake@0.6.0.rbi +0 -246
  77. data/sorbet/rbi/gems/rubocop-shopify@2.6.0.rbi +0 -8
  78. data/sorbet/rbi/gems/rubocop-sorbet@0.6.8.rbi +0 -652
  79. data/sorbet/rbi/gems/rubocop@1.30.0.rbi +0 -36729
  80. data/sorbet/rbi/gems/ruby-progressbar@1.11.0.rbi +0 -732
  81. data/sorbet/rbi/gems/spoom@1.1.11.rbi +0 -1600
  82. data/sorbet/rbi/gems/syntax_tree@2.7.1.rbi +0 -6777
  83. data/sorbet/rbi/gems/tapioca@0.8.1.rbi +0 -1972
  84. data/sorbet/rbi/gems/thor@1.2.1.rbi +0 -2921
  85. data/sorbet/rbi/gems/unicode-display_width@2.1.0.rbi +0 -27
  86. data/sorbet/rbi/gems/unparser@0.6.5.rbi +0 -2789
  87. data/sorbet/rbi/gems/webrick@1.7.0.rbi +0 -1779
  88. data/sorbet/rbi/gems/yard-sorbet@0.6.1.rbi +0 -289
  89. data/sorbet/rbi/gems/yard@0.9.27.rbi +0 -13048
  90. data/sorbet/rbi/shims/fiddle.rbi +0 -4
  91. data/sorbet/rbi/shims/hash.rbi +0 -6
  92. data/sorbet/rbi/shims/rdoc.rbi +0 -4
  93. data/sorbet/tapioca/config.yml +0 -13
  94. data/sorbet/tapioca/require.rb +0 -7
data/Gemfile.lock DELETED
@@ -1,124 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- ruby-lsp (0.1.0)
5
- language_server-protocol
6
- rubocop (>= 1.0)
7
- sorbet-runtime
8
- syntax_tree (>= 2.4)
9
-
10
- GEM
11
- remote: https://rubygems.org/
12
- specs:
13
- ansi (1.5.0)
14
- ast (2.4.2)
15
- builder (3.2.4)
16
- coderay (1.1.3)
17
- debug (1.5.0)
18
- irb (>= 1.3.6)
19
- reline (>= 0.2.7)
20
- diff-lcs (1.5.0)
21
- io-console (0.5.11)
22
- irb (1.4.1)
23
- reline (>= 0.3.0)
24
- language_server-protocol (3.16.0.3)
25
- method_source (1.0.0)
26
- minitest (5.15.0)
27
- minitest-reporters (1.5.0)
28
- ansi
29
- builder
30
- minitest (>= 5.0)
31
- ruby-progressbar
32
- parallel (1.22.1)
33
- parser (3.1.2.0)
34
- ast (~> 2.4.1)
35
- prettier_print (0.1.0)
36
- pry (0.14.1)
37
- coderay (~> 1.1)
38
- method_source (~> 1.0)
39
- rainbow (3.1.1)
40
- rake (13.0.6)
41
- rbi (0.0.14)
42
- ast
43
- parser (>= 2.6.4.0)
44
- sorbet-runtime (>= 0.5.9204)
45
- unparser
46
- regexp_parser (2.5.0)
47
- reline (0.3.1)
48
- io-console (~> 0.5)
49
- rexml (3.2.5)
50
- rubocop (1.30.1)
51
- parallel (~> 1.10)
52
- parser (>= 3.1.0.0)
53
- rainbow (>= 2.2.2, < 4.0)
54
- regexp_parser (>= 1.8, < 3.0)
55
- rexml (>= 3.2.5, < 4.0)
56
- rubocop-ast (>= 1.18.0, < 2.0)
57
- ruby-progressbar (~> 1.7)
58
- unicode-display_width (>= 1.4.0, < 3.0)
59
- rubocop-ast (1.18.0)
60
- parser (>= 3.1.1.0)
61
- rubocop-minitest (0.20.1)
62
- rubocop (>= 0.90, < 2.0)
63
- rubocop-rake (0.6.0)
64
- rubocop (~> 1.0)
65
- rubocop-shopify (2.7.0)
66
- rubocop (~> 1.30)
67
- rubocop-sorbet (0.6.8)
68
- rubocop (>= 0.90.0)
69
- ruby-progressbar (1.11.0)
70
- sorbet (0.5.10092)
71
- sorbet-static (= 0.5.10092)
72
- sorbet-runtime (0.5.10092)
73
- sorbet-static (0.5.10092-universal-darwin-21)
74
- sorbet-static (0.5.10092-x86_64-linux)
75
- sorbet-static-and-runtime (0.5.10092)
76
- sorbet (= 0.5.10092)
77
- sorbet-runtime (= 0.5.10092)
78
- spoom (1.1.11)
79
- sorbet (>= 0.5.9204)
80
- sorbet-runtime (>= 0.5.9204)
81
- thor (>= 0.19.2)
82
- syntax_tree (2.7.1)
83
- prettier_print
84
- tapioca (0.8.1)
85
- bundler (>= 1.17.3)
86
- parallel (>= 1.21.0)
87
- pry (>= 0.12.2)
88
- rbi (~> 0.0.0, >= 0.0.14)
89
- sorbet-static-and-runtime (>= 0.5.9204)
90
- spoom (~> 1.1.0, >= 1.1.11)
91
- thor (>= 1.2.0)
92
- yard-sorbet
93
- thor (1.2.1)
94
- unicode-display_width (2.1.0)
95
- unparser (0.6.5)
96
- diff-lcs (~> 1.3)
97
- parser (>= 3.1.0)
98
- webrick (1.7.0)
99
- yard (0.9.28)
100
- webrick (~> 1.7.0)
101
- yard-sorbet (0.6.1)
102
- sorbet-runtime (>= 0.5)
103
- yard (>= 0.9)
104
-
105
- PLATFORMS
106
- arm64-darwin-21
107
- x86_64-linux
108
-
109
- DEPENDENCIES
110
- debug (~> 1.5)
111
- minitest (~> 5.15)
112
- minitest-reporters (~> 1.5)
113
- rake (~> 13.0)
114
- rubocop-minitest (~> 0.20.1)
115
- rubocop-rake (~> 0.6.0)
116
- rubocop-shopify (~> 2.7)
117
- rubocop-sorbet (~> 0.6)
118
- ruby-lsp!
119
- sorbet-static-and-runtime
120
- tapioca (~> 0.8)
121
- yard (~> 0.9)
122
-
123
- BUNDLED WITH
124
- 2.3.7
data/Rakefile DELETED
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "bundler/gem_tasks"
4
- require "rake/testtask"
5
- require "yard"
6
-
7
- Rake::TestTask.new(:test) do |t|
8
- t.libs << "test"
9
- t.libs << "lib"
10
- t.test_files = FileList["test/**/*_test.rb"]
11
- end
12
-
13
- YARD::Rake::YardocTask.new do |t|
14
- t.options = ["--markup", "markdown", "--output-dir", "docs"]
15
- end
16
-
17
- require "rubocop/rake_task"
18
-
19
- RuboCop::RakeTask.new
20
-
21
- task default: [:test]
data/bin/rubocop DELETED
@@ -1,29 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- #
5
- # This file was generated by Bundler.
6
- #
7
- # The application 'rubocop' is installed as part of a gem, and
8
- # this file is here to facilitate running it.
9
- #
10
-
11
- require "pathname"
12
- ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13
- Pathname.new(__FILE__).realpath)
14
-
15
- bundle_binstub = File.expand_path("../bundle", __FILE__)
16
-
17
- if File.file?(bundle_binstub)
18
- if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19
- load(bundle_binstub)
20
- else
21
- abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
- Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
- end
24
- end
25
-
26
- require "rubygems"
27
- require "bundler/setup"
28
-
29
- load Gem.bin_path("rubocop", "rubocop")
data/bin/tapioca DELETED
@@ -1,29 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- #
5
- # This file was generated by Bundler.
6
- #
7
- # The application 'tapioca' is installed as part of a gem, and
8
- # this file is here to facilitate running it.
9
- #
10
-
11
- require "pathname"
12
- ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13
- Pathname.new(__FILE__).realpath)
14
-
15
- bundle_binstub = File.expand_path("../bundle", __FILE__)
16
-
17
- if File.file?(bundle_binstub)
18
- if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19
- load(bundle_binstub)
20
- else
21
- abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
- Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
- end
24
- end
25
-
26
- require "rubygems"
27
- require "bundler/setup"
28
-
29
- load Gem.bin_path("tapioca", "tapioca")
data/bin/test DELETED
@@ -1,9 +0,0 @@
1
- #!/usr/bin/env bash
2
-
3
- if [[ 2 -eq $# ]]; then
4
- bundle exec rake TEST="$1" TESTOPTS="-n='/$2/'"
5
- elif [[ 1 -eq $# ]]; then
6
- bundle exec rake TEST="$1"
7
- else
8
- bundle exec rake "$@"
9
- fi
data/dev.yml DELETED
@@ -1,20 +0,0 @@
1
- name: ruby-lsp
2
-
3
- type: ruby
4
-
5
- up:
6
- - ruby: 3.1.1
7
- - bundler:
8
- gemfile: Gemfile
9
-
10
- commands:
11
- server: exe/ruby-lsp
12
- style: bin/rubocop
13
- typecheck:
14
- aliases: ["tc"]
15
- run: "bundle exec srb tc"
16
- test:
17
- syntax:
18
- argument: file
19
- optional: args...
20
- run: bin/test
data/lib/ruby_lsp/cli.rb DELETED
@@ -1,88 +0,0 @@
1
- # typed: strict
2
- # frozen_string_literal: true
3
-
4
- require "language_server-protocol"
5
-
6
- require_relative "handler"
7
-
8
- module RubyLsp
9
- module Cli
10
- extend T::Sig
11
-
12
- sig { void }
13
- def self.start
14
- handler = RubyLsp::Handler.new
15
-
16
- handler.config do
17
- on("initialize") do |request|
18
- store.clear
19
- initialization_options = request.dig(:params, :initializationOptions)
20
-
21
- respond_with_capabilities(initialization_options.fetch(:enabledFeatures, []))
22
- end
23
-
24
- on("textDocument/didChange") do |request|
25
- uri = request.dig(:params, :textDocument, :uri)
26
- store.push_edits(uri, request.dig(:params, :contentChanges))
27
-
28
- send_diagnostics(uri)
29
- RubyLsp::Handler::VOID
30
- end
31
-
32
- on("textDocument/didOpen") do |request|
33
- uri = request.dig(:params, :textDocument, :uri)
34
- text = request.dig(:params, :textDocument, :text)
35
- store.set(uri, text)
36
-
37
- send_diagnostics(uri)
38
- RubyLsp::Handler::VOID
39
- end
40
-
41
- on("textDocument/didClose") do |request|
42
- uri = request.dig(:params, :textDocument, :uri)
43
- store.delete(uri)
44
-
45
- RubyLsp::Handler::VOID
46
- end
47
-
48
- on("textDocument/documentSymbol") do |request|
49
- respond_with_document_symbol(request.dig(:params, :textDocument, :uri))
50
- end
51
-
52
- on("textDocument/foldingRange") do |request|
53
- respond_with_folding_ranges(request.dig(:params, :textDocument, :uri))
54
- end
55
-
56
- on("textDocument/selectionRange") do |request|
57
- respond_with_selection_ranges(
58
- request.dig(:params, :textDocument, :uri),
59
- request.dig(:params, :positions),
60
- )
61
- end
62
-
63
- on("textDocument/semanticTokens/full") do |request|
64
- respond_with_semantic_highlighting(request.dig(:params, :textDocument, :uri))
65
- end
66
-
67
- on("textDocument/formatting") do |request|
68
- respond_with_formatting(request.dig(:params, :textDocument, :uri))
69
- end
70
-
71
- on("textDocument/documentHighlight") do |request|
72
- respond_with_document_highlight(request.dig(:params, :textDocument, :uri), request.dig(:params, :position))
73
- end
74
-
75
- on("textDocument/codeAction") do |request|
76
- range = request.dig(:params, :range)
77
- start_line = range.dig(:start, :line)
78
- end_line = range.dig(:end, :line)
79
- respond_with_code_actions(request.dig(:params, :textDocument, :uri), (start_line..end_line))
80
- end
81
-
82
- on("shutdown") { shutdown }
83
- end
84
-
85
- handler.start
86
- end
87
- end
88
- end
@@ -1,60 +0,0 @@
1
- # typed: strict
2
- # frozen_string_literal: true
3
-
4
- require "rubocop"
5
- require "cgi"
6
-
7
- module RubyLsp
8
- module Requests
9
- # :nodoc:
10
- class RuboCopRequest < RuboCop::Runner
11
- extend T::Sig
12
- extend T::Helpers
13
-
14
- abstract!
15
-
16
- COMMON_RUBOCOP_FLAGS = T.let([
17
- "--stderr", # Print any output to stderr so that our stdout does not get polluted
18
- "--format",
19
- "RuboCop::Formatter::BaseFormatter", # Suppress any output by using the base formatter
20
- ].freeze, T::Array[String])
21
-
22
- sig { returns(String) }
23
- attr_reader :file
24
-
25
- sig { returns(String) }
26
- attr_reader :text
27
-
28
- sig { params(uri: String, document: Document).void }
29
- def initialize(uri, document)
30
- @file = T.let(CGI.unescape(URI.parse(uri).path), String)
31
- @document = document
32
- @text = T.let(document.source, String)
33
- @uri = uri
34
- @options = T.let({}, T::Hash[Symbol, T.untyped])
35
- @diagnostics = T.let([], T::Array[Support::RuboCopDiagnostic])
36
-
37
- super(
38
- ::RuboCop::Options.new.parse(rubocop_flags).first,
39
- ::RuboCop::ConfigStore.new
40
- )
41
- end
42
-
43
- sig { overridable.returns(Object) }
44
- def run
45
- # We communicate with Rubocop via stdin
46
- @options[:stdin] = text
47
-
48
- # Invoke the actual run method with just this file in `paths`
49
- super([file])
50
- end
51
-
52
- private
53
-
54
- sig { returns(T::Array[String]) }
55
- def rubocop_flags
56
- COMMON_RUBOCOP_FLAGS
57
- end
58
- end
59
- end
60
- end
@@ -1,57 +0,0 @@
1
- # typed: false
2
- # frozen_string_literal: true
3
-
4
- desc "Check if all LSP requests are documented"
5
- task :check_docs do
6
- require "sorbet-runtime"
7
- require "language_server-protocol"
8
- require "syntax_tree"
9
- require "logger"
10
- require "ruby_lsp/requests/base_request"
11
- require "ruby_lsp/requests/rubocop_request"
12
-
13
- Dir["#{Dir.pwd}/lib/ruby_lsp/requests/*.rb"].each do |file|
14
- require(file)
15
- YARD.parse(file, [], Logger::Severity::FATAL)
16
- end
17
-
18
- spec_matcher = %r{\(https://microsoft.github.io/language-server-protocol/specification#.*\)}
19
- error_messages = RubyLsp::Requests
20
- .constants # rubocop:disable Sorbet/ConstantsFromStrings
21
- .each_with_object(Hash.new { |h, k| h[k] = [] }) do |request, errors|
22
- full_name = "RubyLsp::Requests::#{request}"
23
- docs = YARD::Registry.at(full_name).docstring
24
- next if /:nodoc:/.match?(docs)
25
-
26
- if docs.empty?
27
- errors[full_name] << "Missing documentation for request handler class"
28
- elsif !spec_matcher.match?(docs)
29
- errors[full_name] << <<~MESSAGE
30
- Documentation for request handler classes must link to the official LSP specification.
31
-
32
- For example, if your request handles text document hover, you should add a link to
33
- https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_hover.
34
- MESSAGE
35
- elsif !/# Example/.match?(docs)
36
- errors[full_name] << <<~MESSAGE
37
- Documentation for request handler class must contain an example.
38
-
39
- = Example
40
- def my_method # <-- something happens here
41
- end
42
- MESSAGE
43
- end
44
- end
45
-
46
- formatted_errors = error_messages.map { |name, errors| "#{name}: #{errors.join(", ")}" }
47
-
48
- if error_messages.any?
49
- puts <<~MESSAGE
50
- The following requests have invalid documentation:
51
-
52
- #{formatted_errors.join("\n")}
53
- MESSAGE
54
-
55
- exit!
56
- end
57
- end
data/ruby-lsp.gemspec DELETED
@@ -1,26 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- Gem::Specification.new do |s|
4
- s.name = "ruby-lsp"
5
- s.version = File.read("VERSION").strip
6
- s.authors = ["Shopify"]
7
- s.email = ["ruby@shopify.com"]
8
- s.metadata["allowed_push_host"] = "https://rubygems.org"
9
-
10
- s.summary = "A simple language server for ruby"
11
- s.description = "A simple language server for ruby"
12
- s.homepage = "https://github.com/Shopify/ruby-lsp"
13
- s.license = "MIT"
14
-
15
- s.files = Dir.chdir(File.expand_path(__dir__)) do
16
- %x(git ls-files -z).split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
17
- end
18
- s.bindir = "exe"
19
- s.executables = s.files.grep(/\Aexe/) { |f| File.basename(f) }
20
- s.require_paths = ["lib"]
21
-
22
- s.add_dependency("language_server-protocol")
23
- s.add_dependency("rubocop", ">= 1.0")
24
- s.add_dependency("sorbet-runtime")
25
- s.add_dependency("syntax_tree", ">= 2.4")
26
- end
data/service.yml DELETED
@@ -1,2 +0,0 @@
1
- classification: library
2
-
data/sorbet/config DELETED
@@ -1,4 +0,0 @@
1
- --dir
2
- .
3
- --ignore=vendor/
4
- --ignore=test/fixtures/
@@ -1,8 +0,0 @@
1
- inherit_gem:
2
- rubocop-sorbet: config/rbi.yml
3
-
4
- Lint/EmptyFile:
5
- Enabled: false
6
-
7
- Sorbet/TypeAliasName:
8
- Enabled: false