ruby-lsp-rspec 0.1.14 → 0.1.16

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: 96d32309254df952d00b15dc1a00511df1f9f0c89eacd55882194739ea57b7b0
4
- data.tar.gz: fa9accef54584ffaa86299c6e975f5c5b1298caacc91bc497fde97d66a0b703c
3
+ metadata.gz: 8ee975e071dae85f67f651eae432c395c5e1e11ce0e49d3287a109f4b6bb4015
4
+ data.tar.gz: fe19cccd32213234a643ed076809a9dda8a5e732c5df4a3f692cc8b48976dc82
5
5
  SHA512:
6
- metadata.gz: 8b611c0e6ec010041a1fcc2dac6bd8a0bbe6adebb7d99bf8d420c4f44ab3bc2a6b7e1d1aaed6535817c3e1c3d502f598c07f0c7d21f0510f4724fb1e0d749c80
7
- data.tar.gz: e5cedb8932a7a5ce6e9b097642e12b39efe2f5e1694d7f26b33712f72ed11b97861e5d8a4e6eb7dc6bb180d1d304e4c9866a59f45a8826dbfb4fadee277d1527
6
+ metadata.gz: b413a288abc15b33c20447eea18e8c6825b3ec27c16e3919c9012c492062491b628952d7b3507b5067751f6ae4cba30de1baa069e087e3f6c30940c10835135b
7
+ data.tar.gz: ff98f027f9d7be1a9d2db2ddde55dc5fce4039a22ce406e34afd6beeadc526bd412ed0e57343bf36a712db23d4b9aff393bf5f555918da6884d5847d7770ff30
data/README.md CHANGED
@@ -4,8 +4,6 @@
4
4
 
