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
    Nikon 1 J2 With Stylish Design And Dependable Image And Video Quality
    Canon Powershot D20 - Super-Durable Waterproof Camera
    Fujifilm Finepix F800EXR – Another Excellent EXR
    Sony NEX-6 – The Best Compact Camera
    Teufel Cubycon 2 – An Excellent All-In-One For Films
    Dell S2740L - A Beautifully Crafted 27-inch IPS Monitor
    Philips 55PFL6007T With Fantastic Picture Quality
    Philips Gioco 278G4 – An Excellent 27-inch Screen
    Sony VPL-HW50ES – Sony’s Best Home Cinema Projector
    Windows Vista : Installing and Running Applications - Launching Applications
    Most View
    Bamboo Splash - Powerful Specs And Friendly Interface
    Powered By Windows (Part 2) - Toshiba Satellite U840 Series, Philips E248C3 MODA Lightframe Monitor & HP Envy Spectre 14
    MSI X79A-GD65 8D - Power without the Cost
    Canon EOS M With Wonderful Touchscreen Interface (Part 1)
    Windows Server 2003 : Building an Active Directory Structure (part 1) - The First Domain
    Personalize Your iPhone Case
    Speed ​​up browsing with a faster DNS
    Using and Configuring Public Folder Sharing
    Extending the Real-Time Communications Functionality of Exchange Server 2007 : Installing OCS 2007 (part 1)
    Google, privacy & you (Part 1)
    iPhone Application Development : Making Multivalue Choices with Pickers - Understanding Pickers
    Microsoft Surface With Windows RT - Truly A Unique Tablet
    Network Configuration & Troubleshooting (Part 1)
    Panasonic Lumix GH3 – The Fastest Touchscreen-Camera (Part 2)
    Programming Microsoft SQL Server 2005 : FOR XML Commands (part 3) - OPENXML Enhancements in SQL Server 2005
    Exchange Server 2010 : Track Exchange Performance (part 2) - Test the Performance Limitations in a Lab
    Extra Network Hardware Round-Up (Part 2) - NAS Drives, Media Center Extenders & Games Consoles
    Windows Server 2003 : Planning a Host Name Resolution Strategy - Understanding Name Resolution Requirements
    Google’s Data Liberation Front (Part 2)
    Datacolor SpyderLensCal (Part 1)