How to extend the Visual Studio editor

Source: Internet
Author: User
Tags visual studio 2010

In the era of Visual Studio 2010, there are many ways to extend Visual Studio, and developers can choose to customize extensions for macros, add-in, MEF, and VSPackages. But the macros were castrated in Visual Studio 2012, Add-in was also erased in Visual Studio 2013, which is good for Visual Studio, but for those accustomed to using macros and add-in, it may be depressing The

This article will teach you how to implement extensions to the Visual Studio Code Editor, eventually implementing an extension that supports the following two functions.

1. Automatic task annotations (post-extension support)

Task annotations are annotations that can be treated differently by Visual Studio, such as//todo,//fixme, and different task annotations may require different formats, such as those that need to be commented out first, some that need to be preceded and followed by lines of code, and so on, which in the past is supported by the macro. We can use macros to implement this type of operation. Different project groups use these tags differently, so there are different requirements, and this tool supports custom extensions.

2. Jump to the head or tail of the method

This function seems useless, but when a method has hundreds of rows, or even thousands of lines, how to quickly jump to the beginning or end of the method is more troublesome.

Figure 1 Final Effect animation demo (click to enlarge to view)

Reading this article, you need to know the following knowledge points:

1. MVVM and WPF--hurry to get to know (this article lying on their website, did not have time to sync to the blog park, we will be a bit)
2. MEF--Hurry to find out

If you want to experience this extension quickly, please hit here! (Visual Studio 2012 only)

  Outline of this article

MEF and VSPackage

Preparatory work

The differences between the various Editor templates

Visual Studio Lab Environment

Editor Viewport Adornment Principle analysis

Adding controls and base code

Get the DTE Object

Complete the functional logic

Add extension points to allow annotations to support post-extension

Why VSPackages or MEF?

Source Code Control

Reference Resources

Before entering the text, let's quickly get to know the two surviving heroes.

MEF and VSPackage

Beginning with Visual Studio 2013, only MEF and VSPackage are left for extensions to Visual Studio. Come and introduce yourself to you.

MEF (Managed extensibility Framework)

This framework was originally released independently of the. NET Framework and later integrated into. NET 4.0, and was published with. NET 4.0 (included in the System.ComponentModel.Composition.dll assembly). From the name, the framework is primarily designed to write extensible applications. With the introduction of. Net 4.0, a major change is the editor in the Visual Studio IDE, which was originally developed in the same way as other components in COM, but is now being replaced by WPF technology. Editing with WPF technology can fully support the use of MEF for scaling, which is a perfect improvement. The only regret is that as of 2013, the rest of Visual Studio is still not detached from COM.

The MEF is a. NET library, the lets you add and modify features of a application or component that follows the MEF Progra Mming model. The Visual Studio Editor can both provide and consume MEF component parts. The MEF is contained in the. NET Framework version 4 System.ComponentModel.Composition.dll assembly.

---Managed extensibility Framework in the Editor

