ruby-lsp 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cacbd0ac625037e2671811471792d7f4557bfd71e8ee1259c306ecd81b71974b
4
- data.tar.gz: 58442bd37eaf5954d486556bc0a2a94a093471627791e55c66701fcad3a7ebd4
3
+ metadata.gz: 25bad06533efa8072f0d501520e7429220be622d06a9061eb02171e1d515a498
4
+ data.tar.gz: dc8cc9436d3b57b362661ba36b8f02b90495287386f94ac5b20916ce5e6025bf
5
5
  SHA512:
6
- metadata.gz: bb55d15c4be207b39516891c9e0fc3f82e1412e57e9712932e3c73b354a7b95cf35f3df15990a097d146b849ab3309490236f8ad72b2a678fb142a99a3246372
7
- data.tar.gz: 86269ca803e98331eec3e432f75049ffdf9250439b675a1e3bf335e4ce429f7fdb20ca67a6b0daff2afda8f6a69dbfded2178c9e2e5ed687b000d0ca82b7e08c
6
+ metadata.gz: b8ae688533a36c018cfbca467f7db2b54d121787cff48b7fd56723c03790df34c99a2ace3a0770ee6e3971b5ac1aa5e559b9264d1466ba93556f3d9ec051abaa
7
+ data.tar.gz: 1db946d571c62209b40fc4aef7048ea55f39c446bf87ff638d44aefcbdf2e8abdfad79c60ec5e9f0c3dc1fdda78f867582e4f58b56c861941197651bd286e6b3
@@ -1,20 +1,11 @@
1
1
  version: 2
2
- registries:
3
- rubygems-server-pkgs-shopify-io:
4
- type: rubygems-server
5
- url: https://pkgs.shopify.io
6
- username: ${{secrets.RUBYGEMS_SERVER_PKGS_SHOPIFY_IO_USERNAME}}
7
- password: ${{secrets.RUBYGEMS_SERVER_PKGS_SHOPIFY_IO_PASSWORD}}
8
- github-com:
9
- type: git
10
- url: https://github.com
11
- username: ${{secrets.DEPENDENCIES_GITHUB_USER}}
12
- password: ${{secrets.DEPENDENCIES_GITHUB_TOKEN}}
13
2
  updates:
14
- - package-ecosystem: bundler
3
+ - package-ecosystem: "bundler"
15
4
  directory: "/"
16
5
  schedule:
17
- interval: daily
18
- open-pull-requests-limit: 100
19
- insecure-external-code-execution: allow
20
- registries: '*'
6
+ interval: "weekly"
7
+ reviewers:
8
+ - "Shopify/sorbet"
9
+ labels:
10
+ - "dependencies"
11
+ - "ruby"
@@ -0,0 +1,15 @@
1
+ ### Motivation
2
+
3
+ <!-- Explain why you are making this change. Include links to issues or describe the problem being solved, not the solution. -->
4
+
5
+ ### Implementation
6
+
7
+ <!-- How did you implement your changes? Explain your solution, design decisions, things reviewers should watch out for. -->
8
+
9
+ ### Automated Tests
10
+
11
+ <!-- We hope you added unit tests as part of your changes, just state that you have. If you haven't, state why. -->
12
+
13
+ ### Manual Tests
14
+
15
+ <!-- Explain how we can test these changes in our own instance of VS Code. Provide the step by step instructions. -->
@@ -0,0 +1,23 @@
1
+ name: CI
2
+
3
+ on: [push, pull_request]
4
+
5
+ jobs:
6
+ build:
7
+ runs-on: self-hosted
8
+ strategy:
9
+ fail-fast: false
10
+ matrix:
11
+ ruby: [ "2.7", "3.0", "3.1" ]
12
+ name: Ruby ${{ matrix.ruby }}
13
+ steps:
14
+ - uses: actions/checkout@v2
15
+ - name: Set up Ruby
16
+ uses: ruby/setup-ruby@v1
17
+ with:
18
+ ruby-version: ${{ matrix.ruby }}
19
+ bundler-cache: true
20
+ - name: Lint Ruby files
21
+ run: bin/rubocop
22
+ - name: Run tests
23
+ run: bin/test
data/.gitignore CHANGED
@@ -1,12 +1,9 @@
1
- /.bundle/
2
- /.yardoc
3
- /_yardoc/
4
- /coverage/
5
- /doc/
6
- /pkg/
7
- /spec/reports/
8
- /tmp/
9
- /.dev/
10
- /**/node_modules/
11
- /**/out/
12
- /**/*.vsix
1
+ /**/.bundle/
2
+ /**/.yardoc
3
+ /**/_yardoc/
4
+ /**/coverage/
5
+ /**/doc/
6
+ /**/pkg/
7
+ /**/spec/reports/
8
+ /**/tmp/
9
+ /**/.dev/
data/.rubocop.yml CHANGED
@@ -2,11 +2,13 @@ inherit_gem:
2
2
  rubocop-shopify: rubocop.yml
