Bat: Option to manually set the name of a file passed in through STDIN.

Created on 7 Sep 2019  Â·  16Comments  Â·  Source: sharkdp/bat

As is the case with *nix command line tools, they're often going to be on the receiving end of a pipe. Unless we use a hacky workaround (writing though a named pipe or writing to disk), bat is programmed to display "STDIN" in the header when it's being piped to.

With bat gaining in popularity and various wrappers being created to integrate it with other tools (e.g. code formatters), it would be a really nice quality of life improvement for wrapper scripts to be able to set the name displayed in bat's header component.

An option like --override-file-name should solve this nicely. With multiple files, the name could be mapped like such:

--override-file-name "2:unformatted.rs"

This would only override the second file's name if you passed multiple files like formatted.rs -.

feature-request good first issue

Most helpful comment

As someone who writes shell scripts that use bat, I think it should also apply to non-STDIN files. That would be helpful for the cases where we save the data to a file (for pretty printing maybe?) but still want to show the original file name.

All 16 comments

Good idea.

How about calling it --stdin-file-name? In the … | bat formatted.rs - case, it would be clear that only the name for the second input would be replaced.

A case with multiple inputs from STDIN is really pathological, I think. You can call bat - - interactively, and it will read twice until you press Ctrl-D, but I don't really know if there is an actual use case where using - twice is useful? If it is, we could still set .multiple(true) on the --stdin-file-name argument, which would allow for

bat --stdin-file-name first --stdin-file-name third - formatted.rs -

The drawback of this would be that we can not easily replace file names of other inputs, which could be useful for cases where we use process substitution:

bat <(echo one) <(echo two)

I completely agree that --stdin-file-name would work if we were only going for replacing the name of one STDIN stream, but I think it would make more sense to future-proof this for multiple types of inputs (e.g. process substitution, stdin, or anything else we add down the line). It would be better to have just one --override-file-name option rather than two or more similar --stdin-file-name and --proc-file-name options in the future.

The idea for mapping --override-file-name using a index:value syntax is more or less borrowed from ffmpeg's command line interface, where you map arguments onto specific inputs. It might be a little bit overwhelming for everyday use, but this feature is meant to be used almost exclusively by wrapper scripts or external programs so there shouldn't any significant usability issue.

I completely agree that --stdin-file-name would work if we were only going for replacing the name of one STDIN stream, but I think it would make more sense to future-proof this for multiple types of inputs (e.g. process substitution, stdin, or anything else we add down the line). It would be better to have just one --override-file-name option rather than two or more similar --stdin-file-name and --proc-file-name options in the future.

Ok, agreed. But I'm not a big fan of introducing a custom index:value syntax if we can avoid it. How about simply adding --file-name <name>... with .multiple(true). This way, a file name would have to be provided for every argument, but I guess that's fine if it's mostly called from scripts anyway:

json_pp foo.json | \
  bat --file-name="foo.json" - \
      --file-name="other.json" other.json \
      --file-name="third.json" <(json_pp third.json)

What do you think?

I agree, that would definitely work for this.

Should we consider any other properties that would make more sense per-file (e.g. --highlight-lines) while we're at it? Or would it be better to create a new issue for it, since it might introduce some compatibility-breaking changes?

Should we consider any other properties that would make more sense per-file (e.g. --highlight-lines) while we're at it?

Hm, good idea. The above idea wouldn't really work for --highlight-line, as it can appear multiple times already. By compatibility-breaking, you mean something like:

--highlight-line=3,5,10 first.txt \
--highlight-line=1,20 second.txt

?

I was thinking something along those lines, yeah. A new option could always be introduced to allow it to be specified per-file, but then we would be maintaining two implementations for the same feature for the foreseeable future.

A new option could always be introduced to allow it to be specified per-file, but then we would be maintaining two implementations for the same feature for the foreseeable future.

Yeah, no. I'd rather break backwards-compatibility on this than introduce a second command-line option.

This would also be useful for https://github.com/sharkdp/bat/issues/237#issuecomment-566495835.

I suggest that we implement --file-name <name>… as described in https://github.com/sharkdp/bat/issues/654#issuecomment-529236134 and leave --highlight-line as-is for now.

Hello @sharkdp

Can I take this one?

Sure, welcome!

Is this available? I'd like to work on it.

Is this available? I'd like to work on it.

I think so, sounds great!

Should --file-name option work for both normal files and when data is piped though STDIN? Right now I have a solution which only checks for the --file-name option in the STDIN case. Wondering if I should expand that to allow this for example:

$ bat --file-name="foo.json" ./bar.json
       File: foo.json
   1   {}

Not sure if there is a realistic use case for that but, thought I'd ask.

As someone who writes shell scripts that use bat, I think it should also apply to non-STDIN files. That would be helpful for the cases where we save the data to a file (for pretty printing maybe?) but still want to show the original file name.

released in bat v0.14

Was this page helpful?
0 / 5 - 0 ratings