marijnh/CodeMirror — pull request #984 by mightyguava (2012-11-19 00:40:27+00:00)
Title: [vim] Reimplementation of Vim key mappings

This is a reimplementation of Vim key mappings. The reasons why I felt a reimplementation was necessary are listed in a previous pull request by @jankeromnes at https://github.com/marijnh/CodeMirror/pull/973#issuecomment-10353728. Sorry about the long pull request but there are a lot of changes and a lot to discuss. Thank you in advance for taking the time to read this.

### Summary
This reimplementation has reached feature parity with the original, with some divergence in features. Overall the code is cleaner and more maintainable, which should make future additions significantly less time consuming and less error prone.

I opened this as a pull request because I would like to ask for advice from the community on where to go from here, and see if this can be added to the main repository so that others can use it and contribute. While the reimplementation has not reached reached feature parity, there are only a few missing features and I'm not sure when I'll get to implement them. There are also many behavioral fixes and a few new features that would be useful to existing users.

### Discussion

I am usually against having 2 parallel implementations, and would greatly appreciate any opinions on how we can get the features merged. However, due to the reasons above I think in the short term the best solution would be to have both available, maybe with this as a separate branch?

While investigating how to implement visual mode, I saw that setCursor() clears the selection (let me know if I am mistaken). Would it be possible to add to the exported CodeMirror API a version of setCursor() that does not reset to selection, and/or methods to expand the existing selection? Or do these APIs already exist? If they don't I'd be happy to add them with some assistance.

To support additional key-to-key mappings, like mapping 'Left' to 'j' and 'Y' to 'y$', the Vim keymap would need to expose some API functions to let users define the mapping. This could also be a feature in codemirror.js but it seems to be more of a Vim specific feature. I currently am exporting a Vim instance object as a property of CodeMirror. Is that fine or should we work out a different way?

### Functional differences from original

**Additional features not in original**

+ Support for marks
+ Support for registers
+ Respects orthogonality between motions and operators (newly implemented motions should work with existing operators without additional changes, and vice versa. Also, should be less buggy because action and motion commands execute independently)
+ A combined keymap with no nesting (plus a trivial insert mode keymap), compared to multiple prefix keymaps in the original implementation

**Yet to be implemented**

- Support for text object manipulation (I am not familiar with this and would rather implement Visual mode)
- Ctrl-F, Ctrl-B (they would be easy to do for normal mode, but in order to make them visual mode compatible, need a way to get the position in the next page without moving the cursor)
- Ctrl-N, Ctrl-P, arrow keys, space, and backspace (don't believe these are commonly used over the usual vim navigation keys, though I might be wrong, and I want to implement them via key-to-key mappings instead duplicating them in the main keymap)

### Next steps
The immediate next steps for the reimplementation, in any order, would be:

- visual mode
- key-to-key (and key-to-command) mappings, like mapping Y to y$ (this is an important vim feature that would be very difficult to do in the original, but should be pretty simple in the reimplementation)
- text objects