ruby-lsp-cell 0.1.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 +7 -0
- data/.rubocop.yml +22 -0
- data/.ruby-version +1 -0
- data/.vscode/settings.json +19 -0
- data/LICENSE.txt +21 -0
- data/README.md +59 -0
- data/Rakefile +16 -0
- data/lib/ruby_lsp/cell/version.rb +8 -0
- data/lib/ruby_lsp/cell.rb +11 -0
- data/lib/ruby_lsp/ruby-lsp-cell/addon.rb +71 -0
- data/lib/ruby_lsp/ruby-lsp-cell/code_lens.rb +123 -0
- data/ruby-lsp-cell.gemspec +48 -0
- metadata +56 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: ef542283838f0b02db357300bd9eb16dbd29df6473451799350e7a9000464efc
|
4
|
+
data.tar.gz: 6502422f819758a0f20ce099d93c172f5508d9d115219b3696cb8bf59fe28785
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b7a02eb7ecd15d9894347674c1be575ef4d16e4de5cf54703981df112bb1f8a78ad06e26b2a51f76bb1d3aa0473948aac6df4ed740d31ed1b64fe1171813e1be
|
7
|
+
data.tar.gz: 7885de047e0c9c287ec04fddfe69e26da9b1023a0666c480a2c89b2bc9cc9be91b6f9fc5ac848cdfdd07ee381500164714af26ab333d0d7fcbeac2791ae5864e
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
inherit_gem:
|
2
|
+
rubocop-shopify: rubocop.yml
|
3
|
+
|
4
|
+
plugins:
|
5
|
+
- rubocop-sorbet
|
6
|
+
require:
|
7
|
+
- rubocop-rake
|
8
|
+
|
9
|
+
AllCops:
|
10
|
+
NewCops: disable
|
11
|
+
DisplayCopNames: true
|
12
|
+
SuggestExtensions: false
|
13
|
+
DisabledByDefault: false
|
14
|
+
|
15
|
+
Style/StderrPuts:
|
16
|
+
Enabled: true
|
17
|
+
|
18
|
+
Style/MethodCallWithArgsParentheses:
|
19
|
+
Enabled: false
|
20
|
+
|
21
|
+
Naming/PredicatePrefix:
|
22
|
+
Enabled: false
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
3.4.3
|
@@ -0,0 +1,19 @@
|
|
1
|
+
{
|
2
|
+
"cSpell.words": [
|
3
|
+
"rubocop",
|
4
|
+
"shopify",
|
5
|
+
"cell",
|
6
|
+
],
|
7
|
+
"github.copilot.enable": {
|
8
|
+
"*": true,
|
9
|
+
"plaintext": false,
|
10
|
+
"markdown": false,
|
11
|
+
"scminput": false
|
12
|
+
},
|
13
|
+
"rubyLsp.addonSettings": {
|
14
|
+
"Ruby LSP Cell": {
|
15
|
+
"enabled": true,
|
16
|
+
"defaultViewFileName": "show.erb"
|
17
|
+
}
|
18
|
+
}
|
19
|
+
}
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2025 Edgar Guzmán
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
# Ruby::Lsp::Cell
|
2
|
+
|
3
|
+
ruby-lsp-cell is an **addon for [Ruby LSP][ruby-lsp]** that adds smart CodeLens
|
4
|
+
links and navigation helpers for projects that use **[ViewComponent::Cell][cells]**
|
5
|
+
or any other *Cell-based* view layer. Its goal is to make jumping between a *Cell* class and its ERB/Haml template.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'ruby-lsp-cell'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
> $ bundle install
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
> $ gem install ruby-lsp-cell
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
1. Enable the addon:
|
26
|
+
|
27
|
+
Create (or edit) `.vscode/settings.json` in your project root:
|
28
|
+
|
29
|
+
```json
|
30
|
+
{
|
31
|
+
"rubyLsp.addonSettings": {
|
32
|
+
"Ruby LSP Cell": {
|
33
|
+
"enabled": true,
|
34
|
+
"defaultViewFileName": "show.erb"
|
35
|
+
}
|
36
|
+
}
|
37
|
+
}
|
38
|
+
```
|
39
|
+
|
40
|
+
2. Open a Cell file:
|
41
|
+
|
42
|
+
When you open `app/cells/user_cell.rb` Ruby LSP Cell inserts a single **Go to template** CodeLens in two places:
|
43
|
+
|
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
|
+
* **Any instance method that calls `render`** – jumps to the template rendered by that method.
|
46
|
+
|
47
|
+
## Development
|
48
|
+
|
49
|
+
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.
|
50
|
+
|
51
|
+
To release a new version, update the version number in `version.rb`.
|
52
|
+
|
53
|
+
## Contributing
|
54
|
+
|
55
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/guzmanem/ruby-lsp-cell.
|
56
|
+
|
57
|
+
## License
|
58
|
+
|
59
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "bundler/gem_tasks"
|
4
|
+
require "rake/testtask"
|
5
|
+
|
6
|
+
Rake::TestTask.new(:test) do |t|
|
7
|
+
t.libs << "test"
|
8
|
+
t.libs << "lib"
|
9
|
+
t.pattern = "test/**/*_test.rb"
|
10
|
+
end
|
11
|
+
|
12
|
+
require "rubocop/rake_task"
|
13
|
+
|
14
|
+
RuboCop::RakeTask.new
|
15
|
+
|
16
|
+
task default: [:test, :rubocop]
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# typed: false
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "ruby_lsp/addon"
|
5
|
+
require "ruby_lsp/internal"
|
6
|
+
|
7
|
+
require_relative "code_lens"
|
8
|
+
require_relative "../cell/version"
|
9
|
+
|
10
|
+
RubyLsp::Addon.depend_on_ruby_lsp!("~> 0.23.0")
|
11
|
+
|
12
|
+
module RubyLsp
|
13
|
+
module Cell
|
14
|
+
#
|
15
|
+
# Addon for Ruby LSP Cell Context
|
16
|
+
#
|
17
|
+
class Addon < ::RubyLsp::Addon
|
18
|
+
extend T::Sig
|
19
|
+
|
20
|
+
sig { void }
|
21
|
+
def initialize
|
22
|
+
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))
|
28
|
+
end
|
29
|
+
|
30
|
+
sig { params(global_state: RubyLsp::GlobalState, message_queue: Thread::Queue).void }
|
31
|
+
def activate(global_state, message_queue)
|
32
|
+
@message_queue = message_queue
|
33
|
+
@global_state = global_state
|
34
|
+
@settings = @global_state.settings_for_addon(name) || {}
|
35
|
+
@enabled = @settings.fetch(:enabled, true)
|
36
|
+
@default_view_filename = @settings.fetch(:defaultViewFileName, "show.erb")
|
37
|
+
end
|
38
|
+
|
39
|
+
sig { void }
|
40
|
+
def deactivate; end
|
41
|
+
|
42
|
+
sig { returns(String) }
|
43
|
+
def name
|
44
|
+
"Ruby LSP Cell"
|
45
|
+
end
|
46
|
+
|
47
|
+
sig do
|
48
|
+
params(
|
49
|
+
response_builder: ResponseBuilders::CollectionResponseBuilder,
|
50
|
+
uri: URI::Generic,
|
51
|
+
dispatcher: Prism::Dispatcher,
|
52
|
+
).void
|
53
|
+
end
|
54
|
+
def create_code_lens_listener(response_builder, uri, dispatcher)
|
55
|
+
CodeLens.new(
|
56
|
+
response_builder,
|
57
|
+
uri,
|
58
|
+
dispatcher,
|
59
|
+
T.must(@global_state),
|
60
|
+
enabled: T.must(@enabled),
|
61
|
+
default_view_filename: T.must(@default_view_filename),
|
62
|
+
)
|
63
|
+
end
|
64
|
+
|
65
|
+
sig { returns(String) }
|
66
|
+
def version
|
67
|
+
RubyLsp::Cell::VERSION
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module RubyLsp
|
5
|
+
module Cell
|
6
|
+
class CodeLens
|
7
|
+
extend T::Sig
|
8
|
+
extend T::Generic
|
9
|
+
|
10
|
+
include ::RubyLsp::Requests::Support::Common
|
11
|
+
|
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
|
26
|
+
def initialize(response_builder, uri, dispatcher, global_state, enabled:, default_view_filename:)
|
27
|
+
return unless enabled
|
28
|
+
|
29
|
+
@response_builder = response_builder
|
30
|
+
@global_state = global_state
|
31
|
+
|
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)
|
37
|
+
end
|
38
|
+
|
39
|
+
sig { params(node: Prism::ClassNode).void }
|
40
|
+
def on_class_node_enter(node)
|
41
|
+
@class_name = node.constant_path.slice
|
42
|
+
return unless @class_name.end_with?("Cell")
|
43
|
+
|
44
|
+
add_default_goto_code_lens(node)
|
45
|
+
end
|
46
|
+
|
47
|
+
sig { params(node: Prism::ClassNode).void }
|
48
|
+
def on_class_node_leave(node)
|
49
|
+
@class_name = ""
|
50
|
+
end
|
51
|
+
|
52
|
+
sig { params(node: Prism::DefNode).void }
|
53
|
+
def on_def_node_leave(node)
|
54
|
+
return unless @class_name.end_with?("Cell")
|
55
|
+
return unless contains_render_call?(node.body)
|
56
|
+
|
57
|
+
add_function_goto_code_lens(node, node.name.to_s)
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
sig { params(node: Prism::Node).void }
|
63
|
+
def add_default_goto_code_lens(node)
|
64
|
+
return unless are_required_libraries_installed?
|
65
|
+
|
66
|
+
erb_filename = remove_last_pattern_in_string @default_view_filename, ".erb"
|
67
|
+
uri = compute_erb_view_path @default_view_filename
|
68
|
+
|
69
|
+
@response_builder << create_code_lens(
|
70
|
+
node,
|
71
|
+
title: "Go to #{erb_filename}",
|
72
|
+
command_name: "vscode.open",
|
73
|
+
arguments: [uri],
|
74
|
+
data: { type: "goToFile" },
|
75
|
+
)
|
76
|
+
end
|
77
|
+
|
78
|
+
sig { params(node: T.nilable(Prism::Node)).returns(T::Boolean) }
|
79
|
+
def contains_render_call?(node)
|
80
|
+
return false if node.nil?
|
81
|
+
|
82
|
+
return true if node.is_a?(Prism::CallNode) &&
|
83
|
+
node.receiver.nil? &&
|
84
|
+
node.message == "render"
|
85
|
+
|
86
|
+
node.child_nodes.any? { |child| contains_render_call?(child) }
|
87
|
+
end
|
88
|
+
|
89
|
+
sig { params(node: Prism::Node, name: String).void }
|
90
|
+
def add_function_goto_code_lens(node, name)
|
91
|
+
return unless are_required_libraries_installed?
|
92
|
+
|
93
|
+
uri = compute_erb_view_path("#{name}.erb")
|
94
|
+
|
95
|
+
@response_builder << create_code_lens(
|
96
|
+
node,
|
97
|
+
title: "Go to #{name}",
|
98
|
+
command_name: "vscode.open",
|
99
|
+
arguments: [uri],
|
100
|
+
data: { type: "goToFile" },
|
101
|
+
)
|
102
|
+
end
|
103
|
+
|
104
|
+
sig { params(string: String, pattern: String).returns(String) }
|
105
|
+
def remove_last_pattern_in_string(string, pattern)
|
106
|
+
string.sub(/#{pattern}$/, "")
|
107
|
+
end
|
108
|
+
|
109
|
+
sig { params(name: String).returns(String) }
|
110
|
+
def compute_erb_view_path(name)
|
111
|
+
escaped_pattern = Regexp.escape(@pattern)
|
112
|
+
base_path = @path.sub(/#{escaped_pattern}\.rb$/, "")
|
113
|
+
folder = File.basename(base_path)
|
114
|
+
File.join(File.dirname(base_path), folder, name)
|
115
|
+
end
|
116
|
+
|
117
|
+
sig { returns(T::Boolean) }
|
118
|
+
def are_required_libraries_installed?
|
119
|
+
Bundler.locked_gems.dependencies.keys.include?(REQUIRED_LIBRARY)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path("lib", __dir__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require "ruby_lsp/cell/version"
|
6
|
+
|
7
|
+
Gem::Specification.new do |spec|
|
8
|
+
spec.name = "ruby-lsp-cell"
|
9
|
+
spec.version = RubyLsp::Cell::VERSION
|
10
|
+
spec.authors = ["Edgar Guzmán"]
|
11
|
+
spec.email = ["guzmanem@hotmail.com"]
|
12
|
+
|
13
|
+
spec.summary = "Ruby LSP addon for cell-based development support"
|
14
|
+
spec.description = "A Ruby LSP extension that provides additional language server features for cell-based development workflows"
|
15
|
+
spec.homepage = "https://github.com/guzmanem/ruby-lsp-cell"
|
16
|
+
spec.license = "MIT"
|
17
|
+
spec.required_ruby_version = ">= 3.0.0"
|
18
|
+
|
19
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
20
|
+
spec.metadata["source_code_uri"] = "https://github.com/guzmanem/ruby-lsp-cell"
|
21
|
+
spec.metadata["changelog_uri"] = "https://github.com/guzmanem/ruby-lsp-cell/blob/main/CHANGELOG.md"
|
22
|
+
spec.metadata["rubygems_mfa_required"] = "true"
|
23
|
+
|
24
|
+
# Specify which files should be added to the gem when it is released.
|
25
|
+
spec.files = Dir.chdir(__dir__) do
|
26
|
+
%x(git ls-files -z).split("\x0").reject do |f|
|
27
|
+
(File.expand_path(f) == __FILE__) ||
|
28
|
+
f.start_with?(
|
29
|
+
"bin/",
|
30
|
+
"test/",
|
31
|
+
"spec/",
|
32
|
+
"features/",
|
33
|
+
"examples/",
|
34
|
+
".git",
|
35
|
+
".circleci",
|
36
|
+
"rubocop.yml",
|
37
|
+
"appveyor",
|
38
|
+
"Gemfile",
|
39
|
+
"misc/",
|
40
|
+
"sorbet/",
|
41
|
+
)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
spec.bindir = "exe"
|
46
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
47
|
+
spec.require_paths = ["lib"]
|
48
|
+
end
|
metadata
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ruby-lsp-cell
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Edgar Guzmán
|
8
|
+
bindir: exe
|
9
|
+
cert_chain: []
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
11
|
+
dependencies: []
|
12
|
+
description: A Ruby LSP extension that provides additional language server features
|
13
|
+
for cell-based development workflows
|
14
|
+
email:
|
15
|
+
- guzmanem@hotmail.com
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- ".rubocop.yml"
|
21
|
+
- ".ruby-version"
|
22
|
+
- ".vscode/settings.json"
|
23
|
+
- LICENSE.txt
|
24
|
+
- README.md
|
25
|
+
- Rakefile
|
26
|
+
- lib/ruby_lsp/cell.rb
|
27
|
+
- lib/ruby_lsp/cell/version.rb
|
28
|
+
- lib/ruby_lsp/ruby-lsp-cell/addon.rb
|
29
|
+
- lib/ruby_lsp/ruby-lsp-cell/code_lens.rb
|
30
|
+
- ruby-lsp-cell.gemspec
|
31
|
+
homepage: https://github.com/guzmanem/ruby-lsp-cell
|
32
|
+
licenses:
|
33
|
+
- MIT
|
34
|
+
metadata:
|
35
|
+
homepage_uri: https://github.com/guzmanem/ruby-lsp-cell
|
36
|
+
source_code_uri: https://github.com/guzmanem/ruby-lsp-cell
|
37
|
+
changelog_uri: https://github.com/guzmanem/ruby-lsp-cell/blob/main/CHANGELOG.md
|
38
|
+
rubygems_mfa_required: 'true'
|
39
|
+
rdoc_options: []
|
40
|
+
require_paths:
|
41
|
+
- lib
|
42
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 3.0.0
|
47
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: '0'
|
52
|
+
requirements: []
|
53
|
+
rubygems_version: 3.6.7
|
54
|
+
specification_version: 4
|
55
|
+
summary: Ruby LSP addon for cell-based development support
|
56
|
+
test_files: []
|