ruby-lsp-cell 0.1.2 → 0.2.0

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: d26cf866d9c38fe88db134b7da05d7c883aa8cab0907b064042ef41a01dce7c7
4
- data.tar.gz: d91237300c2695320827a43142dcb84d3392d66486fa72a6f7df16750f490743
3
+ metadata.gz: be16f412b1af125c90034244af33444ce8cb494d3cf442b59159cad19ba4f592
4
+ data.tar.gz: 80db8e5cbf2a28037dd5d44a50d822efc8a65783587573667818204db9cc6294
5
5
  SHA512:
6
- metadata.gz: 3d0b35cd0593bcdc3c71cb18c19c7ffd8202763ce75a26389c1538e6f5ab4650e8996c69efcd8a16dd6e31e3d9c1b7013d869759b1a0bd922fec4f71a384f2be
7
- data.tar.gz: 46d0d9e866cdc4a8a0a75f6b930a31d40861616f5f2212069937cfdd4ba3a7077fe542b2b398f0dca1f6b5b9aa9d1a2a113c4bb5eeda349f03f3b86dc679f1dc
6
+ metadata.gz: fb9a1b6e99c6676aa57732da0c06fb98ba8176ee4252e00c07e3c7206c1e2bdfd2ed65d8a558130233dfb007eb49677cb77089bf366277b6cc75264d3327fa6b
7
+ data.tar.gz: 79b318cf629b1d2d9b9b7eae5607692c88cb902ff9978494b4c6781dd5fb854b40bcd9c616e53fb56bc66dd6ac80548be6c65290b9d694d0607779feccb2af92
data/.rubocop.yml CHANGED
@@ -19,4 +19,7 @@ Style/MethodCallWithArgsParentheses:
19
19
  Enabled: false
20
20
 
21
21
  Naming/PredicatePrefix:
22
- Enabled: false
22
+ Enabled: false
23
+
24
+ Layout/LeadingCommentSpace:
25
+ AllowRBSInlineAnnotation: true
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ ## [0.2.0] - 2025-07-21
2
+
3
+ - Add compatibility with Ruby LSP 0.26.0
4
+
1
5
  ## [0.1.1] - 2025-06-09
2
6
  - Add compatibility with Ruby LSP 0.24.1
3
7
 
@@ -6,4 +10,4 @@
6
10
  - Start of the main project
7
11
 
8
12
  ## [0.0.1] - 2024-06-22
9
- - Add compatibility with Ruby LSP 0.17.17
13
+ - Add compatibility with Ruby LSP 0.17.17
data/README.md CHANGED
@@ -44,6 +44,8 @@ Or install it yourself as:
44
44
  * **Top of the class** – lets you jump directly to the default template (`app/cells/user/show.erb` unless you changed `defaultViewFileName` in `.vscode/settings.json`).
45
45
  * **Any instance method that calls `render`** – jumps to the template rendered by that method.
46
46
 
47
+ ![example-ruby-lsp](example-ruby-lsp.gif)
48
+
47
49
  ## Development
48
50
 
