Documents


Document objects are used to represent an open document in the IDE. To contrast this abstraction with that provided by the Window object: A Window object is used to represent the physical UI aspects of a document window, whereas a Document object is used to represent the physical document that is being displayed within that document window.

A document could be a designer, such as the Windows Forms designer, or it could be a text-based document such as a readme file or a C# code file open in an editor.

Just as you get a list of all open windows using the DTE.Windows collection, you can use the DTE.Documents collection to retrieve a list of all open documents:

Dim documents As Documents = DTE.Documents


The Documents collection is indexed by the document's Name property, which is, in effect, the document's filename without the path information. This makes it easy to quickly retrieve a Document instance:

Dim documents As Documents = DTE.Documents Dim readme As Document = documents.Item("ReadMe.txt")


Using the Document object, you can

  • Close the document (and optionally save changes)

  • Retrieve the filename and path of the document

  • Determine whether the document has been modified since the last time it was saved

  • Determine what, if anything, is currently selected within the document

  • Obtain a ProjectItem instance representing the project item that is associated with the document

  • Read and edit the contents of text documents

Table 10.11 contains the member descriptions for the Document object.

Table 10.11. Document Members

Property

Description

ActiveWindow

The currently active window associated with the document (null or Nothing value indicates that there is no active window).

Collection

The collection of Document objects to which this instance belongs.

DTE

The root-level DTE object.

Extender

Returns a Document extender object.

ExtenderCATID

The extender category ID for the object.

ExtenderNames

A list of extenders available for the current Document object.

FullName

The full path and filename of the document.

Kind

A GUID representing the kind of document.

Name

The name (essentially, the filename without path information) for the document.

Path

The path of the document's file excluding the filename.

ProjectItem

The ProjectItem instance associated with the document.

Saved

Indicates whether the solution has been saved since the last modification.

Selection

An object representing the current selection in the document (if any).

Windows

The Windows collection containing the window displaying the document.


Method

Description

Activate

Moves the focus to the document.

Close

Closes the document. You can indicate, with a vsSaveChanges enum value, whether the window's hosted document should be saved or not saved, or whether the IDE should prompt the user to make that decision.

NewWindow

Opens the document in a new window and returns the new window's Window object.

Object

Returns an object proxy that represents the window and can be referenced by name.

Redo

Re-executes the last user action in the document.

Save

Saves the document.

Undo

Reverses the last used action in the document.


Text Documents

As we mentioned, documents can have textual or nontextual content. For those documents with textual content, a separate objectTextdocumentexists. The TexTDocument object provides access to control functions specifically related to text content.

If you have a valid Document object to start with, and if that document object refers to a text document, then a Textdocument instance can be referenced from the Document.Object property like this:

Dim doc As TextDocument doc = myDocument.Object


Table 10.12 contains the Textdocument members.

Table 10.12. Textdocument Members

Property

Description

DTE

The root-level DTE object

EndPoint

A TextPoint object positioned at the end of the document

Parent

Gets the parent object of the text document

Selection

Returns a TextSelection object representing the currently selected text in the document

StartPoint

A TextPoint object positioned at the start of the document


Method

Description

ClearBookmarks

Removes any unnamed bookmarks present in the document

CreateEditPoint

Returns an edit point at the specific location (if no location is specified, the beginning of the document is assumed)

MarkText

Bookmarks lines in the document that match the specified string pattern

ReplacePattern

Replaces any text in the document that matches the pattern


Tip

A text document will be represented by both a Document instance and a Textdocument instance. Nontext documents, such as a Windows form open in a Windows Forms designer window, will have a Document representation but no corresponding Textdocument representation. Unfortunately, there isn't a great way to distinguish whether a document is text based or not during runtime. One approach is to attempt a cast or assignment to a Textdocument object and catch any exceptions that might occur during the assignment.


Two Textdocument methods are useful for manipulating bookmarks within the document: ClearBookmarks will remove any unnamed bookmarks from the document, and MarkText will perform a string pattern search and place bookmarks against the resulting document lines. A simple macro to bookmark For loops in a VB document is presented in Listing 10.10.

