Some thoughts on Emacs and Vim

This post shows a couple differences between Emacs and Vim.

Now, before I begin, I’d like to say that the only reason why I recently started using Emacs along with Vim is because of Emacs’ org-mode. It is a very powerful outlining platform that really takes advantage of Emacs’ Lisp architecture (well, all Emacs extensions, by design, enjoy the powerful Lisp backend). I’ve started using org-mode recently to act as my digital planner.

Also, I’m a die-hard Vim user, so I am obviously biased.

Cool things about Emacs:

  • Lisp backend (it makes Emacs verrry powerful, perhaps too powerful (see “cons” below)): Emacs is not a text editor. It is a Lisp interpreter, that happens to be used primarily as a text editor. Org-mode, as I mentioned above, is an Emacs extension that really makes Emacs shine.
  • Command-based keybindings: In Vim, keybindings resemble macros, like this:
nmap <F1> :up<CR>

where “:up” is the actual keys that need to be pressed by the user to achieve the affect you want (here, :up and pressing ENTER results in saving a document). In Emacs, instead of specifying the literal key presses, you describe which commands are called on by the keys. So for me, I have

(global-set-key "\C-cl" 'org-store-link)

which maps “CTRL-c, l” to the org-store-link function. You can of course do the same thing in Vim by just calling a Vimscript function for some particular keybinding, but check this out: in Emacs you can easily compose multiple-function hotkeys by defining a big blank function (aka “lambda expression” or “closure”) that is made up of smaller regular functions, like so:

(global-set-key "\C-cl" (lambda ()
                     (function1)
                     (function2)
                     (function3)
                     (function4)
                        ...
                     (functionN)
                     ))

How cool is that? This is yet another example where the Lisp backend makes this possible, and so easy. I actually prefer Emacs’ way of calling the functions/commands directly like this, as it makes keybindings much easier to understand and just sticks to a simple, uniform layout: make keys call either 1 or more functions.

  • Better speed: By speed, I’m judging 3 common areas: startup time, parenthesis matching, and syntax highlighting. Emacs wins 2 out of 3. Here is the breakdown:
  • Startup time: Vim is faster (GVim is faster than Emacs, and console vim starts *instantly* whereas console emacs takes a couple seconds). CORRECTION (Feb 17, 2011): Emacs’ startup time depends on two factors (how you write your ~/.emacs file, and whether you run it as a client of a long-running emacs daemon).
  • Parenthesis matching: Emacs is lightyears ahead. Sadly, Vim slows down to a deathly crawl whenever I edit non-trivial LaTeX files, because whenever I move my cursor around (e.g., by holding down the h/l keys), it re-calculates the matching parenthesis/bracket/brace for every cursor position. Emacs chews up matching parenthesis highlighting in realtime, even for my slowest (on Vim) LaTeX documents. Again, Emacs is lightyears ahead here.
  • Syntax highlighting: Emacs’ syntax highlighting is much faster, and does not slow down *at all* even with my heaviest LaTeX files. Vim slows down to a crawl for some of my LaTeX documents when I hold down the h/l/j/k keys for incremental navigation.
  • Of course, Vim’s Normal mode makes editing files a breeze compared to Emacs’ clunky CTRL CTRL CTRL META META hotkey insanity. But Emacs is not a modal editor, so that’s why I didn’t include it in the breakdown above.

Some Emacs cons:

  • It’s not modal. This is a huuuuuuuuuge issue for me. The *best* complaint against modal editing, from what I gather from the endless Emacs vs. Vim debate, is “Vim users have to keep reaching up to the ESC key with their left pinky every 5 seconds, and the ESC key is too far away from the home row — the same home row that Vimmers proudly call their home!”. And to this complaint, I have two practical answers:
  1. Use the built-in, default CTRL-[ shortcut instead of ESC. (For some reason, this is a big mystery to both Emacs and Vim users alike.)
  2. Map "jk" to ESC. These two keys are: on the home row (and if you learned how to type, your fingers are already on these keys), are faster to type (faster than "jj" or "kk" because in those cases you only use a single finger whereas with "jk" you use two), and almost never come up in English/programming. This is what I do; I never use the ESC key.
  • Emacs's Lisp backend makes it too powerful for its own good. Because "extending Emacs" really means "writing Lisp programs", Emacs has become something of an OS. There are many Emacs users out there who use it as their text editor, as well as: an email/news reader, a PDF viewer, a web browser, version control management system, encryption/decryption mechanism, etc. This bizarre agglomeration of various programs all into Emacs makes it very bulky, and I suspect it is this bulkiness that slows down its startup time (although, as stated above, its parenthesis matching and syntax highlighting speed is lightning fast). CORRECTION (Feb 17, 2011): Actually, the startup time is very fast if my ~/.emacs config file is blank, but apparently my modest, relatively new ~/.emacs file loads up various plugins (Vimpulse and a color theme, among others) which slow the startup time down by a couple seconds.

That's it! If Emacs were modal, then I would probably immediately switch to it. Currently, I use Emacs + Vimpulse whenever I need to use Org-mode (the fact that Vimpulse and Org-mode, two independent Emacs projects, work seamlessly side-by-side, emphasizes Emacs' rich versatility). For all real text editing needs, I use Vim. Vim's Normal mode lets me fly around a document like one of those crazy Harry Potter kids in a quidditch game.

What I don't like about Vim:

  • Vimscript: Vimscript is just painful to use for me. It's a scripting language but it doesn't even have case/switch statements. All functions must start with a capital letter. Yuck! Customizing/extending Emacs with Emacs Lisp is a dream compared to working with Vimscript.

That's about it, apart from the parenthesis/syntax speed issues noted above. I am a die-hard Vim user, by choice.

UPDATE Feb 17, 2011: Wow, apparently this post got over 3k views today, because of referrals from (among others) HackerNews and Reddit. I'll look over the discussions at those sites and post my thoughts on here, to "fill in the holes" in my original post, so to speak. Stay tuned.

UPDATE Feb 17, 2011: So here's the update after reflecting on some of the comments from HN and Reddit:

HN:

  • slysf says "The biggest con about emacs that's not mentioned is that it's just not _everywhere_." Yeah, I'm just a hobbyist programmer so I have not had to deal with sysadmin/remote client issues. But it's obviously a big bonus if you can use your editor of choice everywhere you go. Emacs' saving grace is that it IS very portable, just that it's not installed on every UNIX-y box out there by default...
  • d0mine mentions that Python doesn't have case/switch statements as well. Holy cow, I did not know that! And apparently, you can just use Python's dictionary type to achieve what case/switch statements do. Ruby has case/when statements (same thing as switch/case), and I used them before many times, so I just found it strange when I tried to use Vimscript and there was no such construct. However, I've learned that Vimscript also has a dictionary type, so, like Python, I'm sure it can be used to emulate switch/case statements. Still, in the big picture of things, Vimscript's power will always be dwarfed by larger, more mature languages that get beaten, abused, and tested by armies of professional developers; and this is why Vimscript will always be inferior: there aren't that many users who pound on it daily and work to develop it. Vimscript is sort of like an island on its own, while Emacs Lisp has excellent lineage (it's a LISP dialect).

Reddit:

  • jaybee mentions that startup times really has to do with what's in your init file. This statement is very true, and has already been incorporated in my original post as a correction. The fact that you can also run emacs as a server on boot and just launch clients instantaneously is very valuable advice. I will heed to it!
  • sping says that he just uses one emacs window (frame) and works within it. As an XMonad user on a dual head, I like using multiple windows so much that I just use multiple windows, shells, etc. all the time. If you're on Gnome or KDE, with no tiling window manager, then sping's method would be superior in terms of speed (no mouse dependancy). I think there are legions of Emacs users out there who started using it before the advent of popular tiling window managers, and got used to the notion of "do everything within Emacs" so much that they never bothered to try out tiling window managers (and the benefits they bring --- lightning fast window navigation/management, which makes using multiple shells/programs a breeze).
  • sping also says "I have never yet read someone talking about vim who has actually made a good case for any superiority over Emacs in any significant area." And my answer is: modal editing. Modal editing is a killer feature that Emacs is sorely missing. sping also says "I'm not actually against its modal nature, but I'm still waiting to find out exactly how it's so f'ing awesome in ways which Emacs isn't." Hmm, what part of "modal editing makes navigation verrry fast" did I make unclear? I even made a Harry Potter reference, for goodness' sake! Well, if you don't care about fast cursor movement around, inside a file, then Vim has very little, if *any*, advantages over vanilla Emacs (the only "neat" thing I can think of is Visual Block mode, but that's it). To be fair, sping is a former vi user, so he finds the whole modal editing thing not very impressive. To each his own.
  • Just to expand more on sping's comment about how he has yet to find anything in Vim that is so great over Emacs, I think he's asking fundamentally the wrong question. Vim will never really have more "awesome ways" that make it superior over Emacs, because Vim is just a text editor. And Emacs is waaaay more than a text editor. So feature-wise, Emacs will always win. However, if you're only comparing text editing vs. text editing, then I will re-iterate that Vim's (only real) killer feature over Emacs is modal editing (and super-fast intra-file navigation).
  • zck asks "Wouldn't [pressing "jk"] just move the cursor up and then down?” Well, no. First, we are talking about going from Insert mode to Normal mode. If you’re already in Normal mode, then duh: your cursor will move up and then down. But since we are in Insert mode, and have “jk” insert-mode-mapped to ESC (imap jk <ESC>), every time you press j, Vim starts a little timer and sees if you press k next, and if you do indeed press k next, you escape into Normal mode. This timer is customizable, and I have it at 1 second.

Other thoughts:

On navigation speed: There are still people asking: “Is Vim really faster to navigate around a file than Emacs?” And my answer is: the hotkeys speak for themselves. (Vim is lightyears ahead.) Oh, and I also mapped the Space and Backspace keys in Normal mode like this:

nnoremap <space> 10jzz
nnoremap <backspace> 10kzz

to make navigation even faster. (You should all customize Space/Backspace keys because by default they just do what l/h do.) UPDATE March 2, 2011: Oh, and if you are using vimpulse.el (version 0.5), you can do:

; simulate vim's "nnoremap <space> 10jzz"
(vimpulse-map " " (lambda ()
                     (interactive)
                     (next-line 10)
                     (viper-scroll-up-one 10)
                     ))
; simulate vim's "nnoremap <backspace> 10kzz"
(define-key viper-vi-global-user-map [backspace] (lambda ()
                     (interactive)
                     (previous-line 10)
                     (viper-scroll-down-one 10)
                     ))

to get the same behavior.

UPDATE Feb 17, 2011: Oh, and another thing: for years some people have wanted a “breakindent” (aka “soft wrap”) feature in Vim (i.e., make it so that a very long line gets a virtual indent for all successive “lines”, such that you end up with a neat, clean rectangle for a long line that has been indented at the very beginning).  See this page and this page. Among other things, a breakindent feature would make outlines look very clean, with neat rectangular blocks for lines that start out at a deep indent. Sadly, I don’t imagine breakindent becoming a feature in Vim in the foreseeable future. In Emacs’ org-mode, breakindent is availble! Just put “#+STARTUP: indent” at the top of the .org file you are working on, and voila: sane line wrapping for outlines.

UPDATE August 5, 2011: I’ve recently switched to using the emacs –daemon and emacsclient command. Basically, I have a emacs –daemon & in my ~/.xinitrc, and then I use emacsclient -nw and emacsclient -c instead of emacs -nw and emacs, respectively. The startup times of emacsclient is near-instant — very impressive! The only drawbacks are that the emacs daemon process takes up 37MB on my system (but then again, with machines using gigabytes of RAM these days, it’s a nonissue), and you have to fiddle a bit with your ~/.emacs file to load up the correct font and color scheme (since emacs –daemon does not read the ~/.emacs file like regular standalone emacs with regard to the X11 options; see http://www.tychoish.com/rhizome/getting-emacs-daemon-to-work-right/ and http://old.nabble.com/–daemon-vs.-server-start-td21594587.html).

I’ve also dropped Vimpulse in favor of Evil, since the core developer for it (Vegard Øye) decided to join forces with another Vim-minded emacs extension author (Frank Fischer, of vim-mode) to create a newer, better Vim emulation layer earlier in February this year (just 10 days after the date of my original post!). See http://news.gmane.org/find-root.php?group=gmane.emacs.vim-emulation&article=692. Anyway, the official Evil repo is at http://gitorious.org/evil/ (more info at http://gitorious.org/evil/pages/Home). The only drawback right now is that Evil does not currently emulate Vi’s Ex mode (in Vim, when you type the colon ‘:’ character from Normal mode). If you really want this feature right now, too, then I suggest cloning from Frank Fischer’s personal branch, at https://bitbucket.org/lyro/evil/overview, which includes Ex mode. I suspect that Fischer’s Ex-mode code will be merged into Evil sometime in the future since Fischer keeps his branch in sync with the official Evil repo.

The best part about using Evil is that it does not depend on Viper, the old Vi extension for emacs.

Anyway, here’s how I’ve set up Evil in my ~/.emacs (many of these keymaps only make sense if you’re in org-mode, but whatever):

; evil, the Extensible VI Layer! seee http://gitorious.org/evil/pages/Home
(add-to-list 'load-path "~/.emacs.d/script/evil")
(require 'evil)
(evil-mode 1)
; some keymaps from ~/.vimrc
(define-key evil-insert-state-map [f1] 'save-buffer) ; save
(define-key evil-normal-state-map [f1] 'save-buffer) ; save
(define-key evil-normal-state-map ",w" 'save-buffer) ; save
(define-key evil-normal-state-map ",q" 'kill-buffer) ; quit (current buffer; have to press RETURN)
(define-key evil-normal-state-map ",x" 'save-buffers-kill-emacs) ; save and quit
; make "kj" behave as ESC key ,adapted from http://permalink.gmane.org/gmane.emacs.vim-emulation/684
; you can easily change it to map "jj" or "kk" or "jk" to ESC)
(defun escape-if-next-char (c)
    "Watches the next letter.  If c, then switch to Evil's normal mode; otherwise insert a k and forward unpressed key to unread-command events"
      (self-insert-command 1)
        (let ((next-key (read-event)))
              (if (= c next-key)
                        (progn
                                    (delete-backward-char 1)
                                              (evil-esc))
                              (setq unread-command-events (list next-key)))))

(defun escape-if-next-char-is-j (arg)
    (interactive "p")
      (if (= arg 1)
              (escape-if-next-char ?j)
                  (self-insert-command arg)))

(define-key evil-insert-state-map (kbd "k") 'escape-if-next-char-is-j)
; simulate vim's "nnoremap <space> 10jzz"
(define-key evil-normal-state-map " " (lambda ()
                     (interactive)
                     (next-line 10)
                     (evil-scroll-line-down 10)
                     ))
; simulate vim's "nnoremap <backspace> 10kzz"
(define-key evil-normal-state-map [backspace] (lambda ()
                     (interactive)
                     (previous-line 10)
                     (evil-scroll-line-up 10)
                     ))

; make evil work for org-mode!
(define-key evil-normal-state-map "O" (lambda ()
                     (interactive)
                     (end-of-line)
                     (org-insert-heading)
                     (evil-append nil)
                     ))

(defun always-insert-item ()
     (interactive)
     (if (not (org-in-item-p))
       (insert "\n- ")
       (org-insert-item)))

(define-key evil-normal-state-map "O" (lambda ()
                     (interactive)
                     (end-of-line)
                     (org-insert-heading)
                     (evil-append nil)
                     ))

(define-key evil-normal-state-map "o" (lambda ()
                     (interactive)
                     (end-of-line)
                     (always-insert-item)
                     (evil-append nil)
                     ))

(define-key evil-normal-state-map "t" (lambda ()
                     (interactive)
                     (end-of-line)
                     (org-insert-todo-heading nil)
                     (evil-append nil)
                     ))
(define-key evil-normal-state-map (kbd "M-o") (lambda ()
                     (interactive)
                     (end-of-line)
                     (org-insert-heading)
                     (org-metaright)
                     (evil-append nil)
                     ))
(define-key evil-normal-state-map (kbd "M-t") (lambda ()
                     (interactive)
                     (end-of-line)
                     (org-insert-todo-heading nil)
                     (org-metaright)
                     (evil-append nil)
                     ))
(define-key evil-normal-state-map "T" 'org-todo) ; mark a TODO item as DONE
(define-key evil-normal-state-map ";a" 'org-agenda) ; access agenda buffer
(define-key evil-normal-state-map "-" 'org-cycle-list-bullet) ; change bullet style

; allow us to access org-mode keys directly from Evil's Normal mode
(define-key evil-normal-state-map "L" 'org-shiftright)
(define-key evil-normal-state-map "H" 'org-shiftleft)
(define-key evil-normal-state-map "K" 'org-shiftup)
(define-key evil-normal-state-map "J" 'org-shiftdown)
(define-key evil-normal-state-map (kbd "M-l") 'org-metaright)
(define-key evil-normal-state-map (kbd "M-h") 'org-metaleft)
(define-key evil-normal-state-map (kbd "M-k") 'org-metaup)
(define-key evil-normal-state-map (kbd "M-j") 'org-metadown)
(define-key evil-normal-state-map (kbd "M-L") 'org-shiftmetaright)
(define-key evil-normal-state-map (kbd "M-H") 'org-shiftmetaleft)
(define-key evil-normal-state-map (kbd "M-K") 'org-shiftmetaup)
(define-key evil-normal-state-map (kbd "M-J") 'org-shiftmetadown)

(define-key evil-normal-state-map (kbd "<f12>") 'org-export-as-html)

UPDATE August 12, 2011: Great news! Frank Fischer’s Ex mode branch was merged into upstream just two days ago (commit 46447065ed5a374452504bd311b91902b8ce56d4), so now Evil has Ex mode!

Also, I noticed that Evil uses (kbd “DEL”) instead of [backspace] for binding the Backspace key (commit 8fc3c4065c7ed50a6033a7f1c68deba5a9270043), so I recommend changing the Backspace binding I posted previously to:

; simulate vim's "nnoremap <backspace> 10kzz"
(define-key evil-normal-state-map (kbd "DEL") (lambda ()
                     (interactive)
                     (previous-line 10)
                     (evil-scroll-line-up 10)
                     ))

I tested the change, and indeed, the previous binding with [backspace] was broken for console emacs, but it works with (kbd “DEL”).

UPDATE November 17, 2011: Tom (comment #19) pointed out that you can define hotkeys in a mode-specific way from within evil, as follows:

(evil-declare-key 'normal org-mode-map "T" 'org-todo)
(evil-declare-key 'normal org-mode-map "-" 'org-cycle-list-bullet)

This way, your hotkeys will not collide if you change modes. (Not a problem for me because I only use emacs for org-mode, but there you have it.)

Oh, and the old “kj” escape key function no longer works; here is the new version:

(define-key evil-insert-state-map "k" #'cofi/maybe-exit)

(evil-define-command cofi/maybe-exit ()
  :repeat change
  (interactive)
  (let ((modified (buffer-modified-p)))
    (insert "k")
    (let ((evt (read-event (format "Insert %c to exit insert state" ?j)
			   nil 0.5)))
      (cond
       ((null evt) (message ""))
       ((and (integerp evt) (char-equal evt ?j))
	(delete-char -1)
	(set-buffer-modified-p modified)
	(push 'escape unread-command-events))
       (t (setq unread-command-events (append unread-command-events
					      (list evt))))))))

The original source is at http://article.gmane.org/gmane.emacs.vim-emulation/980. What’s great about this version is that it behaves almost exactly like the original vim mapping; once you type “k”, you have a 0.5-second window to type in “j” to escape — otherwise, you just get “k” on the screen.

UPDATE March 7, 2012: For a long time, I did not realize that the “10<c-e>10j” keybinding for <space> was not what I wanted, as it moved the cursor more than 10 lines down (<c-e> is an “impure” way to scroll). The proper way is to use “zz”, which resets the screen to have the cursor in the middle of the screen (vertically), without changing the current line position.

About these ads

21 thoughts on “Some thoughts on Emacs and Vim

  1. You may wish to check out VIper-mode for Emacs. It adds modality and Vim-like keybindings to Emacs, including h/j/k/l navigation and : to enter the minibuffer instead of Meta-x.

    Additionally, you should try remapping the capslock key to your editor’s favorite function key, whether it’s ESC or CTRL. It helps all over the entire computer, not just in Vim or Emacs.

  2. Hi! I really enjoyed your thoughts on the age old Emacs v. Vi debate. I’m a diehard vim user whose been itching to try out emacs. Org-mode looks like the sort of task manager I’ve wanted for years. Your comments about the power of emacs as a full lisp runtime also resonates with me.

    I tried viper mode a while back, but wasn’t satisfied. I love modal editing as much as you! Viper mode got me close, but I really want Visual mode back. I’m told that there’s a way to get Vimpulse to do what I want. Would you mind walking me through basics of how you got your emacs setup configured with vimpulse?

    It’s ironic, I feel like the only thing missing from emacs is a good vi clone :p.

  3. Interesting, I’ve found gVIM to handle syntax highlighting better than emacs. I had used vim for years, but I convinced myself to learn emacs. Though there was much I liked about it, I found I had to do to too much tinkering to get sane syntax highlighting and code formatting for the languages I worked with. gVIM didn’t require the same hoops.

  4. > This bizarre agglomeration of various programs all into Emacs makes it very bulky, and I suspect it is this bulkiness that slows down its startup time

    This is a common misconception about Emacs, but all the non-core functionality is loaded on-demand, so unless you’ve misconfigured things, extra libraries will not be loaded until you first use them. My Emacs starts up in just under a second.

  5. As an emacs user, I would say start up time is a non-issue the way most emacs users use it. Usually we start it once, and thats about it. I run it for months at a time without reloading, especially because of how easy it is to modify while running. Emacs can be run as a server or daemon and using emacsclient -c for $EDITOR you simply jump into a new frame when you need it. Between that and the awesomeness of TRAMP for remote work, I can’t ask for much more.

  6. I’ve made the switch from gVim to Emacs w/ Viper and Vimpulse, and it’s my primary development environment. Yes, there are a few quirks, but no major obstacles.

  7. Something to note: due to its old-school dynamic scoping, Elisp lambda expressions do not actually form a lexical closure. Generally it’s not an issue, but sometimes closures would be really nice to have. If Guile ever becomes the Lisp back-end (including its Elisp compiler targeting the Guile VM) in the future, this will be corrected.

  8. Try using python/ruby/perl/tcl for scripting vim.

    You still need a decent handle of Vimscript, but it may make writing a script simpler for you.

    The internal documentation and the IBM 5 part vimscript series are a good place to start.

  9. Haha, I didn’t expect so many people to comment on this article. The Editor War still rages on…

    @Vebyast: Did you read the entire post? I said I use Emacs with Vimpulse. (VIMpulse, hint hint.) And regarding remapping the capslock key: sorry, I already have it mapped to my “mod” key for XMonad, which makes my X window navigation lightning fast. No way I’m going to give up my capslock key now!

    @Michael Van Veen: Yeah, same here: I tried Viper a while back and was not satisfied at all. But Vimpulse (a very young script) is great! Vimpulse comes with Visual Mode AND Visual Block Mode! Just google for “emacs vimpulse” and go to the Emacs wiki page on it, where you can grab the latest Vimpulse script and learn more about it. Apparently, in Emacs you have to set up one or more “load paths”, which point to directories where you hold all your external scripts. So for me I have these two lines:

    (add-to-list ‘load-path “~/.emacs.d/script”) ; load path for scripts — choose your own
    (require ‘vimpulse) ; actual command to “load up” vimpulse on startup

    Vimpulse automatically loads viper.el (which comes with your latest emacs install), so you only need to have vimpulse.el in your load-path directory. My emacs installation/setup is extremely spartan: I only have the following emacs packages on Arch Linux: emacs, emacs-color-theme (self-explanatory), emacs-org-mode (for org mode), and emacs-yasnippet (let’s you easily put in snippets of code; haven’t used it myself yet, but I’ll start using it with org mode in the future). I also recommend the following scripts to put into your load-path: vimpulse.el (duh), and undo-tree.el (more sane undo/redo like in Vim).

    Oh, and make sure that you don’t have any old ~/.viper configuration files left over from your old viper mode use. It really messed up my configuration with Vimpulse on my desktop and made me lose a couple hours of time hunting down the issue.

    @bmj: For heavy LaTeX files, with lots of nested expressions that really torture the regexes that Vim uses for syntax highlighting, I’ve found that Emacs handles them much better (holding down “j” in Vim versus holding down “j” in Emacs + Vimpulse). Just a little more background on this issue: I have “xset r rate 250 80″ in my ~/.xinitrc, which makes my keystroke repeat rate VERY fast. If I hold down “j” in my 500-line template LaTeX file (which has very heavily nested expressions and such), I notice some intermittent delays while the screen scrolls down. Also, even after I let go of the “j” key, Vim continues to scroll down! (Vim obviously saves each keystroke onto a stack, and processes this stack regardless of the current keyboard state). But in Emacs, there is very little, if any, intermittent delays while scrolling down, AND Emacs stops immediately after I stop holding down the “j” key.

    @bmj (again): As for the syntax highlighting code tinkering, etc., I’ve been there for Vim as well (creating my own syntax code for my custom outline files), and Vim didn’t really make the process easy at all — you have to work with lots of regular expressions (and I’m pretty good at regexes myself…). I don’t know how syntax highlighting code is messed around with in Emacs (yet). But I’ll take your word that Vim is still better than Emacs in this regard.

    @Phil: Yes, well, if I have a blank ~/.emacs file and ~/.emacs.d directory, emacs (the GUI one) starts up in just under a second as well (and with caching, gets even faster). Apparently, my somewhat simple ~/.emacs file with some customized keybindings, a custom color theme, a default font, Vimpulse mode, and yasnippet (among other trivial customizations) slows down my emacs startup time by about 3 seconds. My ~/.emacs file is only 173 lines long (including comments), too. I’m pretty sure I did everything properly because I only followed the Emacs wiki pages and other reputable Emacs power user sites to help me guide my ~/.emacs configuration.

    @atom: Hmm, I did not know that you could run emacs as a server. Sounds like that will indeed kill startup times to near-zero. I’ll probably explore this possibility in the future, sometime. Thanks!

    @Zaki: I already knew about VimOrganizer before I wrote my post. But the fact that you can use Org-mode (which has a much larger developer/community base) in conjunction with Vimpulse (a better Viper mode) makes VimOrganizer sort of… pointless. I only invest my time/tech into developer/user heavy areas, and Org-mode beats VimOrganizer by a mile in this respect. Besides, Org-mode is written in Lisp, versus VimOrganizer which is written in (shudder) Vimscript. I bet on Org-mode being always superior to VimOrganizer for the foreseeable future.

    @td: I tried the Ruby API for Vim, and it was too difficult to get anything done. Virtually zero working examples exist (the documentation is very sparsely written). The IBM article on Vimscript was my starting point too, by the way, and I simply gave up. I mean, are there any non-trivial Vim plugins that take advantage of the Python/Ruby/Perl/Tcl/etc. API? The fact that every single Vim plugin I’ve encountered uses Vimscript is a testament to how poorly the external scripting API is implemented and/or documented.

  10. What kind of script did you have in mind? Did you query the VIM IRC channel?
    The Ruby/Python/TCL/Perl interface give you the minimum number of methods to automate/drive VIM.

    To write any substantial script one has to cover the following:
    -basic and advanced editing reference sections
    -usr_40.txt to usr_44.txt

    You might want to look at LustyExplorer (a Ruby script)
    http://www.vim.org/scripts/script.php?script_id=1890

  11. @td: The kind of script I originally had in mind (this is a couple years back, by the way) was something along the lines of an org-mode clone (just its outlining capabilities), with hotkeys for promoting/demoting subtrees, moving subtrees around up an down, etc. At the time, I found the docs inaccessible and did not bother trying to hunt down existing Ruby scripts for guidance (perhaps this was my greatest mistake). I just downloaded LustyExplorer and am stunned by the amount of Ruby used in there to “automate/drive” Vim as you put it. So I guess I’ve been living under a rock somewhat…

  12. @Chris: Sorry, I only noticed your comment when I was cleaning out my comment queue, since it was marked as spam by Akismet! (Is even Akismet biased against Emacs? Haha.) Anyway, I was under the impression that lambda expressions and closures were the same thing, but I realize my error, thanks to you. I am a Haskell newbie and was so happy to see lambda expressions in my recent Emacs encounter that I got a little carried away. Here is a link about lambdas vs. closures, for those who are curious: http://stackoverflow.com/questions/220658/what-is-the-difference-between-a-closure-and-a-lambda

  13. Nice post, but I feel I would like to make a few (non-religious, hopefully) remarks about it:

    1. No, navigation isn’t any quicker in vim than it is in Emacs. Srsly. If a good example of how quick it is in vim requires you to write something in your config (or atlest in the modeline thingy), how is that any faster than pressing F3 (start a macro), make the same navigational operations (don’t underestimate the C-u prefix!) and then press F4,F4,F4,F4? If you need the command several times, just name it and save it to your conf.

    2. Macros are awesome. Learn to use them, and a lot of the cool features(I admit that there are cool things about modal editing) of modal editing goes pale in comparison. Name the macro and save it for later use.

    3. If you like working on a dual head setup, just start a new frame my typing M-x make-frame, and you get another frame. Or use Emacs in daemon mode and bind it to a keybinding in your window manager (I use win-f1 on my awesome wm netbook) and it’s slightly quicker. Sure, my Emacs takes a few seconds to load on my netbook (10 s, 3 s on this imac) but it’s loaded while logging in so I don’t notice anything since I never shutdown (suspend ftw) my computer anyways :)

  14. @Oscar

    Regarding your point #1: my example in my config only added 2 *extra* keys to the *many* default navigation keys that Vim offers. These are f, F, h, j, k, l, w, W, b, B, e, E, 0, ^, $, G, gg, [, ], just to name a few. There are more. Yes, you can write up macros in Emacs and save them to your config to emulate all of these Vim navigation commands, but you will *always* be slower in Emacs because you simply cannot beat a 1,2-keypress hotkey with an Emacs macro (I imagine you’d run out of function keys, not to mention how function keys are physically far away from the home row). And I did not mention the ton of useful Vim keys that *combine* navigation with editing, like C, c, I, A, etc. to make it even faster! (Here are just a few nice goodies that Vim provides: cw, ci{, ci(, etc.)

    Regarding your point #2: Yes macros are awesome. But comparing modal editing against macros is simply invalid, because they are two totally different things. Vim has macros, too, just like Emacs. So you should compare Vim’s macro capabilities with Emacs’ macro capabilities (which is sort of what I did in my post regarding key mappings). Modal editing is a Vim feature that Emacs has *zero* support for. I suspect that you have not used Vim enough to appreciate how modal editing allows you to use a ton of cool hotkeys for navigation/editing (like the hotkeys I’ve mentioned in my preceding paragraph).

    Regarding your point #3: Yes, starting emacs as a daemon is definitely an option, and Emacs’ “frames” concept is verrrrry nice. I wish Vim had frames, too. I’ll probably make a macro out of (M-x make-frame) and use that.

  15. @Shinobu: Got it. I didn’t do enough research to realize that vimpulse pulled in viper-mode. Also, agreed on using caps lock for window navigation. I mapped a bunch of my nav hotkeys to control-meta chords and got a keyboard that puts left alt in easy reach of my thumb, so I have close to the best of both worlds.

  16. @Elena: Hmm, I see what you mean because your middle finger is longer than your index finger. To come to think of it, I can’t think of any reasons to stick with “jk”. I’ll try out “kj” — thanks for the suggestion!

  17. With evil, you can do mode specific things like
    (evil-declare-key ‘normal org-mode-map “T” ‘org-todo)
    (evil-declare-key ‘normal org-mode-map “-” ‘org-cycle-list-bullet)

  18. @Shinobu: Don’t vimpulse and evil count as modal editing support in emacs? In my case, I use control-lock-mode to give me some of the benefits of modal editing when I need them (mainly when spell checking).

Comments are closed.