People want those, and value them enough to give up federation.
My personal favorite is Zulip, by the way: https://zulip.org/
Its threaded conversation model really helps with ignoring discussion about topics you're not interested in. When I get back to an IRC/Slack/whatever channel, I spend quite a while catching up. 99% of the conversation does not concern me, yet I have to read it. Zulip's threading is a great solution to this.
Live previews and code formatting don't really have anything to do with the protocol. In Slack, if I send a link to an image or some `code in backticks`, those are sent through the protocol as-is and then the actual formatting is applied on each client receiving the message. There's nothing to prevent these messages being read on a terminal—that client will simply not have all of those features available.
I'd almost call it progressive enhancement—a lot of features can be provided by a client in a way that would be compatible with several underlying protocols.
I want these features too, but on their own they're no excuse to have a unique protocol for every chat project.
(More specifically, you can think of each message body as having a content-type, probably something like "text/x-vnd.com.slack-slackrichtext".)