3
3
 
4
4
  AllCops:
5
- TargetRubyVersion: 3.1
5
+ NewCops: disable
6
+ SuggestExtensions: false
7
+ TargetRubyVersion: 2.7
6
8
  Exclude:
7
9
  - "vendor/**/*"
8
10
  - "features/**/*"
9
11
 
10
12
  Naming/FileName:
11
13
  Exclude:
12
- - "lib/ruby-lsp.rb"
14
+ - "lib/ruby-lsp.rb"
@@ -0,0 +1,5 @@
1
+ {
2
+ // Set this value to `verbose` to see the full JSON content of LSP requests and responses
3
+ "ruby lsp.trace.server": "messages",
4
+ "editor.defaultFormatter": "Shopify.ruby-lsp",
5
+ }
data/CHANGELOG.md ADDED
@@ -0,0 +1,16 @@
1
+ # Change Log
2
+
3
+ All notable changes to the "ruby-lsp" extension will be documented in this file.
4
+
5
+ Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file.
6
+
7
+ ## [Unreleased]
8
+
9
+
10
+ ## [0.0.2]
11
+
12
+ - Alpha release including
13
+ - RuboCop formatting, diagnostics and quick fixes
14
+ - Folding ranges
15
+ - Initial semantic highlighting
16
+ - Document symbols
data/Gemfile CHANGED
@@ -4,10 +4,10 @@ source "https://rubygems.org"
4
4
 
5
5
  gemspec
6
6
 
7
+ gem "debug", "~> 1.5"
7
8
  gem "minitest", "~> 5.15"
8
9
  gem "minitest-reporters", "~> 1.5"
9
10
  gem "rake", "~> 13.0"
10
- gem "rubocop", "~> 1.25"
11
- gem "rubocop-shopify", "~> 2.4"
12
- gem "rubocop-minitest", "~> 0.17.2"
11
+ gem "rubocop-shopify", "~> 2.5"
12
+ gem "rubocop-minitest", "~> 0.19.1"
13
13
  gem "rubocop-rake", "~> 0.6.0"
data/Gemfile.lock CHANGED
@@ -1,8 +1,10 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ruby-lsp (0.0.1)
4
+ ruby-lsp (0.0.2)
5
5
  language_server-protocol
6
+ rubocop (>= 1.0)
7
+ syntax_tree (>= 2.3)
6
8
 
7
9
  GEM
8
10
  remote: https://rubygems.org/
@@ -10,6 +12,12 @@ GEM
10
12
  ansi (1.5.0)
11
13
  ast (2.4.2)
12
14
  builder (3.2.4)
15
+ debug (1.5.0)
16
+ irb (>= 1.3.6)
17
+ reline (>= 0.2.7)
18
+ io-console (0.5.11)
19
+ irb (1.4.1)
20
+ reline (>= 0.3.0)
13
21
  language_server-protocol (3.16.0.3)
14
22
  minitest (5.15.0)
15
23
  minitest-reporters (1.5.0)
@@ -17,31 +25,34 @@ GEM
17
25
  builder
18
26
  minitest (>= 5.0)
19
27
  ruby-progressbar
20
- parallel (1.21.0)
21
- parser (3.1.1.0)
28
+ parallel (1.22.1)
29
+ parser (3.1.2.0)
22
30
  ast (~> 2.4.1)
23
31
  rainbow (3.1.1)
24
32
  rake (13.0.6)
25
- regexp_parser (2.2.1)
33
+ regexp_parser (2.3.1)
34
+ reline (0.3.1)
35
+ io-console (~> 0.5)
26
36
  rexml (3.2.5)
27
- rubocop (1.25.1)
37
+ rubocop (1.28.1)
28
38
  parallel (~> 1.10)
29
39
  parser (>= 3.1.0.0)
