It is useful when you are operating over a high-latency connection. As long as you do not send newline by mistake, you can form the command you want to dispatch with confidence. You do not have to worry about where your cursor is, and you won't find yourself in an unexpected mode, or having done the wrong number of undos or redos.
For a while I used it to write C for a hobby-project on the train, using an android phone and screen keyboard. Simple keypresses are easier than control characters in that setting. If you are interacting with a remote unix system from an ipad, you may find it useful for the same reason.
About once a year I find it useful in situations where I have some kind of broken or low-function TTY, or library problems and want to make an edit.
At times, it would be useful to have an ed-like mode available in bash, so that you could have access to an editor when your system was preventing you from spawning new processes.
With a command based editor you just type commands, no fancy keybindings that get jumbled when you have a different layout.
(And I have plans for writing fired, which is basically hired with a window to see the state of the buffer. It would still be strictly command based though, so not a vim remake.)
As long as you write your code with plenty line-breaks it is often easy to just replace a line to make the change you want, so `s` and `C` are rarely needed (though I am weak and tend to use `C` quite often, for example to get the indentation right when adding lines).
I also like being able to see my changes as I work.
(Although usually I prefer to run my shells in Emacs instead)
(i) fixing mistakes is costly: one needs to think more/be more cautious;
(ii) one needs to grow a "mental image" of the codebase;
(iii) which encourages to be more regular and austere/simpler, while training memory;
(iv) the lack of features encourages creativity, e.g. using "good" regexps to navigate the code; a common example is for C functions to be essentially uniquely identified with `^foo\(`, when the functions are defined with:
int
foo(…) {
…
The dumber the tool, the more intelligent the user has to be, and reciprocally. Of course, there are practical limits; that's just the general idea. /bin/bash <> /dev/tcp/...
With netcat listening my side. Most things kind of worked (no way to send ctrl-c though) but vi couldn't properly redraw it's screen. So I had to use ed.