protected override Action <ITextControl> ExecutePsiTransaction(ISolution solution, IProgressIndicator progress) { IDocCommentNode docCommentNode = _selectedDocCommentNode; ReFlowCommentNode(solution, progress, docCommentNode); return(null); }
public void Start() { _myCurrentNode = null; _myCurrentCommentNode = null; // Our technique for inserting the comment requires extra space at the start so we only chop off the actual /// // Work out the base indent for the comment // Regex re = new Regex(@"^\s*///\s*"); /* * int minLength = -1; * foreach (IDocCommentNode node in _myDocCommentBlock.Children<IDocCommentNode>()) * { * string text = node.GetText(); * Match m = re.Match(text); * if (!m.Success) continue; * * int len = m.Groups[0].Value.Length; * if (len == text.Length) continue; // Ignore short empty lines. * * if (minLength < 0 || len < minLength) minLength = len; * } * _commentStartLength = minLength; */ _commentStartLength = 3; restartLexer(_myDocCommentBlock.FirstChild, 0); }
public IDocCommentNode ReplaceBy(IDocCommentNode docCommentNode) { using (WriteLockCookie.Create(this.IsPhysical())) { return(ModificationUtil.ReplaceChild(this, docCommentNode)); } }
public IDocCommentNode ReplaceBy(IDocCommentNode docCommentNode) { using (WriteLockCookie.Create(this.IsPhysical())) { return ModificationUtil.ReplaceChild(this, docCommentNode); } }
public override bool IsAvailable(IUserDataHolder cache) { using (ReadLockCookie.Create()) { this._selectedDocCommentNode = GetSelectedExpression <IDocCommentNode>(); return(this._selectedDocCommentNode != null); } }
private static bool ShallEscape(IDocCommentNode node, int offset) { IDocCommentBlockNode docBlock = node.GetContainingNode <IDocCommentBlockNode>(true); if (docBlock == null) { return(false); } XmlDocLexer lexer = new XmlDocLexer(docBlock); lexer.Start(); bool inCData = false; bool insideTag = false; while (lexer.TokenType != null) { if (lexer.TokenType == lexer.XmlTokenType.TAG_START) { insideTag = true; } else if (lexer.TokenType == lexer.XmlTokenType.TAG_END) { insideTag = false; } else if (lexer.TokenType == lexer.XmlTokenType.TAG_START1) { insideTag = true; } else if (lexer.TokenType == lexer.XmlTokenType.TAG_END1) { insideTag = false; } else if (lexer.TokenType == lexer.XmlTokenType.CDATA_START) { inCData = true; } else if (lexer.TokenType == lexer.XmlTokenType.CDATA_END) { inCData = false; } else if (offset >= lexer.TokenLocalRange.StartOffset && offset <= lexer.TokenLocalRange.EndOffset) { return(!inCData && !insideTag); } else if (offset < lexer.TokenLocalRange.StartOffset) { return(false); } lexer.Advance(); } return(false); }
/// <summary> /// The execute transaction inner. /// </summary> /// <param name="solution"> /// The solution. /// </param> /// <param name="textControl"> /// The text control. /// </param> public override void ExecuteTransactionInner(ISolution solution, ITextControl textControl) { ITreeNode element = Utils.GetElementAtCaret(solution, textControl); ITreeNode currentNode = element; IDocCommentNode docCommentNode = currentNode as IDocCommentNode; IDocCommentBlockNode containingElement = docCommentNode.GetContainingNode <IDocCommentBlockNode>(true); ITreeNode rightNode = containingElement.FindFormattingRangeToRight(); Utils.RemoveNewLineBefore(rightNode); }
/// <summary> /// Returns the xml for the given declaration or null. /// </summary> /// <param name="declaration"> /// The declaration to get the docs for. /// </param> /// <returns> /// An XmlNode of the docs. /// </returns> private static XmlNode GetXmlNodeForDeclaration(IDeclaration declaration) { IDeclaration declarationTreeNode = declaration; ITreeNode treeNode = declarationTreeNode is IMultipleDeclarationMember ? declarationTreeNode.Parent.FirstChild : declarationTreeNode.FirstChild; XmlNode node; StringBuilder text = new StringBuilder(); text.AppendLine("<member>"); for (ITreeNode child = treeNode.FirstChild; child != null; child = child.NextSibling) { if (child.IsNewLine()) { text.AppendLine(string.Empty); continue; } IDocCommentNode docCommentNode = child as IDocCommentNode; if (docCommentNode != null) { text.Append(docCommentNode.CommentText); } } text.AppendLine("</member>"); try { XmlDocument xmlDoc = new XmlDocument { PreserveWhitespace = true }; xmlDoc.LoadXml(text.ToString()); node = xmlDoc.SelectSingleNode("member"); } catch (XmlException) { return(null); } return(node); }
private void restartLexer(ITreeNode child, uint state) { _myCurrentNode = null; _myCurrentCommentNode = null; while (child != null) { _myCurrentNode = child; _myCurrentCommentNode = child as IDocCommentNode; if (_myCurrentCommentNode != null) { //LeafElementBase leaf = (LeafElementBase)_myCurrentCommentNode; _myLexer = new XmlLexerGenerated(_myCurrentCommentNode.GetTextAsBuffer(), XmlTokenType); //_myLexer.Start(leaf.GetTreeStartOffset().Offset + 3, leaf.GetTreeStartOffset().Offset + leaf.GetTextLength(), state); _myLexer.Start(_commentStartLength, _myCurrentCommentNode.GetTextLength(), state); if (_myLexer.TokenType == null) { restartLexer(_myCurrentCommentNode.NextSibling, state); } return; } IWhitespaceNode whitespaceNode = child as IWhitespaceNode; if (whitespaceNode != null && whitespaceNode.IsNewLine) { _myLexer = new XmlLexerGenerated(new StringBuffer("\n"), XmlTokenType); //_myLexer.Start(leaf.GetTreeStartOffset().Offset + 3, leaf.GetTreeStartOffset().Offset + leaf.GetTextLength(), state); _myLexer.Start(0, 1, state); return; } child = child.NextSibling; } _myLexer = null; }
private static void HandleElement(ITextControl editor, ITreeNode element, int offset) { string stringToInsert = Clipboard.GetText(); if (string.IsNullOrEmpty(stringToInsert)) { return; } IDocCommentNode docCommentNode = element as IDocCommentNode; if (docCommentNode != null) { JetBrains.Util.dataStructures.TypedIntrinsics.Int32 <DocLine> currentLineNumber = editor.Document.GetCoordsByOffset(editor.Caret.Offset()).Line; string currentLine = editor.Document.GetLineText(currentLineNumber); int index = currentLine.IndexOf("///", StringComparison.Ordinal); if (index < 0) { return; } string prefix = currentLine.Substring(0, index); if (ShallEscape(docCommentNode, editor.Caret.Offset()) && JetBrains.UI.RichText.RichTextBlockToHtml.HtmlEncode(stringToInsert) != stringToInsert && MessageBox.ShowYesNo("Do you want the text to be escaped?")) { stringToInsert = JetBrains.UI.RichText.RichTextBlockToHtml.HtmlEncode(stringToInsert); } stringToInsert = stringToInsert.Replace("\n", "\n" + prefix + "///"); } ITokenNode token = element as ITokenNode; if (token != null) { if (token.GetTokenType() == CSharpTokenType.STRING_LITERAL && offset < token.GetTreeTextRange().EndOffset.Offset) { string text = token.GetText(); if (text.StartsWith("@") && offset > token.GetTreeTextRange().StartOffset.Offset + 1) { stringToInsert = stringToInsert.Replace("\"", "\"\""); } else if (!text.StartsWith("@")) { stringToInsert = stringToInsert. Replace("\\", "\\\\"). Replace("\a", "\\a"). Replace("\b", "\\b"). Replace("\f", "\\f"). Replace("\n", "\\n"). Replace("\r", "\\r"). Replace("\t", "\\t"). Replace("\v", "\\v"). Replace("\'", "\\'"). Replace("\"", "\\\""); } } } editor.Document.InsertText(editor.Caret.Offset(), stringToInsert); }
/// <summary> /// Check if this action is available at the constructed context. /// </summary> /// <param name="cache">Cache data to share between actions.</param> public override bool IsAvailable(IUserDataHolder cache) { _commentNode = _provider.GetSelectedElement<IDocCommentNode>(true, false); return _commentNode != null; }
public static void ReFlowCommentNode(ISolution solution, IProgressIndicator progress, [NotNull] IDocCommentNode docCommentNode) { // Get the comment block owner (ie the part of the declaration which will own the comment). IDocCommentBlockNode blockNode = docCommentNode.GetContainingNode <IDocCommentBlockNode>(); if (blockNode == null) { return; } ReFlowCommentBlockNode(solution, progress, blockNode); }
public static void ReflowAndRetagCommentNode(ISolution solution, IProgressIndicator progress, IDocCommentNode docCommentNode) { if (docCommentNode == null) { return; } IDocCommentBlockNode blockNode = docCommentNode.GetContainingNode <IDocCommentBlockNode>(); if (blockNode == null) { return; } ReflowAndRetagCommentBlockNode(solution, progress, blockNode); }
/// <summary> /// Replaces the returns tag text. /// </summary> /// <param name="returns"> /// The returns node <paramref name="text"/>. /// </param> /// <param name="text"> /// The text to replace with. /// </param> private void ReplaceReturnsTagText(IDocCommentNode returns, string text) { using (CommandCookie.Create(string.Format("Context Action {0}", this.GetText()))) { using (var cookie = this.TextControl.Document.EnsureWritable()) { if (cookie.EnsureWritableResult != EnsureWritableResult.SUCCESS) { return; } this.Provider.Document.ReplaceText(returns.GetDocumentRange().TextRange, text); } } }
/// <summary> /// Gets the summary text. /// </summary> /// <param name="summary"> /// The summary. /// </param> /// <returns> /// Returns the string. /// </returns> private static string GetSummaryText(IDocCommentNode summary) { var result = string.Empty; while (summary != null) { var text = summary.CommentText; var line = string.Empty; var start = text.IndexOf("<summary>"); if (start >= 0) { line = text.Substring(start + 9).Trim(); } var end = text.IndexOf("</summary>"); if (end >= 0) { line = text.Substring(0, end).Trim(); } if (start < 0 && end < 0) { line = text; } if (!string.IsNullOrEmpty(line)) { if (!string.IsNullOrEmpty(result)) { result += " "; } result += line; } if (end >= 0) { break; } summary = summary.FindNextNode(node => node is IDocCommentNode ? TreeNodeActionType.ACCEPT : TreeNodeActionType.CONTINUE) as IDocCommentNode; } return result; }
/// <summary> /// Gets the summary and returns. /// </summary> /// <param name="element"> /// The element. /// </param> /// <param name="summary"> /// The summary. /// </param> /// <param name="returns"> /// The returns. /// </param> private static void GetSummaryAndReturns([NotNull] IElement element, out IDocCommentNode summary, out IDocCommentNode returns) { summary = null; returns = null; var docCommentBlockNode = GetDocCommentBlock(element); if (docCommentBlockNode == null) { return; } if (!docCommentBlockNode.Contains(element)) { return; } for (var child = docCommentBlockNode.FirstChild; child != null; child = child.NextSibling) { var docCommentNode = child as IDocCommentNode; if (docCommentNode == null) { continue; } var text = docCommentNode.CommentText; if (text.IndexOf("<summary>") >= 0) { summary = docCommentNode; } if (text.IndexOf("<returns>") >= 0) { returns = docCommentNode; } } }