Thom1729 / Sublime-JS-Custom

Customizable JavaScript syntax highlighting for Sublime Text.
MIT License
137 stars 9 forks source link

Full regex support in lookaheads (or at least \n and \s) #134

Closed nianiam closed 1 year ago

nianiam commented 2 years ago

Sometimes, for the sake of formatting my code to look nice, I like to add a new line immediately after the template literal tick. For example:

const test = await client.query(`
  select * from test
`)

Obviously this simple example does not need the new line (or I could have escaped before the tick), but larger queries often do to maintain alignment. No matter what I try, I cannot get the lookahead to match the whitespace because \s results in a JSCustom error "invalid escape character" .

I have tried "[\n\t ]*select" which will happily match spaces and tabs, but not the new line.

Also, your example in the config settings select\b does not match a template string select 1 from dual.

I find it strange that some regex works, but others don't. Personally, whitespace matching would solve my problem, but it seems sensible to parse all valid regex.

Thom1729 commented 2 years ago

The "select\b" problem is a documentation bug. JSON will try to interpret backslash escapes before JS Custom even sees them: \b means the backspace character, and \s isn't a valid JSON escape sequence at all. You have to double-escape, e.g. "select\\b". I have fixed the broken example.

(In a perfect world, there might be better error handling for this, but it might be difficult since settings parsing is handled by Sublime itself, and JS Custom only gets the values after the settings have been successfully parsed.)

The multiline template isn't working because JS Custom checks the lookahead right before the backtick, and Sublime only parses one line at a time. I can see how this is inconvenient. The best solution would probably be checking the lookahead at the first non-whitespace content of the template. I don't think this would be too hard to implement, and I'll take a whack at it for the next version.

nianiam commented 2 years ago

Perhaps a short note in the docs about this restriction and using double-escape to circumnavigate would be helpful (in case people are doing more complex regex matching).

Ignoring the whitespace makes sense, I can't think of a reason why whitespace at the start of a literal would actually be functional.

Thom1729 commented 2 years ago

@nianiam The first 4.3.0 beta is out. It should handle your example.

nianiam commented 2 years ago

Sorry for the slow reply and excuse my ignorance, but I'm not sure how to install the beta.

What I am doing:

  1. Download the beta release .zip and renaming the file extension to .sublime-package
  2. Use the command palette to Browse Packages
  3. Replace the regular install with the beta in the Installed Packages folder.

This doesn't seem to change anything, the packages shows without a version and description if I list packages and it refuses to open the settings. Obviously I am doing something wrong here, but I am not sure what.

Thom1729 commented 2 years ago

There's an easy way: in your Package Control settings, add:

"install_prereleases": [ "JSCustom"]

Or add "JSCustom" to the array if it already exists.

nianiam commented 2 years ago

Great thanks, got it installed and the update is handling my example.

I don't know if it's worth opening another issue, but I was also wondering whether it might be possible to change the colour_scheme per tag, lookahead etc?

Thom1729 commented 2 years ago

If by color scheme you mean the Sublime color scheme, like Monokai, then unfortunately that is not possible. Color schemes are set per view, and different parts of the same view cannot have different color schemes.

nianiam commented 2 years ago

That’s a shame. Having the literals all in one colour made it easy to recognise where they were in the code. Having syntax highlighting is obviously better, but I did appreciate being able to quickly scan a document for them.

Thom1729 commented 2 years ago

It's probably possible one way or another to give detected template literals a colored background. If that's what you want, let me know and I'll work up an example.

nianiam commented 2 years ago

Having some way of highlighting the literals would be very useful. A background would certainly work.

A similar set of preferences to scope would also be good: a default background, per tag/lookahead setting etc

Thom1729 commented 2 years ago

I wrote up a quick example plugin that highlights all template literals red:

import sublime_plugin

class JsTemplateRegionsListener(sublime_plugin.ViewEventListener):
    def on_modified_async(self):
        if self.view.match_selector(0, 'source.js'):
            regions = self.view.find_by_selector('meta.string - string.quoted.single - string.quoted.double')
            self.view.add_regions('JsTemplateRegionsListener', regions, scope="region.redish")
        else:
            self.view.erase_regions('JsTemplateRegionsListener')

It's just a first pass and might not perform well, but it should basically work.