Vi modes in MonoDevelop

I've recently added simple vi modes emulation to MonoDevelop. It's been a relatively quick and easy hack, though I'm pretty sure I'm now running a deficit of free time. I'm not actually a vi user, but I've been hearing from several of our users that they miss vi navigation and commands. While most editors (for example emacs) can be simulated to some extend through a keybinding theme, it's impossible to replicate even the simplest behaviours of vi this way.

After seeing ViEmu, a successful vi emulation addin for Visual Studio, I realised that a vi mode in MonoDevelop would probably see a lot of use, and, as a challenge, decided to bootstrap it. I'm hoping that real vi/vim users will contribute tweaks and patches to bring it closer to a faithful vi experience.

Some of you might be wondering why I started from scratch, since over a year ago, Ankit embedded vim in MonoDevelop. There are several reasons why I don't think this is the best approach. Embedding vim means you have perfect vim support, but you have to manually integrate all of the MonoDevelop features one by one. Integrating code completion is only the first step. Consider integrating language item tooltips, refactoring/navigation commands, error underlining, code folding, language item combos, semantic highlighting, text templates draggable from the toolbox, debugger breakpoint and stepping markers, debugger value inspection tooltips. Even when you finish this, you have to deal with potential future features like per-project editor settings, contexual multi-field templates, and who knows what else. People using vim integration would always be second-class MonoDevelop users.

I don't want to bring MonoDevelop features to vim, I want to bring vi/vim features to MonoDevelop.

Spelunking deep into Mono.TextEditor code, I implemented vi modes and commands at the very core of the text editor. The action-based architecture made this pretty easy to do at the core, though I'm running into a few problems at the higher levels of MonoDevelop, particularly the C# smart indenter, which relies on hooking <Enter> keystrokes. Fortunately it's still very usable.

The code is in MD SVN, and can be enabled through a checkbox in the Preferences -> Text Editor -> Behaviour panel. Features implemented so far are:

Motions
h j k l w b % 0 ^ _ $ G { }
Delete commands
d d{motion} dd D x X
Change commands
c c{motion} cc C r R
Insert commands
a A i I o O
Ex commands
 :q :w :qw :q! :{linenumber}

In addition, keyboard directional keys act where appropriate, normal MonoDevelop keyboard shortcuts remain functional, and visual mode is implemented but so far can only be used with normal MonoDevelop keyboard shortcuts.

I have a pretty good idea of what I'd like to see and how I'd like to see them implemented, in particular with regard to refactoring so that macros and repeat commands can be implemented. This will not be easy, but there are many other low-hanging fruit: B W e E ( ) word and sentence navigation, simple search/replace, repeated motions (e.g. d10w), cut/copy/paste. I'd also like to add some ex commands for IDE features, e.g. build project, jump to definition, rename variable, go to base class, implement interface. These are pretty easy too, though naming the commands will take some thought. It might be worth borrowing some ideas from jVi/NetBeans.

Unfortunately I'm not likely to have any time to spend on vi modes in the near future, but I welcome contributions, and will be glad to provide guidance to anyone who'd like to contribute.

Comments

Indeed a good thing. The kind of feature I have been waiting for long ;-) Can't wait to test it

great work! I've been using this for a few days now and wow'd a few folks at work.

Cheers are in order!

Hi,

That is the coolest thing since ViEmu for visual studio. You're a god and i love you!

Fantastic to hear!

As the author of vimperator (http://vimperator.org) who brought vim-keys to Firefox, I am so happy to see that MonoDevelop finally gets vim-like behavior as well!

Actually I currently use ViEmu for VisualStudio at work, but maybe I can now plan to replace VS with MD at one time.

Thanks!

BTW: only 3 really really important keys seem to be missing, but might already have been added in SVN in the meanwhile:

1.) gg to go to the top (just like G to go to the bottom)
2.) s deletes the character under the cursor and starts insert mode
3.) S deletes the whole line and starts insert mode.

Of course some other keys like (f,F,t and T) are cool keys in vim, but the 3 above probably are the most often missed ones.

Yes, those three commands were added quite some time ago. I'm pretty sure they made it into the MD 2.0 release. Unfortunately a couple of things (e.g. visual selection) are broken in trunk and 2.2 beta 1. I'll make sure they get fixed up for 2.2.

It's actually quite funny that I wasn't a vi user before I implemented vi mode for MD, but I became a vi user as a result. Now even I miss f, t and /foo motions. I'm been planning to implement them for quite some time but have been plagued with indecision over sorting out the architecture for full multi-character command support, and thing like . and q.

I am currently working in Visual Studio with the ViEmu addin, but am looking at going over to MonoDevelop. The VIM functionallity is one of the things that make me stay, still. With f,t,s and repetitition like d10d or 10dd this would be very usable. Until then, i keep pressing too many keys which do not work. Are there plans to add these or is the project on ice?

I still intend to do it at some point myself if no-one else does it first, but I have too many other high-priority items to worry about right now.

There's a task list for vi mode on the MD wiki.

Hi thanks for the wonderful info. Just installed MonoDevelop 2.4 and started using Vi mode. Was missing Vi big time!!Thanks a ton.

gee thanks.

Is it possible to implement code collapsing (folding)? (eg. zc, zR, zM, etc...)

I don't think it would be hard, someone just has to find the time to do it.

When I saw that MonoDevelop had a VI mode, I decided this is what I was going to use to create my first game in the Unity Engine.

I am sadly disappointed that the VI mode is so half baked, and lacking many features that I consider to be the best features of VI.

Notably:
1. command repetition. The lack of this single feature made it clear that the author doesn't use VI. I discovered this on about my third command into trying to use VI with MonoDevelop, and this single feature (or lack thereof) might honestly be a deal breaker for me. It's FAR too useful to do without.
2.marks. Not being able to set marks means that you can't really use VI...

From the lack of activity on this subject, is it safe to assume that you guys have just dropped this feature? I certainly hope not, because it's a powerful editor that blends incredibly well with an IDE when it's properly implemented. (Eclipse/vrapper being a prime example, even if it's not perfect!).

I suppose that's that. After under 5 minutes spent trying to use VI mode in MD, I am left feeling like a kid teased with the promise of Christmas, who wakes up on Christmas morning to a pair of underwear, and three mis-matched socks under the tree. All of them clearly used.

I strongly recommend that you continue development on this feature, and I would LOVE to see it working soon. Thank you for all your hard work on MonoDevelop - it is a strong product, even without VI! :)

I really wish I had more time to work on the vi mode.

When I started it, I wasn't a vi user, so I made some assumptions that made adding support for multipliers and more complex text objects very hard. I started to rewrite it from scratch, but never finished. I still hope I can continue to work on it eventually, but assistance would be very welcome...

I think that the problem was this consideration:
1) Easier to implement the MonoDevelop features into the embedded VIM
2) Easier to rewrite VIM in MonoDevelop

Choice (1) would have been the clear answer had you known that VIM is more than just a few keybindings. I do appreciate your effort, but unfortunately implementing (some) VIM keybindings in MonoDevelop is not enough to entice one away from VIM. Thank you for your effort, though! I hope to see real VIM embedded in MonoDevelop in a usable state someday.