30
40
  rainbow (>= 2.2.2, < 4.0)
31
41
  regexp_parser (>= 1.8, < 3.0)
32
42
  rexml
33
- rubocop-ast (>= 1.15.1, < 2.0)
43
+ rubocop-ast (>= 1.17.0, < 2.0)
34
44
  ruby-progressbar (~> 1.7)
35
45
  unicode-display_width (>= 1.4.0, < 3.0)
36
- rubocop-ast (1.16.0)
46
+ rubocop-ast (1.17.0)
37
47
  parser (>= 3.1.1.0)
38
- rubocop-minitest (0.17.2)
48
+ rubocop-minitest (0.19.1)
39
49
  rubocop (>= 0.90, < 2.0)
40
50
  rubocop-rake (0.6.0)
41
51
  rubocop (~> 1.0)
42
- rubocop-shopify (2.4.0)
43
- rubocop (~> 1.24)
52
+ rubocop-shopify (2.5.0)
53
+ rubocop (~> 1.25)
44
54
  ruby-progressbar (1.11.0)
55
+ syntax_tree (2.3.1)
45
56
  unicode-display_width (2.1.0)
46
57
 
47
58
  PLATFORMS
@@ -49,13 +60,13 @@ PLATFORMS
49
60
  x86_64-linux
50
61
 
51
62
  DEPENDENCIES
63
+ debug (~> 1.5)
52
64
  minitest (~> 5.15)
53
65
  minitest-reporters (~> 1.5)
54
66
  rake (~> 13.0)
55
- rubocop (~> 1.25)
56
- rubocop-minitest (~> 0.17.2)
67
+ rubocop-minitest (~> 0.19.1)
57
68
  rubocop-rake (~> 0.6.0)
58
- rubocop-shopify (~> 2.4)
69
+ rubocop-shopify (~> 2.5)
59
70
  ruby-lsp!
60
71
 
61
72
  BUNDLED WITH
data/README.md CHANGED
@@ -1,7 +1,5 @@
1
1
  # ruby-lsp
2
2
 
3
- Future home of monorepo for `ruby-lsp` Gem and VSCode extension
4
-
5
3
  ## Contributing
6
4
 
7
5
  Bug reports and pull requests are welcome on GitHub at https://github.com/Shopify/ruby-lsp.
