bcomnes / sublime-standard-format

:sparkles: Runs standard --fix against the javascript in your ST3 window on save or manually.
https://packagecontrol.io/packages/StandardFormat
MIT License
60 stars 21 forks source link

Added functionality to only send a script-tag's content to standard --fix. #59

Closed johannes-z closed 7 years ago

johannes-z commented 7 years ago

I added two new options that are used to pass inline script tags to standard rather than the whole file which then would fail.

Settings changes:

Exposes one new setting, selectors. If the file is of any type of extensions it will try to get the selector for that extension. selector defines a scope that's used to get the region's content. This is, e.g., source.js.embedded.html for the html syntax.

Remark: The default settings could already include the html and selector, but I wasn't sure if this was desired.

References #58

johannes-z commented 7 years ago

An exemplary config might look like this:

{
  "format_on_save": false,
  "extensions": ["js", "html", "vue"],
  "commands": [
    ["standard", "--stdin", "--fix"]
  ],
  "selectors": {
    "html": "source.js.embedded.html",
    "vue": "source.js.embedded.html"
  }
}
johannes-z commented 7 years ago

@bcomnes Sorry for the impatience, but are you going to merge this PR?

bcomnes commented 7 years ago

My apologies, busy over the holidays I will look at this now.

bcomnes commented 7 years ago

Looks like this works from what I can tell. The only issue is that it removes whitespace before the closing html script tag. Maybe capture the last /n[whitespace] and add it back on the end when formatting in a contained in html?

johannes-z commented 7 years ago

Hm, when I format a html with a script tag, it doesn't remove the last whitespace. Can you provide a file where this happens for you?

bcomnes commented 7 years ago
<!DOCTYPE html>
<html>
<head>
  <title>hi</title>
</head>
<body>
  <script type="text/javascript">
    console.log('beep')
  </script>
</body>
</html>

formats to

<!DOCTYPE html>
<html>
<head>
  <title>hi</title>
</head>
<body>
  <script type="text/javascript">
    console.log('beep')

</script>
</body>
</html>
johannes-z commented 7 years ago

Hm this isn't trivial. What I came up with is a regex to get the indention of the closing </script> tag, and restore it after the format command has been executed.

lastLine = re.search('([^\n]*\s)$', s).group(0)

To get rid of the last extra line I was thinking of removing the last line, so I was doing something like this:

        s, err = standard_format(s, command)
        if not err and len(s) > 0:
            s = s[:-1]
            s += lastLine
            view.replace(edit, region, s)

It worked for the trivial test you sent me, and I can't think of any case where this wouldn't work...

What clearly doesn't work though is if you have more than one script tag that's being processed. If something changes in the first script tag, the second format command is run with the old region location, resulting in some errors... A workaround would be to return the character changes of the current format command (old string - new string) and use this to update the region location for the next region. Any ideas?

bcomnes commented 7 years ago

I haven't had a chance to think to deeply about it yet. How about we merge this as is, and make this opt in behavior by default at the moment:

{
  "format_on_save": false,
  "extensions": ["js"],
  "commands": [
    ["standard", "--stdin", "--fix"]
  ],
  "selectors": {
    "html": "source.js.embedded.html",
    "vue": "source.js.embedded.html"
  }
}

One would enable it by overriding extensions with "extensions": ["js", "html", "vue"], in their user preferences.

johannes-z commented 7 years ago

Sure, this behaviour was already added in #59. We can come back at this, as soon as we come up with something clever :smile:

bcomnes commented 7 years ago

Can you add in

"selectors": {
    "html": "source.js.embedded.html",
    "vue": "source.js.embedded.html"
  }

to the default preferences?

bcomnes commented 7 years ago

Ok looks good! Thanks for your work 👍

bcomnes commented 7 years ago

I'll cut a release this afternoon.