Creating a simple text-manipulating Visual Studio 2010 extension
I've been wanting to create a simple text-manipulating extension for Visual Studio for a while, and now I've finally found some time to look into how extensions are written. What I have in mind could be accomplished through VBA macros, but I'd rather implement it as a "real" extension; as a learning process, and because I honestly can't stand VBA.
After a fair amount of googling, blog reading, digging into MSDN and browsing StackOverflow posts, I think I've gathered enough information that I can implement it - but I'd like some feedback on whether I'm approaching things right before I start hacking away :)
What I'd like is:
- Registering Commands that users can bind hotkeys to via Tools->Options->Keyboard.
- Modify the text buffer of the active window when Commands are invoked.
- I don't really care about menus or toolbars, but know how to add it via .vsct files (are there better options?)
For #1, it seems I have to do a full VSPackage, .vsct file et cetera - there's no nice-and-easy MEF extension point I can handle instead? (Perhaps exporting a IWpfTextViewCreationListener
and fiddling around with manual keyboard shortcut handling - but that'd be a major hack).
For #2, I'm unsure how to get an ITextBuffer
for the active document. I could go through DTE.ActiveDocument
, but I'm not sure how to obtain an ITextBuffer
from that. Alternatively, I could do something along the lines of...
var txtMgr = (IVsTextManager)ServiceProvider.GetService(typeof(SV开发者_JAVA技巧sTextManager));
IVsTextView textViewCurrent;
txtMgr.GetActiveView(true, null, out textView);
IWpfTextView wpfViewCurrent = AdaptersFactory.GetWpfTextView(textView);
ITextBuffer textCurrent = wpfViewCurrent.TextBuffer;
...but that sure does look like a roundabout way of doing things?
For both of these, take a look at the Align Assignments extension source. It's a package/MEF component that adds a command and handles it in the active window.
Your answer to #1 is correct. The best way to do commands is with a .vsct file, which requires a package. However, all a package means is that your project will be producing a dll with embedded resources (from the .vsct file) and a .pkgdef file, which adds registry keys according to the attributes you supply on your package. It (hopefully) isn't too much overhead.
For your second question, there is a cleaner way. Take a look at the command filter, which listens for commands in the active view, instead of listening for them globally and then finding the active view. It lets the shell handle the command routing and just concentrates on the implementation.
Not entirely sure what you mean by "the text buffer" but assuming you mean either the current text file that is open or the current selection, here is some code I have in a package to access those:
EnvDTE.DTE app = (EnvDTE.DTE)GetService(typeof(SDTE));
if (app.ActiveDocument != null && app.ActiveDocument.Type == "Text")
{
EnvDTE.TextDocument text = (EnvDTE.TextDocument)app.ActiveDocument.Object(String.Empty);
if (!text.Selection.IsEmpty)
{
//work with text.Selection.Text
}
}
Of course if you're doing an editor extension it would be different.
精彩评论