purcell / emacs-reformatter

Define commands which run reformatters on the current Emacs buffer
265 stars 21 forks source link

Allow reformatter to not output stdout #11

Closed edmundmiller closed 5 years ago

edmundmiller commented 5 years ago

I'm having an issue when trying to create a formatter for styler for R.

 MyFile.R ⚠
────────────────────────────────────────
Status  Count   Legend
✔   1   File unchanged.
ℹ   0   File changed.
✖   0   Styling threw an error.
────────────────────────────────────────

Is written to the buffer.

(use-package reformatter
  :config
  (defconst Rscript-command "Rscript")
  (reformatter-define styler
    :program Rscript-command
    :args (list "--vanilla" "-e" (format "styler::style_file(%S)" buffer-file-name))
    :lighter " styler"))

Is there anyway to disable the stdout output?

Thanks!

wbolster commented 5 years ago

the problem is that your use of buffer-file-name violates the assumption made by reformatter.el that the formatter uses stdin/stdout. also this will fail for buffers without a file name, e.g. unsaved buffers.

perhaps you can adapt your snippet to use stdin/stdout instead? it seems you are injecting code so i guess it's possible.

edmundmiller commented 5 years ago

The issue is that's how styler works. styler

I'm looking to utilize the stdin of reformatter, but essentially cancel the stdout.

wbolster commented 5 years ago

while i don't have experience with r programming, i still think this can be made to work, and

that's how styler works

is not enough to convince me otherwise. :wink:

the snippet that your code evaluates calls style_file, but it seems there's also a style_text [1], which you could leverage. basically you want to read stdin, call style_text, print to stdout, and print errors to stderr, then exit with the right error code. this will make reformatter.el happy and make your formatter work in all cases (also for unsaved files, or for snippets of r code inside markdown files, for instance).

[1] https://styler.r-lib.org/reference/style_text.html

edmundmiller commented 5 years ago

I'm thinking this may take more hacking than it's worth, when I could probably just adapt what I have to call the formatter on save with the file name, but to not write it to the buffer.

purcell commented 5 years ago

Yeah, I'm not an R guy, but I agree with @wbolster that it should be trivial, and it'd be nice to figure it out so that other people could benefit from using your code!

The input to readLines defaults to stdin, from what I can see, and '' apparently denotes stdout for write, so something like one of the following should work:

write(style_text(readChar(file('stdin', 'r'), -1)), '')

or

write(style_text(JOINLINES(readLines()), '')

(if there's a JOINLINES or similar)

edmundmiller commented 5 years ago

https://github.com/r-lib/styler/issues/494

edmundmiller commented 5 years ago

https://github.com/Emiller88/doom-emacs-private/blob/6aedee9bb7a5624f1dd63fcd5b6534aad400101a/config.org#reformatter

Got it working with this from the above. It's quite slow it might the way that it's done rather than R being slow. Thanks for the help all!

wbolster commented 5 years ago

cool! it's likely not emacs being slow here, since other reformatter packages use exactly the same approach (see jq-format for an example) and those do not suffer from this.

purcell commented 5 years ago

Got it working with this from the above.

Yay, nice! It'd be pretty trivial to turn this into a little installable Emacs package. Let me know if you need/want pointers for that.

purcell commented 5 years ago

I'd also note (heretically perhaps) that it's generally unnecessary to explicitly close stdin, so for this particular use case you could inline the code a little and omit the "close" call.

purcell commented 4 years ago

FWIW, reformatter.el now supports programs which don't know how to operate on stdin/stdout.