/// <summary> /// Moves cursor/editpoint exactly. /// </summary> /// <param name="point"></param> /// <param name="count"></param> /// <param name="direction"></param> /// <returns></returns> /// <remarks> /// DTE functions that moves editpoint counts newline as single character, /// since we get the character count from regular regex not the DTE find, the char count is slightly off /// </remarks> public static EditPoint CharMoveExact(EditPoint point, int count, int direction) { while (count > 0) { //Normalize if (direction > 1) { direction = 1; } else if (direction < 0) { direction = -1; } //If we are asking 1 and getting 2, its a newline. This is a quirk/feature of EnvDTE where all its functions treats newline as single character if (point.GetText(direction).Length == 2) { count -= 1; } if (direction < 0) { point.CharLeft(); } else { point.CharRight(); } count -= 1; } return(point); }
/// <summary> /// Moves cursor/editpoint exactly. /// </summary> /// <param name="point"></param> /// <param name="count"></param> /// <param name="direction"></param> /// <returns></returns> /// <remarks> /// DTE functions that moves editpoint counts newline as single character, /// since we get the character count from regular regex not the DTE find, the char count is slightly off /// </remarks> public static EditPoint CharMoveExact(EditPoint point, int count, int direction) { while (count > 0) { //Normalize if (direction > 1) { direction = 1; } else if (direction < 0) { direction = -1; } //If we are asking 1 and getting 2, its a newline. This is a quirk/feature of EnvDTE where all its functions treats newline as single character if (point.GetText(direction).Length == 2) { count -= 1; } if (direction < 0) { point.CharLeft(1); } else { point.CharRight(1); } count -= 1; } return point; }
/// <summary> /// Moves cursor/editpoint exactly. /// </summary> /// <param name="point"></param> /// <param name="count"></param> /// <param name="direction"></param> /// <returns></returns> /// <remarks> /// DTE functions that moves editpoint counts newline as single character, /// since we get the character count from regular regex not the DTE find, the char count is slightly off /// </remarks> public static EditPoint CharMoveExact(EditPoint point, int count, int direction) { while (count > 0) { if (direction > 1) { direction = 1; } else { if (direction < 0) { direction = -1; } } if (point.GetText(direction).Length == 2) { count--; } if (direction < 0) { point.CharLeft(); } else { point.CharRight(); } count--; } return point; }
/// <summary> /// Sorts all using statements in ascending order, with System using statements on top. /// </summary> /// <param name="usingStatementsItems">List of using Statement codeItems</param> /// <param name="namespaceItems">List of namespace codeItems</param> internal void MoveUsingStatementsWithinNamespace(List <CodeItemUsingStatement> usingStatementsItems, List <CodeItemNamespace> namespaceItems) { if (namespaceItems.Count != 1) { //We return back as is, if multiple namespaces are found. return; } CodeItemNamespace theOnlyNamespace = namespaceItems.First(); EditPoint namespaceInsertCursor = theOnlyNamespace.StartPoint; // Setting the start point where we will start inserting using statements. namespaceInsertCursor.LineDown(); namespaceInsertCursor.CharRight(); namespaceInsertCursor.Insert(Environment.NewLine); //Sort the using code items in ascending string order, with system usings on top. usingStatementsItems.Sort((usingStatement1Item, usingStatement2Item) => { string textOfUsingStatement1 = usingStatement1Item.StartPoint.GetText(usingStatement1Item.EndPoint); string textOfUsingStatement2 = usingStatement2Item.StartPoint.GetText(usingStatement2Item.EndPoint); var referenceNameOfStatement1 = ExtractUsingStatementReferenceName(textOfUsingStatement1); var referenceNameOfStatement2 = ExtractUsingStatementReferenceName(textOfUsingStatement2); if (IsSystemReference(referenceNameOfStatement1) && !IsSystemReference(referenceNameOfStatement2)) { return(-1); } else if (!IsSystemReference(referenceNameOfStatement1) && IsSystemReference(referenceNameOfStatement2)) { return(1); } else { return(string.Compare(referenceNameOfStatement1, referenceNameOfStatement2)); } }); foreach (var usingStatement in usingStatementsItems) { var startPoint = usingStatement.StartPoint; var endPoint = usingStatement.EndPoint; string text = startPoint.GetText(usingStatement.EndPoint); startPoint.Delete(usingStatement.EndPoint); namespaceInsertCursor.Insert(text); namespaceInsertCursor.Indent(Count: 1); namespaceInsertCursor.Insert(Environment.NewLine); } }
/// <summary> /// Updates the #endregion directives to match the names of the matching #region directive /// and cleans up any unnecessary white space. /// </summary> /// <remarks> /// This code is very similar to the Common region retrieval function, but since it /// manipulates the cursors during processing the logic is different enough to warrant a /// separate copy of the code. /// </remarks> /// <param name="textDocument">The text document to cleanup.</param> internal void UpdateEndRegionDirectives(TextDocument textDocument) { if (!Settings.Default.Cleaning_UpdateEndRegionDirectives) { return; } var regionStack = new Stack <string>(); EditPoint cursor = textDocument.StartPoint.CreateEditPoint(); TextRanges subGroupMatches = null; // Not used - required for FindPattern. const string pattern = @"^[ \t]*#"; // Keep pushing cursor forwards (note ref cursor parameter) until finished. while (cursor != null && cursor.FindPattern(pattern, TextDocumentHelper.StandardFindOptions, ref cursor, ref subGroupMatches)) { // Create a pointer to capture the text for this line. EditPoint eolCursor = cursor.CreateEditPoint(); eolCursor.EndOfLine(); string regionText = cursor.GetText(eolCursor); if (regionText.StartsWith("region ")) // Space required by compiler. { // Cleanup any whitespace in the region name. string regionName = regionText.Substring(7); string regionNameTrimmed = regionName.Trim(); if (regionName != regionNameTrimmed) { cursor.CharRight(7); cursor.Delete(eolCursor); cursor.Insert(regionNameTrimmed); } // Push the parsed region name onto the top of the stack. regionStack.Push(regionNameTrimmed); } else if (regionText.StartsWith("endregion")) // Space may or may not be present. { if (regionStack.Count > 0) { // Do not trim the endRegionName in order to catch whitespace differences. string endRegionName = regionText.Length > 9 ? regionText.Substring(10) : String.Empty; string matchingRegion = regionStack.Pop(); // Update if the strings do not match. if (matchingRegion != endRegionName) { cursor.CharRight(9); cursor.Delete(eolCursor); cursor.Insert(" " + matchingRegion); } } else { // This document is improperly formatted, abort. return; } } // Note: eolCursor may be outdated now if changes have been made. cursor.EndOfLine(); } }
private void ToggleExpansionAtLine(EditPoint commentStartingPoint, int firstLineOfComment, string commentPrefix) { commentStartingPoint.MoveToLineAndOffset(firstLineOfComment, 1); while(commentStartingPoint.GetText(commentPrefix.Length) != commentPrefix) { commentStartingPoint.CharRight(); } ToggleExpansionAtPoint(commentStartingPoint); }
/// <summary> /// Performs the style task. /// </summary> /// <param name="projectItem">The project Item</param> /// <param name="ideWindow">The IDE window.</param> protected override void DoWork(ProjectItem projectItem, EnvDTE.Window ideWindow) { if (projectItem.Name.EndsWith(".cs")) { Debug.WriteLine("Formatting Spacing Around Comments: " + projectItem.Name); try { TextDocument objTextDoc = (TextDocument)ideWindow.Document.Object("TextDocument"); EditPoint objEditPoint = objTextDoc.CreateEditPoint(objTextDoc.StartPoint); EditPoint commentPoint = objEditPoint.CreateEditPoint(); TextRanges trs = null; while (objEditPoint.FindPattern("//", (int)vsFindOptions.vsFindOptionsMatchCase, ref commentPoint, ref trs)) { bool previousBlank = false; bool isNotInline = true; EditPoint beginningLineEditPoint = objEditPoint.CreateEditPoint(); beginningLineEditPoint.StartOfLine(); if (beginningLineEditPoint.GetText(objEditPoint).Trim() != string.Empty) { isNotInline = false; } if (isNotInline) { EditPoint previousCheckPoint = objEditPoint.CreateEditPoint(); previousCheckPoint.LineUp(1); if (previousCheckPoint.GetText(objEditPoint).Trim() == string.Empty) { previousBlank = true; } commentPoint.CharRight(1); string comment = objEditPoint.GetText(commentPoint); while (!comment.EndsWith(" ") && !commentPoint.AtEndOfLine) { if (comment.EndsWith("/")) { commentPoint.CharRight(1); } else { commentPoint.CharLeft(1); commentPoint.Insert(" "); } comment = objEditPoint.GetText(commentPoint); } commentPoint.CharRight(1); comment = objEditPoint.GetText(commentPoint); if (comment.EndsWith(" ")) { commentPoint.CharLeft(1); commentPoint.DeleteWhitespace(vsWhitespaceOptions.vsWhitespaceOptionsHorizontal); commentPoint.Insert(" "); } if (commentPoint.Line > objEditPoint.Line) { commentPoint.LineUp(1); commentPoint.EndOfLine(); } if (commentPoint.AtEndOfLine) { objEditPoint.Delete(commentPoint); } else { EditPoint endComment = commentPoint.CreateEditPoint(); endComment.EndOfLine(); if (commentPoint.GetText(endComment).Trim() == string.Empty) { objEditPoint.Delete(endComment); } else { objEditPoint.LineDown(1); previousBlank = false; } } objEditPoint.StartOfLine(); commentPoint = objEditPoint.CreateEditPoint(); commentPoint.EndOfLine(); if (objEditPoint.GetText(commentPoint).Trim() == string.Empty) { objEditPoint.DeleteWhitespace(vsWhitespaceOptions.vsWhitespaceOptionsVertical); if (previousBlank) { objEditPoint.Insert("\r\n"); } } } objEditPoint.EndOfLine(); } } catch (Exception exc) { Debug.WriteLine(exc.ToString()); Debug.WriteLine("Formatting Spacing Around Comments failed, skipping"); } } }
/// <summary> /// Generates code in /// </summary> /// <param name="optionTag"></param> /// <param name="parentWriter"></param> /// <remarks></remarks> private void GenInMember(ManagerType.OptionTag optionTag, ManagerType.Writer parentWriter) { var memberName = optionTag.CodeElement.Name; //!Parent can be either CodeFunction(only for ExtraNotifications) or CodeProperty string code = null; var note = ""; if (optionTag.CodeElement is CodeProperty) { switch (optionTag.OptionAttribute.GenerationType) { case NotifyPropertyOptionAttribute.GenerationTypes.NotifyOnly: //Notify Member name note = string.Format("Notify {0}", memberName); code = string.Format(NotifyChangedFormat, memberName); break; default: //Set and property Member name note = string.Format("SetPropertyAndNotify {0}", memberName); code = string.Format("this.SetPropertyAndNotify(ref _{0}, value, \"{0}\");", memberName); break; } } //Extra notifications var extraNotifyCode = GenInMember_ExtraNotifications(optionTag, parentWriter); code = code.Conjoin(Environment.NewLine, extraNotifyCode); //Code Element, could be property setter or a method var prop = (optionTag.CodeElement as CodeProperty2); var codeElement = (CodeFunction2)((prop != null) ? prop.Setter : (CodeFunction2)optionTag.CodeElement); var tag = optionTag.MemberwiseClone(); tag.Trigger.Type = TriggerType; var memberWriter = new ManagerType.Writer(parentWriter) { TagNote = note, OptionTag = (ManagerType.OptionTag)tag, TargetRange = new TaggedRange { StartPoint = codeElement.StartPoint, EndPoint = codeElement.EndPoint, SegmentType = SegmentTypes.Region }, Content = code, }; //Find insertion point EditPoint insertPoint; EditPoint afterClosingBracePoint = null; var insertTag = ManagerType.GeneratedSegment.FindInsertionPoint(memberWriter.TargetRange); if (insertTag == null) { //!No insertion point tag specified, by default insert as last line of setter insertPoint = codeElement.GetClosingBracePosition(); afterClosingBracePoint = insertPoint.CreateEditPoint(); afterClosingBracePoint.CharRight(); //makes sure region is on new line insertPoint.Insert(Environment.NewLine); } else { //!InsertPoint Tag found, insert right after it insertPoint = insertTag.Range.EndPoint.CreateEditPoint(); insertPoint.LineDown(); insertPoint.StartOfLine(); } memberWriter.InsertStart = insertPoint; memberWriter.InsertOrReplace(AlwaysInsert, afterClosingBracePoint); }
/// <summary> /// This function is the callback used to execute the command when the menu item is clicked. /// See the constructor to see how the menu item is associated with this function using /// OleMenuCommandService service and MenuCommand class. /// </summary> /// <param name="sender">Event sender.</param> /// <param name="e">Event args.</param> private void MenuItemCallback(object sender, EventArgs e) { //string message = string.Format(CultureInfo.CurrentCulture, "Inside {0}.MenuItemCallback()", this.GetType().FullName); //string title = "Custom Watch"; //// Show a message box to prove we were here //VsShellUtilities.ShowMessageBox( // this.ServiceProvider, // message, // title, // OLEMSGICON.OLEMSGICON_INFO, // OLEMSGBUTTON.OLEMSGBUTTON_OK, // OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST); if (m_dte == null) { return; } Document doc = m_dte.ActiveDocument; if (doc == null) { return; } if (doc.Type != "Text") { return; } //select text TextSelection selection = (TextSelection)doc.Selection; string strSelectText = selection.Text; strSelectText.Trim(); // invalid selection if (strSelectText.Length == 0) { EditPoint pt = (EditPoint)selection.ActivePoint.CreateEditPoint(); EditPoint ptLeft = pt.CreateEditPoint(); EditPoint ptRight = pt.CreateEditPoint(); for (ptLeft.CharLeft(); !ptLeft.AtStartOfLine; ptLeft.CharLeft()) { if (!IsValidCharOfName(ptLeft.GetText(pt)[0])) { break; } } ptLeft.CharRight(); for (ptRight.CharRight(); !ptRight.AtEndOfLine; ptRight.CharRight()) { var strText = ptRight.GetText(pt); if (!IsValidCharOfName(strText[strText.Length - 1])) { break; } } ptRight.CharLeft(); strSelectText = ptLeft.GetText(ptRight); if (!IsValidStartCharOfName(strSelectText[0])) { return; } } if (strSelectText.Length == 0) { return; } if (m_watchPane != null) { m_watchPane.Clear(); } string strRetValue = ""; string strErrorMsg = ""; if (m_procEvent.CalcExpression(strSelectText, out strErrorMsg, out strRetValue)) { if (strRetValue != "" && strRetValue.IndexOf("Error") == -1 && strRetValue.IndexOf("error") == -1) { Clipboard.SetText(strRetValue); OutputStr("(Inform: Already copy the data below to clipborad)"); } OutputStr(strRetValue); OutputStr("\n"); } else { OutputStr("Error Occur: " + strErrorMsg + "\n"); } }