"rewrite it in rust" gets a lot of hate, but generally the people rewriting things in Rust actually give a shit, which tends to pay dividends. I say this as someone who doesn't use Rust and doesn't particularly like it or its community.
The reason “rewrite in Rust” gets a lot of hate is because it’s often a poorer replica in that it supports a subset of features and sometimes so littered with unsafe blocks that it’s barely any safer than their C counterparts.
Ripgrep and bat are the exceptions in that they’re modernisations in every sense of the term. They’re safer, have more modern features, and better defaults. Even if you don’t give a crap about memory safety, there’s a reason to use ripgrep and bat.
Personally I really don’t see the benefit in rewriting stuff unless you’re bringing other modernisations to the table too. But I suspect for some people, it’s more of an exercise to learn Rust than it is an ambition to displace a particular coreutil.
I have no issue with rewriting the coreutils in rust technically but I also don't think it's that interesting. They work just fine as they are.
However what I truly don't understand is using a different license. For something so fundamental, please just let that be the same.
But I think there are a lot more great examples. I have used pandas and I like polars. I have used latex but I like typst. People are creating generally valuable tools that bring something new to the table. More competition and diversity is rarely a bad thing.
What license would that be? GPLv3 for GNU? GPLv2 for busybox? Or BSD for Toybox (Android)
Or BSD/ISC for FreeBSD, OpenBSD, macOS etc coreutils? All of which also have subtly different implementations from each other.
Or maybe you are talking about other UNIXs like CDDL for OpenSolaris?
Or perhaps you meant a proprietary license like Solaris, AIX, HP-UX, Tru64 UNIX and so on?
Or maybe we just agree that there isn’t a standard license for coreutils and developers should be free to chose to license their own code however they wish?
I think the obvious answer is whatever tool you're attempting to replicate/supplant, you should use the same (or a compatible) license.
The issue is there's a massive leap between GPLv3 and MIT, even something like GPLv2 or anything else is better than MIT or public domain-tier licenses.
MIT/Apache2 is the default in the Rust ecosystem, and so the authors selected it because they didn’t care that much, and so going with the community default makes sense.
In practice, even if they’d chosen the GPL for their own code, they’d be including dependencies that weren’t GPL’d, so unless they were committing to doing everything from scratch (including the Rust standard library!) some parts of the codebase would be non-GPL’d.
> MIT/Apache2 is the default in the Rust ecosystem, and so the authors selected it because they didn’t care that much, and so going with the community default makes sense.
This is exactly the issue most of us have with the rust ecosystem and these 'rewrite in rust' projects, though.
By making everything licensed with the absolute bottom wrung restrictions, you're just made it even easier for corpos to have free pickings of any given tool on the internet to incorporate into their own tools and have never-ending Amazon and Elasticsearch situations.
Obviously the community wouldn't even be here to begin with if it wasn't for Linux going with a GPLv2 license. Going forward, with everything becoming more MIT/BSD licensed, I wonder to see how the community/ecosystem will fare.
I suspect, should there come a time in the future where we realize that this may have been a critical error, it'll be far too late to correct it.
so unless they were committing to doing everything from scratch (including the Rust standard library!) some parts of the codebase would be non-GPL’d.
that doesn't matter. the point of the GPL is to protect the application. that still happens even if libraries used are not GPL. the LGPL would not exist if that were an issue, so using a different more restrictive license for applications, and a less restrictive one for libraries is done intentionally.
bat isn't really a rewrite though. It complements cat and less rather than replace them, and it even uses less. Or maybe it's a rewrite of lesspipe.sh?
If you hang around certain spaces of the internet (here, Reddit, etc), any sufficiently popular post about a Rust-related project is bound to accrue some comments along the lines of "Rust is actually not that great", "rewriting is bound to gain new bugs that won't be caught", "the borrow checker is practically byzantine and not worth the trouble", "C is perfectly adequate", "more advanced type systems are less useful than writing more tests", etc. I would even say that comments of this nature constituted a good chunk of the discussion around the US government's C-to-Rust initiative (a very popular post with a lot of comments).
The Rust Blowback had some reasons: People arbitrarily opening bug-tickets on various projects saying they should be Rewritten in Rust for Safety. This became a Meme.
It's often framed as useless monkey business, rewriting working software to produce a copy of it but in another language, for questionable benefits.
I'd say that rewriting anything in any language (even in the same language) would remove large amounts of cruft, and add long-missing neat things that are easier to add when you build from scratch, and with a good understanding which the original authors lacked. Often it also can afford using a better architecture, see rg vs grep: grep has many brilliant technical solutions, but making it multithreaded would be a major rewrite anyway.
Along with everything else mentioned, there is a certain group of people who consider the language “woke”. Usually that’s not the critique you see on HN, but be wary of it.
I don’t even think you need an alias. There’s a bat config file (`bat —config-file` to find it). You can probably drop `—wrap never` there. I include a few different `—map-syntax` declarations there.
Very cool tool. It's perfect for the "take a quick look" use-case.
I just downloaded it on MacOS and when I ran it the first time it took a really long time on a one-line JSON which disappointed me but then any subsequent run on anything was fast. I'd completely forgotten about MacOS doing that thing on first run.
Uses the pager for large files automatically etc. Very nice.
> Uses the pager for large files automatically etc. Very nice.
If you like that, you can also make less behave like cat if the file fits in one screen. You just need to add F to the LESS environment variable. It's very convenient because so many things depend on less.
That has git integration, like bat does? That shows non-printable characters like bat does? That allows you to concatenate and page multiple files at once like bat does? That supports the --line-range option like bat does? You can pipe the output of tail -f through your alias?
I guess if all you did was read the headline of the post you could assume your alias does all the same things as bat.
Not the GP and I do like bat, but to answer your questions:
> That shows non-printable characters like bat does?
cat does actually support that via the flags with -v (you can also use -t and -e to view tab and line endings too)
> That allows you to concatenate and page multiple files at once like bat does?
cat is literally called “cat” because it’s intended purpose is concatenation.
It’s not a pager though the GPs example did pipe to less anyway.
> That supports the --line-range option like bat does?
‘tail’ and ‘head’ would be muscle memory to a lot of people and not that different in terms of number of keystrokes.
But I do take your point that it’s nice to have that built into your pager.
> You can pipe the output of tail -f through your alias?
I couldn’t see why not. tail -f isn’t doing anything weird with the fd.
———
I’m not arguing against using bat though. I have it aliased to cat on my own machines, so I clearly and would recommend bat. But I do think some people might be surprised how far you can get with coreutils if bat wasn’t available
>> That allows you to concatenate and page multiple files at once like bat does?
>cat is literally called “cat” because it’s intended purpose is concatenation.
cat's behaviour and bat's behaviour is different, though.
>cat a.txt b.txt
It was a dark and stormy night.
Once upon a time.
>bat a.txt b.txt
───────┬──────────────────────────────────────────────────────
│ File: a.txt
───────┼──────────────────────────────────────────────────────
1 │ It was a dark and stormy night.
───────┴──────────────────────────────────────────────────────
───────┬──────────────────────────────────────────────────────
│ File: b.txt
───────┼──────────────────────────────────────────────────────
1 │ Once upon a time.
───────┴──────────────────────────────────────────────────────
This difference becomes more useful once we have a more meaningful example:
It's hard to imagine many people have the muscle memory for the combination of cat, head, and whatever else you need to add headers with the filename and file size, call out empty files, highlight the second line, show line numbers, do syntax formatting, and wrap to the terminal width (head doesn't do this).
What you're showing here is not concatenation, there are fancy borders between file chunks and whatnot. Unless you have very different, unconventional definition of concatenation.
In fact, you're at odds with bat's README:
> you can still use bat to concatenate files. Whenever bat detects a non-interactive terminal (i.e. when you pipe into another process or into a file), bat will act as a drop-in replacement for cat
> It's hard to imagine many people have the muscle memory for the combination of cat, head, and whatever else you need to add headers with the filename and file size, call out empty files, highlight the second line, show line numbers, do syntax formatting
Honestly, it's harder to imagine many people with need for most combinations of these features. I can see general audience who would happily use one feature at a time, and if someone is constantly doing obscure one-off file analysis, chances are bat is just never enough, they're going to write long pipelines with awk/perl or use vim macros anyway, so there are no time savings nor convenience from using bat. (Is it really that much more convenient to read syntax-highlighted heads with line numbers? And I can barely remember the last time when `head` that also shows file sizes could've been much more handy than `du * ; head *`.)
Also, good luck using all that bat muscle memory in docker containers or old-school fleet of remote servers.
> and wrap to the terminal width (head doesn't do this)
Terminals already wrap long lines just fine, they don't need help from anything. They can also re-wrap lines when window gets resized.
looks like you are right, but...
I almost never used all of this features with bat. Maybe tail -f sometimes.
Do you really need this in daily workflow?
I call cat when I need to pipe or copy something, and just bat if I wanna read it myself. I find this as a good compromise, I like how bat formats things.
Your solution would be ok with an alias as well, so thanks. Might try it just so I dont need yet another program lying around
Although I agree with other commenters that your command can't compare to all of bat's features, many of which I appreciate... thank you for sharing this tip, I didn't know about `highlight` and I can't install `bat` at work.
This will live in my .bashrc for a long time:
cat() {
if [[ -t 1 ]]; then
command cat "$@" | highlight --force -O xterm256
else
# plain cat to pipe into other things
command cat "$@"
fi
}
This... doesn't work? Everything just comes out green. It's not clear to me how 'highlight' could even possibly know what syntax it's supposed to be highlighting when processing stdin, unless it ingests the whole thing until EOF and then applies some kind of fuzzy logic. If you feed it a filename as an argument, it just checks the extension.
I know. But that doesn't make it accurate. And in broader strokes, I'm not fond of that thread/comment being used to pretend that all new and shiny things are better than what came before. Sometimes the new thing is barely more than a coat of paint on the existing thing.
Sadly does not work on fish because the developers does not believe that users are intelligent enough to understand the obvious and intuitive outcome of flipping ">" (a valid operator in fish).
Like rg, it's one of those "rewrite it in rust" projects that turned out to actually be quite well thought through.
The reason “rewrite in Rust” gets a lot of hate is because it’s often a poorer replica in that it supports a subset of features and sometimes so littered with unsafe blocks that it’s barely any safer than their C counterparts.
Ripgrep and bat are the exceptions in that they’re modernisations in every sense of the term. They’re safer, have more modern features, and better defaults. Even if you don’t give a crap about memory safety, there’s a reason to use ripgrep and bat.
Personally I really don’t see the benefit in rewriting stuff unless you’re bringing other modernisations to the table too. But I suspect for some people, it’s more of an exercise to learn Rust than it is an ambition to displace a particular coreutil.
However what I truly don't understand is using a different license. For something so fundamental, please just let that be the same.
But I think there are a lot more great examples. I have used pandas and I like polars. I have used latex but I like typst. People are creating generally valuable tools that bring something new to the table. More competition and diversity is rarely a bad thing.
Or BSD/ISC for FreeBSD, OpenBSD, macOS etc coreutils? All of which also have subtly different implementations from each other.
Or maybe you are talking about other UNIXs like CDDL for OpenSolaris?
Or perhaps you meant a proprietary license like Solaris, AIX, HP-UX, Tru64 UNIX and so on?
Or maybe we just agree that there isn’t a standard license for coreutils and developers should be free to chose to license their own code however they wish?
The issue is there's a massive leap between GPLv3 and MIT, even something like GPLv2 or anything else is better than MIT or public domain-tier licenses.
In practice, even if they’d chosen the GPL for their own code, they’d be including dependencies that weren’t GPL’d, so unless they were committing to doing everything from scratch (including the Rust standard library!) some parts of the codebase would be non-GPL’d.
This is exactly the issue most of us have with the rust ecosystem and these 'rewrite in rust' projects, though.
By making everything licensed with the absolute bottom wrung restrictions, you're just made it even easier for corpos to have free pickings of any given tool on the internet to incorporate into their own tools and have never-ending Amazon and Elasticsearch situations.
Obviously the community wouldn't even be here to begin with if it wasn't for Linux going with a GPLv2 license. Going forward, with everything becoming more MIT/BSD licensed, I wonder to see how the community/ecosystem will fare.
I suspect, should there come a time in the future where we realize that this may have been a critical error, it'll be far too late to correct it.
that doesn't matter. the point of the GPL is to protect the application. that still happens even if libraries used are not GPL. the LGPL would not exist if that were an issue, so using a different more restrictive license for applications, and a less restrictive one for libraries is done intentionally.
https://github.com/wofr06/lesspipe
I'd say that rewriting anything in any language (even in the same language) would remove large amounts of cruft, and add long-missing neat things that are easier to add when you build from scratch, and with a good understanding which the original authors lacked. Often it also can afford using a better architecture, see rg vs grep: grep has many brilliant technical solutions, but making it multithreaded would be a major rewrite anyway.
it replaces default `ls` in interactive shells on some distros, which is where I encountered it
https://news.ycombinator.com/from?site=github.com/sharkdp
[0] https://www.gnu.org/software/src-highlite/
Edit, with cURL it's OK… 200.
That makes no sense.
bat: A cat(1) Clone with Wings - https://news.ycombinator.com/item?id=33382307 - Oct 2022 (2 comments)
bat, a cat(1) clone with syntax highlighting, Git integration written in Rust - https://news.ycombinator.com/item?id=24850244 - Oct 2020 (6 comments)
Bat: A cat(1) clone with wings - https://news.ycombinator.com/item?id=17887819 - Aug 2018 (12 comments)
Bat: A cat(1) clone with wings - https://news.ycombinator.com/item?id=17849535 - Aug 2018 (1 comment)
Bat: cat(1) clone with syntax highlighting and Git integration - https://news.ycombinator.com/item?id=16968755 - May 2018 (1 comment)
I just downloaded it on MacOS and when I ran it the first time it took a really long time on a one-line JSON which disappointed me but then any subsequent run on anything was fast. I'd completely forgotten about MacOS doing that thing on first run.
Uses the pager for large files automatically etc. Very nice.
If you like that, you can also make less behave like cat if the file fits in one screen. You just need to add F to the LESS environment variable. It's very convenient because so many things depend on less.
https://www.man7.org/linux/man-pages/man1/less.1.html#:~:tex...
works fine for me.
I guess if all you did was read the headline of the post you could assume your alias does all the same things as bat.
> That shows non-printable characters like bat does?
cat does actually support that via the flags with -v (you can also use -t and -e to view tab and line endings too)
> That allows you to concatenate and page multiple files at once like bat does?
cat is literally called “cat” because it’s intended purpose is concatenation.
It’s not a pager though the GPs example did pipe to less anyway.
> That supports the --line-range option like bat does?
‘tail’ and ‘head’ would be muscle memory to a lot of people and not that different in terms of number of keystrokes.
But I do take your point that it’s nice to have that built into your pager.
> You can pipe the output of tail -f through your alias?
I couldn’t see why not. tail -f isn’t doing anything weird with the fd.
———
I’m not arguing against using bat though. I have it aliased to cat on my own machines, so I clearly and would recommend bat. But I do think some people might be surprised how far you can get with coreutils if bat wasn’t available
cat's behaviour and bat's behaviour is different, though.
This difference becomes more useful once we have a more meaningful example: It's hard to imagine many people have the muscle memory for the combination of cat, head, and whatever else you need to add headers with the filename and file size, call out empty files, highlight the second line, show line numbers, do syntax formatting, and wrap to the terminal width (head doesn't do this).In fact, you're at odds with bat's README:
> you can still use bat to concatenate files. Whenever bat detects a non-interactive terminal (i.e. when you pipe into another process or into a file), bat will act as a drop-in replacement for cat
> It's hard to imagine many people have the muscle memory for the combination of cat, head, and whatever else you need to add headers with the filename and file size, call out empty files, highlight the second line, show line numbers, do syntax formatting
Honestly, it's harder to imagine many people with need for most combinations of these features. I can see general audience who would happily use one feature at a time, and if someone is constantly doing obscure one-off file analysis, chances are bat is just never enough, they're going to write long pipelines with awk/perl or use vim macros anyway, so there are no time savings nor convenience from using bat. (Is it really that much more convenient to read syntax-highlighted heads with line numbers? And I can barely remember the last time when `head` that also shows file sizes could've been much more handy than `du * ; head *`.)
Also, good luck using all that bat muscle memory in docker containers or old-school fleet of remote servers.
> and wrap to the terminal width (head doesn't do this)
Terminals already wrap long lines just fine, they don't need help from anything. They can also re-wrap lines when window gets resized.
(edit: expanded quote, markup fix)
I also use the fzf previewer with --range-limited pretty frequently.
Your solution would be ok with an alias as well, so thanks. Might try it just so I dont need yet another program lying around
This will live in my .bashrc for a long time:
alias bat='f(){ cat "$1" | highlight --force -O xterm256 | less -SRNI; }; f'
You can make an alias.
> For most installs. Or distros. Probably.
Comparing https://repology.org/project/bat-cat/packages vs https://repology.org/project/highlight/packages appears to show them with approximately equal availability. (Unless you're trying some other point, in which case I don't follow.)
Whether this proves or disproves anything in re syntax highlighting utilities I leave as an exercise.
https://news.ycombinator.com/item?id=8863
so apparently, no, it doesn't work.
to be fair, this is how it works:
to avoid getting caught by the useless use of cat police, this does too: however, i have to tell it which syntax to usebut to its credit, highlight even has support for pike, which bat doesn't (yet) (fixed that for myself, at least)
so overall, bat wins.
* https://freshports.org/textproc/highlight/
* https://ftp.netbsd.org/pub/pkgsrc/current/pkgsrc/textproc/hi...
* http://ports.su/textproc/highlight
* https://ports.macports.org/port/highlight/