@@ -10,6 +8,18 @@ are expected to adhere to the
10
8
  [Contributor Covenant](https://github.com/Shopify/ruby-lsp/blob/main/CODE_OF_CONDUCT.md)
11
9
  code of conduct.
12
10
 
11
+ ## Debugging
12
+
13
+ ### Tracing LSP requests and responses
14
+
15
+ LSP server tracing can be controlled through the `ruby lsp.trace.server` config key in the `.vscode/settings.json` config file.
16
+
17
+ Possible values are:
18
+
19
+ * `off`: no tracing
20
+ * `messages`: display requests and responses notifications
21
+ * `verbose`: display each request and response as JSON
22
+
13
23
  ## License
14
24
 
15
25
  The gem is available as open source under the terms of the
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.1
1
+ 0.0.2
data/bin/test CHANGED
@@ -1,3 +1,9 @@
1
1
  #!/usr/bin/env bash
2
2
 
3
- bundle exec rake "$@"
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 CHANGED
@@ -4,15 +4,12 @@ type: ruby
4
4
 
5
5
  up:
6
6
  - ruby: 3.1.1
7
- - bundler
8
- - node:
9
- yarn: 1.22.17
10
- version: v16.14.0
11
- packages: ["./features/vscode_extension"]
7
+ - bundler:
8
+ gemfile: Gemfile
12
9
 
13
10
  commands:
14
- style: bin/style
15
- extension: bin/package_extension
11
+ server: exe/ruby-lsp
12
+ style: bin/rubocop
16
13
  test:
17
14
  syntax:
18
15
  argument: file
data/exe/ruby-lsp CHANGED
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- require_relative "../lib/ruby/lsp"
4
+ require "syntax_tree"
5
+ require "ruby_lsp/cli"
5
6
 
6
- Ruby::Lsp::Cli.start(ARGV)
7
+ RubyLsp::Cli.start(ARGV)
data/lib/ruby-lsp.rb CHANGED
@@ -1,3 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "./ruby/lsp"
3
+ module RubyLsp
4
+ end
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "language_server-protocol"
4
+
5
+ require_relative "handler"
6
+
7
+ module RubyLsp
8
+ module Cli
9
+ def self.start(_argv)
10
+ handler = RubyLsp::Handler.new
11
+
12
+ handler.config do
13
+ on("initialize") do |request|
14
+ store.clear
15
+ respond_with_capabilities(request.dig(:params, :initializationOptions).fetch(:enabledFeatures, []))
16
+ end
17
+
18
+ on("textDocument/didChange") do |request|
19
+ uri = request.dig(:params, :textDocument, :uri)
20
+ text = request.dig(:params, :contentChanges, 0, :text)
21
+ store.set(uri, text)
22
+
23
+ send_diagnostics(uri)
24
+ nil
25
+ end
26
+
27
+ on("textDocument/didOpen") do |request|
28
+ uri = request.dig(:params, :textDocument, :uri)
29
+ text = request.dig(:params, :textDocument, :text)
30
+ store.set(uri, text)
31
+
32
+ send_diagnostics(uri)
33
+ nil
34
+ end
35
+
36
+ on("textDocument/didClose") do |request|
37
+ uri = request.dig(:params, :textDocument, :uri)
38
+ store.delete(uri)
39
+
40
+ nil
41
+ end
42
+
43
+ on("textDocument/documentSymbol") do |request|
44
+ respond_with_document_symbol(request.dig(:params, :textDocument, :uri))
45
+ end
46
+
47
+ on("textDocument/foldingRange") do |request|
48
+ respond_with_folding_ranges(request.dig(:params, :textDocument, :uri))
49
+ end
50
+
51
+ on("textDocument/semanticTokens/full") do |request|
52
+ respond_with_semantic_highlighting(request.dig(:params, :textDocument, :uri))
53
+ end
54
+
55
+ on("textDocument/formatting") do |request|
56
+ respond_with_formatting(request.dig(:params, :textDocument, :uri))
57
+ end
58
+
59
+ on("textDocument/codeAction") do |request|
60
+ range = request.dig(:params, :range)
61
+ start_line = range.dig(:start, :line)
62
+ end_line = range.dig(:end, :line)
63
+ respond_with_code_actions(request.dig(:params, :textDocument, :uri), (start_line..end_line))
64
+ end
65
+
66
+ on("shutdown") { shutdown }
67
+ end
68
+
69
+ handler.start
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyLsp
4
+ class Document
5
+ attr_reader :tree, :parser, :source
6
+
7
+ def initialize(source)
8
+ @source = source
9
+ @parser = SyntaxTree::Parser.new(source)
10
+ @tree = @parser.parse
11
+ @cache = {}
12
+ end
13
+
14
+ def ==(other)
15
+ @source == other.source
16
+ end
17
+
18
+ def cache_fetch(request_name)
19
+ cached = @cache[request_name]
20
+ return cached if cached
21
+
22
+ result = yield(self)
23
+ @cache[request_name] = result
24
+ result
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,133 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "ruby_lsp/requests"
4
+ require "ruby_lsp/store"
5
+
6
+ module RubyLsp
7
+ class Handler
8
+ attr_reader :store
9
+
10
+ Interface = LanguageServer::Protocol::Interface
11
+ Constant = LanguageServer::Protocol::Constant
12
+ Transport = LanguageServer::Protocol::Transport
13
+
14
+ def initialize
15
+ @writer = Transport::Stdio::Writer.new
16
+ @reader = Transport::Stdio::Reader.new
17
+ @handlers = {}
18
+ @store = Store.new
19
+ end
20
+
21
+ def start
22
+ $stderr.puts "Starting Ruby LSP..."
23
+ @reader.read do |request|
24
+ handle(request)
25
+ end
26
+ end
27
+
28
+ def config(&blk)
29
+ instance_exec(&blk)
30
+ end
31
+
32
+ private
33
+
34
+ def on(msg, &blk)
35
+ @handlers[msg.to_s] = blk
36
+ end
37
+
38
+ def handle(request)
39
+ result = @handlers[request[:method]]&.call(request)
40
+ @writer.write(id: request[:id], result: result) if result
41
+ end
42
+
43
+ def shutdown
44
+ $stderr.puts "Shutting down Ruby LSP..."
45
+ store.clear
46
+ end
47
+
48
+ def respond_with_capabilities(enabled_features)
49
+ document_symbol_provider = if enabled_features.include?("documentSymbols")
50
+ Interface::DocumentSymbolClientCapabilities.new(
51
+ hierarchical_document_symbol_support: true,
52
+ symbol_kind: {
53
+ value_set: Requests::DocumentSymbol::SYMBOL_KIND.values,
54
+ }
55
+ )
56
+ end
57
+
58
+ folding_ranges_provider = if enabled_features.include?("foldingRanges")
59
+ Interface::FoldingRangeClientCapabilities.new(line_folding_only: true)
60
+ end
61
+
62
+ semantic_tokens_provider = if enabled_features.include?("semanticHighlighting")
63
+ Interface::SemanticTokensRegistrationOptions.new(
64
+ document_selector: { scheme: "file", language: "ruby" },
65
+ legend: Interface::SemanticTokensLegend.new(
66
+ token_types: Requests::SemanticHighlighting::TOKEN_TYPES,
67
+ token_modifiers: Requests::SemanticHighlighting::TOKEN_MODIFIERS
68
+ ),
69
+ range: false,
70
+ full: {
71
+ delta: true,
72
+ }
73
+ )
74
+ end
75
+
76
+ Interface::InitializeResult.new(
77
+ capabilities: Interface::ServerCapabilities.new(
78
+ text_document_sync: Interface::TextDocumentSyncOptions.new(
79
+ change: Constant::TextDocumentSyncKind::FULL,
80
+ open_close: true,
81
+ ),
82
+ document_symbol_provider: document_symbol_provider,
83
+ folding_range_provider: folding_ranges_provider,
84
+ semantic_tokens_provider: semantic_tokens_provider,
85
+ document_formatting_provider: enabled_features.include?("formatting"),
86
+ code_action_provider: enabled_features.include?("codeActions")
87
+ )
88
+ )
89
+ end
90
+
91
+ def respond_with_document_symbol(uri)
92
+ store.cache_fetch(uri, :document_symbol) do |document|
93
+ RubyLsp::Requests::DocumentSymbol.run(document)
94
+ end
95
+ end
96
+
97
+ def respond_with_folding_ranges(uri)
98
+ store.cache_fetch(uri, :folding_ranges) do |document|
99
+ Requests::FoldingRanges.run(document)
100
+ end
101
+ end
102
+
103
+ def respond_with_semantic_highlighting(uri)
104
+ store.cache_fetch(uri, :semantic_highlighting) do |document|
105
+ Requests::SemanticHighlighting.run(document)
106
+ end
107
+ end
108
+
109
+ def respond_with_formatting(uri)
110
+ Requests::Formatting.run(uri, store.get(uri))
111
+ end
112
+
113
+ def send_diagnostics(uri)
114
+ response = store.cache_fetch(uri, :diagnostics) do |document|
115
+ Requests::Diagnostics.run(uri, document)
116
+ end
117
+
118
+ @writer.write(
119
+ method: "textDocument/publishDiagnostics",
120
+ params: Interface::PublishDiagnosticsParams.new(
121
+ uri: uri,
122
+ diagnostics: response.map(&:to_lsp_diagnostic)
123
+ )
124
+ )
125
+ end
126
+
127
+ def respond_with_code_actions(uri, range)
128
+ store.cache_fetch(uri, :code_actions) do |document|
129
+ Requests::CodeActions.run(uri, document, range)
130
+ end
131
+ end
132
+ end
133
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyLsp
4
+ module Requests
5
+ class BaseRequest < SyntaxTree::Visitor
6
+ def self.run(document)
7
+ new(document).run
8
+ end
9
+
10
+ def initialize(document)
11
+ @document = document
12
+
13
+ super()
14
+ end
15
+
16
+ def run
17
+ raise NotImplementedError, "#{self.class}#run must be implemented"
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyLsp
4
+ module Requests
5
+ class CodeActions
6
+ def self.run(uri, document, range)
7
+ new(uri, document, range).run
8
+ end
9
+
10
+ def initialize(uri, document, range)
11
+ @document = document
12
+ @uri = uri
13
+ @range = range
14
+ end
15
+
16
+ def run
17
+ diagnostics = Diagnostics.run(@uri, @document)
18
+ corrections = diagnostics.select { |diagnostic| diagnostic.correctable? && diagnostic.in_range?(@range) }
19
+ return if corrections.empty?
20
+
21
+ corrections.map!(&:to_lsp_code_action)
22
+ end
23
+ end
24
+ end
25
+ end