Listing 10.10. Bookmarking For Loops in a VB Document

Imports EnvDTE Imports EnvDTE80 Imports Microsoft.VisualStudio.CommandBars Imports System.Diagnostics Imports System.Windows.Forms Public Module MacroExamples     ' Bookmark all 'For' tokens in the current     ' document     Public Sub BookmarkFor()         Dim doc As Document         Dim txtDoc As TextDocument         ' Reference the current document         doc = DTE.ActiveDocument         ' Retrieve a TextDocument instance from         ' the document         txtDoc = doc.Object         ' Call the MarkText method with the 'For' string         Dim found As Boolean = _             txtDoc.MarkText("For", vsFindOptions.vsFindOptionsFromStart)         ' MarkText returns a boolean flag indicating whether or not         ' the search pattern was found in the textdocument         If found Then             MessageBox.Show("All instances of 'For' have been bookmarked.")         Else             MessageBox.Show("No instances of 'For' were found.")         End If     End Sub End Module

The other key functionality exposed by the Textdocument object is the capability to read and edit the text within the document.

Editing Text Documents

From a Visual Studio perspective, text in a text document actually has two distinct "representations": a virtual one and a physical one. The physical representation is the straight, unadulterated code file that sits on disk. The virtual representation is what Visual Studio presents on the screen: It is an interpreted view of the text in the code file that takes into account various editor document features such as code outlining/regions, virtual spacing, word wrapping, and so on.

Figure 10.7 shows this relationship. When displaying a text document, Visual Studio reads the source file into a text buffer, and then the text editor presents one view of that text file to you (based on options you have configured for the editor).

Figure 10.7. Presentation of text documents within the IDE.


Text in a document is manipulated or read either on the buffered text or on the "view" text that you see in the editor. There are four different automation objects that allow you to affect text; two work on the text buffer and two work on the editor view.

For the text buffer:

  • TextPoint objects are used to locate specific points within a text document. By querying the TextPoint properties, you can determine the line number of the text point, the number of characters it is offset from the start of a line, the number of characters it is offset from the start of the document, and its display column within the text editor window. You can also retrieve a reference to a CodeModel object representing the code at the text point's current location.

  • The EditPoint object inherits from the TextPoint object; this is the primary object used for manipulating text in the text buffer. You can add, delete, or move text using edit points, and they can be moved around within the text buffer.

And, for the editor view:

  • The VirtualPoint object is equivalent to the TextPoint object except that it can be used to query text locations that reside in the "virtual" space of the text view (virtual space is the whitespace that exists after the last character in a document line). VirtualPoint instances are returned through the TextSelection object.

  • The TextSelection object operates on text within the text editor view as opposed to the text buffer and is equivalent to the EditPoint interface. When you use the TextSelection object, you are actively affecting the text that is being displayed within the text editor. The methods and properties of this object, therefore, end up being programmatic approximations of the various ways that you would manually affect text: You can page up or page down within the view; cut, copy, and paste text; select a range of text; or even outline and expand or collapse regions of text.

Because the VirtualPoint object is nearly identical to the TextPoint object, and the TextSelection object is nearly identical to the EditPoint object, we won't bother to cover each of these four objects in detail. Instead, we will focus on text buffer operations using EditPoint and TextPoint. You should be able to easily apply the concepts here to the text view.

Because EditPoint objects expose the most functionality and play the central role with text editing, we have provided a list of their type members in Table 10.13.

Table 10.13. EditPoint2 Members

Property

Description

AbsoluteCharOffset

The number of characters from the start of the document to the current location of the edit point

AtEndOfDocument

Boolean flag indicating whether the point is at the end of the document

AtEndOfLine

Boolean flag indicating whether the point is at the end of a line in the document

AtStartOfDocument

Boolean flag indicating whether the point is at the beginning of the document

AtStartOfLine

Boolean flag indicating whether the point is at the start of a line in the document

CodeElement