49
51
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `bundle exec rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
Binary file
@@ -3,6 +3,6 @@
3
3
 
4
4
  module RubyLsp
5
5
  module Cell
6
- VERSION = "0.1.2"
6
+ VERSION = "0.2.0"
7
7
  end
8
8
  end
@@ -1,4 +1,4 @@
1
- # typed: false
1
+ # typed: true
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require "ruby_lsp/addon"
@@ -7,28 +7,28 @@ require "ruby_lsp/internal"
7
7
  require_relative "code_lens"
8
8
  require_relative "../cell/version"
9
9
 
10
- RubyLsp::Addon.depend_on_ruby_lsp!("~> 0.24.0")
10
+ RubyLsp::Addon.depend_on_ruby_lsp!("~> 0.26.0")
11
11
 
12
12
  module RubyLsp
13
13
  module Cell
14
- #
15
14
  # Addon for Ruby LSP Cell Context
16
15
  #
17
16
  class Addon < ::RubyLsp::Addon
18
- extend T::Sig
19
-
20
- sig { void }
17
+ #: -> void
21
18
  def initialize
22
19
  super
23
- @global_state = T.let(nil, T.nilable(RubyLsp::GlobalState))
24
- @message_queue = T.let(nil, T.nilable(Thread::Queue))
25
- @settings = T.let(nil, T.nilable(T::Hash[String, T.untyped]))
26
- @enabled = T.let(nil, T.nilable(T::Boolean))
27
- @default_view_filename = T.let(nil, T.nilable(String))
20
+ @global_state = nil #: RubyLsp::GlobalState?
21
+ @message_queue = nil #: Thread::Queue?
22
+ @settings = nil #: Hash[Symbol, untyped]?
23
+ @enabled = nil #: bool?
24
+ @default_view_filename = nil #: String?
28
25
  end
29
26
 
30
- sig { params(global_state: RubyLsp::GlobalState, message_queue: Thread::Queue).void }
27
+ # @override
28
+ #: (RubyLsp::GlobalState global_state, Thread::Queue message_queue) -> void
31
29
  def activate(global_state, message_queue)
30
+ return unless are_required_libraries_installed?
31
+
32
32
  @message_queue = message_queue
33
33
  @global_state = global_state
34
34
  @settings = @global_state.settings_for_addon(name) || {}
@@ -36,36 +36,42 @@ module RubyLsp
36
36
  @default_view_filename = @settings.fetch(:defaultViewFileName, "show.erb")
37
37
  end
38
38
 
39
- sig { void }
39
+ # @override
40
+ #: -> void
40
41
  def deactivate; end
41
42
 
42
- sig { returns(String) }
43
+ # @override
44
+ #: -> String
43
45
  def name
44
46
  "Ruby LSP Cell"
45
47
  end
46
48
 
47
- sig do
48
- params(
49
- response_builder: ResponseBuilders::CollectionResponseBuilder,
50
- uri: URI::Generic,
51
- dispatcher: Prism::Dispatcher,
52
- ).void
53
- end
49
+ # @override
50
+ #: (RubyLsp::ResponseBuilders::CollectionResponseBuilder[untyped] response_builder, URI::Generic uri, Prism::Dispatcher dispatcher) -> void
54
51
  def create_code_lens_listener(response_builder, uri, dispatcher)
55
52
  CodeLens.new(
56
53
  response_builder,
57
54
  uri,
58
55
  dispatcher,
59
- T.must(@global_state),
60
- enabled: T.must(@enabled),
61
- default_view_filename: T.must(@default_view_filename),
56
+ @global_state, #: as !nil
57
+ enabled: @enabled, #: as !nil
58
+ default_view_filename: @default_view_filename, #: as !nil
62
59
  )
63
60
  end
64
61
 
65
- sig { returns(String) }
62
+ # @override
63
+ #: -> String
66
64
  def version
67
65
  RubyLsp::Cell::VERSION
68
66
  end
67
+
68
+ def are_required_libraries_installed?
69
+ Bundler.definition.specs.any? do |spec|
70
+ spec.name == "cells"
71
+ end
72
+ rescue Bundler::GemNotFound
73
+ false
74
+ end
69
75
  end
70
76
  end
71
77
  end
@@ -1,124 +1,127 @@
1
- # typed: strict
1
+ # typed: false
2
2
  # frozen_string_literal: true
3
3
 
4
4
  module RubyLsp
5
5
  module Cell
6
6
  class CodeLens
7
- extend T::Sig
8
- extend T::Generic
9
-
10
7
  include ::RubyLsp::Requests::Support::Common
11
8
 
12
- REQUIRED_LIBRARY = T.let("cells-rails", String)
13
-
14
- ResponseType = type_member { { fixed: T::Array[CodeRay] } }
15
-
16
- sig do
17
- params(
18
- response_builder: RubyLsp::ResponseBuilders::CollectionResponseBuilder,
19
- uri: URI::Generic,
20
- dispatcher: Prism::Dispatcher,
21
- global_state: RubyLsp::GlobalState,
22
- enabled: T::Boolean,
23
- default_view_filename: String,
24
- ).void
25
- end
9
+ #: (
10
+ #| RubyLsp::ResponseBuilders::CollectionResponseBuilder[untyped] response_builder,
11
+ #| URI::Generic uri,
12
+ #| Prism::Dispatcher dispatcher,
13
+ #| RubyLsp::GlobalState global_state,
14
+ #| enabled: bool,
15
+ #| default_view_filename: String
16
+ #| ) -> void
26
17
  def initialize(response_builder, uri, dispatcher, global_state, enabled:, default_view_filename:)
27
18
  return unless enabled
28
19
 
29
20
  @response_builder = response_builder
30
21
  @global_state = global_state
31
22
 
32
- @path = T.let(uri.to_standardized_path, String)
33
- @class_name = T.let("", String)
34
- @pattern = T.let("_cell", String)
35
- @default_view_filename = T.let(default_view_filename, String)
36
- dispatcher.register(self, :on_class_node_enter, :on_def_node_leave)
23
+ @path = uri.to_standardized_path #: String
24
+ @class_name = ""
25
+ @pattern = "_cell"
26
+ @default_view_filename = default_view_filename
27
+ @in_cell_class = false
28
+ @nesting = [] #: Array[String]
29
+ dispatcher.register(
30
+ self,
31
+ :on_module_node_enter,
32
+ :on_module_node_leave,
33
+ :on_class_node_enter,
34
+ :on_class_node_leave,
35
+ :on_def_node_enter,
36
+ )
37
37
  end
38
38
 
39
- sig { params(node: Prism::ClassNode).void }
39
+ #: (Prism::ModuleNode node) -> void
40
+ def on_module_node_enter(node)
41
+ @nesting.push(node.constant_path.slice)
42
+ end
43
+
44
+ #: (Prism::ModuleNode node) -> void
45
+ def on_module_node_leave(node)
46
+ @nesting.pop
47
+ end
48
+
49
+ #: (Prism::ClassNode node) -> void
40
50
  def on_class_node_enter(node)
41
- @class_name = node.constant_path.slice
42
- return unless @class_name.end_with?("Cell")
43
- return unless @global_state.index.linearized_ancestors_of(@class_name).include?("Cell::ViewModel")
51
+ @nesting.push(node.constant_path.slice)
52
+ class_name = @nesting.join("::")
53
+ return unless class_name.end_with?("Cell")
54
+ return unless @global_state.index.linearized_ancestors_of(class_name).include?("Cell::ViewModel")
44
55
 
56
+ @in_cell_class = true
45
57
  add_default_goto_code_lens(node)
46
58
  end
47
59
 
48
- sig { params(node: Prism::ClassNode).void }
60
+ #: (Prism::ClassNode node) -> void
49
61
  def on_class_node_leave(node)
50
- @class_name = ""
62
+ @nesting.pop
63
+ @in_cell_class = false
51
64
  end
52
65
 
53
- sig { params(node: Prism::DefNode).void }
54
- def on_def_node_leave(node)
55
- return unless @class_name.end_with?("Cell")
66
+ #: (Prism::DefNode node) -> void
67
+ def on_def_node_enter(node)
68
+ return unless @in_cell_class
56
69
  return unless contains_render_call?(node.body)
57
- return unless @global_state.index.linearized_ancestors_of(@class_name).include?("Cell::ViewModel")
58
70
 
59
71
  add_function_goto_code_lens(node, node.name.to_s)
60
72
  end
61
73
 
62
74
  private
63
75
 
64
- sig { params(node: Prism::Node).void }
76
+ #: (Prism::Node node) -> void
65
77
  def add_default_goto_code_lens(node)
66
- return unless are_required_libraries_installed?
67
-
68
78
  erb_filename = remove_last_pattern_in_string @default_view_filename, ".erb"
69
79
  uri = compute_erb_view_path @default_view_filename
70
80
 
71
- @response_builder << create_code_lens(
72
- node,
73
- title: "Go to #{erb_filename}",
74
- command_name: "vscode.open",
75
- arguments: [uri],
76
- data: { type: "goToFile" },
77
- )
81
+ create_go_to_file_code_lens(node, erb_filename, uri)
78
82
  end
79
83
 
80
- sig { params(node: T.nilable(Prism::Node)).returns(T::Boolean) }
84
+ #: (Prism::Node? node) -> bool
81
85
  def contains_render_call?(node)
82
86
  return false if node.nil?
83
87
 
84
- return true if node.is_a?(Prism::CallNode) &&
85
- node.receiver.nil? &&
86
- node.message == "render"
88
+ if node.is_a?(Prism::CallNode)
89
+ return true if node.receiver.nil? && node.name == :render
90
+ end
87
91
 
88
92
  node.child_nodes.any? { |child| contains_render_call?(child) }
89
93
  end
90
94
 
91
- sig { params(node: Prism::Node, name: String).void }
95
+ #: (Prism::Node node, String name) -> void
92
96
  def add_function_goto_code_lens(node, name)
93
- return unless are_required_libraries_installed?
94
-
95
97
  uri = compute_erb_view_path("#{name}.erb")
96
-
97
- @response_builder << create_code_lens(
98
- node,
99
- title: "Go to #{name}",
100
- command_name: "vscode.open",
101
- arguments: [uri],
102
- data: { type: "goToFile" },
103
- )
98
+ create_go_to_file_code_lens(node, name, uri)
104
99
  end
105
100
 
106
- sig { params(string: String, pattern: String).returns(String) }
101
+ #: (String string, String pattern) -> String
107
102
  def remove_last_pattern_in_string(string, pattern)
108
103
  string.sub(/#{pattern}$/, "")
109
104
  end
110
105
 
111
- sig { params(name: String).returns(String) }
106
+ #: (String name) -> String
112
107
  def compute_erb_view_path(name)
113
108
  escaped_pattern = Regexp.escape(@pattern)
114
109
  base_path = @path.sub(/#{escaped_pattern}\.rb$/, "")
115
110
  folder = File.basename(base_path)
116
- File.join(File.dirname(base_path), folder, name)
111
+ path = File.join(File.dirname(base_path), folder, name)
112
+ uri = URI::File.from_path(path: path).to_s
113
+ uri
117
114
  end
118
115
 
119
- sig { returns(T::Boolean) }
120
- def are_required_libraries_installed?
121
- Bundler.locked_gems.dependencies.keys.include?(REQUIRED_LIBRARY)
116
+ #: (Prism::Node node, String name, String uri) -> void
117
+ def create_go_to_file_code_lens(node, name, uri)
118
+ @response_builder << create_code_lens(
119
+ node,
120
+ title: "Go to #{name}",
121
+ command_name: "rubyLsp.openFile",
122
+ arguments: [[uri]],
123
+ data: { type: "file" },
124
+ )
122
125
  end
123
126
  end
124
127
  end
data/tools/cell_fake.rb CHANGED
@@ -1,4 +1,4 @@
1
- # typed: false
1
+ # typed: strict
2
2
  # frozen_string_literal: true
3
3
 
4
4
  raise "Do not load this file!" unless defined?(RubyIndexer)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-lsp-cell
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Edgar Guzmán
@@ -24,6 +24,7 @@ files:
24
24
  - LICENSE.txt
25
25
  - README.md
26
26
  - Rakefile
27
+ - example-ruby-lsp.gif
27
28
  - lib/ruby_lsp/cell.rb
28
29
  - lib/ruby_lsp/cell/version.rb
29
30
  - lib/ruby_lsp/ruby-lsp-cell/addon.rb