Open benfrain opened 6 years ago
No, this is not supported
If you open up ~/ .vscode/extensions/bierner.lit-html-1.2.0/syntaxes/lit-html.json and change line 18 to be this: "begin": "(`\\s\<!--.-->)", Then you can do things like this
return `<!--html-->
<div class="mb-Summary" data-mb-controls="${idx}" aria-selected="${data.summarySelected}">
<a class="mb-Summary_TitleAndStatus">
<h2 class="mb-Summary_Title">${data.Stake} ${data.Type}</h2>
</a>
</div>
`
You can also change \ to something like \ so it will be more specific. You will have to make that change each time the plugin updates, but it works well for me.
@lancetipton04 I changed my json file slightly different from yours to get it working for me:
// Original
"begin": "(?x)(\\s+?(\\w+\\.)?(?:html|raw)\\s*)(`)",
// My change
"begin": "(?x)(\\s+?(`)(?:<!--.*-->)\\s*)",
any reason why the following wouldn't work for any template literal that contains HTML?
"begin": "(?x)(\\s+?(`)(?:[\\n\\s]*<[a-zA-Z!]))"
FWIW, I've landed a PR to relax this parser: https://github.com/mjbvz/vscode-lit-html/pull/21
@WebReflection the code in your PR #21 works great to allow any html template string! Thanks.
"begin": "(?x)(\\s+?(\\w+\\.)?(?:html|raw|render)\\s*)?(`)(?=$|\\s*<[a-zA-Z!])",
@BBlackwo watch out that RegExp is wrong. My ideal scenario is to use the followed by but that RegExp assumes any template literal that starts with a new line is HTML, which is not the case.
The latest version in literally-html is better and it's been tested with both hyperHTML and lit-html.
This enables syntax highlighting for almost any template literal containing one or more HTML tag, regardless of whether it's single or multi-line:
"begin": "(`)(?=$|[\\s\\S]*<[a-zA-Z][\\s\\S]*>[\\s\\S]*)",
@neilrackett I think that has exact same issue with new lines, handling as HTML even regular text
Everything we've tried so far works without any problems, with the exception of multi-line template literals that have text on the first line that doesn't contain a tag, e.g.
let foo = `this
doesn't
<b>work</b>
`;
but
let foo = `
but
this
<b>works just fine</b>
`;
Everything we've tried so far works without any problems
the problem is that you are switching to HTML highlight even regular multiline text ... if that's your cup of tea, good for you.
Please, make this work with innerHTML
:
const template = document.createElement('template')
template.innerHTML = `
<pre>Highlight here</pre>
`
Even GitHub highlights it 🙂
innerHTML
and also outerHTML
please :)
I've succeeded to highlight html, but without intellisense. I suppose that typescript-lit-html-plugin just works for tagged template literals.
To enable HTML highlighting for all template literals, you could use something like this in lit-html.json
:
"begin": "(`)"
how about something like this
return /* html */`
<h2>foo</h2>
`;
that is at least how it works in es6-string-html
how about something like this
return /* html */` <h2>foo</h2> `;
that is at least how it works in es6-string-html
Matt has already an extension that does that bierner.comment-tagged-templates. No intellisense tho.
as a workaround, for now, we can fool the highlighter by using a tagged-template function named "html" that actually doesn't do anything at all
const html = (strings, ...values) => {
let result = ""
strings.forEach((string, index) => {
result += string + (values[index] || "");
})
return result
}
thus we can
return html`<div awesome>cool</div>`
edit: see later incarnation of template-noop.ts
below
@chase-moskal you can use i18n-dummy if you need a no-op for template literals.
const html = require('i18n-dummy');
that's it
edit
actually, I've just published dummy-tag for this very unique purpose (since it's more common that I've thought)
how about something like this
return /* html */` <h2>foo</h2> `;
that is at least how it works in es6-string-html
This is how it works now, so this issue should be closed.
Some kind of comment tag would be a good solution although supporting custom patterns would be even better. This would enable support for something like inline Angular templates by adding a custom pattern to match against template: `
.
@iansan5653
This is how it works now, so this issue should be closed.
It does not work for me like this - how did you get it to work with a comment? Any more settings required?
@falco467 I'm not sure anymore - I haven't used this in a long time and it doesn't seem to work now. It's possible that I may have been using a different extension; I'm not sure.
@WebReflection, @benfrain, @mjbvz, @nicolasparada, @falco467 — hey all you silly geese!
isn't it obvious enough that a template noop is proper the answer? :rofl:
template-noop.ts
export function noop(strings: TemplateStringsArray, ...keys: any[]) {
const lastIndex = strings.length - 1
return strings
.slice(0, lastIndex)
.reduce((a, b, c) => a + b + keys[c], "")
+ strings[lastIndex]
}
whatever.ts
import {noop as html} from "./template-noop.js"
document.body.innerHTML = html`
<h1>tada!</h1>
`
i've been doing this a long while, works like a charm, this should be the official answer
all the comment-based regex hacking madness above is making my tummy grumble!
:tumbler_glass: /thread
edit: ahahah, i already posted this technique but nobody noticed it, self included... or maybe the way i didn't explain it before was too tricky to get your grippers on XD
@chase-moskal that's dummy-tag which I've linked already
i know, but you and i are the only ones who noticed that this issue is resolved and has a good answer :)
it can be closed, but a note in the readme would be good, if there isn't one already
@chase-moskal I saw your answer and I've been using this Work-Around for a while. But it's a silly function/dependency I have to include and document in every project - and the doc of the function says "this noop dummy function is a necessary Work-Around for a particular vs-code extension, see bug *link to this issue"
I agree this is a workaround, but a real solution would either work with a comment / html / or by recognizing the variable name or even peeking the content of the literal - without needing changes in the code.
An additional noop function is irritating to other developers and a potential source of errors. And a single extension used by some developers on a single IDE should not require code changes in a big project.
@falco467, @diminutivesloop -- noop is more elegant, i no longer consider it a workaround. it's the correct answer, and it's great, and i have a concrete argument for why you should reconsider
it's refactorable. you see, the noop buys us an ability to more cleanly bring in new features without even having to refactor every line we had used the templates. it's a slight thing, but if you keep looking at this from different angles, the conceptual elegance of the noop starts to shine through. stay with me here
it's actually an interesting and desirable pattern, to use noops wherever this principal makes sense. we should use template noop's anywhere we're embedding any structured string information, like little dsl's that we could identify and enhance later. here's a great example
import {noop as csv} from "../toolbox/template-noop.js"
whatever.lol = csv`
name,value,occupation
jim,1x,frontend
chase,10x,fullstack
`
then in the future, we might replace the csv
noop with a real implementation which performs validation for the csv format. this is a great pattern because it can make refactoring easy. it's hot-swappable, it's a stand-in. great pattern
and so we have a similar attitude for the html
noop. it's a stand-in for whatever future functionality we might want to refactor in. this extension can hitch a ride on this convention to apply highlighting. it's great!
i know you're bummed about an extra module. maybe template noop should have been a new javascript builtin and you'd feel better about it. but let's face it, we always have a little toolbox of tiny functions like these anyways. you certainly can't avoid 'em
honestly friend, gross comment-hacks to influence syntax highlighting? magic variable names? think about it some more through this lens, i really think it's a show-stopper gotchya, and you'll have to reluctantly agree:
and now another important point,
And a single extension used by some developers on a single IDE should not require code changes in a big project.
oh dear, friend, i see you have it exactly backwards.
you see, it's in fact the noop which best disappears into regular-looking javascript syntax. your coworkers are likely to not even notice anything funny about the noop. html
is a conventional name for a block of html markup, and the implementation is ready for swapping
on the other hand: comment-hacking or magic variables? now THAT is putting an ugly imposition onto your coworkers. if they aren't using the extension, will honestly say "what the hell is this gross comment?" and likely just delete it. i mean just think about it
// from the perspective of somebody without the extension and no knowledge of it
// you think this is going to fly on a real team?
// it looks identical to one of those ridiculous comments that must be deleted
// it is seriously indistinguishable from a mistake that should be cleaned up
return /* html */ `
<div></div>
`
// this makes sense. natural template syntax. it's even functionally valuable
return html`
<div></div>
`
my teams have always had a policy against "silly" comments that don't really explain anything. i don't know about your policy, but these comment hacks are indistinguishable from those silly comments that we regularly seek and destroy
mull it over and make the right choice. fall on the right side of history here, and your coworkers will thank you :tumbler_glass:
i'll also point out that somehow or another, github is syntax highlighting this the correct way. awesome! things are on the right track right now. this is a good convention, and as i explained, using noops actually have legitimate functional qualities for refactorability
slick and cool
const lol = html`<div github="supports">the highligting</div>`
gross and bunk
const lol = /* html */ `<div github="supports">the highligting</div>`
praise the lord :raised_hands:
/thread
FWIW, I kinda agree a noop is the solution, and it's not more workaround than a comment that cannot be removed. It's actually declarative, and it works in every situation.
import css from 'dummy-tag';
import html from 'dummy-tag';
const style = css`
body {
color: green;
}
`;
const node = html`
<div>hello world</div>
`;
The current dummy-tag is 97 bytes minified (but not gzipped), which is so irrelevant, that once gzipped it weights more (107).
The only caveat is Babel targeting IE, which would create some bloat that, however, will not be a big deal once minified and gzipped.
P.S. I'm proposing a String.tag
function in ES Discuss, but they pointed out that String.raw
might be already a good compromise, although it's footgun ish because of the implicit escape.
const html = String.raw;
const css = String.raw;
const style = css`
body {
color: green;
}
`;
const node = html`
<div>hello world</div>
`;
This requires zero dependencies, except, eventually, a String.raw
polyfill.
My main concern about being a footgun, is transpiled code, or parts with \n
chars, where these would be part of the output too.
Dare I say const tag = (raw, ...values) => String.raw({raw}, ...values);
might be it, but having it native would be nice.
This extension could support cu
how about something like this
return /* html */` <h2>foo</h2> `;
that is at least how it works in es6-string-html
This still would be the best solution for this. The question is, how to make it work for intellisense?
This syntax highlight can be achieved by something like
"begin": "(/\\*html\\*/\\ `)",
Should this be working with non-tagged template literals?
For example, running insiders 1.20 and a ts file including the following I don't get any syntax highlighting:
Should that work?