ruby-lsp-rails-partial 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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: b2262132a35328b7bb8515a4cef737de185fc42aa2daf334685655721f9e1357
4
+ data.tar.gz: 6cef6d521642ca0e9a9e1b01343c6dd820c9c5eebab3b2297a40d7dd4fee961a
5
+ SHA512:
6
+ metadata.gz: ec7ab69646adadc23d3d9eccc5768257d364994c8f5a542b06680f4dd7a344a39d3bf8b93ead06b05b5a1cb12fc3db05d998b64d6a673fbb47d049f82af93481
7
+ data.tar.gz: f0396414c88f72616c91926db9205051951492742c79c54bf25b883e656657cf7930c4d0bad3d6843d35fa7af8abf4a048e6aec089a77073e9237eacde23b8eb
data/CHANGELOG.md ADDED
@@ -0,0 +1,20 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.1.0]
11
+
12
+ ### Added
13
+
14
+ - Initial release.
15
+ - Go to definition from a Rails `render` partial name string to the matching partial file.
16
+ - Completion for partial names while typing inside the string.
17
+ - Hover showing the list of resolved partial files as Markdown links.
18
+
19
+ [Unreleased]: https://github.com/aki77/ruby-lsp-rails-partial/compare/v0.1.0...HEAD
20
+ [0.1.0]: https://github.com/aki77/ruby-lsp-rails-partial/releases/tag/v0.1.0
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2026 aki77
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,45 @@
1
+ # ruby-lsp-rails-partial
2
+
3
+ [![CI](https://github.com/aki77/ruby-lsp-rails-partial/actions/workflows/ci.yml/badge.svg)](https://github.com/aki77/ruby-lsp-rails-partial/actions/workflows/ci.yml)
4
+
5
+ A [Ruby LSP](https://github.com/Shopify/ruby-lsp) add-on that understands the partial name string
6
+ of Rails `render` calls and provides:
7
+
8
+ - **Go to definition** — jump from `render 'admin/areas/form'` (or `render partial: '...'`) to the
9
+ matching partial file. When multiple formats match, all candidates are offered.
10
+ - **Completion** — complete partial names while typing inside the string. Partials in the same
11
+ directory are offered as bare names; others use the path form.
12
+ - **Hover** — show the list of resolved partial files as Markdown links.
13
+
14
+ Bare names (`render 'form'`) are resolved relative to the current view's directory, or to the
15
+ controller name when called from a controller. Locale and variant qualifiers
16
+ (`_form.en.html.erb`, `_form.html+phone.erb`) are treated as the same partial.
17
+
18
+ ## Installation
19
+
20
+ Add the gem to your application's `Gemfile`:
21
+
22
+ ```ruby
23
+ group :development do
24
+ gem 'ruby-lsp-rails-partial', require: false
25
+ end
26
+ ```
27
+
28
+ Then run `bundle install` and restart the Ruby LSP server in your editor. The add-on is discovered
29
+ automatically by Ruby LSP via the `lib/ruby_lsp/**/addon.rb` convention.
30
+
31
+ ## Scope
32
+
33
+ The view root is fixed to `app/views`. `prepend_view_path` / `append_view_path` and independent
34
+ engines are not supported.
35
+
36
+ ## Development
37
+
38
+ ```sh
39
+ bundle install
40
+ bundle exec rake test
41
+ ```
42
+
43
+ ## License
44
+
45
+ MIT
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "version"
4
+ require_relative "util"
5
+ require_relative "partial_index"
6
+ require_relative "partial_resolver"
7
+ require_relative "definition"
8
+ require_relative "completion"
9
+ require_relative "hover"
10
+
11
+ module RubyLsp
12
+ module RailsPartial
13
+ # Ruby LSP add-on that provides go-to-definition and completion for the partial name string of
14
+ # a render call.
15
+ #
16
+ # The view root is fixed to app/views (this add-on does not support prepend/append_view_path or
17
+ # independent engines).
18
+ class Addon < ::RubyLsp::Addon
19
+ WATCHER_REGISTRATION_ID = "rails-partial-watcher"
20
+
21
+ def activate(global_state, outgoing_queue)
22
+ views_path = File.join(global_state.workspace_path, "app", "views")
23
+ @index = PartialIndex.new(views_path)
24
+ @resolver = PartialResolver.new(@index, views_path)
25
+
26
+ register_file_watcher(global_state, outgoing_queue)
27
+ end
28
+
29
+ def deactivate; end
30
+
31
+ def name
32
+ "Rails Partial"
33
+ end
34
+
35
+ def version
36
+ VERSION
37
+ end
38
+
39
+ def create_definition_listener(response_builder, uri, node_context, dispatcher)
40
+ return unless @resolver
41
+
42
+ Definition.new(response_builder, uri, node_context, @resolver, dispatcher)
43
+ end
44
+
45
+ def create_completion_listener(response_builder, node_context, dispatcher, uri)
46
+ return unless @resolver
47
+
48
+ Completion.new(response_builder, node_context, @resolver, uri, dispatcher)
49
+ end
50
+
51
+ def create_hover_listener(response_builder, node_context, dispatcher)
52
+ return unless @resolver
53
+
54
+ Hover.new(response_builder, node_context, @resolver, dispatcher)
55
+ end
56
+
57
+ # Watches partial changes under app/views and updates the index incrementally.
58
+ def workspace_did_change_watched_files(changes)
59
+ return unless @index
60
+
61
+ changes.each do |change|
62
+ path = Util.uri_to_path(change[:uri])
63
+ next unless path
64
+
65
+ case change[:type]
66
+ when Constant::FileChangeType::CREATED, Constant::FileChangeType::CHANGED
67
+ @index.add(path)
68
+ when Constant::FileChangeType::DELETED
69
+ @index.remove(path)
70
+ end
71
+ end
72
+ end
73
+
74
+ private
75
+
76
+ def register_file_watcher(global_state, outgoing_queue)
77
+ return unless global_state.supports_watching_files
78
+
79
+ outgoing_queue << Request.register_watched_files(
80
+ 1,
81
+ Interface::RelativePattern.new(
82
+ base_uri: global_state.workspace_uri.to_s,
83
+ pattern: "app/views/**/_*"
84
+ ),
85
+ registration_id: WATCHER_REGISTRATION_ID
86
+ )
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyLsp
4
+ module RailsPartial
5
+ # Completes partial names while typing the partial name string of a render call.
6
+ # Candidates are always offered in path form (e.g. "admin/areas/form").
7
+ #
8
+ # NOTE: A completion request dispatches only the single node directly under the cursor, and the
9
+ # target node types do not include StringNode. When the cursor is inside the string, what gets
10
+ # dispatched is the enclosing CallNode (render), so this is handled in `on_call_node_enter`
11
+ # rather than `on_string_node_enter`.
12
+ class Completion
13
+ include Requests::Support::Common
14
+
15
+ # uri is part of the fixed listener signature but unused: candidates do not depend on the
16
+ # current file's directory (always path form).
17
+ def initialize(response_builder, node_context, resolver, _uri, dispatcher)
18
+ @response_builder = response_builder
19
+ @node_context = node_context
20
+ @resolver = resolver
21
+
22
+ dispatcher.register(self, :on_call_node_enter)
23
+ end
24
+
25
+ def on_call_node_enter(node)
26
+ return unless Util.render_call?(node)
27
+
28
+ string_node = Util.partial_string_argument(node)
29
+ return unless string_node
30
+
31
+ edit_range = content_range(string_node)
32
+ prefix = string_node.unescaped
33
+
34
+ @resolver.completion_candidates.each do |key, path|
35
+ # label, new_text, and the implicit filter_text (defaults to label) are all the path-form
36
+ # key, so the item survives the client-side filter regardless of how the user typed the
37
+ # reference. Mirrors ruby-lsp's require completion (build_completion).
38
+ next unless key.start_with?(prefix)
39
+
40
+ @response_builder << Interface::CompletionItem.new(
41
+ label: key,
42
+ kind: Constant::CompletionItemKind::FILE,
43
+ text_edit: Interface::TextEdit.new(range: edit_range, new_text: key),
44
+ detail: relative_detail(path)
45
+ )
46
+ end
47
+ end
48
+
49
+ private
50
+
51
+ # Range pointing at the inside of the string node's quotes. Falls back to the whole node if
52
+ # content_loc is absent.
53
+ def content_range(node)
54
+ location = node.content_loc || node.location
55
+ range_from_location(location)
56
+ end
57
+
58
+ def relative_detail(path)
59
+ return unless path
60
+
61
+ Util.relative_to_views(path)
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyLsp
4
+ module RailsPartial
5
+ # When the cursor is on the partial name string of a render call, provides go-to-definition
6
+ # to the matching partial file. When multiple formats match, returns all Locations and lets
7
+ # ruby-lsp present the candidate picker.
8
+ class Definition
9
+ include Requests::Support::Common
10
+
11
+ def initialize(response_builder, uri, node_context, resolver, dispatcher)
12
+ @response_builder = response_builder
13
+ @uri = uri
14
+ @node_context = node_context
15
+ @resolver = resolver
16
+
17
+ dispatcher.register(self, :on_string_node_enter)
18
+ end
19
+
20
+ def on_string_node_enter(node)
21
+ return unless render_partial_argument?(node)
22
+
23
+ reference = node.unescaped
24
+ return if reference.empty?
25
+
26
+ # Highlight range of the origin. Pointing at the whole partial name (inside the quotes)
27
+ # makes the entire string a link even for names containing `/` like `admin/areas/form`.
28
+ origin_range = range_from_location(node.content_loc || node.location)
29
+
30
+ # The partial body is not parsed, so a leading zero-width range is reused as the target for
31
+ # all candidates. target_selection_range must be contained within target_range, so both are
32
+ # made identical.
33
+ target_range = Interface::Range.new(
34
+ start: Interface::Position.new(line: 0, character: 0),
35
+ end: Interface::Position.new(line: 0, character: 0)
36
+ )
37
+
38
+ @resolver.resolve(reference, @uri.to_s).each do |path|
39
+ @response_builder << Interface::LocationLink.new(
40
+ target_uri: URI::Generic.from_path(path:).to_s,
41
+ target_range:,
42
+ target_selection_range: target_range,
43
+ origin_selection_range: origin_range
44
+ )
45
+ end
46
+ end
47
+
48
+ private
49
+
50
+ # Whether this string node is the render call's partial argument (the first positional
51
+ # argument or the value of `partial:`). Decided by whether the StringNode under the cursor
52
+ # is identical to that render call's partial argument node.
53
+ def render_partial_argument?(node)
54
+ call_node = @node_context.call_node
55
+ return false unless call_node && Util.render_call?(call_node)
56
+
57
+ Util.partial_string_argument(call_node).equal?(node)
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyLsp
4
+ module RailsPartial
5
+ # When the cursor is on the partial name string of a render call, shows the list of resolved
6
+ # file paths in a tooltip (Markdown).
7
+ #
8
+ # NOTE: A hover request does not pass a uri to the listener (unlike definition/completion).
9
+ # A bare name `render 'form'` needs a uri to infer the current directory, so it is out of
10
+ # scope; only slash-qualified names like `render 'admin/areas/form'` are resolved.
11
+ class Hover
12
+ def initialize(response_builder, node_context, resolver, dispatcher)
13
+ @response_builder = response_builder
14
+ @node_context = node_context
15
+ @resolver = resolver
16
+
17
+ dispatcher.register(self, :on_string_node_enter)
18
+ end
19
+
20
+ def on_string_node_enter(node)
21
+ return unless render_partial_argument?(node)
22
+
23
+ reference = node.unescaped
24
+ return if reference.empty?
25
+
26
+ paths = @resolver.resolve_without_context(reference)
27
+ return if paths.empty?
28
+
29
+ @response_builder.push("**Rails partial: `#{reference}`**", category: :title)
30
+ @response_builder.push(links_markdown(paths), category: :links)
31
+ end
32
+
33
+ private
34
+
35
+ # Renders each resolved file as a Markdown bullet link with its view-root-relative path.
36
+ def links_markdown(paths)
37
+ paths.sort.map { |path| link_line(path) }.join("\n")
38
+ end
39
+
40
+ def link_line(path)
41
+ uri = URI::Generic.from_path(path:).to_s
42
+ "- [#{Util.relative_to_views(path)}](#{uri})"
43
+ end
44
+
45
+ # Whether this string node is the render call's partial argument.
46
+ # This duplicates Definition's logic, but it is intentionally re-stated here so that the
47
+ # behavior can be followed within a single file (explicit duplication over implicit
48
+ # abstraction).
49
+ def render_partial_argument?(node)
50
+ call_node = @node_context.call_node
51
+ return false unless call_node && Util.render_call?(call_node)
52
+
53
+ Util.partial_string_argument(call_node).equal?(node)
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyLsp
4
+ module RailsPartial
5
+ # In-memory index of partials (`_*.*`) under the view root.
6
+ #
7
+ # ## Key normalization
8
+ # The path relative to the view root is normalized to "directory + basename without the
9
+ # leading underscore". All qualifiers that follow the partial name (format, handler, locale,
10
+ # variant) are dropped.
11
+ # app/views/admin/areas/_form.html.erb -> "admin/areas/form"
12
+ # app/views/admin/areas/_form.en.html.erb -> "admin/areas/form" (locale variant shares the key)
13
+ # app/views/admin/areas/_form.html+phone.erb -> "admin/areas/form" (variant shares the key)
14
+ # Since multiple formats can map to the same key, the value is always an array of file paths.
15
+ #
16
+ # The index is updated incrementally via file-watching events rather than re-globbing on every
17
+ # request (performance requirement).
18
+ class PartialIndex
19
+ def initialize(views_path)
20
+ @views_path = views_path
21
+ # normalized key => Array[absolute path]
22
+ @entries = Hash.new { |hash, key| hash[key] = [] }
23
+ build
24
+ end
25
+
26
+ # Returns the array of partial file paths for the normalized key, or an empty array if none.
27
+ def lookup(key)
28
+ @entries.fetch(key, [])
29
+ end
30
+
31
+ def all_entries
32
+ @entries
33
+ end
34
+
35
+ # Incremental update from a file-watching event. Paths that are not partials are ignored.
36
+ def add(absolute_path)
37
+ key = key_for(absolute_path)
38
+ return unless key
39
+
40
+ paths = @entries[key]
41
+ paths << absolute_path unless paths.include?(absolute_path)
42
+ end
43
+
44
+ def remove(absolute_path)
45
+ key = key_for(absolute_path)
46
+ return unless key
47
+
48
+ paths = @entries[key]
49
+ paths.delete(absolute_path)
50
+ @entries.delete(key) if paths.empty?
51
+ end
52
+
53
+ private
54
+
55
+ def build
56
+ Dir.glob(File.join(@views_path, "**", "_*.*")).each { |path| add(path) }
57
+ end
58
+
59
+ # Converts an absolute path to a normalized key. Returns nil unless it is a partial
60
+ # (basename starts with `_`).
61
+ def key_for(absolute_path)
62
+ relative = relative_from_views(absolute_path)
63
+ return unless relative
64
+
65
+ dir = File.dirname(relative)
66
+ basename = File.basename(relative)
67
+ return unless basename.start_with?("_")
68
+
69
+ # Strip the leading `_` and drop everything after the first `.`
70
+ # (format/handler/locale/variant).
71
+ name = basename[1..].split(".").first
72
+ return unless name
73
+
74
+ dir == "." ? name : "#{dir}/#{name}"
75
+ end
76
+
77
+ def relative_from_views(absolute_path)
78
+ prefix = "#{@views_path}/"
79
+ return unless absolute_path.start_with?(prefix)
80
+
81
+ absolute_path[prefix.length..]
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyLsp
4
+ module RailsPartial
5
+ # Resolves the partial reference string of a `render` call to a PartialIndex key.
6
+ # Because resolution depends on the reference form and on the context of "which file the
7
+ # render is called from", this class is responsible only for bridging to the index's
8
+ # normalized key.
9
+ class PartialResolver
10
+ def initialize(index, views_path)
11
+ @index = index
12
+ @views_path = views_path
13
+ end
14
+
15
+ # Resolves a partial reference string ("foo" / "dir/foo") in the context of the current file
16
+ # and returns the array of absolute paths of the matching partial files.
17
+ def resolve(reference, current_uri)
18
+ key = key_for(reference, current_uri)
19
+ return [] unless key
20
+
21
+ @index.lookup(key)
22
+ end
23
+
24
+ # For contexts without a uri (hover). Only resolves references that contain a slash.
25
+ # Bare names are out of scope (they need a uri for directory inference) and return [].
26
+ def resolve_without_context(reference)
27
+ return [] unless reference.include?("/")
28
+
29
+ @index.lookup(reference)
30
+ end
31
+
32
+ # Returns completion candidates as an array of [key (path form), representative path].
33
+ # The key is always the normalized path form so that the display label, filter text, and
34
+ # inserted text all match, which keeps the item past the client-side filter regardless of
35
+ # how the user typed the reference.
36
+ def completion_candidates
37
+ @index.all_entries.map { |key, paths| [key, paths.first] }
38
+ end
39
+
40
+ private
41
+
42
+ # Converts a reference string to a normalized key.
43
+ # A slash means root-relative; otherwise it is relative to the current file's directory.
44
+ def key_for(reference, current_uri)
45
+ return if reference.empty?
46
+
47
+ if reference.include?("/")
48
+ reference
49
+ else
50
+ dir = current_dir(current_uri)
51
+ dir ? "#{dir}/#{reference}" : reference
52
+ end
53
+ end
54
+
55
+ # Derives the view-root-relative directory from the current file's URI.
56
+ # A view (under the view root) uses its own directory; a controller derives it from the
57
+ # controller name.
58
+ def current_dir(current_uri)
59
+ path = Util.uri_to_path(current_uri)
60
+ return unless path
61
+
62
+ if path.start_with?("#{@views_path}/")
63
+ relative = path[(@views_path.length + 1)..]
64
+ dir = File.dirname(relative)
65
+ dir == "." ? nil : dir
66
+ elsif path.include?("/app/controllers/")
67
+ controller_dir_from(path)
68
+ end
69
+ end
70
+
71
+ # Derives the view prefix from a controller file path.
72
+ # app/controllers/admin/areas_controller.rb -> "admin/areas"
73
+ def controller_dir_from(path)
74
+ relative = path.split("/app/controllers/", 2).last
75
+ return unless relative
76
+
77
+ dir = relative.delete_suffix("_controller.rb")
78
+ dir.empty? ? nil : dir
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "uri"
4
+
5
+ module RubyLsp
6
+ module RailsPartial
7
+ # AST inspection / path conversion helpers. Shared by the Definition / Completion / Hover
8
+ # listeners and by Addon / PartialResolver.
9
+ module Util
10
+ RENDER_METHODS = %i[render render_to_string].freeze
11
+ VIEWS_MARKER = "/app/views/"
12
+
13
+ class << self
14
+ # Converts a file:// URI to a filesystem path. Non-file:// URIs are returned as-is.
15
+ def uri_to_path(uri)
16
+ return uri unless uri.start_with?("file://")
17
+
18
+ URI.parse(uri).path
19
+ rescue URI::InvalidURIError
20
+ nil
21
+ end
22
+
23
+ # Returns the path relative to the app/views root. Falls back to the basename if the path
24
+ # is not under views.
25
+ def relative_to_views(path)
26
+ index = path.index(VIEWS_MARKER)
27
+ index ? path[(index + VIEWS_MARKER.length)..] : File.basename(path)
28
+ end
29
+
30
+ # Whether call_node is a render call with no receiver (or self).
31
+ def render_call?(call_node)
32
+ return false unless RENDER_METHODS.include?(call_node.message&.to_sym)
33
+
34
+ receiver = call_node.receiver
35
+ receiver.nil? || receiver.is_a?(Prism::SelfNode)
36
+ end
37
+
38
+ # Returns the string node of the render call's partial argument.
39
+ # The target is (1) the first positional argument, or (2) the value of the `partial:`
40
+ # keyword. Returns nil if neither is present.
41
+ def partial_string_argument(call_node)
42
+ arguments = call_node.arguments&.arguments
43
+ return unless arguments&.any?
44
+
45
+ first = arguments.first
46
+ return first if first.is_a?(Prism::StringNode)
47
+
48
+ partial_keyword_value(arguments)
49
+ end
50
+
51
+ private
52
+
53
+ # Returns the string node for the `partial:` keyword.
54
+ def partial_keyword_value(arguments)
55
+ keyword_hash = arguments.find { |arg| arg.is_a?(Prism::KeywordHashNode) }
56
+ return unless keyword_hash
57
+
58
+ assoc =
59
+ keyword_hash.elements.find do |element|
60
+ element.is_a?(Prism::AssocNode) &&
61
+ partial_key?(element.key) &&
62
+ element.value.is_a?(Prism::StringNode)
63
+ end
64
+ assoc&.value
65
+ end
66
+
67
+ def partial_key?(key)
68
+ key.is_a?(Prism::SymbolNode) && key.unescaped == "partial"
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyLsp
4
+ module RailsPartial
5
+ VERSION = "0.1.0"
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,75 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruby-lsp-rails-partial
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - aki77
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: ruby-lsp
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: 0.26.0
19
+ - - "<"
20
+ - !ruby/object:Gem::Version
21
+ version: 0.27.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ version: 0.26.0
29
+ - - "<"
30
+ - !ruby/object:Gem::Version
31
+ version: 0.27.0
32
+ description: Provides go-to-definition, completion, and hover for the partial name
33
+ string of Rails render calls.
34
+ email:
35
+ - 163168+aki77@users.noreply.github.com
36
+ executables: []
37
+ extensions: []
38
+ extra_rdoc_files: []
39
+ files:
40
+ - CHANGELOG.md
41
+ - LICENSE.txt
42
+ - README.md
43
+ - lib/ruby_lsp/ruby_lsp_rails_partial/addon.rb
44
+ - lib/ruby_lsp/ruby_lsp_rails_partial/completion.rb
45
+ - lib/ruby_lsp/ruby_lsp_rails_partial/definition.rb
46
+ - lib/ruby_lsp/ruby_lsp_rails_partial/hover.rb
47
+ - lib/ruby_lsp/ruby_lsp_rails_partial/partial_index.rb
48
+ - lib/ruby_lsp/ruby_lsp_rails_partial/partial_resolver.rb
49
+ - lib/ruby_lsp/ruby_lsp_rails_partial/util.rb
50
+ - lib/ruby_lsp/ruby_lsp_rails_partial/version.rb
51
+ homepage: https://github.com/aki77/ruby-lsp-rails-partial
52
+ licenses:
53
+ - MIT
54
+ metadata:
55
+ source_code_uri: https://github.com/aki77/ruby-lsp-rails-partial
56
+ changelog_uri: https://github.com/aki77/ruby-lsp-rails-partial/blob/main/CHANGELOG.md
57
+ rubygems_mfa_required: 'true'
58
+ rdoc_options: []
59
+ require_paths:
60
+ - lib
61
+ required_ruby_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: '3.4'
66
+ required_rubygems_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ requirements: []
72
+ rubygems_version: 4.0.10
73
+ specification_version: 4
74
+ summary: Ruby LSP add-on for Rails partials
75
+ test_files: []