sbdchd / neoformat

:sparkles: A (Neo)vim plugin for formatting code.
BSD 2-Clause "Simplified" License
1.98k stars 187 forks source link

Make it possible to see error messages from formatters #71

Open pmorch opened 7 years ago

pmorch commented 7 years ago

If I run Neoformat! javascript prettier on a snippet with an syntax error, I get the not so helpful message:

Neoformat: attempted all formatters for current filetype

but the actual error is not visible anywhere. I can see in function! s:neoformat() in neoformat.vim that it does this inside the loop where it tries all the formatters, so if any are outright missing then I understand we of course don't want to see error messages about that. But I would've liked to see the actual reason for the formatting error and that it is in line X...

I've noticed that if there are errors in the input for e.g. vanilla javascript prettier, it prints error information to stderr and then exits with exit code 2:

londo@peter:~> cat /tmp/ost.js 
    if (true) {
    doSomething();
    <%= template().stuff() %>
    }
londo@peter:~> prettier /tmp/ost.js 

/tmp/ost.js: SyntaxError: Unexpected token (3:5)
  1 |     if (true) {
  2 |     doSomething();
> 3 |     <%= template().stuff() %>
    |      ^
  4 |     }
  5 | 
londo@peter:~> echo $?
2

(The actual use-case is a formatting a tiny selection in a larger file, so to actually get the error message, I have to copy the selection to another file, save it, open a terminal, run prettier manually. Not fun.)

Workaround

I noticed that perltidy for perl files just showed any formatting errors inline as a result. That was because perltidy has an exit code of 0 regardless of any errors. (Which definitely could be problematic for other reasons...).

But this led me to create a tiny wrapper script, prettier_noerror:

#!/bin/bash
prettier "$@"
exit 0

And this in .vimrc:

let g:neoformat_javascript_prettier = {
            \ 'exe': '/path/to/prettier_noerror',
            \ 'args': ['--tab-width', '4', '--single-quote'],
            \ 'stdin': 1,
            \ }

Now I can see the errors (but they aren't detected).

Is there a better way?

sbdchd commented 7 years ago

Currently, Neoformat runs a command and uses the combined output of stdin & stderr (this is what system() provides). If there is a proper error code, then Neoformat will not update the buffer and ignore the output formatter, and then try the next formatter available.

pmorch commented 7 years ago

Yeah, I realized that from reading function! s:neoformat() in neoformat.vim.

I guess the core of this issue is a an enhancement request to be able to see the output in error conditions.

Especially when being explicit about using exactly one particular formatter as in my usage example - Neoformat! javascript prettier - when trying the next formatter is not applicable.

sbdchd commented 7 years ago

I agree, I think the error messaging could be improved.