Creating a simple text-manipulating Visual Studio 2010 extension
Asked Answered
G

2

6

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:

  1. Registering Commands that users can bind hotkeys to via Tools->Options->Keyboard.
  2. Modify the text buffer of the active window when Commands are invoked.
  3. 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(SVsTextManager));
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?

Groats answered 3/11, 2010 at 8:15 Comment(0)
G
9

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.

Gamaliel answered 4/11, 2010 at 7:1 Comment(1)
Thanks! There's something about adding a filter to every VsTextView that irks me a bit, but the solution is definitely better. Too bad one still has to deal with ugly com/ole legacy, but at least it's minimal and can be abstracted away :)Groats
F
0

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.

Fagan answered 3/11, 2010 at 11:14 Comment(1)
I mean getting the ITextBuffer for the current/active document - which is the new way to interface with the text editing services, instead of the more limited DTE/Selection methods.Groats

© 2022 - 2024 — McMap. All rights reserved.