private bool Apply(TextSelection selection, string value) { selection.CharLeft(true, _match.Length); if (selection.Text != _match) { selection.CharRight(false); return(false); } selection.Insert(value, (int)vsInsertFlags.vsInsertFlagsContainNewText); selection.CharRight(false); return(true); }
void ProcessOpenConApp(object sender, EventArgs e) { Debug.WriteLine("Open Console App"); DTE dte = (DTE)GetService(typeof(EnvDTE.DTE)); var prjs = dte.Solution.Projects; if (prjs.Count > 0) { string s = prjs.Item(1).FullName; s = s.Replace(".vcxproj", ".cpp"); dte.ItemOperations.OpenFile(s); dte.ActiveDocument.Activate(); dte.Find.PatternSyntax = vsFindPatternSyntax.vsFindPatternSyntaxRegExpr; dte.Find.FindWhat = "int main\\(.*\\n\\{.*\\n"; dte.Find.Target = vsFindTarget.vsFindTargetCurrentDocument; dte.Find.MatchCase = false; dte.Find.MatchWholeWord = false; dte.Find.Backwards = false; dte.Find.MatchInHiddenText = false; dte.Find.Action = vsFindAction.vsFindActionFind; if (dte.Find.Execute() == vsFindResult.vsFindResultNotFound) { throw new System.Exception("vsFindResultNotFound"); } dte.Windows.Item("{CF2DDC32-8CAD-11D2-9302-005345000000}").Close(); TextSelection ts = (TextSelection)dte.ActiveDocument.Selection; ts.CharRight(); ts.Indent(); dte.ExecuteCommand("File.SaveAll", string.Empty); dte.ExecuteCommand("Build.BuildSolution"); dte.ActiveDocument.Activate(); } }
private void JoinLine(TextSelection textSelection) { // If the selection has no length, try to pick up the next line. if (textSelection.IsEmpty) { textSelection.LineDown(true); textSelection.EndOfLine(true); } const string fluentPattern = @"[ \t]*\r?\n[ \t]*\."; const string pattern = @"[ \t]*\r?\n[ \t]*"; var selection = textSelection.Text; // do regex replace for fluent style selection = Regex.Replace(selection, fluentPattern, "."); // do regex replace for everything else selection = Regex.Replace(selection, pattern, " "); textSelection.Text = selection; // Move the cursor forward, clearing the selection. textSelection.CharRight(); }
/// <summary> /// Removes special characters after inserting header /// </summary> /// <param name="textSelection">Text selection</param> /// <param name="template">Template</param> private void RemoveSpecialCharacters(TextSelection textSelection, string template) { // Remove special characters from beginning of each line in template textSelection.StartOfDocument(); for (int i = 0; i < template.Split('\n').Length; i++) { textSelection.StartOfLine(); textSelection.CharRight(true, SpecialCharacters.Length); textSelection.Delete(); textSelection.LineDown(); } }
public ItemInfo Create(Project project) { string file = Path.Combine(_folder, Path.Combine(_relativePath)); string dir = Path.GetDirectoryName(file); try { if (!Directory.Exists(dir)) { Directory.CreateDirectory(dir); } } catch (Exception) { System.Windows.Forms.MessageBox.Show("Error creating the folder: " + dir); return(ItemInfo.Empty); } if (!File.Exists(file)) { int position = WriteFile(file); try { if (AddFileToActiveProject(project, file)) { Window window = _dte.ItemOperations.OpenFile(file); // Move cursor into position if (position > 0) { TextSelection selection = (TextSelection)window.Selection; selection.CharRight(Count: position - 1); } return(new ItemInfo { Extension = Path.GetExtension(file), FileName = file }); } } catch (Exception ex) { System.Diagnostics.Debug.Write(ex); } } else { System.Windows.Forms.MessageBox.Show("The file '" + file + "' already exist."); } return(ItemInfo.Empty); }
private void BeforeKeyPress(string keypress, TextSelection selection, bool inStatementCompletion, ref bool cancelKeypress) { if (!ConvertTabsToSpaces || !selection.IsEmpty || inStatementCompletion) return; switch (keypress) { case BACKSPACE_KEY: do { selection.CharLeft(true); if (selection.Text == " ") { cancelKeypress = true; selection.Delete(); continue; } selection.CharRight(true); return; } while (selection.CurrentColumn%IndentSize != 1); return; case DELETE_KEY: for (var i = 0; i < IndentSize; i++) { selection.CharRight(true); if (selection.Text == " ") { cancelKeypress = true; selection.Delete(); continue; } selection.CharLeft(true); return; } return; } }
public ItemInfo Create(Project project) { string file = Path.Combine(_folder, Path.Combine(_relativePath)); string dir = Path.GetDirectoryName(file); try { if (!Directory.Exists(dir)) { Directory.CreateDirectory(dir); } } catch (Exception) { MessageBox.Show("Error creating the folder: " + dir); return(ItemInfo.Empty); } if (!File.Exists(file)) { int position = WriteFile(file); try { if (AddFileToActiveProject(project, file)) { EnvDTE.Window window = _projectService.OpenFile(file); // Move cursor into position if (position > 0) { TextSelection selection = (TextSelection)window.Selection; selection.CharRight(Count: position - 1); } return(new ItemInfo() { Extension = Path.GetExtension(file), FileName = file }); } } catch { /* Something went wrong. What should we do about it? */ } } else { MessageBox.Show($"The file '{file}' already exist."); } return(ItemInfo.Empty); }
void ProcessOpenCSharpConApp(object sender, EventArgs e) { Debug.WriteLine("Open CSharp Console App"); DTE dte = (DTE)GetService(typeof(EnvDTE.DTE)); var prjs = dte.Solution.Projects; if (prjs.Count > 0) { // get full path of solution (including name of solution file): string solutionFullPathname = dte.Solution.FullName; // extract the directory of the solution: string dir = System.IO.Path.GetDirectoryName(solutionFullPathname); // get the name of the first project string projectName = dte.Solution.Projects.Item(1).Name; // combine the solution dir with the project dir and "program.cs": string programfname = System.IO.Path.Combine(dir, projectName, "program.cs"); //System.Windows.Forms.MessageBox.Show("hello: " + programfname); dte.ItemOperations.OpenFile(programfname, EnvDTE.Constants.vsViewKindCode); var findString = @"static void Main\(string\[\] args\)\r?\n +{"; dte.ActiveDocument.Activate(); dte.Find.PatternSyntax = vsFindPatternSyntax.vsFindPatternSyntaxRegExpr; dte.Find.FindWhat = findString; dte.Find.Target = vsFindTarget.vsFindTargetCurrentDocument; dte.Find.MatchCase = false; dte.Find.MatchWholeWord = false; dte.Find.Backwards = false; dte.Find.MatchInHiddenText = false; dte.Find.Action = vsFindAction.vsFindActionFind; if (dte.Find.Execute() == vsFindResult.vsFindResultNotFound) { throw new System.Exception("vsFindResultNotFound"); } dte.Windows.Item("{CF2DDC32-8CAD-11D2-9302-005345000000}").Close(); TextSelection ts = (TextSelection)dte.ActiveDocument.Selection; ts.CharRight(); ts.Indent(); dte.ExecuteCommand("File.SaveAll", string.Empty); dte.ExecuteCommand("Build.BuildSolution"); dte.ActiveDocument.Activate(); } }
/// <summary> /// Joins the text within the specified text selection. /// </summary> /// <param name="textSelection">The text selection.</param> private void JoinText(TextSelection textSelection) { // If the selection has no length, try to pick up the next line. if (textSelection.IsEmpty) { textSelection.LineDown(true); textSelection.EndOfLine(true); } const string pattern = @"[ \t]*\r?\n[ \t]*"; const string replacement = @" "; // Substitute all new lines (and optional surrounding whitespace) with a single space. TextDocumentHelper.SubstituteAllStringMatches(textSelection, pattern, replacement); // Move the cursor forward, clearing the selection. textSelection.CharRight(); }
/// <summary> /// Show selected project file /// </summary> /// <param name="file"></param> /// <param name="row"></param> /// <param name="column"></param> /// <param name="length"></param> /// <returns></returns> private bool ShowProblemFile(string file, int row, int column, int length) { FileInfo fileInfo = new FileInfo(file); if (fileInfo.Exists) { try { _applicationObject.ItemOperations.OpenFile(file, EnvDTEConstants.vsViewKindCode); _applicationObject.ActiveDocument.Activate(); TextSelection selection = (TextSelection)_applicationObject.ActiveDocument.Selection; try { selection.MoveToLineAndOffset(row, column, false); selection.CharRight(true, length); } catch (ArgumentException ex) { if (IsJavaScriptFile(fileInfo)) { string errMsg = "“This plugin does not support showing results in a compressed min.js file. \n" + "To view the full results, please navigate to the Checkmarx results viewer."; TopMostMessageBox.Show(errMsg); return(true); } } return(true); } catch (Exception ex) { Logger.Create().Error(ex.ToString()); TopMostMessageBox.Show(ex.Message); } } return(false); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Inserts the method header. /// </summary> /// ------------------------------------------------------------------------------------ public void InsertMethodHeader() { TextSelection sel = (TextSelection)m_applicationObject.ActiveDocument.Selection; CodeElement codeElement = GetMethodOrProperty(sel); if (codeElement == null) { codeElement = sel.ActivePoint.get_CodeElement(vsCMElement.vsCMElementClass); if (codeElement == null) { codeElement = sel.ActivePoint.get_CodeElement(vsCMElement.vsCMElementInterface); } if (codeElement == null || codeElement.StartPoint.Line != sel.ActivePoint.Line) { // not a function or property, so just insert /// <summary/> sel.LineUp(false, 1); if (!IsXmlCommentLine) { sel.EndOfLine(false); sel.NewLine(1); sel.Text = "///"; sel.LineDown(true, 1); sel.Delete(1); sel.LineUp(false, 1); sel.EndOfLine(false); sel.WordRight(true, 2); sel.Delete(1); } else { sel.LineDown(false, 1); } return; } } sel.MoveToPoint(codeElement.StartPoint, false); // Figure out indentation and build dashed line sel.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstColumn, false); sel.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstText, true); string indent = sel.Text; sel.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstText, false); string dashedLine = indent + "/// " + new string('-', kLineLen - sel.ActivePoint.VirtualDisplayColumn - 4); bool fGhostDoc = true; try { // Use GhostDoc if available string addinName = string.Empty; foreach (AddIn addin in m_applicationObject.AddIns) { if (addin.Name == "GhostDoc") { addinName = (addin.ProgID == "SubMain.GhostDoc.Connect") ? "Tools.SubMain.GhostDoc.DocumentThis" : "Weigelt.GhostDoc.AddIn.DocumentThis"; break; } } if (addinName != string.Empty) { m_applicationObject.ExecuteCommand(addinName, string.Empty); } else { fGhostDoc = false; } } catch { fGhostDoc = false; } if (fGhostDoc) { int nLine = sel.ActivePoint.Line; int nLineOffset = sel.ActivePoint.LineCharOffset; // Check to see if we're in the middle of the comment or at the beginning of // the method. sel.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstText, false); if (GetMethodOrProperty(sel) == null) { // we're in the middle of the comment - move to the end of the comment MoveDownAfterComment(sel); // we're inserting one line (//---) above nLine++; } else { // We are at the beginning of the method. // Check to see if the line above the current line is an attribute. If it is we want to // start there, otherwise we start at the current line. sel.LineUp(false, 1); sel.CharRight(false, 1); if (sel.ActivePoint.get_CodeElement(vsCMElement.vsCMElementAttribute) == null) { sel.MoveToLineAndOffset(nLine, 1, false); } // we're inserting two lines above nLine += 2; } // In case the line is wrapped, we want to go to the real beginning of the line sel.MoveToLineAndOffset(sel.ActivePoint.Line, 1, false); sel.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstColumn, false); // Insert a new line and then insert our dashed line. sel.Insert(dashedLine + Environment.NewLine, (int)vsInsertFlags.vsInsertFlagsCollapseToEnd); sel.LineUp(false, 1); sel.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstText, false); MoveUpBeforeComment(sel); sel.Insert(Environment.NewLine + dashedLine, (int)vsInsertFlags.vsInsertFlagsCollapseToEnd); sel.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstText, false); // put IP at previous location sel.MoveToLineAndOffset(nLine, nLineOffset, false); } else { // check if we already have a comment sel.LineUp(false, 1); if (!IsXmlCommentLine) { // Insert comment sel.EndOfLine(false); sel.NewLine(1); sel.Text = "///"; } // Insert line above MoveUpBeforeComment(sel); sel.EndOfLine(false); sel.NewLine(1); sel.Text = dashedLine; int upperLine = sel.ActivePoint.Line; sel.LineDown(false, 1); // reformat text for (; IsXmlCommentLine;) { int curLine = sel.CurrentLine; // go through all words in this line for (; sel.CurrentLine == curLine; sel.WordRight(false, 1)) { if (sel.ActivePoint.VirtualDisplayColumn > kLineLen) { // we have to break before this word sel.WordLeft(true, 1); // skip all punctuation characters for (; sel.Text.Length == 1 && char.IsPunctuation(sel.Text[0]);) { sel.CharLeft(false, 1); // removes selection sel.WordLeft(true, 1); } sel.CharLeft(false, 1); // removes selection // break the line sel.NewLine(1); // join next line with remainder of current line sel.EndOfLine(false); sel.LineDown(true, 1); sel.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstText, true); sel.WordRight(true, 1); sel.Delete(1); // insert a space between the two lines sel.Text = " "; } } } // Insert line below sel.GotoLine(upperLine + 1, false); MoveDownAfterComment(sel); sel.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstText, false); sel.NewLine(1); sel.LineUp(false, 1); sel.Text = dashedLine; sel.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstText, false); sel.LineDown(false, 1); } }
private void MenuItemCallback(object sender, EventArgs e) { UIHierarchyItem item = GetSelectedItem(); if (item == null) { return; } string folder = FindFolder(item); if (string.IsNullOrEmpty(folder) || !Directory.Exists(folder)) { return; } string input = PromptForFileName(folder).TrimStart('/', '\\').Replace("/", "\\"); if (string.IsNullOrEmpty(input)) { return; } string file = Path.Combine(folder, input); string dir = Path.GetDirectoryName(file); try { if (!Directory.Exists(dir)) { Directory.CreateDirectory(dir); } } catch (Exception) { System.Windows.Forms.MessageBox.Show("Error creating the folder: " + dir); return; } if (!File.Exists(file)) { int position = WriteFile(file); try { AddFileToActiveProject(file); Window window = _dte.ItemOperations.OpenFile(file); // Move cursor into position if (position > 0) { TextSelection selection = (TextSelection)window.Selection; selection.CharRight(Count: position - 1); } SelectCurrentItem(); } catch { /* Something went wrong. What should we do about it? */ } } else { System.Windows.Forms.MessageBox.Show("The file '" + file + "' already exist."); } }
private static void addContentToProject(SolutionData solutionData, Project project, DTE2 dte2) { #region CPP Writing if (solutionData.projectType == ProjectType.CppEmpty) //CPP Example { Directory.CreateDirectory(solutionData.directoryPath + "\\Source Files"); Directory.CreateDirectory(solutionData.directoryPath + "\\Header Files"); foreach (ClassData classData in solutionData.classes) { #region Class if (classData.classType == ClassType.Class) { Document doc = dte2.ItemOperations.NewFile("General\\Text File", classData.className).Document; TextSelection txtsel = (TextSelection)doc.Selection; txtsel.Text = ""; txtsel.Insert("#include \"" + classData.className + ".h\"\n\n" + classData.className + "::" + classData.className + "()\n{\n}\n\n" + classData.className + "::~" + classData.className + "()\n{\n}"); doc.Save(solutionData.directoryPath + "\\Source Files\\" + classData.className + ".cpp"); project.ProjectItems.AddFromFile(solutionData.directoryPath + "\\Source Files\\" + classData.className + ".cpp"); Document doc2 = dte2.ItemOperations.NewFile("General\\Text File", classData.className).Document; TextSelection txtsel2 = (TextSelection)doc2.Selection; txtsel2.Text = ""; txtsel2.Insert("#pragma once"); if (classData.superClassName != "") { txtsel2.Insert("\n#include \"" + classData.superClassName + "\""); } foreach (string interfaceName in classData.interfaceNames) { txtsel2.Insert("\n#include \"" + interfaceName + "\""); } txtsel2.Insert("\n\nclass " + classData.className); if (classData.superClassName != "") { txtsel2.Insert(" : public " + classData.superClassName); foreach (string interfaceName in classData.interfaceNames) { txtsel2.Insert(", " + interfaceName); } } else if (classData.interfaceNames.Count != 0) { txtsel2.Insert(" : " + classData.interfaceNames[0]); for (int i = 1; i < classData.interfaceNames.Count; ++i) { txtsel2.Insert(", " + classData.interfaceNames[i]); } } txtsel2.Insert("\n{\npublic:\n\t" + classData.className + "();\n\t~" + classData.className + "();\n\nprivate:\n\n};"); doc2.Save(solutionData.directoryPath + "\\Header Files\\" + classData.className + ".h"); project.ProjectItems.AddFromFile(solutionData.directoryPath + "\\Header Files\\" + classData.className + ".h"); } #endregion #region Enum else if (classData.classType == ClassType.Enum) { EnvDTE.Document doc2 = dte2.ItemOperations.NewFile("General\\Text File", classData.className).Document; TextSelection txtsel2 = (TextSelection)doc2.Selection; txtsel2.Text = ""; txtsel2.Insert("#pragma once\n\nenum " + classData.className + "\n{\n\n};"); doc2.Save(solutionData.directoryPath + "\\Header Files\\" + classData.className + ".h"); project.ProjectItems.AddFromFile(solutionData.directoryPath + "\\Header Files\\" + classData.className + ".h"); } #endregion } } #endregion #region C# Writing else //C# Example { foreach (ProjectItem pItem in project.ProjectItems) { if (pItem.Name == "Form1.cs") { pItem.Remove(); } } foreach (ClassData classData in solutionData.classes) { if (classData.classType == ClassType.Enum || classData.classType == ClassType.Class || classData.classType == ClassType.Interface) { project.ProjectItems.AddFromTemplate(@"C:\Program Files (x86)\Microsoft Visual Studio " + dte2.Version + @"\Common7\IDE\ItemTemplates\CSharp\Code\1033\Class\Class.vstemplate", classData.className + ".cs"); } else if (classData.classType == ClassType.Form) { project.ProjectItems.AddFromTemplate(@"c:\Program Files (x86)\Microsoft Visual Studio " + dte2.Version + @"\Common7\IDE\ItemTemplates\CSharp\Windows Forms\1033\Form\windowsform.vstemplate", classData.className + ".cs"); } ProjectItem projectItem = null; foreach (ProjectItem pItem in project.ProjectItems) { if (pItem.Name == classData.className + ".cs") { projectItem = pItem; break; } } projectItem.Save(); TextSelection txtsel = (TextSelection)projectItem.Document.Selection; #region Class if (classData.classType == ClassType.Class) { txtsel.GotoLine(9); txtsel.EndOfLine(); if (classData.superClassName != "") { txtsel.Insert(" : " + classData.superClassName); foreach (string interfaceName in classData.interfaceNames) { txtsel.Insert(", " + interfaceName); } } else if (classData.interfaceNames.Count != 0) { txtsel.Insert(" : " + classData.interfaceNames[0]); for (int i = 1; i < classData.interfaceNames.Count; ++i) { txtsel.Insert(", " + classData.interfaceNames[i]); } } } #endregion #region Enum else if (classData.classType == ClassType.Enum) { txtsel.GotoLine(9); txtsel.StartOfLine(); txtsel.CharRight(false, 4); txtsel.DestructiveInsert("enum"); txtsel.Delete(); } #endregion #region Interface else if (classData.classType == ClassType.Interface) { txtsel.GotoLine(9); txtsel.StartOfLine(); txtsel.CharRight(false, 4); txtsel.Insert("interface"); txtsel.Delete(5); } #endregion } } #endregion }
private static void ResetSelection(TextSelection selection, int lineNumber, int offset, int length) { selection.MoveToLineAndOffset(lineNumber, offset); selection.CharRight(true, length); }
void BeforeKeyPress(string Keypress, TextSelection Selection, bool InStatementCompletion, ref bool CancelKeypress) { if (isOn) { bool isAlpha = (Keypress[0] >= 'A' && Keypress[0] <= 'Z') || (Keypress[0] >= 'a' && Keypress[0] <= 'z'); bool swap = Selection.IsActiveEndGreater; if (isAlpha) { if (!nextShouldBeCaps) { if (swap) Selection.SwapAnchor(); Selection.CharLeft(true); if (Selection.Text[0] == '_') nextShouldBeCaps = true; Selection.CharRight(true); if (swap) Selection.SwapAnchor(); } if (nextShouldBeCaps) { CancelKeypress = true; if (!Selection.IsEmpty) { Selection.Delete(); } Selection.Insert(Keypress.ToUpper()); } } else if (Keypress == " ") { CancelKeypress = true; if (!Selection.IsEmpty) { Selection.Delete(); } Selection.Insert("_"); } else if (Keypress == "(") { CancelKeypress = false; ToggleIsOn(); } nextShouldBeCaps = false; } }
// Collapses all regions in the current document public static void CollapseAllRegions(DTE dte, Language language, MainPackage package, bool showErrors = true) { if (IsSupportedLanguage(language)) { dte.SuppressUI = true; // Disable UI while we do this try { // Outling must be enabled. If Outlining is turned off then the rest of this method will get stuck in an infinite loop. // It can be turned off by default from the C# advanced text editor properties, or it can be turned off by running // the Edit.StopOutlining command (e.g., in the Command window or via Edit -> Outlining -> Stop Outlining). // If the Edit.StartAutomaticOutlining command is available, then that means outlining needs to be turned back on. const string StartOutliningCommand = "Edit.StartAutomaticOutlining"; EnvDTE.Command command = dte.Commands.Item(StartOutliningCommand); if (command.IsAvailable) { dte.ExecuteCommand(StartOutliningCommand); } const string ToggleOutliningExpansion = "Edit.ToggleOutliningExpansion"; command = dte.Commands.Item(ToggleOutliningExpansion); const int MaxAttempts = 3; int maxAttempts = command.IsAvailable ? MaxAttempts : 0; string regionBeginRegex = GetRegionBeginRegex(language); // Sometimes VS can't collapse some regions, so we'll try the whole operation a few times if necessary. bool failedToCollapse = true; for (int attempt = 1; attempt <= maxAttempts && failedToCollapse; attempt++) { failedToCollapse = false; ExpandAllRegions(dte, language); // Force the expansion of all regions TextSelection selection = (TextSelection)dte.ActiveDocument.Selection; // Hook up to the ActiveDocument's selection selection.EndOfDocument(); // Shoot to the end of the document // Find the first occurence of #region from the end of the document to the start of the document. int currentFindOffset = 0; int previousFindOffset = int.MaxValue; const int FindOptions = (int)vsFindOptions.vsFindOptionsBackwards + (int)vsFindOptions.vsFindOptionsMatchCase + (int)vsFindOptions.vsFindOptionsRegularExpression; while (selection.FindText(regionBeginRegex, FindOptions)) { currentFindOffset = selection.TopPoint.AbsoluteCharOffset; if (currentFindOffset >= previousFindOffset) { // I don't want to get stuck in an infinite loop. I'd rather throw if something unexpected happens. throw new InvalidOperationException(string.Format( "FindText did not go backward! Previous offset: {0}; Current offset: {1}.", previousFindOffset, currentFindOffset)); } // We can ignore matches where #region is used inside a string or single line comment. // However, this still won't detect if it's used inside a multiline comment with the opening // delimiter on another line. selection.SelectLine(); string lineText = selection.Text ?? string.Empty; // Make sure the region begin token is the first non-whitespace on the line. Match match = Regex.Match(lineText.TrimStart(), regionBeginRegex); if (match.Success && match.Index == 0) { // The SelectLine call above will leave the end anchor on the next line. If there's no blank line between // a #region line and an XML doc comment after it, then having the end anchor on the line with the // XML doc comment will cause the comment to collapse instead of the #region. So we'll avoid that // by moving back to the find offset. selection.MoveToAbsoluteOffset(currentFindOffset); // Try to increase the chances that the ToggleOutliningExpansion command will be available. selection.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstText); // Collapse this #region. Sometimes VS reports that the Edit.ToggleOutliningExpansion command // isn't available even though it should be. Poke it and give it a little bit of time to sync up. if (!command.IsAvailable) { const int WaitMilliseconds = 20; System.Threading.Thread.Sleep(WaitMilliseconds); int tempOffset = selection.TopPoint.AbsoluteCharOffset; selection.CharRight(); selection.MoveToAbsoluteOffset(tempOffset); System.Threading.Thread.Sleep(WaitMilliseconds); } if (command.IsAvailable) { // If #region is found in a multiline comment, then this will collapse the enclosing block. dte.ExecuteCommand(ToggleOutliningExpansion); } else { // We couldn't collapse a #region. failedToCollapse = true; } } // Move to the start of the last FindText match, so we can continue searching backward from there. selection.MoveToAbsoluteOffset(currentFindOffset); previousFindOffset = currentFindOffset; } selection.StartOfDocument(); // All done, head back to the start of the doc } if (failedToCollapse && package != null && showErrors) { package.ShowMessageBox( "Some regions couldn't be collapsed because Visual Studio's Edit.ToggleOutliningExpansion command wasn't available.", true); } } finally { dte.SuppressUI = false; // Reenable the UI } } }