/// <summary> /// Indents the switch body by the same indent the whole snippet has and adds one TAB. /// </summary> string GetBodyIndent(IDocument document, int offset) { int lineStart = document.GetLineForOffset(offset).Offset; string indent = DocumentUtilitites.GetWhitespaceAfter(document, lineStart); return(indent); }
void EditorKeyPress(object sender, KeyEventArgs e) { if (e.Key == Key.Tab || e.Key == Key.Enter || e.Key == Key.Return) { using (editor.Document.OpenUndoGroup()) { // is there a better way to calculate the optimal insertion point? DomRegion region = resolveResult.CallingMember.BodyRegion; editor.Caret.Line = region.EndLine; editor.Caret.Column = region.EndColumn; editor.Document.Insert(editor.Caret.Offset, this.newHandlerCode); editor.Language.FormattingStrategy.IndentLines(editor, region.EndLine, editor.Caret.Line); IDocumentLine line = editor.Document.GetLine(editor.Caret.Line - 1); int indentationLength = DocumentUtilitites.GetWhitespaceAfter(editor.Document, line.Offset).Length; editor.Select(line.Offset + indentationLength, line.Length - indentationLength); } e.Handled = true; } // detatch our keydown filter to return to the normal processing state RemoveEventHandlers(); }
static void ApplyToRange(ITextEditor editor, Stack <string> indentation, List <int> eols, int blockStart, int blockEnd, int selectionStart, int selectionEnd) { LoggingService.InfoFormatted("indenting line {0} to {1} with {2}", blockStart, blockEnd, (indentation.PeekOrDefault() ?? "").Length); int nextEol = -1; bool wasMultiLine = false; for (int i = blockStart; i <= blockEnd; i++) { IDocumentLine curLine = editor.Document.GetLine(i); string lineText = curLine.Text.TrimStart(); string noComments = lineText.TrimComments().TrimEnd(); // adjust indentation if the current line is not selected // lines between the selection will be aligned to the selected level if (i < selectionStart || i > selectionEnd) { indentation.PopOrDefault(); indentation.Push(DocumentUtilitites.GetWhitespaceAfter(editor.Document, curLine.Offset)); } // look for next eol if line is not empty // (the lexer does not produce eols for empty lines) if (!string.IsNullOrEmpty(noComments) && i >= nextEol) { int search = eols.BinarySearch(i); if (search < 0) { search = ~search; } nextEol = search < eols.Count ? eols[search] : i; } // remove indentation in last line of multiline array(, collection, object) initializers if (i == nextEol && wasMultiLine && noComments == "}") { wasMultiLine = false; Unindent(indentation); } // apply the indentation editor.Document.SmartReplaceLine(curLine, (indentation.PeekOrDefault() ?? "") + lineText); // indent line if it is ended by (implicit) line continuation if (i < nextEol && !wasMultiLine) { wasMultiLine = true; Indent(editor, indentation); } // unindent if this is the last line of a multiline statement if (i == nextEol && wasMultiLine) { wasMultiLine = false; Unindent(indentation); } } }
void DoInsertionOnLine(string terminator, IDocumentLine currentLine, IDocumentLine lineAbove, string textToReplace, ITextEditor editor, int lineNr) { string curLineText = currentLine.Text; if (Regex.IsMatch(textToReplace.Trim(), "^If .*[^_]$", RegexOptions.IgnoreCase)) { if (!Regex.IsMatch(textToReplace, "\\bthen\\b", RegexOptions.IgnoreCase)) { string specialThen = "Then"; // do special check in cases like If t = True' comment if (editor.Document.GetCharAt(lineAbove.Offset + textToReplace.Length) == '\'') { specialThen += " "; } if (editor.Document.GetCharAt(lineAbove.Offset + textToReplace.Length - 1) != ' ') { specialThen = " " + specialThen; } editor.Document.Insert(lineAbove.Offset + textToReplace.Length, specialThen); textToReplace += specialThen; } } // check #Region statements if (Regex.IsMatch(textToReplace.Trim(), "^#Region", RegexOptions.IgnoreCase) && LookForEndRegion(editor)) { string indentation = DocumentUtilitites.GetWhitespaceAfter(editor.Document, lineAbove.Offset); textToReplace += indentation + "\r\n" + indentation + "#End Region"; editor.Document.Replace(currentLine.Offset, currentLine.Length, textToReplace); } foreach (VBStatement statement_ in statements) { VBStatement statement = statement_; // allow passing statement byref if (Regex.IsMatch(textToReplace.Trim(), statement.StartRegex, RegexOptions.IgnoreCase)) { string indentation = DocumentUtilitites.GetWhitespaceAfter(editor.Document, lineAbove.Offset); if (IsEndStatementNeeded(editor, ref statement, lineNr)) { editor.Document.Replace(currentLine.Offset, currentLine.Length, terminator + indentation + statement.EndStatement); } if (!IsInsideInterface(editor, lineNr) || statement == interfaceStatement) { for (int i = 0; i < statement.IndentPlus; i++) { indentation += editor.Options.IndentationString; } } editor.Document.Replace(currentLine.Offset, currentLine.Length, indentation + curLineText.Trim()); editor.Caret.Line = currentLine.LineNumber; editor.Caret.Column = indentation.Length; return; } } }
static void InsertDocumentationComments(ITextEditor editor, int lineNr, int cursorOffset) { string terminator = DocumentUtilitites.GetLineTerminator(editor.Document, lineNr); IDocumentLine currentLine = editor.Document.GetLine(lineNr); IDocumentLine previousLine = (lineNr > 1) ? editor.Document.GetLine(lineNr - 1) : null; string curLineText = currentLine.Text; string lineAboveText = previousLine == null ? null : previousLine.Text; if (curLineText != null && curLineText.EndsWith("'''", StringComparison.OrdinalIgnoreCase) && (lineAboveText == null || !lineAboveText.Trim().StartsWith("'''", StringComparison.OrdinalIgnoreCase))) { string indentation = DocumentUtilitites.GetWhitespaceAfter(editor.Document, currentLine.Offset); object member = GetMemberAfter(editor, lineNr); if (member != null) { StringBuilder sb = new StringBuilder(); sb.Append(" <summary>"); sb.Append(terminator); sb.Append(indentation); sb.Append("''' "); sb.Append(terminator); sb.Append(indentation); sb.Append("''' </summary>"); if (member is IMethod) { IMethod method = (IMethod)member; if (method.Parameters != null && method.Parameters.Count > 0) { for (int i = 0; i < method.Parameters.Count; ++i) { sb.Append(terminator); sb.Append(indentation); sb.Append("''' <param name=\""); sb.Append(method.Parameters[i].Name); sb.Append("\"></param>"); } } if (method.ReturnType != null && !method.IsConstructor && method.ReturnType.FullyQualifiedName != "System.Void") { sb.Append(terminator); sb.Append(indentation); sb.Append("''' <returns></returns>"); } } editor.Document.Insert(cursorOffset, sb.ToString()); editor.Caret.Position = editor.Document.OffsetToPosition(cursorOffset + indentation.Length + "/// ".Length + " <summary>".Length + terminator.Length); } } }
public virtual void IndentLine(ITextEditor editor, IDocumentLine line) { IDocument document = editor.Document; int lineNumber = line.LineNumber; if (lineNumber > 1) { IDocumentLine previousLine = document.GetLine(lineNumber - 1); string indentation = DocumentUtilitites.GetWhitespaceAfter(document, previousLine.Offset); // copy indentation to line string newIndentation = DocumentUtilitites.GetWhitespaceAfter(document, line.Offset); document.Replace(line.Offset, newIndentation.Length, indentation); } }
public override void IndentLine(ITextEditor editor, IDocumentLine line) { if (line.LineNumber > 1) { IDocumentLine above = editor.Document.GetLine(line.LineNumber - 1); string up = above.Text.Trim(); if (up.StartsWith("--") == false) { // above line is an indent statement if (up.EndsWith("do") || up.EndsWith("then") || (up.StartsWith("function") && up.EndsWith(")")) || (up.Contains("function") && up.EndsWith(")"))) // e.g. aTable.x = function([...]) { string indentation = DocumentUtilitites.GetWhitespaceAfter(editor.Document, above.Offset); string newLine = line.Text.TrimStart(); newLine = indentation + editor.Options.IndentationString + newLine; editor.Document.SmartReplaceLine(line, newLine); } else // above line is not an indent statement { string indentation = DocumentUtilitites.GetWhitespaceAfter(editor.Document, above.Offset); string newLine = line.Text.TrimStart(); newLine = indentation + newLine; editor.Document.SmartReplaceLine(line, newLine); } } if (line.Text.StartsWith("end")) { string indentation = DocumentUtilitites.GetWhitespaceAfter(editor.Document, above.Offset); string newLine = line.Text.TrimStart(); string newIndent = ""; if (indentation.Length >= editor.Options.IndentationSize) { newIndent = indentation.Substring(0, indentation.Length - editor.Options.IndentationSize); } newLine = newIndent + newLine; editor.Document.SmartReplaceLine(line, newLine); } } else { } //base.IndentLine(editor, line); }
public static void ToggleBookmark(ITextEditor editor, int line, Predicate <SDBookmark> canToggle, Func <Location, SDBookmark> bookmarkFactory) { foreach (SDBookmark bookmark in GetBookmarks(new FileName(editor.FileName))) { if (canToggle(bookmark) && bookmark.LineNumber == line) { BookmarkManager.RemoveMark(bookmark); return; } } // no bookmark at that line: create a new bookmark int lineStartOffset = editor.Document.GetLine(line).Offset; int column = 1 + DocumentUtilitites.GetWhitespaceAfter(editor.Document, lineStartOffset).Length; BookmarkManager.AddMark(bookmarkFactory(new Location(column, line))); }
public override void IndentLine(ITextEditor editor, IDocumentLine line) { IDocument document = editor.Document; int lineNumber = line.LineNumber; if (lineNumber > 1) { IDocumentLine previousLine = document.GetLine(line.LineNumber - 1); if (previousLine.Text.EndsWith(":", StringComparison.Ordinal)) { string indentation = DocumentUtilitites.GetWhitespaceAfter(document, previousLine.Offset); indentation += editor.Options.IndentationString; string newIndentation = DocumentUtilitites.GetWhitespaceAfter(document, line.Offset); document.Replace(line.Offset, newIndentation.Length, indentation); return; } } base.IndentLine(editor, line); }
public static void InsertCode(this ITextEditor editor, AbstractNode target, AbstractNode insert, int insertOffset, bool updateCaretPos) { if (insertOffset < 0) { return; } var regionCorrectVisitor = new SetRegionInclusionVisitor(); insert.AcceptVisitor(regionCorrectVisitor, null); var doc = editor.Document; var codeGen = editor.Language.Properties.CodeGenerator; string indent = DocumentUtilitites.GetWhitespaceAfter(doc, doc.GetLineStartOffset(target.StartLocation)); string code = codeGen.GenerateCode(insert, indent); doc.Insert(insertOffset, code); if (updateCaretPos) { editor.Caret.Offset = insertOffset + code.Length - 1; } }
void FormatLineInternal(ITextEditor textArea, int lineNr, int cursorOffset, char ch) { IDocumentLine curLine = textArea.Document.GetLine(lineNr); IDocumentLine lineAbove = lineNr > 1 ? textArea.Document.GetLine(lineNr - 1) : null; string terminator = DocumentUtilitites.GetLineTerminator(textArea.Document, lineNr); string curLineText; //// local string for curLine segment if (ch == '/') { curLineText = curLine.Text; string lineAboveText = lineAbove == null ? "" : lineAbove.Text; if (curLineText != null && curLineText.EndsWith("///") && (lineAboveText == null || !lineAboveText.Trim().StartsWith("///"))) { string indentation = DocumentUtilitites.GetWhitespaceAfter(textArea.Document, curLine.Offset); object member = GetMemberAfter(textArea, lineNr); if (member != null) { StringBuilder sb = new StringBuilder(); sb.Append(" <summary>"); sb.Append(terminator); sb.Append(indentation); sb.Append("/// "); sb.Append(terminator); sb.Append(indentation); sb.Append("/// </summary>"); if (member is IMethod) { IMethod method = (IMethod)member; if (method.Parameters != null && method.Parameters.Count > 0) { for (int i = 0; i < method.Parameters.Count; ++i) { sb.Append(terminator); sb.Append(indentation); sb.Append("/// <param name=\""); sb.Append(method.Parameters[i].Name); sb.Append("\"></param>"); } } if (method.ReturnType != null && !method.IsConstructor && method.ReturnType.FullyQualifiedName != "System.Void") { sb.Append(terminator); sb.Append(indentation); sb.Append("/// <returns></returns>"); } } textArea.Document.Insert(cursorOffset, sb.ToString()); textArea.Caret.Offset = cursorOffset + indentation.Length + "/// ".Length + " <summary>".Length + terminator.Length; } } return; } if (ch != '\n' && ch != '>') { if (IsInsideStringOrComment(textArea, curLine, cursorOffset)) { return; } } switch (ch) { case '>': if (IsInsideDocumentationComment(textArea, curLine, cursorOffset)) { curLineText = curLine.Text; int column = cursorOffset - curLine.Offset; int index = Math.Min(column - 1, curLineText.Length - 1); while (index >= 0 && curLineText[index] != '<') { --index; if (curLineText[index] == '/') { return; // the tag was an end tag or already } } if (index > 0) { StringBuilder commentBuilder = new StringBuilder(""); for (int i = index; i < curLineText.Length && i < column && !Char.IsWhiteSpace(curLineText[i]); ++i) { commentBuilder.Append(curLineText[i]); } string tag = commentBuilder.ToString().Trim(); if (!tag.EndsWith(">")) { tag += ">"; } if (!tag.StartsWith("/")) { textArea.Document.Insert(cursorOffset, "</" + tag.Substring(1), AnchorMovementType.BeforeInsertion); } } } break; case ':': case ')': case ']': case '}': case '{': //if (textArea.Document.TextEditorProperties.IndentStyle == IndentStyle.Smart) { IndentLine(textArea, curLine); //} break; case '\n': string lineAboveText = lineAbove == null ? "" : lineAbove.Text; //// curLine might have some text which should be added to indentation curLineText = curLine.Text; if (lineAbove != null && lineAbove.Text.Trim().StartsWith("#region") && NeedEndregion(textArea.Document)) { textArea.Document.Insert(cursorOffset, "#endregion"); return; } ISyntaxHighlighter highlighter = textArea.GetService(typeof(ISyntaxHighlighter)) as ISyntaxHighlighter; bool isInMultilineComment = false; bool isInMultilineString = false; if (highlighter != null && lineAbove != null) { var spanStack = highlighter.GetSpanColorNamesFromLineStart(lineNr); isInMultilineComment = spanStack.Contains(SyntaxHighligherKnownSpanNames.Comment); isInMultilineString = spanStack.Contains(SyntaxHighligherKnownSpanNames.String); } bool isInNormalCode = !(isInMultilineComment || isInMultilineString); if (lineAbove != null && isInMultilineComment) { string lineAboveTextTrimmed = lineAboveText.TrimStart(); if (lineAboveTextTrimmed.StartsWith("/*", StringComparison.Ordinal)) { textArea.Document.Insert(cursorOffset, " * "); return; } if (lineAboveTextTrimmed.StartsWith("*", StringComparison.Ordinal)) { textArea.Document.Insert(cursorOffset, "* "); return; } } if (lineAbove != null && isInNormalCode) { IDocumentLine nextLine = lineNr + 1 <= textArea.Document.TotalNumberOfLines ? textArea.Document.GetLine(lineNr + 1) : null; string nextLineText = (nextLine != null) ? nextLine.Text : ""; int indexAbove = lineAboveText.IndexOf("///"); int indexNext = nextLineText.IndexOf("///"); if (indexAbove > 0 && (indexNext != -1 || indexAbove + 4 < lineAbove.Length)) { textArea.Document.Insert(cursorOffset, "/// "); return; } if (IsInNonVerbatimString(lineAboveText, curLineText)) { textArea.Document.Insert(cursorOffset, "\""); textArea.Document.Insert(lineAbove.Offset + lineAbove.Length, "\" +"); } } if (textArea.Options.AutoInsertBlockEnd && lineAbove != null && isInNormalCode) { string oldLineText = lineAbove.Text; if (oldLineText.EndsWith("{")) { if (NeedCurlyBracket(textArea.Document.Text)) { int insertionPoint = curLine.Offset + curLine.Length; textArea.Document.Insert(insertionPoint, terminator + "}"); IndentLine(textArea, textArea.Document.GetLine(lineNr + 1)); textArea.Caret.Offset = insertionPoint; } } } return; } }
void FormatLineInternal(ITextEditor textArea, int lineNr, int cursorOffset, char ch) { IDocumentLine curLine = textArea.Document.GetLine(lineNr); IDocumentLine lineAbove = lineNr > 1 ? textArea.Document.GetLine(lineNr - 1) : null; string terminator = DocumentUtilitites.GetLineTerminator(textArea.Document, lineNr); string curLineText; //// local string for curLine segment if (ch == '-') { curLineText = curLine.Text; string lineAboveText = lineAbove == null ? "" : lineAbove.Text; if (curLineText != null && curLineText.EndsWith("---") && (lineAboveText == null || !lineAboveText.Trim().StartsWith("---"))) { string indentation = DocumentUtilitites.GetWhitespaceAfter(textArea.Document, curLine.Offset); StringBuilder sb = new StringBuilder(); sb.Append(" <summary>"); sb.Append(terminator); sb.Append(indentation); sb.Append("--- "); sb.Append(terminator); sb.Append(indentation); sb.Append("--- </summary>"); //sb.Append(terminator); //sb.Append(indentation); //sb.Append("--- <returns></returns>"); textArea.Document.Insert(cursorOffset, sb.ToString()); textArea.Caret.Offset = cursorOffset + indentation.Length + "--- ".Length + " <summary>".Length + terminator.Length; } else if (curLineText != null && curLineText.Trim() == "-" && (lineAboveText != null && lineAboveText.Trim().StartsWith("---"))) { StringBuilder sb = new StringBuilder(); sb.Append("-- "); //sb.Append(terminator); //sb.Append(indentation); //sb.Append("--- <returns></returns>"); textArea.Document.Insert(cursorOffset, sb.ToString()); textArea.Caret.Offset = cursorOffset + "-- ".Length; } return; } if (ch != '\n' && ch != '>') { if (IsInsideStringOrComment(textArea, curLine, cursorOffset)) { return; } } if (IsInsideStringOrComment(textArea, curLine, cursorOffset) == false && textArea.Caret.Offset == curLine.EndOffset && // end of line, not editing something inside the line (curLine.Text.TrimEnd().EndsWith("then") || curLine.Text.TrimEnd().EndsWith("do"))) { string indentation = DocumentUtilitites.GetWhitespaceAfter(textArea.Document, curLine.Offset); StringBuilder sb = new StringBuilder(); sb.Append(terminator); sb.Append(indentation + textArea.Options.IndentationString); sb.Append(terminator); sb.Append(indentation); sb.Append("end"); textArea.Document.Insert(cursorOffset, sb.ToString()); textArea.Caret.Offset = cursorOffset + terminator.Length // end of line + indentation.Length // indentation + textArea.Options.IndentationString.Length ; } if (IsInsideStringOrComment(textArea, curLine, cursorOffset) == false && textArea.Caret.Offset == curLine.EndOffset && // end of line, not editing something inside the line curLine.Text.TrimStart().StartsWith("repeat")) { string indentation = DocumentUtilitites.GetWhitespaceAfter(textArea.Document, curLine.Offset); StringBuilder sb = new StringBuilder(); sb.Append(terminator); sb.Append(indentation + textArea.Options.IndentationString); sb.Append(terminator); sb.Append(indentation); sb.Append("until "); textArea.Document.Insert(cursorOffset, sb.ToString()); textArea.Caret.Offset = cursorOffset + indentation.Length + terminator.Length // line 1 + indentation.Length + textArea.Options.IndentationString.Length + terminator.Length // line 2 + "until ".Length ; } switch (ch) { case '>': if (IsInsideDocumentationComment(textArea, curLine, cursorOffset)) { curLineText = curLine.Text; int column = cursorOffset - curLine.Offset; int index = Math.Min(column - 1, curLineText.Length - 1); while (index >= 0 && curLineText[index] != '<') { --index; if (curLineText[index] == '/') { return; // the tag was an end tag or already } } if (index > 0) { StringBuilder commentBuilder = new StringBuilder(""); for (int i = index; i < curLineText.Length && i < column && !Char.IsWhiteSpace(curLineText[i]); ++i) { commentBuilder.Append(curLineText[i]); } string tag = commentBuilder.ToString().Trim(); if (!tag.EndsWith(">")) { tag += ">"; } if (!tag.StartsWith("/")) { textArea.Document.Insert(cursorOffset, "</" + tag.Substring(1), AnchorMovementType.BeforeInsertion); } } } break; case ')': if (curLine.Text.TrimStart().StartsWith("function")) { string indentation = DocumentUtilitites.GetWhitespaceAfter(textArea.Document, curLine.Offset); StringBuilder sb = new StringBuilder(); sb.Append(terminator); sb.Append(indentation + textArea.Options.IndentationString); sb.Append(terminator); sb.Append(indentation); sb.Append("end"); textArea.Document.Insert(cursorOffset, sb.ToString()); textArea.Caret.Offset = cursorOffset + terminator.Length // end of line + indentation.Length // indentation + textArea.Options.IndentationString.Length ; } else { IndentLine(textArea, curLine); } break; case ':': case ']': case '}': case '{': IndentLine(textArea, curLine); break; case '\n': string lineAboveText = lineAbove == null ? "" : lineAbove.Text; //// curLine might have some text which should be added to indentation curLineText = curLine.Text; ISyntaxHighlighter highlighter = textArea.GetService(typeof(ISyntaxHighlighter)) as ISyntaxHighlighter; bool isInMultilineComment = false; bool isInMultilineString = false; if (highlighter != null && lineAbove != null) { var spanStack = highlighter.GetSpanColorNamesFromLineStart(lineNr); isInMultilineComment = spanStack.Contains(SyntaxHighligherKnownSpanNames.Comment); isInMultilineString = spanStack.Contains(SyntaxHighligherKnownSpanNames.String); } bool isInNormalCode = !(isInMultilineComment || isInMultilineString); if (lineAbove != null && isInMultilineComment) { string lineAboveTextTrimmed = lineAboveText.TrimStart(); if (lineAboveTextTrimmed.StartsWith("--[[", StringComparison.Ordinal)) { textArea.Document.Insert(cursorOffset, " - "); return; } if (lineAboveTextTrimmed.StartsWith("-", StringComparison.Ordinal)) { textArea.Document.Insert(cursorOffset, "- "); return; } } if (lineAbove != null && isInNormalCode) { IDocumentLine nextLine = lineNr + 1 <= textArea.Document.TotalNumberOfLines ? textArea.Document.GetLine(lineNr + 1) : null; string nextLineText = (nextLine != null) ? nextLine.Text : ""; int indexAbove = lineAboveText.IndexOf("---"); int indexNext = nextLineText.IndexOf("---"); if (indexAbove > 0 && (indexNext != -1 || indexAbove + 4 < lineAbove.Length)) { textArea.Document.Insert(cursorOffset, "--- "); return; } if (IsInNonVerbatimString(lineAboveText, curLineText)) { textArea.Document.Insert(cursorOffset, "\""); textArea.Document.Insert(lineAbove.Offset + lineAbove.Length, "\" +"); } } return; } }
static int SmartIndentInternal(ITextEditor editor, int begin, int end) { ILexer lexer = ParserFactory.CreateLexer(SupportedLanguage.VBNet, new StringReader(editor.Document.Text)); Stack <string> indentation = new Stack <string>(); indentation.Push(string.Empty); List <int> eols = new List <int>(); bool inInterface = false; bool isMustOverride = false; bool isDeclare = false; bool isDelegate = false; Token currentToken = null; Token prevToken = null; int blockStart = 1; int lambdaNesting = 0; while ((currentToken = lexer.NextToken()).Kind != Tokens.EOF) { if (prevToken == null) { prevToken = currentToken; } if (currentToken.Kind == Tokens.MustOverride) { isMustOverride = true; } if (currentToken.Kind == Tokens.Delegate) { isDelegate = true; } if (currentToken.Kind == Tokens.Declare) { isDeclare = true; } if (currentToken.Kind == Tokens.EOL) { isDelegate = isDeclare = isMustOverride = false; eols.Add(currentToken.Location.Line); } if (IsBlockEnd(currentToken, prevToken)) { // indent the lines inside the block // this is an End-statement // hence we indent from blockStart to the previous line int blockEnd = currentToken.Location.Line - 1; // if this is a lambda end include End-Statement in block // if (lambdaNesting > 0 && (currentToken.Kind == Tokens.Function || currentToken.Kind == Tokens.Sub)) { // blockEnd++; // } ApplyToRange(editor, indentation, eols, blockStart, blockEnd, begin, end); if (lambdaNesting > 0 && (currentToken.Kind == Tokens.Function || currentToken.Kind == Tokens.Sub)) { Unindent(indentation); ApplyToRange(editor, indentation, eols, currentToken.Location.Line, currentToken.Location.Line, begin, end); } if (currentToken.Kind == Tokens.Interface) { inInterface = false; } if (!inInterface && !isMustOverride && !isDeclare && !isDelegate) { Unindent(indentation); if (currentToken.Kind == Tokens.Select) { Unindent(indentation); } } // block start is this line (for the lines between two blocks) blockStart = currentToken.Location.Line; if (lambdaNesting > 0 && (currentToken.Kind == Tokens.Function || currentToken.Kind == Tokens.Sub)) { blockStart++; lambdaNesting--; } } bool isMultiLineLambda; if (IsBlockStart(lexer, currentToken, prevToken, out isMultiLineLambda)) { // indent the lines between the last and this block // this is a Begin-statement // hence we indent from blockStart to the this line int lastVisualLine = FindNextEol(lexer); eols.Add(lastVisualLine); ApplyToRange(editor, indentation, eols, blockStart, lastVisualLine, begin, end); if (isMultiLineLambda && (currentToken.Kind == Tokens.Function || currentToken.Kind == Tokens.Sub)) { lambdaNesting++; int endColumn = currentToken.Location.Column; int startColumn = DocumentUtilitites.GetWhitespaceAfter(editor.Document, editor.Document.GetLine(lastVisualLine).Offset).Length; if (startColumn < endColumn) { Indent(editor, indentation, new string(' ', endColumn - startColumn - 1)); } } if (!inInterface && !isMustOverride && !isDeclare && !isDelegate) { Indent(editor, indentation); if (currentToken.Kind == Tokens.Select) { Indent(editor, indentation); } } if (currentToken.Kind == Tokens.Interface) { inInterface = true; } // block start is the following line (for the lines inside a block) blockStart = lastVisualLine + 1; } prevToken = currentToken; } ApplyToRange(editor, indentation, eols, blockStart, editor.Document.TotalNumberOfLines, begin, end); return((indentation.PeekOrDefault() ?? string.Empty).Length); }
void FormatLineInternal(ITextEditor editor, int lineNr, int cursorOffset, char ch) { string terminator = DocumentUtilitites.GetLineTerminator(editor.Document, lineNr); doCasing = PropertyService.Get("VBBinding.TextEditor.EnableCasing", true); doInsertion = PropertyService.Get("VBBinding.TextEditor.EnableEndConstructs", true); IDocumentLine currentLine = editor.Document.GetLine(lineNr); IDocumentLine lineAbove = lineNr > 1 ? editor.Document.GetLine(lineNr - 1) : null; string curLineText = currentLine == null ? "" : currentLine.Text; string lineAboveText = lineAbove == null ? "" : lineAbove.Text; if (ch == '\'') { InsertDocumentationComments(editor, lineNr, cursorOffset); } if (ch == '\n' && lineAboveText != null) { if (LanguageUtils.IsInsideDocumentationComment(editor, lineAbove, lineAbove.EndOffset)) { editor.Document.Insert(cursorOffset, "''' "); return; } string textToReplace = lineAboveText.TrimLine(); if (doCasing) { DoCasingOnLine(lineAbove, textToReplace, editor); } if (doInsertion) { DoInsertionOnLine(terminator, currentLine, lineAbove, textToReplace, editor, lineNr); } if (IsInString(lineAboveText)) { if (IsFinishedString(curLineText)) { editor.Document.Insert(lineAbove.EndOffset, "\" & _"); editor.Document.Insert(currentLine.Offset, "\""); } else { editor.Document.Insert(lineAbove.EndOffset, "\""); } } else { string indent = DocumentUtilitites.GetWhitespaceAfter(editor.Document, lineAbove.Offset); if (indent.Length > 0) { string newLineText = indent + currentLine.Text.Trim(); editor.Document.Replace(currentLine.Offset, currentLine.Length, newLineText); } editor.Caret.Column = indent.Length + 1; } IndentLines(editor, lineNr - 1, lineNr); } else if (ch == '>') { if (LanguageUtils.IsInsideDocumentationComment(editor, currentLine, cursorOffset)) { int column = editor.Caret.Offset - currentLine.Offset; int index = Math.Min(column - 1, curLineText.Length - 1); while (index > 0 && curLineText[index] != '<') { --index; if (curLineText[index] == '/') { return; // the tag was an end tag or already } } if (index > 0) { StringBuilder commentBuilder = new StringBuilder(""); for (int i = index; i < curLineText.Length && i < column && !Char.IsWhiteSpace(curLineText[i]); ++i) { commentBuilder.Append(curLineText[i]); } string tag = commentBuilder.ToString().Trim(); if (!tag.EndsWith(">", StringComparison.OrdinalIgnoreCase)) { tag += ">"; } if (!tag.StartsWith("/", StringComparison.OrdinalIgnoreCase)) { string endTag = "</" + tag.Substring(1); editor.Document.Insert(editor.Caret.Offset, endTag); editor.Caret.Offset -= endTag.Length; } } } } }
internal void ExecuteIntroduceMethod(UnknownMethodResolveResult rr, Ast.Expression invocationExpr, ITextEditor editor, bool isNew, object result) { IClass targetClass = IsEqualClass(rr.CallingClass, rr.Target.GetUnderlyingClass()) ? rr.CallingClass : rr.Target.GetUnderlyingClass(); CodeGenerator gen = targetClass.ProjectContent.Language.CodeGenerator; IAmbience ambience = targetClass.ProjectContent.Language.GetAmbience(); ClassFinder finder = new ClassFinder(rr.CallingMember); ModifierEnum modifiers = ModifierEnum.None; bool isExtension = !targetClass.IsUserCode(); if (IsEqualClass(rr.CallingClass, targetClass)) { if (rr.CallingMember != null) { modifiers |= (rr.CallingMember.Modifiers & ModifierEnum.Static); } } else { if (isExtension) { if (isNew) { targetClass = rr.CallingClass; } else { targetClass = result as IClass; } } // exclude in Unit Test mode if (WorkbenchSingleton.Workbench != null) { editor = (FileService.OpenFile(targetClass.CompilationUnit.FileName) as ITextEditorProvider).TextEditor; } if (targetClass.ClassType != ClassType.Interface) { modifiers |= ModifierEnum.Public; } if (rr.IsStaticContext) { modifiers |= ModifierEnum.Static; } } NRefactoryResolver resolver = Extensions.CreateResolverForContext(targetClass.ProjectContent.Language, editor); IReturnType type = resolver.GetExpectedTypeFromContext(invocationExpr); Ast.TypeReference typeRef = CodeGenerator.ConvertType(type, finder); if (typeRef.IsNull) { if (invocationExpr.Parent is Ast.ExpressionStatement) { typeRef = new Ast.TypeReference("void", true); } else { typeRef = new Ast.TypeReference("object", true); } } Ast.MethodDeclaration method = new Ast.MethodDeclaration { Name = rr.CallName, Modifier = CodeGenerator.ConvertModifier(modifiers, finder), TypeReference = typeRef, Parameters = CreateParameters(rr, finder, invocationExpr as Ast.InvocationExpression).ToList(), }; if (targetClass.ClassType != ClassType.Interface) { method.Body = CodeGenerator.CreateNotImplementedBlock(); } RefactoringDocumentAdapter documentWrapper = new RefactoringDocumentAdapter(editor.Document); if (isExtension) { method.Parameters.Insert(0, new Ast.ParameterDeclarationExpression(CodeGenerator.ConvertType(rr.Target, finder), "thisInstance")); method.IsExtensionMethod = true; method.Modifier |= Ast.Modifiers.Static; } if (isNew) { Ast.TypeDeclaration newType = new Ast.TypeDeclaration(isExtension ? Ast.Modifiers.Static : Ast.Modifiers.None, null); newType.Name = result as string; newType.AddChild(method); gen.InsertCodeAfter(targetClass, documentWrapper, newType); } else { if (IsEqualClass(rr.CallingClass, targetClass)) { gen.InsertCodeAfter(rr.CallingMember, documentWrapper, method); } else { gen.InsertCodeAtEnd(targetClass.BodyRegion, documentWrapper, method); } } if (targetClass.ClassType == ClassType.Interface) { return; } ParseInformation info = ParserService.ParseFile(targetClass.CompilationUnit.FileName); if (info != null) { IMember newMember; if (isNew) { targetClass = info.CompilationUnit.Classes.FirstOrDefault(c => c.DotNetName == c.Namespace + "." + (result as string)); } else { targetClass = info.CompilationUnit.Classes.Flatten(c => c.InnerClasses).FirstOrDefault(c => c.DotNetName == targetClass.DotNetName); } if (targetClass == null) { return; } if (IsEqualClass(rr.CallingClass, targetClass)) { newMember = targetClass.GetInnermostMember(editor.Caret.Line, editor.Caret.Column); newMember = targetClass.AllMembers .OrderBy(m => m.BodyRegion.BeginLine) .ThenBy(m2 => m2.BodyRegion.BeginColumn) .First(m3 => m3.BodyRegion.BeginLine > newMember.BodyRegion.BeginLine); } else { newMember = targetClass.Methods.Last(); } IDocumentLine line = editor.Document.GetLine(newMember.BodyRegion.BeginLine + 2); int indentLength = DocumentUtilitites.GetWhitespaceAfter(editor.Document, line.Offset).Length; editor.Select(line.Offset + indentLength, "throw new NotImplementedException();".Length); } }
protected string GetIndentation(IDocument document, int line) { return(DocumentUtilitites.GetWhitespaceAfter(document, document.GetLine(line).Offset)); }
protected override string GenerateCode(LanguageProperties language, IClass currentClass) { IDocumentLine line = editor.Document.GetLineForOffset(anchor.Offset); string indent = DocumentUtilitites.GetWhitespaceAfter(editor.Document, line.Offset); List <PropertyOrFieldWrapper> filtered = this.varList.SelectedItems.OfType <PropertyOrFieldWrapper>() .OrderBy(p => p.Index) .ToList(); BlockStatement block = new BlockStatement(); foreach (PropertyOrFieldWrapper w in filtered) { if (w.AddCheckForNull) { // true = reference, null = generic or unknown if (w.Type.IsReferenceType != false) { block.AddChild( new IfElseStatement( new BinaryOperatorExpression(new IdentifierExpression(w.ParameterName), BinaryOperatorType.Equality, new PrimitiveExpression(null)), new ThrowStatement(new ObjectCreateExpression(new TypeReference("ArgumentNullException"), new List <Expression>() { new PrimitiveExpression(w.ParameterName, '"' + w.ParameterName + '"') })) ) ); } else { block.AddChild( new IfElseStatement( new UnaryOperatorExpression(new MemberReferenceExpression(new IdentifierExpression(w.MemberName), "HasValue"), UnaryOperatorType.Not), new ThrowStatement(new ObjectCreateExpression(new TypeReference("ArgumentNullException"), new List <Expression>() { new PrimitiveExpression(w.ParameterName, '"' + w.ParameterName + '"') })) ) ); } } if (w.AddRangeCheck) { block.AddChild( new IfElseStatement( new BinaryOperatorExpression( new BinaryOperatorExpression(new IdentifierExpression(w.ParameterName), BinaryOperatorType.LessThan, new IdentifierExpression("lower")), BinaryOperatorType.LogicalOr, new BinaryOperatorExpression(new IdentifierExpression(w.ParameterName), BinaryOperatorType.GreaterThan, new IdentifierExpression("upper")) ), new ThrowStatement( new ObjectCreateExpression( new TypeReference("ArgumentOutOfRangeException"), new List <Expression>() { new PrimitiveExpression(w.ParameterName, '"' + w.ParameterName + '"'), new IdentifierExpression(w.ParameterName), new BinaryOperatorExpression(new PrimitiveExpression("Value must be between "), BinaryOperatorType.Concat, new BinaryOperatorExpression(new IdentifierExpression("lower"), BinaryOperatorType.Concat, new BinaryOperatorExpression(new PrimitiveExpression(" and "), BinaryOperatorType.Concat, new IdentifierExpression("upper")))) } ) ) ) ); } } foreach (PropertyOrFieldWrapper w in filtered) { block.AddChild(new ExpressionStatement(new AssignmentExpression(new MemberReferenceExpression(new ThisReferenceExpression(), w.MemberName), AssignmentOperatorType.Assign, new IdentifierExpression(w.ParameterName)))); } AnchorElement parameterListElement = context.ActiveElements .OfType <AnchorElement>() .FirstOrDefault(item => item.Name.Equals("parameterList", StringComparison.OrdinalIgnoreCase)); if (parameterListElement != null) { StringBuilder pList = new StringBuilder(); var parameters = filtered .Select(p => new ParameterDeclarationExpression(ConvertType(p.Type), p.ParameterName)) .ToList(); for (int i = 0; i < parameters.Count; i++) { if (i > 0) { pList.Append(", "); } pList.Append(language.CodeGenerator.GenerateCode(parameters[i], "")); } parameterListElement.Text = pList.ToString(); } StringBuilder builder = new StringBuilder(); foreach (var element in block.Children.OfType <AbstractNode>()) { builder.Append(language.CodeGenerator.GenerateCode(element, indent)); } return(builder.ToString().Trim()); }
protected override string GenerateCode(LanguageProperties language, IClass currentClass) { StringBuilder builder = new StringBuilder(); IDocumentLine line = editor.Document.GetLineForOffset(anchor.Offset); string indent = DocumentUtilitites.GetWhitespaceAfter(editor.Document, line.Offset); bool implementInterface = this.implementInterface.IsChecked == true; bool hasOnPropertyChanged = HasOnPropertyChanged(currentClass); bool useEventArgs = false; if (implementInterface && !currentClass.IsStatic) { if (!hasOnPropertyChanged) { var nodes = new List <AbstractNode>(); var rt = new GetClassReturnType(currentClass.ProjectContent, "System.ComponentModel.INotifyPropertyChanged", 0); if (!currentClass.ClassInheritanceTree.Any(bt => bt.FullyQualifiedName == "System.ComponentModel.INotifyPropertyChanged")) { int insertion = editor.Document.PositionToOffset(currentClass.BodyRegion.BeginLine, currentClass.BodyRegion.BeginColumn); if (currentClass.BaseTypes.Count > 0) { editor.Document.Insert(insertion, ", INotifyPropertyChanged"); } else { editor.Document.Insert(insertion, " : INotifyPropertyChanged"); } } language.CodeGenerator.ImplementInterface(nodes, rt, false, currentClass); var ev = rt.GetEvents().First(e => e.Name == "PropertyChanged"); MethodDeclaration onEvent = language.CodeGenerator.CreateOnEventMethod(new DefaultEvent(ev.Name, ev.ReturnType, ev.Modifiers, ev.Region, ev.BodyRegion, currentClass)); nodes.Add(onEvent); onEvent.Parameters[0].TypeReference = new TypeReference("string", true); onEvent.Parameters[0].ParameterName = "propertyName"; ((RaiseEventStatement)onEvent.Body.Children[0]).Arguments[1] = new ObjectCreateExpression(new TypeReference("PropertyChangedEventArgs"), new List <Expression> { new IdentifierExpression("propertyName") }); foreach (var node in nodes) { builder.AppendLine(language.CodeGenerator.GenerateCode(node, indent)); } useEventArgs = false; } else { useEventArgs = currentClass.DefaultReturnType.GetMethods().First(m => m.Name == "OnPropertyChanged").Parameters[0].ReturnType.FullyQualifiedName != "System.String"; } } foreach (FieldWrapper field in listBox.SelectedItems) { var prop = language.CodeGenerator.CreateProperty(field.Field, true, field.AddSetter); if (!field.Field.IsStatic && !currentClass.IsStatic && field.AddSetter && implementInterface) { var invocation = new ExpressionStatement(CreateInvocation(field.PropertyName, useEventArgs)); var assignment = prop.SetRegion.Block.Children[0]; prop.SetRegion.Block.Children.Clear(); prop.SetRegion.Block.AddChild( new IfElseStatement( new BinaryOperatorExpression(new IdentifierExpression(field.MemberName), BinaryOperatorType.InEquality, new IdentifierExpression("value")), new BlockStatement { Children = { assignment, invocation } } ) ); } builder.AppendLine(language.CodeGenerator.GenerateCode(prop, indent)); } return(builder.ToString().Trim()); }
protected override string GenerateCode(LanguageProperties language, IClass currentClass) { StringBuilder code = new StringBuilder(); var line = editor.Document.GetLineForOffset(startAnchor.Offset); string indent = DocumentUtilitites.GetWhitespaceAfter(editor.Document, line.Offset); CodeGenerator generator = language.CodeGenerator; if (Options.AddIEquatableInterface) { // TODO : add IEquatable<T> to class // IAmbience ambience = currentClass.CompilationUnit.Language.GetAmbience(); // // IReturnType baseRType = currentClass.CompilationUnit.ProjectContent.GetClass("System.IEquatable", 1).DefaultReturnType; // // IClass newClass = new DefaultClass(currentClass.CompilationUnit, currentClass.FullyQualifiedName, currentClass.Modifiers, currentClass.Region, null); // // foreach (IReturnType type in currentClass.BaseTypes) { // newClass.BaseTypes.Add(type); // } // // // newClass.BaseTypes.Add(new ConstructedReturnType(baseRType, new List<IReturnType>() { currentClass.DefaultReturnType })); // // ambience.ConversionFlags = ConversionFlags.IncludeBody; // // string a = ambience.Convert(currentClass); // // int startOffset = editor.Document.PositionToOffset(currentClass.Region.BeginLine, currentClass.Region.BeginColumn); // int endOffset = editor.Document.PositionToOffset(currentClass.BodyRegion.EndLine, currentClass.BodyRegion.EndColumn); // // editor.Document.Replace(startOffset, endOffset - startOffset, a); } if (Options.SurroundWithRegion) { editor.Document.InsertNormalized(startAnchor.Offset, "#region Equals and GetHashCode implementation\n" + indent); } string codeForMethodBody; if ("Equals".Equals(selectedMethod.Name, StringComparison.Ordinal)) { IList <MethodDeclaration> equalsOverrides = CreateEqualsOverrides(currentClass); MethodDeclaration defaultOverride = equalsOverrides.First(); equalsOverrides = equalsOverrides.Skip(1).ToList(); StringBuilder builder = new StringBuilder(); foreach (AbstractNode element in defaultOverride.Body.Children.OfType <AbstractNode>()) { builder.Append(language.CodeGenerator.GenerateCode(element, indent + "\t")); } codeForMethodBody = builder.ToString().Trim(); if (addOtherMethod.IsChecked == true) { if (equalsOverrides.Any()) { code.Append(indent + "\n" + string.Join("\n", equalsOverrides.Select(item => generator.GenerateCode(item, indent)))); } code.Append(indent + "\n" + generator.GenerateCode(CreateGetHashCodeOverride(currentClass), indent)); } } else { StringBuilder builder = new StringBuilder(); foreach (AbstractNode element in CreateGetHashCodeOverride(currentClass).Body.Children.OfType <AbstractNode>()) { builder.Append(language.CodeGenerator.GenerateCode(element, indent + "\t")); } codeForMethodBody = builder.ToString().Trim(); if (addOtherMethod.IsChecked == true) { code.Append(indent + "\n" + string.Join("\n", CreateEqualsOverrides(currentClass).Select(item => generator.GenerateCode(item, indent)))); } } if (Options.AddOperatorOverloads) { var checkStatements = new[] { new IfElseStatement( new InvocationExpression( new IdentifierExpression("ReferenceEquals"), new List <Expression>() { new IdentifierExpression("lhs"), new IdentifierExpression("rhs") } ), new ReturnStatement(new PrimitiveExpression(true)) ), new IfElseStatement( new BinaryOperatorExpression( new InvocationExpression( new IdentifierExpression("ReferenceEquals"), new List <Expression>() { new IdentifierExpression("lhs"), new PrimitiveExpression(null) } ), BinaryOperatorType.LogicalOr, new InvocationExpression( new IdentifierExpression("ReferenceEquals"), new List <Expression>() { new IdentifierExpression("rhs"), new PrimitiveExpression(null) } ) ), new ReturnStatement(new PrimitiveExpression(false)) ) }; BlockStatement equalsOpBody = new BlockStatement() { Children = { new ReturnStatement( new InvocationExpression( new MemberReferenceExpression(new IdentifierExpression("lhs"), "Equals"), new List <Expression>() { new IdentifierExpression("rhs") } ) ) } }; if (currentClass.ClassType == Dom.ClassType.Class) { equalsOpBody.Children.InsertRange(0, checkStatements); } BlockStatement notEqualsOpBody = new BlockStatement() { Children = { new ReturnStatement( new UnaryOperatorExpression( new ParenthesizedExpression( new BinaryOperatorExpression( new IdentifierExpression("lhs"), BinaryOperatorType.Equality, new IdentifierExpression("rhs") ) ), UnaryOperatorType.Not ) ) } }; code.Append(indent + "\n" + generator.GenerateCode(CreateOperatorOverload(OverloadableOperatorType.Equality, currentClass, equalsOpBody), indent)); code.Append(indent + "\n" + generator.GenerateCode(CreateOperatorOverload(OverloadableOperatorType.InEquality, currentClass, notEqualsOpBody), indent)); } if (Options.SurroundWithRegion) { code.AppendLine(indent + "#endregion"); } editor.Document.InsertNormalized(insertionEndAnchor.Offset, code.ToString()); return(codeForMethodBody); }
static void TryIndent(ITextEditor editor, int begin, int end) { string currentIndentation = ""; Stack <string> tagStack = new Stack <string>(); IDocument document = editor.Document; string tab = editor.Options.IndentationString; int nextLine = begin; // in #dev coordinates bool wasEmptyElement = false; XmlNodeType lastType = XmlNodeType.XmlDeclaration; using (StringReader stringReader = new StringReader(document.Text)) { XmlTextReader r = new XmlTextReader(stringReader); r.XmlResolver = null; // prevent XmlTextReader from loading external DTDs while (r.Read()) { if (wasEmptyElement) { wasEmptyElement = false; if (tagStack.Count == 0) { currentIndentation = ""; } else { currentIndentation = tagStack.Pop(); } } if (r.NodeType == XmlNodeType.EndElement) { if (tagStack.Count == 0) { currentIndentation = ""; } else { currentIndentation = tagStack.Pop(); } } while (r.LineNumber >= nextLine) { if (nextLine > end) { break; } if (lastType == XmlNodeType.CDATA || lastType == XmlNodeType.Comment) { nextLine++; continue; } // set indentation of 'nextLine' IDocumentLine line = document.GetLine(nextLine); string lineText = line.Text; string newText; // special case: opening tag has closing bracket on extra line: remove one indentation level if (lineText.Trim() == ">") { newText = tagStack.Peek() + lineText.Trim(); } else { newText = currentIndentation + lineText.Trim(); } if (newText != lineText) { int extraCharsToBeAddedAtStartedOfLine = newText.Length - lineText.Length; document.Replace(line.Offset, line.Length, newText); Location caretPosition = document.OffsetToPosition(line.Offset + extraCharsToBeAddedAtStartedOfLine); editor.Caret.Position = caretPosition; } nextLine++; } if (r.LineNumber > end) { break; } wasEmptyElement = r.NodeType == XmlNodeType.Element && r.IsEmptyElement; string attribIndent = null; if (r.NodeType == XmlNodeType.Element) { tagStack.Push(currentIndentation); if (r.LineNumber < begin) { currentIndentation = DocumentUtilitites.GetWhitespaceAfter(editor.Document, editor.Document.PositionToOffset(r.LineNumber, 1)); } if (r.Name.Length < 16) { attribIndent = currentIndentation + new string(' ', 2 + r.Name.Length); } else { attribIndent = currentIndentation + tab; } currentIndentation += tab; } lastType = r.NodeType; if (r.NodeType == XmlNodeType.Element && r.HasAttributes) { int startLine = r.LineNumber; r.MoveToAttribute(0); // move to first attribute if (r.LineNumber != startLine) { attribIndent = currentIndentation; // change to tab-indentation } r.MoveToAttribute(r.AttributeCount - 1); while (r.LineNumber >= nextLine) { if (nextLine > end) { break; } // set indentation of 'nextLine' IDocumentLine line = document.GetLine(nextLine); string newText = attribIndent + line.Text.Trim(); document.SmartReplaceLine(line, newText); nextLine++; } } } r.Close(); } }