Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Visual Studio 2010 extension that does code expansion

I want to build a Visual Studio 2010 VSIX extension that expands some text based on a call to a method (using the Zen Coding selector-based syntax). Ideally, a user would type a string of text, hit a hotkey, and the string of text would be expanded.

I've looked at a lot of samples, but they all focus either on full-blown language services or on simple adornments. Ideally, I'd like to find a full working sample, but I'd be happy with the interfaces / classes and some code.

Some references I looked at:

  • http://msdn.microsoft.com/en-us/library/bb165336.aspx
  • http://msdn.microsoft.com/en-US/vstudio/ff718165.aspx
  • http://msdn.microsoft.com/en-us/library/ee372314.aspx

Update: I know that Resharper and CodeRush do this kind of thing. I'd like to do this as a stand-alone plugin if possible.

like image 964
Jon Galloway Avatar asked Jul 01 '11 08:07

Jon Galloway


People also ask

How do I expand all methods in Visual Studio?

CTRL + M + P will expand all and disable outlining. CTRL + M + M will collapse/expand the current section.

How do I collapse and expand code in Visual Studio?

There are actions to fold level 1 ( Ctrl + K Ctrl + 1 ) to level 5 ( Ctrl + K Ctrl + 5 ). To unfold, use Unfold All ( Ctrl + Shift + Alt + ] ).

How do I add code to Visual Studio?

Import a code snippet You can import a snippet to your Visual Studio installation by using the Code Snippets Manager. Open it by choosing Tools > Code Snippets Manager. Click the Import button. Go to the location where you saved the code snippet in the previous procedure, select it, and click Open.

What are IDE extensions?

What are extensions? Extensions are add-ons that allow you to customize and enhance your experience in Visual Studio by adding new features or integrating existing tools. An extension can range in all levels of complexity, but its main purpose is to increase your productivity and cater to your workflow.


2 Answers

It sounds like you're looking for a good example / reference on how to do keyboard handling to drive text insertion into the Visual Studio buffer.

Unfortunately this is not a question that has a straight forward answer. Keyboard handling in Visual Studio is complex at best and hair pulling frustrating at times. I've tried to keep this answer as simple as possible but unfortunately the topic doesn't lend itself to simplicity

To start there are at least 5 different mechanisms by which Visual Studio routes keyboard input into commands.

  • Binding to known Visual Studio commands
  • Via KeyProcessor (2010 and above only)
  • Via IVsFilterKeys.TranslateAccelerator (2005 and above IIRC)
  • Via IOleCommandTarget
  • Alt key mapping (something I don't actually understand well at all)

Which of these you need to hook into depends on a couple of factors

  • What versions of Visual Studio you want the addin to function in?
  • What type of add-in will you be building: an actual Addin, Vs Package or VSIX
  • How deeply you care about winning the battle for keyboard input

Which of these you need to hook into depends a lot on how you want your addin to function and in what versions of Visual Studio you want it to work. Though there are 2 basic routes you can take though

The first is develop a Visual Studio Package and register a DTE.Command for every hotkey in your extension. You'd then need to add on IOleCommandTarget into the IVsTextViews filter chain to process your commands. This approach will allow you to process your hot keys in the majority of scenarios.

The second is to develop a VSIX, hook into the IOleCommandTarget chain of the IVsTextView and intercept real Visual Studio commands which map to your hot keys.

Both of these approaches have their ups and downs but my answer is already a bit too long as it is. If you can give me some more details I can try and give you a more concise and helpful answer.

As for examples. VsVim does pretty extensive keyboard handling for Visual Studio and has an example for any of the above methods I mentioned.

  • https://github.com/jaredpar/VsVim

Let me know which one interests you and I can point you to the right place in the source code.

Additionally while working myself on figuring out the tangle of keyboard input I tried to keep a record of what all I'd learned. It's not fully up to date but this document describes the more basic aspects of how input gets routed

  • https://github.com/jaredpar/VsVim/blob/master/Src/VsVim/KeyboardInputRouting.txt

EDIT

Jon indicated in comments the VSIX + IOleCommandTarget route

This is IMHO the simplest approach. The one thing to be aware of though is how command bindings affects the data which gets passed down the IOleCommandTarget chain. Visual Studio command binding happens before the data is passed to the IOleCommandTarget chain. So if a given key input is bound to a command it will be passed down IOleCommandTarget as the command and not the keyboard input.

For example CTRL-Z is commonly mapped to the Visual Studio Undo command. If the user hits CTRL-Z then IOleCommandTarget will see the Undo command and not the keyboard input CTRL-Z.

Here are a few samples you may be interested in looking at

  • VsCommandTarget: Sample implementation of IOleCommandTarget
  • OleCommandUtil: Used to convert the data passed into IOleCommandTarget into actual commands and keyboard input
  • HostFactory: Details how actually hookup an IOleCommandTarget into an IVsTextView from a VSIX extension.
like image 145
JaredPar Avatar answered Oct 10 '22 08:10

JaredPar


Maybe this could help: http://resharperpowertoys.codeplex.com/wikipage?title=ZenCoding

It uses ReSharper as a plug-in host though.

like image 29
henriksen Avatar answered Oct 10 '22 07:10

henriksen