Returns the code element that maps to the edit point's current location

DisplayColumn

The column number of the edit point

DTE

Returns the root automation DTE object

Line

The line number where the point is positioned

LineCharOffset

The character offset, within a line, of the edit point

LineLength

The length of the line where the edit point is positioned

Parent

Returns the parent object of the EditPoint2 object


Method

Description

ChangeCase

Changes the case of a range of text

CharLeft

Moves the edit point to the left the specified number of characters

CharRight

Moves the edit point to the right the specified number of characters

ClearBookmark

Clears any unnamed bookmarks that exist on the point's current line location

Copy

Copies a range of text to the Clipboard

CreateEditPoint

Creates a new EditPoint2 object at the same location as the current EditPoint2 object

Cut

Cuts a range of text and places it on the Clipboard

Delete

Deletes a range of text from the document

DeleteWhitespace

Deletes any whitespace found around the edit point

EndOfDocument

Moves the edit point to the end of the document

EndOfLine

Moves the edit point to the end of the current line

EqualTo

A Boolean value indicating whether the edit point's AbsoluteCharOffset value is equal to another edit point's offset

FindPattern

Finds any matching string patterns in the document

GetLines

A string representing the text between two lines in the document

GetText

A string representing the text between the edit point and another location in the document

GreaterThan

A Boolean value indicating whether the edit point's AbsoluteCharOffset value is greater than another edit point's offset

Indent

Indents the selected lines by the given number of levels

Insert

Inserts a string into the document, starting at the edit point's current location

InsertFromFile

Inserts the entire contents of a text file into the document starting at the edit point's current location

LessThan

Returns a Boolean value indicating whether the edit point's AbsoluteCharOffset value is less than another edit point's offset

LineDown

Moves the point down one or more lines

LineUp

Moves the point up one or more lines

MoveToAbsoluteOffset

Moves the edit point to the given character offset

MoveToLineAndOffset

Moves the edit point to the given line and to the character offset within that line

MoveToPoint

Moves the edit point to the location of another EditPoint or TextPoint object

NextBookmark

Moves the edit point to the next available bookmark in the document

OutlineSection

Creates an outline section between the point's current location and another location in the document

PadToColumn

Pads spaces in the current line up to the indicated column number

Paste

Pastes the contents of the Clipboard to the edit point's current location

PreviousBookmark

Moves the edit point to the previous bookmark

ReadOnly

Returns a Boolean flag indicating whether a text range in the document is read only

ReplacePattern

Replaces any text that matches the provided pattern

ReplaceText

Replaces a range of text with the provided string

SetBookmark

Creates an unnamed bookmark on the edit point's current line in the document

StartOfDocument

Moves the edit point to the start of the document

StartOfLine

Moves the edit point to the beginning of the line where it is positioned

TRyToShow

Attempts to display the point's current location within the text editor window

Unindent

Removes the given number of indentation levels from a range of lines in the document

WordLeft

Moves the edit point to the left the given number of words

WordRight

Moves the edit point to the right the given number of words


Now let's look at various text manipulation scenarios.

Adding Text

EditPoint objects are the key to adding text, and you create them either by using a Textdocument object or by using a TextPoint object.

A TextPoint instance can create an EditPoint instance in its same exact location by calling TextPoint.CreateInstance. With the Textdocument type, you can call the CreateEditPoint method and pass in a valid TextPoint.

Because TextPoint objects are used to locate specific points in a document, a TextPoint object is leveraged as an input parameter to CreateEditPoint. In essence, the TextPoint object tells the method where to create the edit point. If you do not provide a TextPoint object, the edit point will be created at the start of the document.

This code snippet shows an edit point being created at the end of a document:

Dim doc As Document = DTE.ActiveDocument Dim txtDoc As TextDocument = doc.Object Dim tp As TextPoint = txtDoc.EndPoint Dim ep As EditPoint2 = txtDoc.CreateEditPoint(tp) ' This line of code would have the same effect ep = tp.CreateEditPoint


