Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lsp: Support goToDefinition from a Go file to a templ file #387

Open
guettli opened this issue Jan 2, 2024 · 7 comments
Open

lsp: Support goToDefinition from a Go file to a templ file #387

guettli opened this issue Jan 2, 2024 · 7 comments
Labels
enhancement New feature or request lsp NeedsFix Needs implementing

Comments

@guettli
Copy link
Contributor

guettli commented Jan 2, 2024

If I ctrl-click on page() then ...

image

then I get to the autogenerated Go code:

image

It would be great if I could get to the templ-file instead:

image

@a-h
Copy link
Owner

a-h commented Jan 2, 2024

Yes, that would be much more useful!

If you're in a *.templ file, then the templ LSP is operating and will carry out a remapping operation from templ position -> go file position -> gopls -> templ position, as per here:

for i := 0; i < len(result); i++ {
if isTemplGoFile, templURI := convertTemplGoToTemplURI(result[i].URI); isTemplGoFile {
result[i].URI = templURI
result[i].Range = p.convertGoRangeToTemplRange(templURI, result[i].Range)
}
}

But currently, if you start from a *.go file, then gopls is operating and there's no templ code running at all. To rewrite the responses from gopls, templ would have to proxy all Go LSP operations (i.e. for all *.go files) and work out that if a _templ.go file was being referenced, then, it should look up the various source code mapping positions and switch it to *.templ instead. I'm not sure if replacing (as a proxy) gopls for all projects is ideal (higher risk?), but it would work.

It may also possible for the templ LSP to capture *_templ.go file usage too, and be able to ctrl+click on the function name to get to the *.templ file. (Worse UX, but maybe a good first step)

@joerdav
Copy link
Collaborator

joerdav commented Jan 3, 2024

I know you can have multiple LSPs attached to a file, but I wonder what would happen if you had 2 trying to respond to a jump to definition request.

@guettli
Copy link
Contributor Author

guettli commented Jan 7, 2024

I asked the gopls maintainers. Maybe they know a hook which templ could implement: golang/go#65001

@joerdav joerdav changed the title Hyperlink from Go code to templ file. lsp: Support goToDefinition from a Go file to a templ file Jan 30, 2024
@joerdav joerdav added enhancement New feature or request lsp NeedsFix Needs implementing labels Jan 30, 2024
@joerdav
Copy link
Collaborator

joerdav commented Jan 30, 2024

We have the following issue to implement the line directive #415, and then I think it's a case of closing this ticket and helping the gopls team implement golang/go#65001

@guettli
Copy link
Contributor Author

guettli commented Jan 31, 2024

@joerdav thank you for your work! This is great!

@joerdav
Copy link
Collaborator

joerdav commented Jan 31, 2024

Thank @af-md !

@meistertigran
Copy link

Here's a quick and dirty fix for anyone using neovim. It doesn't go directly to the location of the definition in the file, but at least it opens the correct file.

local go_to_definition = function()
    if vim.bo.filetype == "go" then
        vim.lsp.buf.definition({
            on_list = function(options)
                if options == nil or options.items == nil or #options.items == 0 then
                    return
                end

                local targetFile = options.items[1].filename
                local prefix = string.match(targetFile, "(.-)_templ%.go$")

                if prefix then
                    options.items[1].filename = prefix .. ".templ"
                end

                vim.fn.setqflist({}, ' ', options)
                vim.api.nvim_command('cfirst')
            end
        })
    else
        vim.lsp.buf.definition()
    end
end

and then in your key map

vim.keymap.set("n", "gd", go_to_definition)

Note that the check for being in a go buffer will run every time you try to go to definition. You probably would want to add this modification only if you are using templ a lot and should remember to remove it once the actual fix is implemented.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request lsp NeedsFix Needs implementing
Projects
None yet
Development

No branches or pull requests

4 participants