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

VSCode extensions htmx-tags + templ-vscode don't work together. #407

Closed
mdrideout opened this issue Jan 8, 2024 · 6 comments
Closed

VSCode extensions htmx-tags + templ-vscode don't work together. #407

mdrideout opened this issue Jan 8, 2024 · 6 comments

Comments

@mdrideout
Copy link

Is there a way to get the VSCode extension htmx-tags to work with GO + Templ (templ-vscode)? (same issue with Hyperscript extension)

Adding this to my settings.json makes the htmx-tags plugin work on .templ files, however, it breaks the templ-vscode extension's treatment of .templ files.

  "files.associations": {
      "*.templ": "html"
  }

I am not sure if it's on the templ extension to make this compatibility, or if the htmx-tags and hyperscript extensions need to be updated to work with templ files?

@joerdav
Copy link
Collaborator

joerdav commented Jan 9, 2024

I believe that in this issue the solution would be for the htmx/hyperscript extensions to support other filetypes. Potentially not specifically templ, but they could provide a way to configure what files are supported, as I imagine attempting to use these extensions with other templating languages that have their own filetype would suffer the same issue.

@a-h
Copy link
Owner

a-h commented Jan 9, 2024

As a feature of templ, I think the way we'd want to implement it is...

Make templ lsp be able to proxy multiple concurrent LSPs, not just gopls.

The templ parser would need to be updated. At the moment, the templ parser only records the text range position (start line:col to end line:col) for Go expressions so that it can map the templ file range over to the generated Go code range.

However, the templ parser would also need to record the file positions of attributes, elements and other stuff so that it can know when to send messages over to the HTMX, HTML or other LSP (i.e., you're editing text within a generic HTML attribute, or you're editing a HTMX attribute).

It would also need to run a pre-send operation to update the document that the downstream LSP sees. For example, given this file:

package main

func Hello() {
  <div hx::on="something" onClick={ something() }>Content</div>
}

If you're making a change between <div and hx, we'd want to activate the HTML LSP, but instead of sending it the templ file, we'd want to use a textDocument/didChange to simply replace all the non-HTML text with spaces:

  <div hx::on="something"                        >Content</div>

That way, there's no need to re-map file positions between the LSP, which makes it a much easier job, but... to replace the content with spaces requires understanding of their positions in the templ file.

When we start the client LSPs, we could tell it that we can hardly do anything, i.e our capabilities are simple, and disable text formatting and other complex operations.

Doing this sort of thing in the templ lsp command instead of the extension is quite appealing, because then all the editors get the benefit.

There have been some reports of templ users saying that they'd like extra HTML LSP, or Hyperscript LSP, or tailwind LSP etc., but I don't yet understand whether we could get most of the value with a smaller implementation, e.g. we could add all the tailwind CSS names and values as completions in the templ LSP if that's going to help lots of people, and it would be simpler than implementing the proxy. In particular, Same with HTML - do people really want a list of common HTML tags and attribute names? I don't know.

If there's really good value in those other LSPs, then having a generic LSP proxy capability would be a good way to allow people to start experimenting.

When the templ LSP is running, it could alert people that they don't have a specific LSP installed on the path, and if they did, templ could use it, i.e. some sort of probe for files like a tailwind config.

@joerdav
Copy link
Collaborator

joerdav commented Jan 10, 2024

I think in the case of the htmx-tags extension mentioned here, there's no LSP involved. So templ having support for proxying HTML based LSPs wouldn't help.

I still think the only solution here would be for the htmx-tags extension to support more filetypes or have the filetypes be configurable.

Or a templ-htmx-tags fork would do the trick too if the maintainer wasn't open to this change.

@a-h
Copy link
Owner

a-h commented Jan 10, 2024

Oh, I see how the HTMX Tags VS Code extension works now: https://github.com/otovo/htmx-tags/blob/main/package.json

In this file, it "contributes" the data to support the extra attributes: https://github.com/otovo/htmx-tags/blob/main/package.json

This is something specific to the VS Code HTML support: https://code.visualstudio.com/api/extension-guides/custom-data-extension

So, you can plug lots of things into the base VS Code HTML support, e.g. bootstrap styles, or HTMX attributes.

So, I don't know if the htmx-tags extension could "support" templ files. I wonder if templ-vscode can tell VS Code that sections of the file are HTML, and therefore to use its standard HTML behaviour, and get all this stuff for free.

Not sure... would be good to get some help from the VS Code team on the best approach.

@kanutron
Copy link

I managed to have a working setup in VSCode where I can get auto-completions for:

  • TailwindCSS classes (at least the built-in ones) using a config setup of the official Tailwind Intellisense plugin.
  • HTMX attributes using another plugin with a very similar approach to htmx-tags.
  • AlpineJS attributes using a non-official plugin that demonstrates something very interesting discussed below.

The good point is that plugins can let the user choose which file formats or scopes to apply the provided customizations (as demonstrated below).

Instructions to get my setup:

TailwindCSS

For TailwindCSS official plugin to be active in the HTML scope of *.templ files, add this in settings.json:

    "tailwindCSS.includeLanguages": {
      "templ": "html"
    },

I don't know yet (not tested) if this also provides auto-completions of custom classes.

HTMX

I like the auto-completions of the plugin you just referenced named htmx-tags. But it doesn't apply to *.templ files nor allows the user to specify that option.

However, there is an alternative plugin named HTMX Atrributes that out-fo-the-box applies the customizations into the HTML scope of *.templ files among others. That is not configurable either, but at least it works.

AlpineJS Intellisense

Similarly to the plugin htmx-tags, the official AlpineJS Intellisesne plugin doesn't apply the customizations into *.templ files and does not allow users to configure that, however, there is an alternative plugin that confusingly enough, has the same name here.

That one has an option to set this in your settings.json:

"alpine-intellisense.settings.languageScopes": "html, templ", // adding templ have the desired impact

And it works well in my *.templ files.

In their documentation, they say:

alpine-intellisense.settings.languageScopes: Defines the language scopes for which the snippets will be available. Use comma separated values. For example: html,php,twig,nunjucks. Default is html.

Conclusion

Plugins can let users choose in which scopes they are activated like TailwindCSS and the alternative AlpineJS plugins do. So, we could propose a change in htmx-tags and the official AlpineJS to let the user add scopes where they want those plugins to be activated (in our case, ´templ´)

templ-vscode is currently well-implemented IMHO and doing a proxy and stuff like that is, or it could be an over-complication.

@joerdav
Copy link
Collaborator

joerdav commented Jan 30, 2024

Closing with the recommendation of the HTMX-Attributes plugin, or a change on htmx-tags to allow confugurable filetypes.

@joerdav joerdav closed this as completed Jan 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants