ruby-lsp 0.0.1 → 0.0.2

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 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