I use both vim and emacs regularly1. For me, the most important difference between the two isn’t the modal/modeless thing. Nor is it even that emacs encourages working on multiple buffers within a single instance whereas vim users generally fire up a new instance for each file2.
No, what emacs has that vim does not is its superb handling of asynchronous processes.
The magic of comint
Comint is an emacs lisp library designed to simplify interaction with external interpreters. Here is an example of controlling a DOS prompt.
(require 'comint) (progn (apply 'make-comint "cmd" "cmd" nil '()) (delete-other-windows) (switch-to-buffer-other-window "*cmd*") (other-window -1)) (comint-send-string (get-buffer-process "*cmd*") "dir\n")
And lo and behold, scroll up and scroll down work properly!
Sure, for a trivial example like this you would probably use dired, eshell or even my shell wrappers. However, in a similar way to expect, comint makes it easy to interact with anything that provides a stdin/stdout interface. The potential applications are limitless.
In my next comint post, I’ll show you how to interact with a simple subscriber.
1. Is that the sound of 90% of my readers leaving?
2. Yes, I’m aware that vim can work on multiple buffers. In my experience most vimmers (myself included) don’t work like that.