prettier / prettier-emacs

Minor mode to format JS code on file save
http://jlongster.com/A-Prettier-Formatter
372 stars 53 forks source link

Add support for vue files. #3

Closed giodamelio closed 7 years ago

giodamelio commented 7 years ago

I would love it if this package could suppord .vue files. Basically a file looks like this, and all the JS is in the script tags. I took a look at the code, but my elisp chops simply aren't that good.

<template>
  <h1>Hello World!</h1>
</template>

<script>
const a = "hhhha"
</script>

<style>
</style>
rcoedo commented 7 years ago

Hello @giodamelio

This package is a wrapper around https://github.com/prettier/prettier, so we can support vue if they add the feature. Could you move this issue to the main repository?

Thanks!

giodamelio commented 7 years ago

There are some issues (prettier/prettier#1882, prettier/prettier#1674 and prettier/prettier#651) related to it on the prettier side, but there is some question as to weather this should be supported in prettier itself or in the editor integration layer. As far as I understand it, right now prettier parses the entire input file with it's JS parser, so it would take a decent amount of work to make this happen. I was thinking it might be easier to handle it at the editor level, at least until prettier figures out what is going to happen.

rcoedo commented 7 years ago

Since Prettier supports JSX syntax, we can't just skip tags, so this is not trivial.

Prettier already has a --parser flag that is used to specify what parser to use (flow, babel, typescript or postcss are currently supported). In my humble opinion, this would be the right way to support Vue.

For now, what we can do here is make a new function prettier-js-region that uses the --range-start and --range-end flags. Would this help?

giodamelio commented 7 years ago

I tried the --range-start and --range-end flags, but because of some changes (see prettier/prettier#1659 and this) prettier tries to parse the whole file first.

I was thinking about somehow grabbing just the JS out, sending it to prettier via stdin then replacing the original with the output, not sure how well that would work with emacs though.

rcoedo commented 7 years ago

Grabbing the JS out is a really hard task because there is a lot of mixed syntax already. Prettier supports JSX (embedded html tags inside javascript) and Postcss. In this case I think the best option would be to make a new parser in the tool itself.

About the --range-start and --range-end, I think we can work that problem out. Currently, this package writes the buffer to a temporal file and then invokes prettier. I think we can make another function that just sends the region to that temporal file and then do the rest of the stuff.

I'll do some experiments. Thanks!

giodamelio commented 7 years ago

Awesome, Thanks so much for working on this. I have only been using prettier for a few days, and I already miss it pretty hard.

rcoedo commented 7 years ago

I did some refactors and I added the prettier-js-prettify-region here cf95226fd83e80e54ba91071591ea378ccb74c68. For now, I will keep it in a separate branch until we test it out.

There is a couple of caveats though:

Binding this function to your keyboard and using a package like expand-region may cover your use case until we can improve it.

I hope this helps!

giodamelio commented 7 years ago

Wow, that was fast. This is works great.

One thing though, I can't get it to follow prettier-js--prettier-args anymore. It's probably because of the weird way I am loading this directly from a file. Not sure exactly what is happening, and I have been banging my head against the wall trying to get it to work. It's probably not a bug, but I though I'd mention it anyways.

rcoedo commented 7 years ago

I will be traveling and I'll be back next Tuesday. If you know some elisp I encourage you to take a look at the code, it is quite simple. Otherwise this will have to wait until then.

Sorry! πŸ˜₯

giodamelio commented 7 years ago

No problem at all, thanks again for all your fantastic and speedy work.

rcoedo commented 7 years ago

I've been thinking, can you check the readme again? There has been some refactors to publish the package in Melpa and maybe you have an outdated configuration ☺️

giodamelio commented 7 years ago

Dam, the config var name changed and I didn't notice! Everything is working great now. Thanks again.

rcoedo commented 7 years ago

Cheers! 🍻

giodamelio commented 7 years ago

For anyone that finds this looking for vue support, here is my cobbled together, probably bug ridden function to format all the JS in between a set of script tags in a file. It's very sensitive to things like white space.

(defun prettier-vue ()
  (interactive)
  (let ((original (point)))
    (goto-char 0)
    (let* ((script-start (re-search-forward "<script>" nil t))
           (start (+ script-start 1))
           (script-end (re-search-forward "</script>" nil t))
           (end (- script-end 10)))
      (prettier-js--prettify start end)
      (goto-char original))))
azz commented 7 years ago

FYI, work is in progress in prettier to natively support Vue.js: prettier/prettier#2086

nickmccurdy commented 6 years ago

@giodamelio This was released in Prettier 1.5.0. πŸ˜„ Does this fix it for you or is a patch for this package still necessary?

giodamelio commented 6 years ago

That's awesome to hear! I haven't been working with Vue lately, so I'll just assume it works until I try it again.