Skip to content

Commit 79213e3

Browse files
committed
Handle custom view paths of controller subclasses
While here, we undo changes in code lens to handle custom view paths. If this approach is accepted, we can always update the code lens later.
1 parent 1dd9370 commit 79213e3

File tree

3 files changed

+41
-18
lines changed

3 files changed

+41
-18
lines changed

lib/ruby_lsp/ruby_lsp_rails/code_lens.rb

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -194,14 +194,7 @@ def add_jump_to_view(node)
194194
action_name = node.name
195195
controller_name = underscore(class_name.delete_suffix("Controller"))
196196

197-
controller_info = @client.controller(class_name)
198-
return unless controller_info
199-
200-
view_paths = controller_info[:view_paths].select do |path|
201-
path.start_with?(@client.rails_root)
202-
end
203-
204-
view_uris = Dir.glob("{#{view_paths.join(",")}}/#{controller_name}/#{action_name}*").filter_map do |path|
197+
view_uris = Dir.glob("#{@client.rails_root}/app/views/#{controller_name}/#{action_name}*").filter_map do |path|
205198
# it's possible we could have a directory with the same name as the action, so we need to skip those
206199
next if File.directory?(path)
207200

lib/ruby_lsp/ruby_lsp_rails/definition.rb

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
# typed: strict
22
# frozen_string_literal: true
33

4+
require "pathname"
5+
46
module RubyLsp
57
module Rails
68
# ![Definition demo](../../definition.gif)
@@ -280,20 +282,27 @@ def view_template_details(arguments)
280282
end
281283
end
282284

285+
# Determine controller name for given template path by matching segments
286+
# of its directory path to controller paths and checking if the controllers'
287+
# view paths complete the rest of the template directory path.
288+
#
283289
#: (String template_path) -> String?
284290
def controller_for_template(template_path)
285-
controller_info = @client.controller("ActionController::Base")
286-
return unless controller_info
287-
288-
view_paths = controller_info[:view_paths]
289-
template_directory = File.dirname(template_path)
290-
291-
view_path = view_paths.find { |path| template_directory.start_with?(path + "/") }
292-
return unless view_path
291+
template_directory = Pathname(template_path).dirname.relative_path_from(@client.rails_root)
292+
directory_segments = template_directory.each_filename.to_a
293+
possible_controller_paths = (1..directory_segments.count).map do |n|
294+
directory_segments.last(n).join("/")
295+
end
293296

294-
controller_path = template_directory.delete_prefix(view_path + "/")
297+
controller_path = possible_controller_paths.find do |controller_path|
298+
controller_name = camelize(controller_path) + "Controller"
299+
view_paths = @client.controller(controller_name)&.dig(:view_paths) || []
300+
view_paths.any? do |view_path|
301+
File.join(view_path, controller_path) == File.dirname(template_path)
302+
end
303+
end
295304

296-
camelize(controller_path) + "Controller"
305+
camelize(controller_path) + "Controller" if controller_path
297306
end
298307
end
299308
end

test/ruby_lsp_rails/definition_test.rb

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,27 @@ def name; end
503503
FileUtils.rm("#{dummy_root}/app/views/users/_partial.html.erb")
504504
end
505505

506+
test "handles custom view paths" do
507+
FileUtils.mkdir_p("#{dummy_root}/app/custom/views/admin")
508+
FileUtils.touch("#{dummy_root}/app/custom/views/admin/_partial.html.erb")
509+
File.write("#{dummy_root}/app/controllers/admin_controller.rb", <<~RUBY)
510+
class AdminController < ApplicationController
511+
prepend_view_path "#{dummy_root}/app/custom/views"
512+
end
513+
RUBY
514+
515+
uri = Kernel.URI("file://#{dummy_root}/app/custom/views/admin/render.html.erb")
516+
source = <<~ERB
517+
<%= render "partial" %>
518+
ERB
519+
520+
response = generate_definitions_for_source(source, { line: 0, character: 12 }, uri)
521+
assert_equal("file://#{dummy_root}/app/custom/views/admin/_partial.html.erb", response.first.uri)
522+
ensure
523+
FileUtils.rm_r("#{dummy_root}/app/custom/views/admin")
524+
FileUtils.rm("#{dummy_root}/app/controllers/admin_controller.rb")
525+
end
526+
506527
test "handles template formats, variants and handlers" do
507528
FileUtils.touch("#{dummy_root}/app/views/users/_partial.html.erb")
508529
FileUtils.touch("#{dummy_root}/app/views/users/_partial.text.erb")

0 commit comments

Comments
 (0)