ENTERPRISE

Visual Studio 2010 : Introducing the Visual Studio Extensibility - Extending the Code Editor

7/30/2012 5:48:03 PM
One of the most important new features in the Visual Studio 2010 is the capability of extending the code editor, which is now based on WPF. Code editor extensions get the instance of the WPF objects keeping the editor itself alive. For a better understanding, instead of building a particular extension, we explain required objects taking advantage of one of the sample projects added by the Visual Studio 2010 SDK. Create a new project and select the Visual Basic, Extensibility folder; finally select the Editor Text Adornment project template, as shown in Figure 1.
Figure 1. Selecting the code editor extension template.

The goal of this sample project is simple: adorning each “a” character in the code with a different background color. The most important object in providing editor extensions is the Microsoft.VisualStudio.Text.Editor.IWpfTextView type that represents the instance of the code editor. For the current example, there is the need of placing an adornment on all occurrences of the specified character. To place adornments, you need an instance of the IAdornmentLayer type that represents a space for placing adornments. Listing 1 shows the complete code; read comments that can help you understand what is under the hood.

Listing 1. Providing a Code Editor Extension with Adornments
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Media
Imports Microsoft.VisualStudio.Text
Imports Microsoft.VisualStudio.Text.Editor
Imports Microsoft.VisualStudio.Text.Formatting

''' <summary>
''' ScarletCharacter adornment places red boxes behind all
''' the "a"s in the editor window
''' </summary>
Class ScarletCharacter

    Private WithEvents _view As IWpfTextView
    Private ReadOnly _layer As IAdornmentLayer
    Private ReadOnly _brush As Brush
    Private ReadOnly _pen As Pen

    'The IWpFTextView object represents the
    'instance of the code editor
    Public Sub New(ByVal view As IWpfTextView)
        _view = view

        'IAdornmentLayer represents the place where
        'adorners are placed
        _layer = view.GetAdornmentLayer("ScarletCharacter")

        'Create the pen and brush to color the box behind the a's
        Dim brush As New SolidColorBrush(Color.
                         FromArgb(&H20, &H0, &H0, &HFF))
        brush.Freeze()
        Dim penBrush As New SolidColorBrush(Colors.Red)
        penBrush.Freeze()
        Dim pen As New Pen(penBrush, 0.5)
        pen.Freeze()

        _brush = brush
        _pen = pen
    End Sub

    ''' <summary>
    ''' On layout change add the adornment to any reformated lines
    ''' </summary>
    Private Sub OnLayoutChanged(ByVal sender As Object,
                                ByVal e As TextViewLayoutChangedEventArgs) _
                                Handles _view.LayoutChanged

        'TextViewLayoutChangedEventArgs provides information when
        'the code editor layout changes
        For Each line In e.NewOrReformattedLines
            Me.CreateVisuals(line)
        Next line
    End Sub

    ''' <summary>
    ''' Within the given line add the scarlet box behind the a
    ''' </summary>
    Private Sub CreateVisuals(ByVal line As ITextViewLine)
        'grab a reference to the lines in the current TextView
        Dim textViewLines = _view.TextViewLines
        Dim lineStart As Integer = line.Start
        Dim lineEnd As Integer = line.End

        'Loop through each character, and place a box around any a
        For i = lineStart To lineEnd - 1
            If _view.TextSnapshot(i) = "a"c Then
                Dim charSpan As New SnapshotSpan(_view.TextSnapshot,
                                    Span.FromBounds(i, i + 1))
                Dim g As Geometry = textViewLines.GetMarkerGeometry(charSpan)
                If g IsNot Nothing Then
                    Dim drawing As New GeometryDrawing(_brush, _pen, g)
                    drawing.Freeze()

                    Dim drawingImage As New DrawingImage(drawing)
                    drawingImage.Freeze()

                    Dim image As New Image()
                    image.Source = drawingImage

                    'Align the image with the top of the bounds of the text geometry
                    Canvas.SetLeft(image, g.Bounds.Left)
                    Canvas.SetTop(image, g.Bounds.Top)

                    'AdornmentPositioningBehavior sets how
                    'the adornment is placed
                    _layer.AddAdornment(AdornmentPositioningBehavior.
                                        TextRelative, charSpan,
                                        Nothing, image, Nothing)
                End If
            End If
        Next
    End Sub

