eth-p / bat-extras

Bash scripts that integrate bat with various command line tools.
MIT License
1.21k stars 81 forks source link

prettybat can't read from pipe #51

Open prettyv opened 3 years ago

prettyv commented 3 years ago

When trying to preview a remote file (e.g. an installer shell script) I'd like to be able to fetch a file from a server with curl and pipe the result to prettybat. This works fine when using just bat for the syntax highlighting, but prettybat either doesn't seem to support that use case or needs to be fixed.

$ curl https://sh.rustup.rs | prettybat
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0[prettybat error]: -: No such file or directory
 85 18636   85 15971    0     0   318k      0 --:--:-- --:--:-- --:--:--  318k
curl: (23) Failure writing output to destination

It would be nice if this could be supported.

prettyv commented 3 years ago

While trying to investigate formatting of XML/SVG I also (accidentally) passed prettier output prettybat via pipe and got this potentially helpful output:

$ prettier attention.svg --parser=html | pcat
[prettybat error]: -: No such file or directory
node:events:346
      throw er; // Unhandled 'error' event
      ^

Error: write EPIPE
    at afterWriteDispatched (node:internal/stream_base_commons:160:15)
    at writeGeneric (node:internal/stream_base_commons:151:3)
    at Socket._writeGeneric (node:net:773:11)
    at Socket._write (node:net:785:8)
    at writeOrBuffer (node:internal/streams/writable:395:12)
    at Socket.Writable.write (node:internal/streams/writable:340:10)
    at writeOutput (/usr/lib/prettier/bin-prettier.js:15761:18)
    at Object.formatFiles (/usr/lib/prettier/bin-prettier.js:16111:7)
    at Object.run (/usr/lib/prettier/bin-prettier.js:16538:14)
    at Object.<anonymous> (/usr/lib/prettier/bin-prettier.js:16553:5)
Emitted 'error' event on Socket instance at:
    at emitErrorNT (node:internal/streams/destroy:188:8)
    at emitErrorCloseNT (node:internal/streams/destroy:153:3)
    at processTicksAndRejections (node:internal/process/task_queues:81:21) {
  errno: -32,
  code: 'EPIPE',
  syscall: 'write'
}
eth-p commented 3 years ago

Fixed in 860638715a58fb3284fff8bf09b1faec5178c572, but with a caveat. Because STDIN doesn't have a file extension, it won't know what formatter to use. You'll need to use curl https://sh.rustup.rs | prettybat -lsh for it to format the file as well.

prettyv commented 3 years ago

Great, thanks, this works nicely already! I see that bat itself employs some heuristics based on the first line of a file when passed via stdin, mostly (or exclusively?) looking at the shebang. Would it make sense to replicate that logic here in bash or is that not feasible / too much work?

eth-p commented 3 years ago

It would be a bit of work, unfortunately. When bat looks at the first line, it actually uses the installed .sublime-syntax syntaxes to figure out which language it is. I don't think it's the greatest idea to hardcode that list in prettybat, since it'll likely become outdated pretty fast (or when someone uses their own syntaxes with bat cache). Hell, I'm not even a fan of my hardcoded approach to file extension either.

I was actually thinking of eventually rewriting prettybat, and when I do, I'll probably use file -ib - to detect the MIME type instead of just looking at the extension. That should make it a bit more flexible, I think.

prettyv commented 3 years ago

That sounds like a good plan. Looking at it again, bat uses syntect for syntax detection and highlighting (using sublime syntaxes, as you state), which going by its documentation prefers using file extension, and falls back to looking at the first line of the file. Using file -ib - for mimetype detection fares better than that and e.g. detects my SVGs correctly as image/svg+xml when piped in, while bat itself doesn't detect a syntax to highlight.

Maybe for types that prettybat knows a formatter for this could even be used to help bat along, even though file isn't foolproof - it detected on of my JavaScript files as text/x-java - but better than nothing.

SMC242 commented 1 year ago

Are there any updates on automatic syntax detection? I would love to use prettybat for prettifying REST responses in the terminal