After creating an edit point, you can use it to add text into the document (remember, you are editing the buffered text whenever you use an EditPoint object). To inject a string into the document, you use the Insert method:

' Insert a C# comment line ep.Insert("// some comment")


You can even grab the contents of a file and throw that into the document with the EditPoint.InsertFromFile method:

' Insert comments from a comments file ep.InsertFromFile("C:\Contoso\std comments.txt")


Editing Text

The EditPoint object supports deleting, replacing, cutting, copying, and pasting text in a document.

Some of these operations require more than a single point to operate. For instance, if you wanted to cut a word or an entire line of code from a document, you would need to specify a start point and end point that define that range of text (see Figure 10.8).

Figure 10.8. Using points within a document to select text.


This snippet uses two end points, one at the start of a document and one at the end, to delete the entire contents of the document:

Dim doc As Document = DTE.ActiveDocument Dim txtDoc As TextDocument = doc.Object Dim tpStart As TextPoint = txtDoc.StartPoint Dim tpEnd As TextPoint = txtDoc.EndPoint Dim epStart As EditPoint2 = txtDoc.CreateEditPoint(tpStart) Dim epEnd As EditPoint2 = txtDoc.CreateEditPoint(tpEnd) epStart.Delete(epEnd)


Besides accepting a second EditPoint, the methods that operate on a range of text will also accept an integer identifying a count of characters. This also has the effect of defining a select. For example, this snippet cuts the first 10 characters from a document:

epStart.Cut(10)


Repositioning an EditPoint

After establishing an EditPoint, you can move it to any given location in the document by using various methods. The CharLeft and CharRight methods will move the point any number of characters to the left or right, while the WordLeft and WordRight methods perform the same operation with words:

' Move the edit point 4 words to the right epStart.WordRight(4)


The LineUp and LineDown methods will jog the point up or down the specified number of lines. You can also move EditPoints to any given line within a document by using MoveToLineAndOffset. This method will also position the point any number of characters into the line:

' Move the edit point to line 100, and then ' in 5 characters to the right epStart.MoveToLineAndOffset(100, 5)


The macro code in Listing 10.11 pulls together some of the areas that we have covered with editing text documents. This macro and its supporting functions illustrate the use of EditPoints to write text into a document. In this case, the macro automatically inserts a comment "flowerbox" immediately preceding a routine. To accomplish this, the macro goes through the following process:

  1. A reference is obtained for the current document in the IDE.

  2. The active cursor location in that document is obtained via the Textdocument.Selection.ActivePoint property.

  3. An EditPoint is created using the VirtualPoint returned from the ActivePoint.

  4. A second EditPoint is then created; these two points are used to obtain the entire content of the routine definition line.

  5. The routine definition is then parsed to try to ferret out items such as its name, return value, and parameter list.

  6. A string is built using the routine information and is inserted into the text document using an EditPoint.

Listing 10.11. Inserting Comments into a Text Window

