Figure 5 vsInsertFlags Values
vsInsertFlagsCollapseToEnd
|
The selection's current contents are deleted before performing the insertion, and the TextSelection is left empty at the end of the newly inserted text.
|
vsInsertFlagsCollapseToStart
|
The selection's current contents are deleted before performing the insertion, and the TextSelection is left empty at the beginning of the newly inserted text.
|
vsInsertFlagsContainNewText
|
The selection's current contents are replaced with the inserted text, and the TextSelection is left containing the new text.
|
vsInsertFlagsInsertAtStart
|
The inserted text is placed at the beginning of the TextSelection, and the resulting TextSelection contains both the new and previous text.
|
vsInsertFlagsInsertAtEnd
|
The inserted text is placed at the end of the TextSelection, and the resulting TextSelection contains both the new and previous text.
|
Figure 6 AddCommand
// AddCommand
// Add one of the commands, dealing with the errors that might result.
//
// szName -name of the command being added
// szButtonText text displayed on menu or button
// szToolTip - text displayed in tool tip
// szKey - default key assignment, or empty string if none
// szMenuToAddTo - default menu to place on, or empty if none
//
private void AddCommand (String szName, String szButtonText,
String szToolTip, String szKey,
String szMenuToAddTo)
{
Command cmd = null;
Object [] GuidArray = {};
// The IDE identifies commands by their full name, which include
// the add-in name
//
String szNameFull = "TextUtil.Connect." + szName;
try
{
cmd = applicationObject.Commands.Item (szNameFull, -1);
}
catch(System.ArgumentException /* e */)
{
// Thrown if command doesn't already exist.
}
if (null != cmd)
{
// While in development I delete the command each time in order
// to ensure any changes I make in development are picked up.
// Doing this will probably also remove any key bindings. You
// will probably want to remove this prior to distributing.
cmd.Delete();
cmd = null;
}
if (null == cmd)
{
// Add new command to the IDE
//
cmd = applicationObject.Commands.AddNamedCommand (addInInstance
, szName
, szButtonText
, szToolTip
, false, 1, ref GuidArray, 0);
}
if ("" != szKey)
{
// a default keybinding specified
//
object [] bindings;
bindings = (object [])cmd.Bindings;
if (0 >= bindings.Length)
{
// there is no preexisting key binding, so add the default
bindings = new object[1];
bindings[0] = (object)szKey;
cmd.Bindings = (object)bindings;
}
}
if ("" != szMenuToAddTo)
{
// caller specified that this be added to a menu (aka,
// commandbar).
//
CommandBar commandBar = (CommandBar)
applicationObject.CommandBars[szMenuToAddTo];
cmd.AddControl(commandBar, commandBar.Controls.Count);
}
}
Figure 7 JustifySimple
// JustifySimple
// Justify a block of text between margins
// Just justify from current point to next blank line.
//
bool JustifySimple ()
{
int lineStart; // line containing start of selection
int lineEnd; // line containing end of selection
EditPoint pointCur; // beginning of text to be justified
EditPoint pointDelete; // end of text to be justified
string [] rgszLines; // array of lines contained in original text
string szLineTemp; // temporary string while rebuilding text
string szText; // text to be justified, as a single line
// Locate the blank line that delimits the end of a "paragraph"
//
pointCur = ((TextSelection)
applicationObject.ActiveDocument.Selection).AnchorPoint.CreateEditPoint();
lineEnd = lineStart = pointCur.Line;
do
{
lineEnd++;
}
while (("" != pointCur.GetLines(lineEnd,lineEnd+1).Trim())
&& !pointCur.AtEndOfDocument);
// Grab copy of text to be justified. Split into an array of
// lines while I'm at it to facilitate EOL removal and space
// trimming.
//
rgszLines = pointCur.GetLines(lineStart,lineEnd).Split('\r
// Remove text from buffer.
//
pointCur.MoveToLineAndOffset(lineStart,1);
pointDelete = pointCur.CreateEditPoint();
pointDelete.MoveToLineAndOffset(lineEnd,1);
pointCur.Delete (pointDelete);
// Now concatenate all lines into one, with the line breaks
// removed, spaces trimmed, and a single space between what
// used to be the individual lines.
//
szText = "";
for (int i = 0; i < rgszLines.Length; i++)
{
szLineTemp = TrimEOL(rgszLines[i]).Trim();
if ("" != szLineTemp)
szText += " " + szLineTemp;
}
szText = szText.Trim();
// I now have one string that contains all the text to be
// formatted out. I try to grab iWidth chunks from its
// beginning and output each, until there is nothing left.
//
while ("" != szText)
{
if (iWidth < szText.Length)
{
int iSpace;
// String is longer than width, so I need to parse off
// a segment. I hope for word breaks (spaces), but if none,
// I'll chop indiscriminately.
//
szLineTemp = szText.Substring (0, iWidth);
iSpace = szLineTemp.LastIndexOf ('
if (0 <= iSpace)
szLineTemp = szText.Substring (0, iSpace);
szText = szText.Substring (szLineTemp.Length).Trim();
}
else
{
// String is shorter than width, so I just copy the remaining
// string.
//
szLineTemp = szText;
szText = "";
}
// output the modified line.
//
szLineTemp = szLineTemp.Trim() + "\r\n";
pointCur.Insert (szLineTemp);
}
return true;
}
// TrimEOL
// remove all EOL characters (CR & LF) from a string.
//
private String TrimEOL(String sz)
{
return sz.Replace ("\n", "").Replace ("\r", "");
}
Figure 8 Specifying Margins
int iColStart = 1; // default starting column
int iColEnd = 73; // default ending column
if ((txt.Mode == EnvDTE.vsSelectionMode.vsSelectionModeBox) &&
(txt.BottomPoint.VirtualDisplayColumn !=
txt.TopPoint.VirtualDisplayColumn))
{
// Selection is a box of some sort. That means I take the
// left and right limits of the box as the margins.
//
iColStart = txt.TopPoint.VirtualDisplayColumn;
iColEnd = txt.BottomPoint.VirtualDisplayColumn;
}
Figure 9 Justify
// Justify
// Justify a block of text between margins
// Justify text multiline selection, if it exists,
// otherwise to blank line. Use existing selection width to
// determine width of justification. Treat as single, undoable
// action. Handles preserving line-prepended strings and reading
// defaults from the registry
//
bool Justify (string szPrepend)
{
bool fUndoWasOpen; // undo context state on entry
int iColStart = 1; // default starting column
int iColEnd = iWidth+1; // default ending column
int iWidthWrap; // width of text to justify
// (End-Start)
int lineStart;
int lineEnd;
EditPoint pointCur; // beginning of text to be justified
EditPoint pointDelete; // end of text to be justified
string [] rgszLines; // array of lines contained in
// original text
string szLineTemp; // temporary string while rebuilding
// text
string szText; // text to be justified, as a single
// line
TextSelection txt; // the initial text selection
fUndoWasOpen = applicationObject.UndoContext.IsOpen;
if (!fUndoWasOpen)
applicationObject.UndoContext.Open("TextUtil.Justify", false);
try
{
txt = (TextSelection)applicationObject.ActiveDocument.Selection;
pointCur = txt.TopPoint.CreateEditPoint();
lineStart = pointCur.Line;
if (txt.BottomPoint.Line == pointCur.Line)
{
// Selection is on a single line, or nonexistent.
// Locate the blank line that delimits the end of a paragraph
//
lineEnd = lineStart;
do
{
lineEnd++;
}
while (("" != pointCur.GetLines(lineEnd,lineEnd+1).Trim())
&& !pointCur.AtEndOfDocument);
}
else
{
lineEnd = txt.BottomPoint.Line+1;
}
if ((txt.Mode == EnvDTE.vsSelectionMode.vsSelectionModeBox) &&
(txt.BottomPoint.VirtualDisplayColumn !=
txt.TopPoint.VirtualDisplayColumn))
{
// selection is a box of some sort. That means I take the
// left and right limits of the box as the margins
//
iColStart = txt.TopPoint.VirtualDisplayColumn;
iColEnd = txt.BottomPoint.VirtualDisplayColumn;
}
// Grab copy of text to be justified. I split into an array of
// lines while I'm at it to facilitate EOL removal and space
// trimming.
//
rgszLines = pointCur.GetLines(lineStart,lineEnd).Split('\r
// Remove text from buffer.
//
pointCur.MoveToLineAndOffset(lineStart,1);
pointDelete = pointCur.CreateEditPoint();
pointDelete.MoveToLineAndOffset(lineEnd,1);
pointCur.Delete (pointDelete);
// If the first line begins with our prepend string,
// then check all the lines for that string, and remove
//
if ("" != szPrepend)
if (!rgszLines[0].StartsWith (szPrepend))
szPrepend = "";
// Now concatenate all lines into one, with the line breaks
// removed, spaces trimmed, and a single space between what
// were the lines.
//
szText = "";
for (int i = 0; i < rgszLines.Length; i++)
{
szLineTemp = TrimEOL(rgszLines[i]).Trim();
if (0 < szPrepend.Length)
if (szLineTemp.StartsWith (szPrepend))
szLineTemp = szLineTemp.Substring
(szPrepend.Length);
if ("" != szLineTemp)
szText += " " + szLineTemp;
}
szText = szText.Trim();
// I now have one string that contains all the text to be
// formatted out. I try to grab iWidthWrap chunks from its
// beginning and output each, until there is nothing left.
//
iWidthWrap = iColEnd - iColStart - szPrepend.Length;
while ("" != szText)
{
if (iWidthWrap < szText.Length)
{
int iSpace;
// String is longer than width, so I need to parse off
// a segment. I hope for word breaks (spaces), but if none,
// I'll chop indiscriminately.
//
szLineTemp = szText.Substring (0, iWidthWrap);
iSpace = szLineTemp.LastIndexOf ('
if (0 <= iSpace)
szLineTemp = szText.Substring (0, iSpace);
szText = szText.Substring (szLineTemp.Length).Trim();
}
else
{
// String is shorter than width, so I just copy the
// remaining string.
//
szLineTemp = szText;
szText = "";
}
// output the modified line.
//
szLineTemp = szPrepend + szLineTemp.Trim() + "\r\n";
szLineTemp = szLineTemp.PadLeft (iColStart - 1 +
szLineTemp.Length,'
pointCur.Insert (szLineTemp);
}
}
finally
{
if (!fUndoWasOpen)
applicationObject.UndoContext.Close();
}
return true;
}
Figure 11 OnAfterCreated and OnOK
// Called each time the options page is about to be
// displayed. Load up current values and pre-fill
// edit boxes.
//
public void OnAfterCreated(
DTE DTEObject
){
int iWidth;
RegistryKey key;
key = Registry.LocalMachine.OpenSubKey
("Software\\Microsoft\\VisualStudio\\7.0\\Addins\\TextUtil.Connect\\Options");
iWidth = (int)key.GetValue("iwidth", 72);
txtRightColumn.Text = iWidth.ToString();
txtCodePrefix.Text = (string)key.GetValue ("codeprefix", "// ");
txtMailPrefix.Text = (string)key.GetValue ("mailprefix", "| ");
}
public void OnOK(){
RegistryKey key;
key = Registry.LocalMachine.OpenSubKey
("Software\\Microsoft\\VisualStudio\\7.0\\Addins\\TextUtil.Connect\\Options", true);
key.SetValue ("iwidth", System.Convert.ToInt32(txtRightColumn.Text));
key.SetValue ("codeprefix", txtCodePrefix.Text);
key.SetValue ("mailprefix", txtMailPrefix.Text);
}
Figure 12 Installing VSToolsOp
|