ruby-lsp-rspec 0.1.14 → 0.1.16

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