Therefore, if you want to extend an existing editor, you can develop it based on MEF (such as modifying the highlight color for the C # code Editor, smart hints, and brace completion).

VSPackage

It can be said that in addition to the editor, Visual Studio is a collection of multiple vspackage, so the use of a vspackage can be perfectly integrated with Visual studio, and can achieve almost all the capabilities. You can choose a vspackage if you want to develop a toolbar, a menu bar, or even a new editor that provides parsing, smart hints, and so on for a new language.

Preparatory work

Children's shoes, would you please check the guy who ate the meal ready?

1. The English version of Visual Studio, the Chinese version of Visual Studio, cannot see templates such as Editor Text adornment.

2. To extend the editor or the entire visual Stuio, you must first download the installation of the visual Studio SDK (VS2012 version, click the link download), after installation, you can find the template on the "other project type" template.

Figure 2 The template after the SDK installation

  

All of the code in this article was developed based on Visual Studio 2012, and if you are using a different version, download the SDK that is appropriate for your version. The process of extended development may have a small gap between versions, but does not affect the overall development process.

The differences between the various Editor templates

After installing the SDK, you will have a variety of extension templates as shown in the four types and Editor-related templates, what is the difference between them?

Editor Classifier

You can modify the code in the editor to highlight, add some smart tags (such as when we modify a variable name, will appear in the name of a small short horizontal, when you move the mouse will be prompted if you want to modify all references), etc., the example effect is as follows:

Figure 3 Editor Classifier Example

Editor Margin

Add some WPF elements around the editor, such as when the current file is read-only, the edge hint file can be read-only in the editor, and the sample effect is as follows:

Figure 4 Adding a green message box on the next edge

Editor Text Adornment

To decorate the text in the editor, add some WPF elements, as shown in the following example:

Figure 5 Wrapping all characters A in a box

Editor Viewport Adornment

For decorating the editor itself, add some WPF elements, as shown in the following example:

Figure 6 Adds a rectangle element in the upper-right corner of the editor

This tool uses Editor Viewport adornment as a template.

Visual Studio Lab Environment

For these extended tests, Visual Studio provides experimental Instance for the lab environment, which is exactly the same as the real Visual studio, except that it and the real version have their own set of configuration files, The configuration of the lab environment does not affect the real environment.

The first time you start the lab environment, you will enter the interface of the default environment configuration shown in 7.

Figure 7 Default Environment configuration

Data in the experimental environment can be initialized

Tools in the SDK directory provide the "Reset the Visual Studio experimental Instance" command-line tool, which initializes the lab environment.

Figure 10 Initialization Tool

Editor Viewport Adornment Principle analysis

To understand it, you must first use it. When you create a new editor Viewport adornment project from a template, the sample code is already included, and the function of the sample code is 6 to add a purple rectangle to the edit area.

Figure 11 What it's like when it's just created

You must modify the Author field in the Source.extension.vsixmanifest file before running the sample code, otherwise the run will error.

Figure 12 Completion Author Field

Implementation principle

In introducing the MEF and the VSPackage, I said that the whole Editor was developed based on the MEF idea. In short, Visual Studio Editor provides a product (Export), recipient (Import), and various protocols to third-party extensions, and third-party extensions produce compliant products based on the corresponding protocol. Then VS will combine the product of a third party with one of its own recipients (as if it were a shape-matching building block in a box). That way, we'll be able to use this extension the next time we start VS.

Figure MEF Thought

The main two files in this project are:TskCommentFactory.cs and TskComment.cs.

Among them, the purpleboxadornmentfactory in the Tskcommentfactory file is the product of this protocol based on Iwpftextviewcreationlistener and the main entrance of this project. Use this protocol to add the actions we want when the editor view is created. The most important of these is the Textviewcreated method, which invokes the Tskcomment constructor to add a purple area to the editor.

 1 [Export (typeof (Iwpftextviewcreationlistener))] 2 [ContentType ("text")] 3 [Textviewrole (Predefinedtextviewro Les. Document)] 4 internal sealed class Purpleboxadornmentfactory:iwpftextviewcreationlistener 5 {6//< Summary> 7//defines the adornment layer for the scarlet adornment. This layer is ordered 8///After the selection layer in the Z-order 9///&LT;/SUMMARY&GT;10 [Ex Port (typeof (Adornmentlayerdefinition))]11 [Name ("Tskcomment")]12 [Order (after = Predefinedadornmentlayers.         Caret)]13 public adornmentlayerdefinition Editoradornmentlayer = null;14//<summary>16 Instantiates a tskcomment manager when a textView is created.17//</summary>18//<param         Name= "TextView" >the <see cref= "Iwpftextview"/> upon which the adornment should be placed</param>19         public void textviewcreated (Iwpftextview textView) 20{tskcomment new (TextView); 22}23} 

There are two main methods in the Tskcomment file: Constructors and Onsizechange methods. In the constructor, a purple rectangle is drawn from the Brush and the Onsizechange method is bound to the editor view.

1     Brush brush = new SolidColorBrush (colors.blueviolet); 2     Brush. Freeze (); 3     Brush Penbrush = new SolidColorBrush (colors.red); 4     Penbrush.freeze (); 5     Pen pen = new Pen (penbrush, 0.5); 6     Pen. Freeze (); 7   8     //draw a square with the created brush and pen 9     System.Windows.Rect r = new System.Windows.Rect (0, 0, 30 ,     Geometry g = new RectangleGeometry (r),     geometrydrawing drawing = new GeometryDrawing (brush, pen, g);     Drawing. Freeze ();     drawingimage drawingimage = new Drawingimage (drawing);     Drawingimage.freeze (); 16     _image = new Image ();     _image. Source = Drawingimage;

The above code creates a purple rectangle. It does not matter if you do not understand, because this part of the code is to be deleted.

The Addadornment method is called in Onsizechange, which adds the purple rectangle to the editor.

1 public     void Onsizechange () 2     {3         //clear the adornment layer of previous adornments 4         _ADORNMENTLAYER.R Emovealladornments (); 5   6         //place the image in the top right hand corner of the Viewport 7         canvas.setleft (_image, _view. VIEWPORTRIGHT-60); 8         canvas.settop (_image, _view. Viewporttop + 30); 9  //add The image to the         adornment layer and make it relative to the viewport11         _adornmentlayer.addadornm ENT (adornmentpositioningbehavior.viewportrelative, NULL, NULL, _image, NULL);     

By now, the principle part has been finished, whether you believe it or not, you can modify the Tskcomment in the two methods to achieve their own expansion.

Adding controls and base code

How do I implement the function I want?

First of all, our tools need an interface that can be interacted with, which is no way to simply draw with a Brush. Therefore, you need to create a new WPF control (not a Winform control, addadornment can only accept WPF elements).

Figure 14 Creating a new WPF user control

According to the idea of MVVM, add Delegatecommand, ViewModelBase, Mainviewmodel these files, our core logic is all in Mainviewmodel.

Figure 15 The new file

The code in MainWindow.xaml is as follows (omitting some elements that are not logically related).

1 <usercontrol x:class= "Tskcomment.maincontrol" 2              ... 3              d:designheight= "width=" > 4     <UserControl.DataContext> 5         <local:MainViewModel> </local:MainViewModel> 6     </UserControl.DataContext> 7   8     <Expander> 9         <grid height= "verticalalignment=" "Top" >10             <button content= "{} {"  command= "{Binding movetotopofblockcmd} "/>11             <button content="} "command=" {Binding movetobottomofblockcmd} "/>12             <button content=" execution "command=" {Binding executecmd} "isdefault=" true "/>13             <combobox iseditable=" true "itemssource=" {Binding Cmtcollection} "selecteditem=" {Binding SelectedItem} "name=" Cmtcol "/>14         </grid>15     </ Expander>16 </UserControl>

The code in Mainviewmodel is as follows (omitting some extraneous code), where the code for Movetotoporbottomofblock and Execute two methods is temporarily empty because of a missing key element.

 1 #region Properties and fields 2 3 private observablecollection<basecomment> _cmtcollection = new Ob Servablecollection<basecomment> ();         4 Public observablecollection<basecomment> cmtcollection 5 {6 get {return _cmtcollection;} 7 set {_cmtcollection = value; raisePropertyChanged ("Cmtcollection");  } 8} 9 private Basecomment SelectedItem = null;11 public basecomment SelectedItem12 {get { return SelectedItem; }14 set {SelectedItem = value; raisePropertyChanged ("SelectedItem"); }15}16 Delegatecommand movetotopofblockcmd {get; set;} Public Delegatecommand Movetobottomofblockcmd {get; set;} Public Delegatecommand Executecmd {get; set;} #endregion22 #region Ctor24 Public Mainviewmodel () movetotopofblockcm D = new Delegatecommand ((o) = Movetotoporbottomofblock (true)); Movetobottomofblockcmd =New Delegatecommand ((o) = Movetotoporbottomofblock (False)), Executecmd = new Delegatecommand ((o) = Comme NT ());}31 #endregion33 #region Methods35 (+)-private void Movetotoporbottomofblock (bool up) 37 {38//... Missing key element}40 Comment () 42 {43//... Missing key elements}45 #endregion

Get the DTE Object

The key element missing in the previous section is actually the DTE, which is equivalent to an instance of Visual Studio that can manipulate the object in the editor (see reference Resource [1] If you want to know more about it), such as Cut, paste, new row, jump to method body, and so on. So, if you want to implement the tool I'm talking about, I'm going to rely on this object.

In the macro editor, it's easy to get the object, but it's a little bit cumbersome here. We have to use one of the products of Visual Studio (Export)--Svsserviceprovider. This object can be obtained by the GetService of the product.

Modify the Tskcommentfactory code as follows:

1 internal sealed class Tskcommentfactory:iwpftextviewcreationlistener 2 {3     [Import] 4     Internal Svsserviceprov Ider serviceprovider = null;   <--through this code, you can get the product of Visual Studio 5           6     //Omit unrelated code 7   8 public     void textviewcreated (Iwpftextview TextView) 9     {Ten         DTE DTE = (DTE) Serviceprovider.getservice (typeof (DTE));//<--get DTE object one by one         new tskcomment (TextView, DTE); <--Pass DTE to View12     }13  14}

Note: The DTE exists in the EnvDTE.dll assembly, Svsserviceprovider exists in the Microsoft.visualstudio.shell.immutable.10.0.dll assembly, and you need to add these assemblies to the project first

Complete the functional logic

Now that we've got the key elements, we'll refine the code in Mainviewmodel.

1 private void Movetotoporbottomofblock (bool up) 2 {3     if (DTE = = null) 4     {5         return; 6     } 7   8     Code Function func = selection.activepoint.codeelement[vscmelement.vscmelementfunction] as CodeFunction; 9     if (func! = null) One-by-one     {         if (UP)             Selection.movetopoint (func. StartPoint),         }16         else17         {             selection.movetopoint (func. EndPoint);         }20     }21}22-  private void Comment (),     selection.startofline ();     Selection.newline ();     selection.lineup ();     Selection.Text = "//todo:";     DTE. ExecuteCommand ("Edit.formatselection"); 30}

Modify the MainWindow code to allow it to accept the DTE.

1 public     partial class Mainwindow:usercontrol2     {3 public         MainWindow (DTE DTE) 4         {5             InitializeComponent (); 6             ((Mainviewmodel) this. DataContext). DTE = dte;7         }8     }

Modify the corresponding section in the TskComment.cs

1 private MainWindow _win; 2   3//... Omit part code 4   5 Public tskcomment (Iwpftextview view,dte DTE) 6 {7     _win = new MainWindow (DTE);           8   9     //... Ten}11 public  void Onsizechange () ...     canvas.setleft (_win, _view. VIEWPORTRIGHT-310); <--Adjust position     canvas.settop (_win, _view. Viewporttop + 90); <--adjustment position     _adornmentlayer.addadornment (adornmentpositioningbehavior.viewportrelative, NULL, NULL, _win, NULL); <--to put win on the interface 20}

Oh, now it's ready to run!

Figure 16 Animation Demo

Add extension points to allow annotations to support post-extension

The above code has been completed, but this comment is too impersonal, if I want to add a Phase0 comments or fixme comments, but also to modify the code. As a result, the code is upgraded in the same way as MEF thought.

Only the key code is explained here, the other part, please see the source code of the children's shoes.

New Protocol Item

Add a separate project to hold the Protocol interface and provide an abstract class based on this interface.

1 Public     Interface Icomment 2     {3         string Title {get;} 4         string Description {get;} 5         void Execute (D TE DTE); Give the DTE to a third party so that you can manipulate the editor with this 6     } 7       8 public     abstract class Basecomment:icomment 9     {ten         public abstract string Title{get;} One  public         abstract string Description{get;} Public         abstract void Execute (DTE DTE), Public         override string ToString (),         {18             return title;19         }         protected TextSelection Selection (DTE DTE), {at the             return DTE. activedocument.selection;24         }25         protected CodeFunction Function (DTE DTE)             Selection (DTE). Activepoint.codeelement[vscmelement.vscmelementfunction] as codefunction;29         }30     }

new "Recipient"

With the agreement, it is time to add a recipient to our tool so that MEF can help us to combine the products of third parties with our receivers.

Modify the Mainviewmodel to increase the recipient because there may be more than one comment, so use ImportMany.

    [ImportMany (typeof (Basecomment))]    Public ienumerable<basecomment> Comments;

New combination engine

1     private void Init () 2     {3         //Set directory 4         var catalog = new Aggregatecatalog (); 5         catalog. Catalogs.add (New Directorycatalog ("d:\\plugin\\")); 6   7         _container = new compositioncontainer (catalog); 8         try 9         {ten             this._container. Composeparts (this);         }12         catch (compositionexception compositionexception)             Console.WriteLine (Compositionexception.tostring ());         }16         //Bind the new annotation to the collection so that the interface can display         foreach (Basecomment itm in Comments)         {             cmtcollection.add (ITM);         }22 (         Comments!) = null && comments.count () > 0) (             SelectedItem = cmtcollection[0];26         }27     }

Well, if you can keep up with my rhythm, that's gratifying, you've mastered the MEF's ideas and the ability to expand the Editor.

How to extend the Visual Studio editor

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.