8

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:

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.

Jon Galloway
  • 52,327
  • 25
  • 125
  • 193
  • 2
    Sounds like "code snippets" on steroids. I wonder if there is something you can leverage from that feature. – Merlyn Morgan-Graham Jul 01 '11 at 08:20
  • If the expansion doesn't rely on contextual details of the codebase, perhaps an AutoHotKey script would suffice. – AakashM Jul 01 '11 at 12:31
  • I just released an Extension like this actually.. Check it out here: http://yngvenilsen.wordpress.com/2011/11/19/zencoding-visual-studio-2010-extension-v1-7/ – Yngve B-Nilsen Nov 19 '11 at 13:13

3 Answers3

9

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.

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.

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

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.
rpjohnst
  • 1,612
  • 14
  • 21
JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
  • Thanks! I'd like to add Zen Coding support to Visual Studio, preferably as a VSIX. Here's an overview: http://coding.smashingmagazine.com/2009/11/21/zen-coding-a-new-way-to-write-html-code/ - seems like maybe the IOleCommandTarget with IVsTextView would work? Zen Coding is written in JavaScript, thinking I could call into that using a .NET JavaScript impl like IronJs / Jurassic. – Jon Galloway Jul 01 '11 at 17:46
  • @Jon I updated my answer to have a bit more detail on that scenario. Please let me know if you need any other info – JaredPar Jul 01 '11 at 18:08
  • @JaredPar Sorry for digging up an old post, but I hope you can help me with my current problem. I'm doing something similar to what Jon is doing. I follow the VSIX + IOleCommandTarget approach. I want to listen to the Ctrl+K, Ctrl+C key. However, when this key combination is pressed, VS shows "The key combination (Ctrl+K, Ctrl+C) is bound to command (Comment Selection) which is not currently available" in the status bar, and my Exec() function is not invoked. Any idea how I can fix that? – superkinhluan Jan 02 '20 at 12:14
1

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

It uses ReSharper as a plug-in host though.

henriksen
  • 1,137
  • 1
  • 11
  • 24
1

I would look at building on ReSharper's LiveTemplates. You can do a lot with macros to make the expansion more intelligent than simple fill-in-the-blanks. I'm not an expert in that area, but I have seen some fairly sophisticated templates built this way.

Mel
  • 2,337
  • 19
  • 25