// Expands all regions in the current document public static void ExpandAllRegions(DTE dte, Language language) { if (IsSupportedLanguage(language)) { bool suppressedUI = false; if (!dte.SuppressUI) { dte.SuppressUI = true; // Disable UI while we do this suppressedUI = true; } try { if (language == Language.Python) { // The Python Tools language provider outlines a #region as "#region Test[...]". // Using FindText(...) to force a region expansion won't work for Python because // the "#region" part is still in the visible, non-hidden, non-collapsed text. // So we'll use the ExpandAllOutlining command instead. It will also expand // non-region collapses (e.g., if someone has collapsed a function definition), // so it's not really just an "ExpandAllRegions" command like we want. :-( // Note: This command is only available if outlining is enabled and something // in the document is collapsed. const string ExpandAllCommand = "Edit.ExpandAllOutlining"; EnvDTE.Command command = dte.Commands.Item(ExpandAllCommand, 0); if (command.IsAvailable) { dte.ExecuteCommand(ExpandAllCommand); } } else { TextSelection selection = (TextSelection)dte.ActiveDocument.Selection; // Hook up to the ActiveDocument's selection selection.StartOfDocument(); // Shoot to the start of the document string regionBeginRegex = GetRegionBeginRegex(language); // Loop through the document finding all instances of #region. This action has the side benefit // of actually zooming us to the text in question when it is found and ALSO expanding it since it // is an outline. const int FindOptions = (int)vsFindOptions.vsFindOptionsMatchInHiddenText + (int)vsFindOptions.vsFindOptionsMatchCase + (int)vsFindOptions.vsFindOptionsRegularExpression; while (selection.FindText(regionBeginRegex, FindOptions)) { // The FindText command will expand the #region block if "#region" is hidden. } selection.StartOfDocument(); // Shoot us back to the start of the document } } finally { if (suppressedUI) { dte.SuppressUI = false; // Reenable the UI } } } }
private void UpdateCallback(object sender, EventArgs e) { ThreadHelper.ThrowIfNotOnUIThread(); DTE dte = ServiceProvider.GetServiceAsync(typeof(DTE)).Result as DTE; if (dte == null) { return; } TextSelection section = dte.ActiveDocument.Selection as TextSelection; // 光标移动至第一行第一列 section.MoveToLineAndOffset(1, 1); bool result = section.FindText("database", (int)vsFindOptions.vsFindOptionsRegularExpression); if (!result) { section.SelectAll(); section.Delete(); } else { //需要添加此操作,否则不会替换成功 section.SelectAll(); section.Text = ""; } }
private Boolean FindCommentEnd(ref TextSelection selection, out int Index) { Microsoft.VisualStudio.Shell.ThreadHelper.ThrowIfNotOnUIThread(); var result = selection.FindText(DocumentTag.CommentBaseEnd.JavaDocTag, vsFindOptionsNone); Index = selection.CurrentLine; return(result); }
/// <summary> /// Runs custom wizard logic when the wizard has completed all tasks. /// </summary> public void RunFinished() { try { // The interface implmentation inserted in the ProjectFinishedGenerating event has its Region twistie open // This code is to close the interface implmentation twistie so that the region appears like the common methods and support code twisties TL.Enabled = true; TL.LogMessage("RunFinished", "Start"); Diagnostics.Enter(); if (myProjectItem != null) // We do have a project item to work on { myProjectItem.Open(); // Open the item for editing TL.LogMessage("RunFinished", "Done Open"); Document itemDocument = myProjectItem.Document; // Get the open file's document object TL.LogMessage("RunFinished", "Created Document"); itemDocument.Activate(); // Make this the current document TL.LogMessage("RunFinished", "Activated Document"); TextSelection documentSelection = (TextSelection)itemDocument.Selection; // Create a document selection TL.LogMessage("RunFinished", "Created Selection object"); documentSelection.StartOfDocument(); // GO to the top of the document TL.LogMessage("RunFinished", "Done StartOfDocument Region"); string pattern = "[Rr]egion \"*I" + DeviceClass; // Cerate a regular expression string that works for region in both VB and C# TL.LogMessage("", "RegEx search pattern: " + pattern); if (documentSelection.FindText(pattern, (int)vsFindOptions.vsFindOptionsRegularExpression)) // Search for the interface implemnetation start of region { // Found the interface implementation region so toggle its twistie closed documentSelection.SelectLine(); TL.LogMessage("RunFinished", "Found region I" + DeviceClass + " - " + documentSelection.Text); // Log the line actuall found myDTE.ExecuteCommand("Edit.ToggleOutliningExpansion"); // Toggle the twistie closed TL.LogMessage("RunFinished", "Done ToggleOutliningExpansion Region"); } itemDocument.Close(vsSaveChanges.vsSaveChangesYes); // SAve changes and close the file TL.LogMessage("RunFinished", "Done Save"); } else // No project item so just report this (happens when a test project is being created) { TL.LogMessage("RunFinished", "Project item is null, no action taken"); } TL.LogMessage("RunFinished", "End"); Diagnostics.Exit(); } catch (Exception ex) { TL.LogMessageCrLf(" RunFinished Exception", ex.ToString()); // Log any error message MessageBox.Show(ex.ToString(), "RunFinished Wizard Error", MessageBoxButtons.OK, MessageBoxIcon.Error); // Show an error message } }
public static void Execute(ProjectItem projectItem) { TextSelection txtSel = (TextSelection)projectItem.Document.Selection; usingSystemFound = false; txtSel.StartOfDocument(); if (txtSel.FindText("using System;")) { usingSystemFound = true; } foreach (var codeElement in projectItem.FileCodeModel.CodeElements) { if ((codeElement as CodeElement) != null) { AddCommentsTo(codeElement as CodeElement); } } }
public static void navigate(KnowledgeController controller, Object tag, String sourceFile) { try { log.Debug(" navigation ... "); string regExpression = getRegExpr(tag); if (regExpression == null) { return; } string actualString = getActualString(sourceFile, regExpression); if (actualString == null) { return; } Window textEditor = controller.environment.ApplicationObject.OpenFile(Constants.vsViewKindCode, sourceFile); TextSelection textSelection = (TextSelection)textEditor.Document.Selection; textSelection.StartOfDocument(false); textSelection.EndOfDocument(false); // TODO: textSelection.findPattern doesn't work for some reason if (textSelection.FindText(actualString, (int)vsFindOptions.vsFindOptionsFromStart)) { textSelection.SelectLine(); } else { log.Debug("log. actualString is not found in text file, actualString=" + actualString); } textEditor.Visible = true; textEditor.Activate(); // TODO: save of the document } catch (Exception e0) { MessageBox.Show(e0.Message); } }
private void postCompileCpp(string generatedFile, int mode, string functionOfInterest, string curCodeLine) { if (!File.Exists(generatedFile)) { package.showMsgBox("Could not find expected output file\n" + generatedFile); return; } // clean the preprocessed output // TODO: do this in a better way if (mode == 2) { var input = new StreamReader(generatedFile); generatedFile = Path.GetTempFileName() + ".cpp"; var output = new StreamWriter(generatedFile); while (input.Peek() >= 0) { string curReadLine = input.ReadLine(); if (curReadLine != "") { output.WriteLine(curReadLine); } } input.Close(); output.Close(); } // TODO: there are a thousand ways to open a file // dte.Documents.Open(asmFile, EnvDTE.Constants.vsViewKindCode); // dte.ExecuteCommand("File.OpenFile", asmFile); Window tmp = dte.ItemOperations.OpenFile(generatedFile, Constants.vsViewKindCode); TextDocument genFileWindow = (TextDocument)tmp.Document.Object("TextDocument"); // crashes VS // bool ddd = genFileWindow.ReplacePattern("^$\n", "", (int)vsFindOptions.vsFindOptionsRegularExpression); // http://stackoverflow.com/questions/12453160/remove-empty-lines-in-text-using-visual-studio // ^:b*$\n -> ^(?([^\r\n])\s)*\r?$\r?\n // now try to find the function the user was looking at // if it's a template the fullName will be like ns::bar<T> // try to find an instantiation instead then int bracketPos = functionOfInterest.IndexOf("<", StringComparison.Ordinal); if (bracketPos > 0) { functionOfInterest = functionOfInterest.Substring(0, bracketPos + 1); } TextSelection textSelObj = genFileWindow.Selection; // first try to find the function // TODO: for some reason vsFindOptions.vsFindOptionsFromStart option doesn't work textSelObj.StartOfDocument(); bool res = textSelObj.FindText("PROC ; " + functionOfInterest, (int)vsFindOptions.vsFindOptionsMatchCase); if (!res && mode == 1) { dte.StatusBar.Text = "Couldn't find function '" + functionOfInterest + "'"; dte.StatusBar.Highlight(true); } // then search for the code line // it might not be there if it's optimized away if (!string.IsNullOrWhiteSpace(curCodeLine)) { textSelObj.FindText(curCodeLine.Trim(), (int)vsFindOptions.vsFindOptionsMatchCase); } textSelObj.StartOfLine(); }
/// <summary> /// Runs custom wizard logic when a project has finished generating. /// </summary> /// <param name="project"></param> public void ProjectFinishedGenerating(Project project) { // Iterate through the project items and // remove any files that begin with the word "Placeholder". // and the Rates class unless it's the Telescope class // done this way to avoid removing items from inside a foreach loop List <string> rems = new List <string>(); foreach (ProjectItem item in project.ProjectItems) { if (item.Name.StartsWith("Placeholder", StringComparison.OrdinalIgnoreCase) || item.Name.StartsWith("Rate", StringComparison.OrdinalIgnoreCase) && !this.DeviceClass.Equals("Telescope", StringComparison.OrdinalIgnoreCase)) { //MessageBox.Show("adding " + item.Name); rems.Add(item.Name); } } foreach (string item in rems) { //MessageBox.Show("Deleting " + item); project.ProjectItems.Item(item).Delete(); } // Special handling for VB and C# driver template projects to add the interface implementation to the core driver code try { // Check the name of each item in the project and execute if this is a driver template project (contains Driver.vb or Driver.cs) foreach (ProjectItem projectItem in project.ProjectItems) { TL.LogMessage("ProjectFinishedGenerating", "Item name: " + projectItem.Name); if ((projectItem.Name.ToUpperInvariant() == "DRIVER.CS") | (projectItem.Name.ToUpperInvariant() == "DRIVER.VB")) { driverTemplate = projectItem; // Save the driver item // This is a driver template // Get the filename and directory of the Driver.xx file string directory = Path.GetDirectoryName(projectItem.FileNames[1].ToString()); TL.LogMessage("ProjectFinishedGenerating", "File name: " + projectItem.FileNames[1].ToString() + ", Directory: " + directory); TL.LogMessage("ProjectFinishedGenerating", "Found " + projectItem.Name); projectItem.Open(); // Open the item for editing TL.LogMessage("ProjectFinishedGenerating", "Done Open"); Document itemDocument = projectItem.Document; // Get the open file's document object TL.LogMessage("ProjectFinishedGenerating", "Created Document"); itemDocument.Activate(); // Make this the current document TL.LogMessage("ProjectFinishedGenerating", "Activated Document"); TextSelection documentSelection = (TextSelection)itemDocument.Selection; // Create a document selection TL.LogMessage("ProjectFinishedGenerating", "Created Selection object"); const string insertionPoint = "//INTERFACECODEINSERTIONPOINT"; // Find the insertion point in the Driver.xx item documentSelection.FindText(insertionPoint, (int)vsFindOptions.vsFindOptionsMatchWholeWord); TL.LogMessage("ProjectFinishedGenerating", "Done INTERFACECODEINSERTIONPOINT FindText:" + documentSelection.Text); // Create the name of the device interface file to be inserted string insertFile = directory + "\\Device" + this.DeviceClass + Path.GetExtension(projectItem.Name); TL.LogMessage("ProjectFinishedGenerating", "Opening file: " + insertFile); documentSelection.InsertFromFile(insertFile); // Insert the required file at the current selection point TL.LogMessage("ProjectFinishedGenerating", "Done InsertFromFile"); // Remove the top lines of the inserted file until we get to #Region // These lines are only there to make the file error free in the template develpment project and are not required here documentSelection.SelectLine(); // Select the current line TL.LogMessage("ProjectFinishedGenerating", "Selected initial line: " + documentSelection.Text); while (!documentSelection.Text.ToUpperInvariant().Contains("#REGION")) { TL.LogMessage("ProjectFinishedGenerating", "Deleting start line: " + documentSelection.Text); documentSelection.Delete(); // Delete the current line documentSelection.SelectLine(); // Select the new current line ready to test on the next loop } // Find the end of file marker that came from the inserted file const string endOfInsertFile = "//ENDOFINSERTEDFILE"; documentSelection.FindText(endOfInsertFile, (int)vsFindOptions.vsFindOptionsMatchWholeWord); TL.LogMessage("ProjectFinishedGenerating", "Done ENDOFINSERTEDFILE FindText:" + documentSelection.Text); // Delete the marker line and the last 2 lines from the inserted file documentSelection.SelectLine(); TL.LogMessage("ProjectFinishedGenerating", "Found end line: " + documentSelection.Text); while (!documentSelection.Text.ToUpperInvariant().Contains("#REGION")) { TL.LogMessage("ProjectFinishedGenerating", "Deleting end line: " + documentSelection.Text); documentSelection.Delete(); // Delete the current line documentSelection.SelectLine(); // Select the new current line ready to test on the next loop TL.LogMessage("ProjectFinishedGenerating", "Found end line: " + documentSelection.Text); } // Reformat the document to make it look pretty documentSelection.SelectAll(); TL.LogMessage("ProjectFinishedGenerating", "Done SelectAll"); documentSelection.SmartFormat(); TL.LogMessage("ProjectFinishedGenerating", "Done SmartFormat"); itemDocument.Save(); // Save the edited file readyfor use! TL.LogMessage("ProjectFinishedGenerating", "Done Save"); itemDocument.Close(vsSaveChanges.vsSaveChangesYes); TL.LogMessage("ProjectFinishedGenerating", "Done Close"); } } // Iterate through the project items and remove any files that begin with the word "Device". // These are the partial device implementations that are merged in to create a complete device driver template by the code above // They are not required in the final project // Done this way to avoid removing items from inside a foreach loop rems = new List <string>(); foreach (ProjectItem item in project.ProjectItems) { if (item.Name.StartsWith("Device", StringComparison.OrdinalIgnoreCase)) { //MessageBox.Show("adding " + item.Name); rems.Add(item.Name); } } foreach (string item in rems) { TL.LogMessage("ProjectFinishedGenerating", "Deleting file: " + item); project.ProjectItems.Item(item).Delete(); } } catch (Exception ex) { TL.LogMessageCrLf("ProjectFinishedGenerating Exception", ex.ToString()); // Log any error message MessageBox.Show(ex.ToString(), "ProjectFinishedGenerating Wizard Error", MessageBoxButtons.OK, MessageBoxIcon.Error); // Show an error message } TL.LogMessage("ProjectFinishedGenerating", "End"); TL.Enabled = 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 } } }