End Class

					  

Notice how the Microsoft.VisualStudio.Text namespace exposes objects and other namespaces for interacting with the code editor. Now run the extension by pressing F5. Try to create a new console project and write some text containing “a” characters and you will see how they are surrounded with a different background, as shown in Figure 2.

Figure 2. The WPF editor extension adorning some text.

There are so many scenarios in which you might need to extend the Visual Studio code editor. You can find lots of interesting extensions by searching the Visual Studio Gallery with the Extension Manager.

Other  
  •  Visual Studio 2010 : Managing Extensions with the Extension Manager, Managing Add-Ins with the Add-In Manager
  •  Intel Xeon Phi: Coprocessor speeding at 1 teraflops in a PCIe Card
  •  Visual Studio Team System 2008 : Working with Test Results (part 2) - Build report and test result
  •  Visual Studio Team System 2008 : Working with Test Results (part 1) - Test as part of Team Foundation Server build
  •  Finance - Apple Versus Google
  •  Oracle Coherence 3.5 : Testing and debugging Coherence applications
  •  Oracle Coherence 3.5 : Accessing the data grid (part 6) - Using the Coherence API - Implementing CoherenceTarget, Testing the Cache loader
  •  Oracle Coherence 3.5 : Accessing the data grid (part 5) - Using the Coherence API - Loader design, Implementing CsvSource
  •  Oracle Coherence 3.5 : Accessing the data grid (part 4) - Using the Coherence API - The basics: NamedCache and CacheFactory
  •  Oracle Coherence 3.5 : Accessing the data grid (part 3) - Configuring Coherence
  •  Oracle Coherence 3.5 : Accessing the data grid (part 2) - Configuring the development environment
  •  Oracle Coherence 3.5 : Accessing the data grid (part 1) - Coherence console
  •  Oracle Coherence 3.5 : Installing Coherence, Starting up the Coherence cluster
  •  The Go-To Reference Design Map For The Cloud?
  •  Separating BPM and SOA Processes : SOA-Oriented Disputes with BEA
  •  Science! – Spintronics
  •  Linux - The Operating System With A Pure Heart (Part 2)
  •  Linux - The Operating System With A Pure Heart (Part 1)
  •  What's Your Strategy For Today’s Server Room Challenges?
  •  Truly Transparent Trinkets
  •  
    Top 10
    A Look At Truecrypt The Open Source Security Tool
    Price Of Piracy
    Acer Aspire 5600U 23" Touchscreen All-in-One PC
    Zalman FX100-Cube Fanless Cooler
    Devolo dLAN LiveCam Starter Kit
    Has Apple Lost It? (Part 2)
    Has Apple Lost It? (Part 1)
    Sony Computer Entertainment (Part 3)
    Sony Computer Entertainment (Part 2)
    Sony Computer Entertainment (Part 1)
    Most View
    Create Your Own E-Books (Part 1)
    Android Security : Files and Preferences
    Protect your passwords (Part 1)
    Connectivity Matters
    Wilson Audio Alexia - High Performance Loudspeakers (Part 3)
    How To Buy The Perfect Gear (Part 7)
    Windows 7 : Managing Your Schedule - Understanding Calendaring, Exploring Windows Live Calendar
    Sharepoint 2007: Upload a File Using Web Folders
    Plustek PS406U - Scanner For Medium And Small Offices
    Get to a SharePoint Site
    The Truth About Comparing… Raspberry Pi vs Intel NUC
    MySQL Server Monitoring (part 1) - SQL Commands
    ASP.NET AJAX : Timed Refreshes
    Is It Time To Quarantine Infected Pcs?
    iPhone 3D Programming : Adding Depth and Realism - Surface Normals (part 1)
    Implementing Security in Windows 7 : Set the Junk E-mail Protection Level
    Handwriting Input And Recognition (Part 2)
    Graphics Cards for All Budgets (Part 3) - Radeon HD 7950, GeForce GTX 580, GeForce GTX670
    Orange San Diego - The First Intel Phone
    HP Pavilion G7 - Affordable Desktop Replacement