VSCode extensions htmx-tags + templ-vscode don't work together.
mdrideout opened this issue · 6 comments
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?
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.
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.
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.
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.
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.
Closing with the recommendation of the HTMX-Attributes plugin, or a change on htmx-tags to allow confugurable filetypes.