Implement "go to definition" for render calls in ERB templates#659
Open
janko wants to merge 4 commits intoShopify:mainfrom
Open
Implement "go to definition" for render calls in ERB templates#659janko wants to merge 4 commits intoShopify:mainfrom
render calls in ERB templates#659janko wants to merge 4 commits intoShopify:mainfrom
Conversation
It's common to want to traverse through several partials while updating HTML that a controller action renders. Rails.vim has a neat `gf` shortcut for this, though it probably doesn't have the precision that Prism would provide. This brings the same functionality to Ruby LSP Rails, by implementing "go to definition" support for render calls inside ERB templates. It supports partial name passed as positional argument, or via `:partial`, `:layout`, and `:spacer_template` keyword arguments. It even handles `:variants`, `:formats`, and `:handlers` options, as well as `:template` for rendering non-partial templates. Relative lookup will also check in view directories of controller ancestors. For the latter, I considered doing a call to the Rails process that will return `ActionController::Base._prefixes`. However, I couldn't think of a good enough interface, and that method ableit public is undocumented, so it seems like we shouldn't rely on it. Given that this ancestry lookup is non-configurable anyway, I chose to implement it in Ruby LSP land based on indexed controller files. To avoid the overhead of booting the Rails process too many times in tests, I updated the test helpers to allow sending multiple `textDocument/definition` requests to the same server.
Member
rafaelfranca
left a comment
There was a problem hiding this comment.
Made a few comments. Typechecker is failing and new methods are missing typing information.
Also add missing type annotations.
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.
Contributor
Author
|
@rafaelfranca I believe I addressed all your feedback and fixed typechecking. |
rafaelfranca
approved these changes
Nov 5, 2025
Member
rafaelfranca
left a comment
There was a problem hiding this comment.
Amazing work!
@Shopify/ruby-dx can someone do a second review?
Contributor
Author
|
I have signed the CLA! |
In our app, we have an `app/views/shared/components` directory that contains shared "component" partials. It doesn't have any matching controller, and components can render other components, you just need to specify the full path to the render call (we have a helper method for that). We should make go to definition work for these cases as well.
|
Very cool feature! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
It's common to want to traverse through several partials while updating HTML that a controller action renders. Rails.vim has a neat
gfshortcut for this. This brings the same functionality to Ruby LSP Rails, by implementing "go to definition" support forrendercalls inside ERB templates.Screen.Recording.2025-10-28.at.21.08.51.mov
It supports partial name passed as positional argument, or via
:partial,:layout, and:spacer_templatekeyword arguments. It even handles:variants,:formats, and:handlersoptions, as well as:templatefor rendering non-partial templates.The initial implementation mimicked the template lookup logic inside the language server. However, that turned out to be more complex and didn't handle custom
view_paths. So, I ended up callingActionView::LookupContextto perform the actual template lookup on the server. I also needed to determine the controller from the template directory in a way that handles customview_paths, as well as handle controllerless template directories.To avoid the overhead of booting the Rails process too many times in tests, I updated the test helpers to allow sending multiple
textDocument/definitionrequests to the same server.