/// <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; }
protected static string GetSelectedText(EditPoint selPoint) { return selPoint.GetText(selPoint.LineLength).Trim(); }
private void ToggleExpansionAtLine(EditPoint commentStartingPoint, int firstLineOfComment, string commentPrefix) { commentStartingPoint.MoveToLineAndOffset(firstLineOfComment, 1); while(commentStartingPoint.GetText(commentPrefix.Length) != commentPrefix) { commentStartingPoint.CharRight(); } ToggleExpansionAtPoint(commentStartingPoint); }
public Dictionary <string, BaseObject> ReadCodeLines() { EditPoint editPoint = null; EditPoint movePoint = null; string startPattern = "#region XnaLevelEditor"; string endPattern = "#endregion"; #region var declaration regex /* reference http://stackoverflow.com/questions/585853/regex-for-variable-declaration-and-initialization-in-c-sharp * tested at http://rubular.com/ * * (a line can start with some spaces) followed by, * (Type) followed by * (at least one space) * (variable_1) * (optionally * (comma // next var | | '='number // initialization | ) ...` * * ^ \s* \w+ \s+ \w+ ? (',' | '=' \d+ ) ... * line some type at least var optionally more or init some * start spaces (some chars) one space (some chars) vars val digits * * * variable <variable> * [a-zA-Z_][a-zA-Z0-9_]* * simple declaration of DrawingObject * \s*(DrawingObject|Camera)\s+<variable>\s* * instantiation DrawingObject * \s*<variable>\s*=\s*new\s+DrawingObject\(\s*this\s*,\s*camera\s*,\s*\"\w+\"\s*,\s*world\s*\)\s* * declaration (and instantiationon) of DrawingObject * \s*DrawingObject\s+<variable>(\s*=\s*new\s+DrawingObject\(\))?(,\s*<variable>\s*(=\s*new\s+DrawingObject\(\))))* * integer or float <integerFloat> * \-\d+(\.\d+)?f? * variable, integer, or float <variableIntegerFloat> * (<integerFloat>|<variable>) * Content load * ^\s*<variable>\s*\.\s*DrawingModel\s*=\s*Content\s*.\s*Load\s*<\s*Model\s*>\s*\(\s*\"\w+\"\s*\)\s*$ * instantiation Vector3 <instantiationVector3> * \s*new\s+Vector3\s*\((\s*(<variableIntegerFloat>)\s*,\s*(<variableIntegerFloat>)\s*,\s*(<variableIntegerFloat>)\s*)?\)\s* * set a DrawingObject's Position value * \s*<variable>\s*\.\s*Position\s*=<instantiationVector3> * set a DrawingObject's Rotation value * \s*<variable>\s*\.\s*Rotation\s*=<instantiationVector3> * * set a DrawingObject's Scale value * \s*<variable>\s*\.\s*Scale\s*=<instantiationVector3> * set PhysicsEnabled * \s*<variable>\s*\.\s*PhysicsEnabled\s*=\s*(true|false)\s* * set IsActive * \s*<variable>\s*\.\s*PhysicsAdapter\s*.\s*Body\s*.\s*IsActive\s*=\s*(true|false)\s* * set IsStatic * \s*<variable>\s*\.\s*PhysicsAdapter\s*.\s*Body\s*.\s*IsStatic\s*=\s*(true|false)\s* * set CharacterControllerEnabled * \s*<variable>\s*\.\s*PhysicsAdapter\s*.\s*EnableCharacterController\s*\(\s*\)\s* * change PhysicsAdapter * \s*<variable>\s*\.\s*ChangePhysicsAdapter\s*\(\s*typeof\s*\(\s*[a-zA-Z_][a-zA-Z0-9_]*\s*\)\s*,\s*new\s*object\s*\[\s*\]\s*{[\s\w\,\(\)\-\d\.]*}\s*\)\s* * add script * \s*<variable>\s*\.AddScript\s*\(new\s*<variable>\s*\(\s*\)\s*\)\s* * */ #endregion const string variableRegex = "[a-zA-Z_][a-zA-Z0-9_]*"; const string integerOrFloatRegex = "\\-?\\d+(.\\d+)?f?"; const string variableIntegerFloatRegex = integerOrFloatRegex + "|" + variableRegex; const string declarationRegex = "^\\s*(DrawingObject|Camera)\\s+" + variableRegex + "\\s*$"; const string instantiationRegex = "^\\s*" + variableRegex + "\\s*=\\s*new\\s+DrawingObject\\(\\s*this\\s*,\\s*camera\\s*,\\s*\\\"\\w+\\\"\\s*,\\s*world\\s*\\)\\s*$"; //const string loadContentRegex = "^\\s*" + variableRegex + "\\s*.\\s*DrawingModel\\s*=\\s*Content\\s*.\\s*Load\\s*<\\s*Model\\s*>\\s*\\(\\s*\\\"\\w+\\\"\\s*\\)\\s*$"; const string instantiationVector3Regex = "\\s*new\\s+Vector3\\s*\\((\\s*(" + variableIntegerFloatRegex + ")\\s*,\\s*(" + variableIntegerFloatRegex + ")\\s*,\\s*(" + variableIntegerFloatRegex + ")\\s*)?\\)\\s*"; const string setPositionRegex = "^\\s*" + variableRegex + "\\s*\\.\\s*Position\\s*=" + instantiationVector3Regex + "$"; const string setRotationRegex = "^\\s*" + variableRegex + "\\s*\\.\\s*EulerRotation\\s*=" + instantiationVector3Regex + "$"; const string setScaleRegex = "^\\s*" + variableRegex + "\\s*\\.\\s*Scale\\s*=" + instantiationVector3Regex + "$"; const string setPhysicsEnabledRegex = "^\\s*" + variableRegex + "\\s*\\.\\s*PhysicsEnabled\\s*=\\s*(true|false)\\s*$"; const string setIsActiveRegex = "^\\s*" + variableRegex + "\\s*\\.\\s*PhysicsAdapter\\s*.\\s*Body\\s*.\\s*IsActive\\s*=\\s*(true|false)\\s*$"; const string setIsStaticRegex = "^\\s*" + variableRegex + "\\s*\\.\\s*PhysicsAdapter\\s*.\\s*Body\\s*.\\s*IsStatic\\s*=\\s*(true|false)\\s*$"; const string enableCharacterControllerRegex = "^\\s*" + variableRegex + "\\s*\\.\\s*PhysicsAdapter\\s*.\\s*EnableCharacterController\\s*\\(\\s*\\)\\s*$"; const string changePhysicsAdapterRegex = "^\\s*" + variableRegex + "\\s*\\.\\s*ChangePhysicsAdapter\\s*\\(\\s*typeof\\s*\\(\\s*[a-zA-Z_][a-zA-Z0-9_]*\\s*\\)\\s*,\\s*new\\s*object\\s*\\[\\s*\\]\\s*{.*}\\s*\\)\\s*$"; const string addScriptRegex = "^\\s*" + variableRegex + "\\s*\\.AddScript\\s*\\(new\\s*" + variableRegex + "\\s*\\(\\s*\\)\\s*\\)\\s*$"; Dictionary <string, BaseObject> objects = new Dictionary <string, BaseObject>(); if (codeClass != null) { editPoint = codeClass.GetStartPoint(vsCMPart.vsCMPartBody).CreateEditPoint(); editPoint.FindPattern(startPattern, (int)vsFindOptions.vsFindOptionsNone, ref editPoint); movePoint = editPoint.CreateEditPoint(); movePoint.FindPattern(endPattern, (int)vsFindOptions.vsFindOptionsNone); string lines = editPoint.GetText(movePoint); foreach (string line in lines.Split(';')) { if (Regex.IsMatch(line, declarationRegex)) { ParseDeclaration(objects, line); } } } if (constructorFunction != null) { editPoint = constructorFunction.GetStartPoint(vsCMPart.vsCMPartBody).CreateEditPoint(); editPoint.FindPattern(startPattern, (int)vsFindOptions.vsFindOptionsNone, ref editPoint); movePoint = editPoint.CreateEditPoint(); movePoint.FindPattern(endPattern, (int)vsFindOptions.vsFindOptionsNone); string lines = editPoint.GetText(movePoint); foreach (string line in lines.Split(';')) { if (Regex.IsMatch(line, instantiationRegex)) { ParseInstantiation(variableRegex, objects, line, contentProject); } if (Regex.IsMatch(line, setPositionRegex)) { ParseSetPosition(variableRegex, objects, line); } if (Regex.IsMatch(line, setRotationRegex)) { ParseSetRotation(variableRegex, objects, line); } if (Regex.IsMatch(line, setScaleRegex)) { ParseSetScale(variableRegex, objects, line); } if (Regex.IsMatch(line, setPhysicsEnabledRegex)) { ParseSetPhysicsEnabled(variableRegex, objects, line); } if (Regex.IsMatch(line, setIsActiveRegex)) { ParseSetIsActiveRegex(variableRegex, objects, line); } if (Regex.IsMatch(line, setIsStaticRegex)) { ParseSetIsStaticRegex(variableRegex, objects, line); } if (Regex.IsMatch(line, enableCharacterControllerRegex)) { ParseEnableCharacterController(variableRegex, objects, line); } if (Regex.IsMatch(line, changePhysicsAdapterRegex)) { ParseChangePhysicsAdapter(variableRegex, integerOrFloatRegex, instantiationVector3Regex, objects, line); } if (Regex.IsMatch(line, addScriptRegex)) { string varName = Regex.Match(line, "^\\s*" + variableRegex).Value.Trim(); if (objects.Keys.Contains(varName)) { string scriptName = Regex.Match(line, "new\\s*" + variableRegex).Value.Replace("new", "").Trim() + ".cs"; string scriptsFolderPath = Path.GetDirectoryName(currentProject.FullName) + "\\Scripts"; objects[varName].Scripts.Add(new EditorModel.PropertyModel.Script() { Name = scriptName, Path = scriptsFolderPath + "\\" + scriptName }); } } } } return(objects); }
public static void DoRemoveInvocationWithFilter(this CodeFunction codeFunction, string[] classNames, List <FluentAPIEntityNode> filter) { if (classNames == null) { return; } if (codeFunction == null) { return; } EditPoint editPoint = codeFunction.StartPoint.CreateEditPoint(); editPoint.SmartFormat(codeFunction.EndPoint); editPoint = codeFunction.StartPoint.CreateEditPoint(); string buff = editPoint.GetText(codeFunction.EndPoint); SyntaxTree tree = CSharpSyntaxTree.ParseText(buff); SyntaxNode root = tree.GetRoot(); if (root == null) { return; } MethodDeclarationSyntax methodDeclaration = root.GetOnModelCreatingParameterName("DbModelBuilder", "ModelBuilder", out string parameterName); if ((methodDeclaration == null) || string.IsNullOrEmpty(parameterName)) { return; } if (methodDeclaration.Body == null) { return; } List <TextSpan> spans = new List <TextSpan>(); foreach (StatementSyntax ss in methodDeclaration.Body.Statements) { if (ss.Kind() != SyntaxKind.ExpressionStatement) { continue; } ExpressionStatementSyntax expressionStatementSyntax = ss as ExpressionStatementSyntax; if (expressionStatementSyntax.Expression == null) { continue; } if (expressionStatementSyntax.Expression.Kind() != SyntaxKind.InvocationExpression) { continue; } InvocationExpressionSyntax invocationExpressionSyntax = expressionStatementSyntax.Expression as InvocationExpressionSyntax; if (!parameterName.Equals(invocationExpressionSyntax.InvocationExpressionRootName(classNames))) { continue; } FluentAPIEntityNode faen = expressionStatementSyntax.Expression.InvocationExpressionMethods(null); if (faen == null) { continue; } if (faen.Methods == null) { continue; } if (faen.IsSatisfiedTheFilter(filter)) { spans.Insert(0, expressionStatementSyntax.Span); } } foreach (TextSpan ts in spans) { buff = buff.Remove(ts.Start, ts.Length); // // the commented code does not work : ts.Start does not correctly point to begining of the operator //editPoint.CharRight(ts.Start); //editPoint.Delete(ts.Length); //editPoint.CharLeft(ts.Start); //if (codeFunction.ProjectItem != null) //{ // codeFunction.ProjectItem.Save(); //} } buff = buff.Replace(Environment.NewLine + Environment.NewLine, Environment.NewLine); editPoint = codeFunction.StartPoint.CreateEditPoint(); editPoint.Delete(codeFunction.EndPoint); editPoint.Insert(buff); if (codeFunction.ProjectItem != null) { codeFunction.ProjectItem.Save(); } }
/// <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(); const string pattern = @"^[ \t]*#"; // Keep pushing cursor forwards (note ref cursor parameter) until finished. while (cursor != null && TextDocumentHelper.TryFindNextMatch(startPoint: cursor, endPoint: ref cursor, pattern)) { // 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 ReorderMembers(CodeElement2 type, IEnumerable <CodeMember> members, string orderedCode, TextPoint startPoint) { ThreadHelper.ThrowIfNotOnUIThread(); // Removing members will shift the startPoint back one line. // So we'll use the absolute offset to jump back to that insert point. int startPointOffset = 0; if (startPoint != null) { startPointOffset = startPoint.AbsoluteCharOffset; } FileCodeModel2 codeModel = this.textHandler.Document.ProjectItem.FileCodeModel as FileCodeModel2; codeModel.BeginBatch(); try { foreach (CodeMember member in members) { member.Remove(); } } finally { codeModel.EndBatch(); } if (startPoint != null) { EditPoint startEdit = startPoint.CreateEditPoint(); startEdit.MoveToAbsoluteOffset(startPointOffset); startEdit.StartOfLine(); // If the line above startEdit isn't empty and isn't the start of the class/struct/interface/enum, // then insert a blank line so the sortedCode will be separated from the code above it. EditPoint lineAboveEdit = startEdit.CreateEditPoint(); lineAboveEdit.LineUp(); lineAboveEdit.StartOfLine(); string lineText = lineAboveEdit.GetText(lineAboveEdit.LineLength).Trim(); if (lineText.Length != 0 && lineAboveEdit.Line > type.StartPoint.Line && (this.language != Language.CSharp || lineText != "{")) { startEdit.Insert(Environment.NewLine); } startEdit.Insert(orderedCode); // If the line after startEdit isn't empty and isn't the end of the class/struct/interface/enum, // then insert a blank line so the sortedCode will be separated from the code below it. startEdit.StartOfLine(); lineText = startEdit.GetText(startEdit.LineLength).Trim(); if (lineText.Length != 0 && startEdit.Line < type.EndPoint.Line && (this.language != Language.CSharp || lineText != "}")) { startEdit.Insert(Environment.NewLine); } } }
protected bool GetConflictPositions(out EditPoint ep, out int myCodeOffset, out int cgCodeOffset, out int endConflictOffset) { Document document; TextDocument textDoc; // Values will be ignored, if we return mit false ep = null; myCodeOffset = 0; cgCodeOffset = 0; endConflictOffset = 0; document = this.VisualStudioApplication.ActiveDocument; if (document == null) { return(false); } textDoc = (TextDocument)document.Object("TextDocument"); if (textDoc == null) { return(false); } ep = textDoc.Selection.ActivePoint.CreateEditPoint(); textDoc.Selection.SelectLine(); if (textDoc.Selection.Text.IndexOf("!!!! ClassGenerator merge conflict !!!! Your code follows:") < 0) { return(false); // Nothing to do } ep.StartOfLine(); myCodeOffset = ep.AbsoluteCharOffset; while (true) { if (ep.AtEndOfDocument) { return(false); } ep.LineDown(1); if (ep.GetText(ep.LineLength).IndexOf("!!!! The ClassGenerator's code follows:") >= 0) { break; } } cgCodeOffset = ep.AbsoluteCharOffset; while (true) { if (ep.AtEndOfDocument) { return(false); } ep.LineDown(1); if (ep.GetText(ep.LineLength).IndexOf("!!!! End of merge conflict") >= 0) { break; } } endConflictOffset = ep.AbsoluteCharOffset; return(true); }
/// <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 async void Execute(object sender, EventArgs e) { // Switch to UI thread await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(package.DisposalToken); // Get the Development Tools Extensibility service DTE dte = await ServiceProvider.GetServiceAsync(typeof(DTE)) as DTE; if (dte != null && dte.ActiveDocument != null) { // Operation succeeded bool success = false; // Get the text selection var selection = dte.ActiveDocument.Selection as TextSelection; if (selection is null) { return; } // Find the start and end of the line EditPoint startPoint = selection.AnchorPoint.CreateEditPoint(); EditPoint endPoint = selection.AnchorPoint.CreateEditPoint(); startPoint.StartOfLine(); endPoint.EndOfLine(); // Denote insertion location EditPoint insertPoint = startPoint.CreateEditPoint(); // Get the line as a string string line = startPoint.GetText(endPoint); // Check if string is a function signature, if it is insert the header success = ValidateAndInsert(line, insertPoint); // If a function header wasn't inserted, check if the // function signature is spread across multiple lines if (!success && startOfFunction.Match(line).Success) { // Count all parentheses on the starting line int openingCount = line.Length - line.Replace("(", "").Length; int closingCount = line.Length - line.Replace(")", "").Length; int parenDiff = openingCount - closingCount; // Copy starting position string multiLine = line; // Move the active point to the anchor point selection.MoveToPoint(selection.ActivePoint); while (true) { // Move down the document concatenating the lines onto the starting line selection.LineDown(); startPoint = selection.AnchorPoint.CreateEditPoint(); endPoint = selection.AnchorPoint.CreateEditPoint(); startPoint.StartOfLine(); endPoint.EndOfLine(); string nextLine = startPoint.GetText(endPoint).Trim(); multiLine += nextLine; // Count all parentheses on this line, and add them to the diff openingCount = nextLine.Length - nextLine.Replace("(", "").Length; closingCount = nextLine.Length - nextLine.Replace(")", "").Length; parenDiff += openingCount - closingCount; // Exit if there are more closing parentheses than opening, or if there is a matching set // This will cause the while loop to exit if an opening parenthesis is not detected within // one line after the line we start on if (parenDiff <= 0) { break; } // Exit if we reached the end of the document if (endPoint.AtEndOfDocument) { break; } } // Check if string is a function signature, if it is insert the header success = ValidateAndInsert(multiLine, insertPoint); } // The selected line wasn't a function header, notify user in output if (!success) { // Get the debug output pane IVsOutputWindow outputWindow = Package.GetGlobalService(typeof(SVsOutputWindow)) as IVsOutputWindow; Guid paneGuid = VSConstants.GUID_OutWindowDebugPane; IVsOutputWindowPane pane; outputWindow.GetPane(ref paneGuid, out pane); if (pane is null) { return; } // Print the line that the was not a function signature, and then show the debug output pane.OutputString(String.Format("The following line is not a function signature:\n\t{0}\n", line)); pane.Activate(); } } }
/// <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"); } }
public static string GetText(this EditPoint startPoint, EditPoint endPoint) { Microsoft.VisualStudio.Shell.ThreadHelper.ThrowIfNotOnUIThread(); return(startPoint.GetText(endPoint)); }
public static CodeElement GetCodeElement(DTE dte, vsCMElement[] searchScopes) { if (dte.ActiveDocument == null) { return(null); } if (dte.ActiveDocument.ProjectItem == null) { return(null); } if (dte.ActiveDocument.ProjectItem.FileCodeModel == null) { return(null); } TextSelection selection = (TextSelection)dte.ActiveWindow.Selection; if (selection == null || selection.ActivePoint == null) { return(null); } EditPoint selPoint = selection.ActivePoint.CreateEditPoint(); CodeLanguage currentLang = CodeLanguage.CSharp; selPoint.StartOfLine(); while (true) { string BlockText = selPoint.GetText(selPoint.LineLength).Trim(); // *** Skip over any XML Doc comments and Attributes if (currentLang == CodeLanguage.CSharp && BlockText.StartsWith("/// ") || currentLang == CodeLanguage.CSharp && BlockText.StartsWith("[") || currentLang == CodeLanguage.VB && BlockText.StartsWith("''' ") || currentLang == CodeLanguage.VB && BlockText.StartsWith("<")) { selPoint.LineDown(1); selPoint.StartOfLine(); } else { break; } } // *** Make sure the cursor is placed inside of the definition always // *** Especially required for single line methods/fields/events etc. selPoint.EndOfLine(); selPoint.CharLeft(1); // Force into the text string xBlockText = selPoint.GetText(selPoint.LineLength).Trim(); // get the element under the cursor CodeElement element = null; FileCodeModel2 CodeModel = dte.ActiveDocument.ProjectItem.FileCodeModel as FileCodeModel2; // *** Supported scopes - set up here in the right parsing order // *** from lowest level to highest level // *** NOTE: Must be adjusted to match any CodeElements supported foreach (vsCMElement scope in searchScopes) { try { element = CodeModel.CodeElementFromPoint(selPoint, scope); if (element != null) { break; // if no exception - break } } catch {; } } if (element == null) { return(null); } return(element); }