Imports EnvDTE Imports EnvDTE80 Imports Microsoft.VisualStudio.CommandBars Imports System Imports System.Collections Imports System.Diagnostics Imports System.Text Imports System.Windows.Forms Public Module MacroExamples     ' This routine demonstrates various text editing scenarios     ' using the EditPoint and TextPoint types. If you place your     ' cursor on a subroutine or function, it will build a default     ' "flower box" comment area, insert it immediately above the     ' sub/function, and outline it.     '     ' To use:     '   1) put cursor anywhere on the Sub/Function line     '   2) run macro     '   The macro will fail silently (e.g., will not insert any     '   comments) if it is unable to determine the start     '   of the Sub/Function     '     Public Sub InsertTemplateFlowerbox()         ' Get reference to the active document         Dim doc As Document = DTE.ActiveDocument         Dim txtDoc As TextDocument = doc.Object         Dim isFunc As Boolean         Try             Dim ep As EditPoint2 = txtDoc.Selection.ActivePoint.CreateEditPoint()             ep.StartOfLine()             Dim ep2 As EditPoint2 = ep.CreateEditPoint()             ep2.EndOfLine()             Dim lineText As String = ep.GetText(ep2).Trim()             If InStr(lineText, " Function ") > 0 Then                 isFunc = True             ElseIf InStr(lineText, " Sub ") > 0 Then                 isFunc = False             Else                 Exit Sub             End If             ' Parse out info that we can derive from the routine             ' definition: the return value type (if this is a function),             ' the names of the parameters, and the name of the routine.             Dim returnType As String = ""             If isFunc Then                 returnType = ParseRetValueType(lineText)             End If             Dim parameters As String() = ParseParameters(lineText)             Dim name As String = ParseRoutineName(lineText)             Dim commentBlock As String = BuildCommentBlock(isFunc, name, _ returnType, parameters)             ' Move the edit point up one line (to position             ' immediately preceding the routine)             ep.LineUp(1)             ' Give us some room by inserting a new blank line             ep.InsertNewLine()             ' Insert our comment block             ep.Insert(commentBlock.ToString())         Catch ex As Exception         End Try     End Sub     Private Function BuildCommentBlock(ByVal isFunc As Boolean, _         ByVal name As String, _         ByVal returnType As String, ByVal parameters As String())         Try             Dim comment As StringBuilder = New StringBuilder()             ' Build up a sample comment block using the passed in info             comment.Append("''''''''''''''''''''''''''''''''''''''''''''''''")             comment.Append(vbCrLf)             comment.Append("' Routine: " + name)             comment.Append(vbCrLf)             comment.Append("' Description: [insert routine desc here]")             comment.Append(vbCrLf)             comment.Append("'")             comment.Append(vbCrLf)             If isFunc Then                 comment.Append("' Returns: A " & returnType & _ " [insert return value description here]")             End If             comment.Append(vbCrLf)             comment.Append("'")             comment.Append(vbCrLf)             comment.Append("' Parameters:")             comment.Append(vbCrLf)             For i As Integer = 0 To parameters.GetUpperBound(0)                 comment.Append("'     ")                 comment.Append(parameters(i))                 comment.Append(": [insert parameter description here]")                 comment.Append(vbCrLf)             Next             comment.Append("''''''''''''''''''''''''''''''''''''''''''''''''")             Return comment.ToString()         Catch ex As Exception             Return ""         End Try     End Function     Private Function ParseRetValueType(ByVal code As String) As String         Try             ' Parse out the return value of a function (VB)             ' Search for 'As', starting from the end of the string             Dim length As Integer = code.Length             Dim index As Integer = code.LastIndexOf(" As ")             Dim retVal As String = code.Substring(index + 3, length - (index + 3))             Return retVal.Trim()         Catch ex As Exception             Return ""         End Try     End Function     Private Function ParseParameters(ByVal code As String) As String()         Try             ' Parse out the parameters specified (if any) for             ' a VB sub/func definition             Dim length As Integer = code.Length             Dim indexStart As Integer = code.IndexOf("(")             Dim indexEnd As Integer = code.LastIndexOf(")")             Dim params As String = code.Substring(indexStart + 1, _ indexEnd - (indexStart + 1))             Return params.Split(",")         Catch ex As Exception             Return Nothing         End Try     End Function     Private Function ParseRoutineName(ByVal code As String) As String         Try             Dim name As String             Dim length As Integer = code.Length             Dim indexStart As Integer = code.IndexOf(" Sub ")             Dim indexEnd As Integer = code.IndexOf("(")             If indexStart = -1 Then                 indexStart = code.IndexOf(" Function ")                 If indexStart <> -1 Then                     indexStart = indexStart + 9                 End If             Else                 indexStart = indexStart + 5             End If             name = code.Substring(indexStart, indexEnd - indexStart)             Return name.Trim()         Catch ex As Exception             Return ""         End Try     End Function End Module




Microsoft Visual Studio 2005 Unleashed
Microsoft Visual Studio 2005 Unleashed
ISBN: 0672328194
EAN: 2147483647
Year: 2006
Pages: 195

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net