5
5
  Ruby LSP RSpec is a [Ruby LSP](https://github.com/Shopify/ruby-lsp) addon for displaying CodeLens for RSpec tests.
6
6
 
7
- ![Screenshot of the code lenses](/misc/example.gif)
8
-
9
7
  ## Installation
10
8
 
11
9
  To install, add the following line to your application's Gemfile:
@@ -19,14 +17,41 @@ end
19
17
 
20
18
  After running `bundle install`, restart Ruby LSP and you should start seeing CodeLens in your RSpec test files.
21
19
 
22
- ## Usages (with VS Code)
20
+ ## Features
21
+
22
+ ### CodeLens
23
+
24
+ 1. When clicking `Run`, the test(s) will be executed via the Test Explorer
25
+ - However, deeply nested tests may not be displayed correctly at the moment
26
+ 2. When clicking `Run In Terminal`, a test command will be generated in the terminal
27
+ 3. When clicking `Debug`, the test(s) will be executed with VS Code debugger enabled (requires the [`debug`](https://github.com/ruby/debug) gem)
28
+ - [Learn how to set breakpoints in VS Code](https://code.visualstudio.com/docs/editor/debugging#_breakpoints)
29
+
30
+ <img src="misc/code-lens.gif" alt="CodeLens" width="75%">
31
+
32
+ ### Document Symbols
33
+
34
+ Document Symbols can be triggered by:
35
+
36
+ - Typing `@` in VS Code's command palette
37
+ - Pressing `Cmd+Shift+O`
38
+
39
+ <img src="misc/document-symbol.gif" alt="Document Symbols" width="75%">
40
+
41
+ ### Go to definition
42
+
43
+ `ruby-lsp-rspec` supports go-to-definition on methods defined through `let` and `subject` DSLs in spec files.
44
+
45
+ In VS Code this feature can be triggered by one of the following methods:
46
+
47
+ - `Right click` on the target, and then select `Go to Definition`
48
+ - Placing the cursor on the target, and then hit `F12`
49
+ - `Command + click` the target
23
50
 
24
- 1. When clicking `Run`, the test(s) will be executed via the Test Explorer.
25
- - However, deeply nested tests may not be displayed correctly at the moment.
26
- 2. When clicking `Run In Terminal`, a test command will be generated in the terminal.
27
- 3. When clicking `Debug`, the test(s) will be executed with VS Code debugger enabled (requires the [`debug`](https://github.com/ruby/debug) gem).
28
- - [Learn how to set breakpoints in VS Code](https://code.visualstudio.com/docs/editor/debugging#_breakpoints).
51
+ > [!Note]
52
+ > This feature requires indexing your spec files so they can't be excluded from Ruby LSP's indexing.
29
53
 
54
+ <img src="misc/go-to-definition.gif" alt="Go to definition" width="75%">
30
55
 
31
56
  ## Development
32
57
 
@@ -6,6 +6,8 @@ require "ruby_lsp/internal"
6
6
 
7
7
  require_relative "code_lens"
8
8
  require_relative "document_symbol"
9
+ require_relative "definition"
10
+ require_relative "indexing_enhancement"
9
11
 
10
12
  module RubyLsp
11
13
  module RSpec
@@ -13,7 +15,10 @@ module RubyLsp
13
15
  extend T::Sig
14
16
 
15
17
  sig { override.params(global_state: GlobalState, message_queue: Thread::Queue).void }
16
- def activate(global_state, message_queue); end
18
+ def activate(global_state, message_queue)
19
+ @index = T.let(global_state.index, T.nilable(RubyIndexer::Index))
20
+ global_state.index.register_enhancement(IndexingEnhancement.new)
21
+ end
17
22
 
18
23
  sig { override.void }
19
24
  def deactivate; end
@@ -47,6 +52,21 @@ module RubyLsp
47
52
  DocumentSymbol.new(response_builder, dispatcher)
48
53
  end
49
54
 
55
+ sig do
56
+ override.params(
57
+ response_builder: ResponseBuilders::CollectionResponseBuilder[T.any(
58
+ Interface::Location,
59
+ Interface::LocationLink,
60
+ )],
61
+ uri: URI::Generic,
62
+ node_context: NodeContext,
63
+ dispatcher: Prism::Dispatcher,
64
+ ).void
65
+ end
66
+ def create_definition_listener(response_builder, uri, node_context, dispatcher)
67
+ Definition.new(response_builder, uri, node_context, T.must(@index), dispatcher)
68
+ end
69
+
50
70
  sig { override.returns(String) }
51
71
  def name
52
72
  "Ruby LSP RSpec"
@@ -21,6 +21,7 @@ module RubyLsp
21
21
  @path = T.let(T.must(uri.to_standardized_path), String)
22
22
  @group_id = T.let(1, Integer)
23
23
  @group_id_stack = T.let([], T::Array[Integer])
24
+ @anonymous_example_count = T.let(0, Integer)
24
25
  dispatcher.register(self, :on_call_node_enter, :on_call_node_leave)
25
26
 
26
27
  @base_command = T.let(
@@ -93,7 +94,8 @@ module RubyLsp
93
94
  argument.slice
94
95
  end
95
96
  else
96
- "<unnamed>"
97
+ @anonymous_example_count += 1
98
+ "<unnamed-#{@anonymous_example_count}>"
97
99
  end
98
100
  end
99
101
 
@@ -0,0 +1,55 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module RubyLsp
5
+ module RSpec
6
+ class Definition
7
+ extend T::Sig
8
+
9
+ include ::RubyLsp::Requests::Support::Common
10
+
11
+ sig do
12
+ params(
13
+ response_builder: ResponseBuilders::CollectionResponseBuilder[T.any(
14
+ Interface::Location,
15
+ Interface::LocationLink,
16
+ )],
17
+ uri: URI::Generic,
18
+ node_context: NodeContext,
19
+ index: RubyIndexer::Index,
20
+ dispatcher: Prism::Dispatcher,
21
+ ).void
22
+ end
23
+ def initialize(response_builder, uri, node_context, index, dispatcher)
24
+ @response_builder = response_builder
25
+ @uri = uri
26
+ @node_context = node_context
27
+ @index = index
28
+ dispatcher.register(self, :on_call_node_enter)
29
+ end
30
+
31
+ sig { params(node: Prism::CallNode).void }
32
+ def on_call_node_enter(node)
33
+ message = node.message
34
+ return unless message
35
+
36
+ return if @node_context.locals_for_scope.include?(message)
37
+
38
+ entries = @index[message]
39
+ return unless entries
40
+ return if entries.empty?
41
+
42
+ entries.each do |entry|
43
+ # Technically, let can be defined in a different file, but we're not going to handle that case yet
44
+ next unless entry.file_path == @uri.to_standardized_path
45
+
46
+ @response_builder << Interface::LocationLink.new(
47
+ target_uri: URI::Generic.from_path(path: entry.file_path).to_s,
48
+ target_range: range_from_location(entry.location),
49
+ target_selection_range: range_from_location(entry.name_location),
50
+ )
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -74,7 +74,7 @@ module RubyLsp
74
74
 
75
75
  case argument
76
76
  when Prism::StringNode
77
- argument.content.dump
77
+ argument.unescaped
78
78
  when Prism::CallNode
79
79
  "<#{argument.name}>"
80
80
  when nil
@@ -0,0 +1,95 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module RubyLsp
5
+ module RSpec
6
+ class IndexingEnhancement
7
+ extend T::Sig
8
+ include RubyIndexer::Enhancement
9
+
10
+ sig do
11
+ override.params(
12
+ index: RubyIndexer::Index,
13
+ owner: T.nilable(RubyIndexer::Entry::Namespace),
14
+ node: Prism::CallNode,
15
+ file_path: String,
16
+ code_units_cache: T.any(
17
+ T.proc.params(arg0: Integer).returns(Integer),
18
+ Prism::CodeUnitsCache,
19
+ ),
20
+ ).void
21
+ end
22
+ def on_call_node(index, owner, node, file_path, code_units_cache)
23
+ return if node.receiver
24
+
25
+ name = node.name
26
+
27
+ case name
28
+ when :let, :let!
29
+ block_node = node.block
30
+ return unless block_node
31
+
32
+ arguments = node.arguments
33
+ return unless arguments
34
+
35
+ return if arguments.arguments.count != 1
36
+
37
+ method_name_node = T.must(arguments.arguments.first)
38
+
39
+ method_name = case method_name_node
40
+ when Prism::StringNode
41
+ method_name_node.slice
42
+ when Prism::SymbolNode
43
+ method_name_node.unescaped
44
+ end
45
+
46
+ return unless method_name
47
+
48
+ index.add(RubyIndexer::Entry::Method.new(
49
+ method_name,
50
+ file_path,
51
+ RubyIndexer::Location.from_prism_location(block_node.location, code_units_cache),
52
+ RubyIndexer::Location.from_prism_location(block_node.location, code_units_cache),
53
+ nil,
54
+ [RubyIndexer::Entry::Signature.new([])],
55
+ RubyIndexer::Entry::Visibility::PUBLIC,
56
+ owner,
57
+ ))
58
+ when :subject, :subject!
59
+ block_node = node.block
60
+ return unless block_node
61
+
62
+ arguments = node.arguments
63
+
64
+ if arguments && arguments.arguments.count == 1
65
+ method_name_node = T.must(arguments.arguments.first)
66
+ end
67
+
68
+ method_name = if method_name_node
69
+ case method_name_node
70
+ when Prism::StringNode
71
+ method_name_node.slice
72
+ when Prism::SymbolNode
73
+ method_name_node.unescaped
74
+ end
75
+ else
76
+ "subject"
77
+ end
78
+
79
+ return unless method_name
80
+
81
+ index.add(RubyIndexer::Entry::Method.new(
82
+ method_name,
83
+ file_path,
84
+ RubyIndexer::Location.from_prism_location(block_node.location, code_units_cache),
85
+ RubyIndexer::Location.from_prism_location(block_node.location, code_units_cache),
86
+ nil,
87
+ [RubyIndexer::Entry::Signature.new([])],
88
+ RubyIndexer::Entry::Visibility::PUBLIC,
89
+ owner,
90
+ ))
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
@@ -3,6 +3,6 @@
3
3
 
4
4
  module RubyLsp
5
5
  module RSpec
6
- VERSION = "0.1.14"
6
+ VERSION = "0.1.16"
7
7
  end
8
8
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-lsp-rspec
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.14
4
+ version: 0.1.16
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stan Lo
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-10-03 00:00:00.000000000 Z
11
+ date: 2024-10-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ruby-lsp
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.19.0
19
+ version: 0.20.1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.19.0
26
+ version: 0.20.1
27
27
  description: RSpec addon for ruby-lsp
28
28
  email:
29
29
  - stan001212@gmail.com
@@ -41,7 +41,9 @@ files:
41
41
  - lib/ruby-lsp-rspec.rb
42
42
  - lib/ruby_lsp/ruby_lsp_rspec/addon.rb
43
43
  - lib/ruby_lsp/ruby_lsp_rspec/code_lens.rb
44
+ - lib/ruby_lsp/ruby_lsp_rspec/definition.rb
44
45
  - lib/ruby_lsp/ruby_lsp_rspec/document_symbol.rb
46
+ - lib/ruby_lsp/ruby_lsp_rspec/indexing_enhancement.rb
45
47
  - lib/ruby_lsp_rspec/version.rb
46
48
  homepage: https://github.com/st0012/ruby-lsp-rspec
47
49
  licenses: