protected override void Run() { CommandRange range = _selector(); ChangeRange(range); if (range != CommandRange.Empty) { // Move caret inside if it is on on opening character and block is empty if (range.Length == 0 && Editor.Caret.Offset < range.Start) { Editor.Caret.Offset++; } else { // if block still has two newlines inside, then drop inside block and indent int del1 = NewLine.GetDelimiterLength(Editor.Text[range.Start - 1], Editor.Text[range.Start]); if (del1 > 0) { int del2Start = range.Start - 1 + del1; int del2 = NewLine.GetDelimiterLength(Editor.Text[del2Start], Editor.Text[del2Start + 1]); if (del2 > 0) { IndentCaretInBlock(range.Start - 2); } } } } }
protected override void Run() { var range = _selector(); DeleteRange(range); if (range != CommandRange.Empty) { // Make sure there is no more than one newline left inside block int del1 = NewLine.GetDelimiterLength(Editor.Text[range.Start - 1], Editor.Text[range.Start]); if (del1 > 0) { int del2Start = range.Start - 1 + del1; int del2 = NewLine.GetDelimiterLength(Editor.Text[del2Start], Editor.Text[del2Start + 1]); if (del2 > 0) { Editor.SetSelection(del2Start, del2Start + del2); ClipboardActions.Cut(Editor); // put caret on closingChar int caret = Editor.Caret.Offset; while (Char.IsWhiteSpace(Editor.Text[caret])) { caret++; } Editor.Caret.Offset = caret; } } } }
static unsafe internal Delimiter NextDelimiter(string text, int offset) { fixed(char *start = text) { char *p = start + offset; char *endPtr = start + text.Length; while (p < endPtr) { char *nextp = p + 1; char nextChar = nextp < endPtr ? *nextp : '\0'; var nl = NewLine.GetDelimiterLength(*p, nextChar); if (nl > 0) { return(new Delimiter((int)(p - start), nl)); } p++; } return(Delimiter.Invalid); } }
private static unsafe TextLocation AdvanceLocation(TextLocation startLocation, string str) { int line = startLocation.Line; int col = startLocation.Column; fixed(char *start = str) { char *p = start; char *endPtr = start + str.Length; while (p < endPtr) { var nl = NewLine.GetDelimiterLength(*p, () => { char *nextp = p + 1; if (nextp < endPtr) { return(*nextp); } return('\0'); }); if (nl > 0) { line++; col = 1; if (nl == 2) { p++; } } else { col++; } p++; } } return(new TextLocation(line, col)); }
internal static string HomogenizeEol(string str) { var sb = new StringBuilder(); for (int i = 0; i < str.Length; i++) { var ch = str[i]; var possibleNewline = NewLine.GetDelimiterLength(ch, i + 1 < str.Length ? str[i + 1] : '\0'); if (possibleNewline > 0) { sb.AppendLine(); if (possibleNewline == 2) { i++; } } else { sb.Append(ch); } } return(sb.ToString()); }
/// <inheritdoc /> string ITextPasteHandler.FormatPlainText(int offset, string text, byte[] copyData) { if (copyData != null && copyData.Length == 1) { var strategy = TextPasteUtils.Strategies[(PasteStrategy)copyData[0]]; text = strategy.Decode(text); } engine.Update(offset); if (engine.IsInsideStringLiteral) { int idx = text.IndexOf('"'); if (idx > 0) { var o = offset; while (o < engine.Document.TextLength) { char ch = engine.Document.GetCharAt(o); engine.Push(ch); if (NewLine.IsNewLine(ch)) { break; } o++; if (!engine.IsInsideStringLiteral) { return(TextPasteUtils.StringLiteralStrategy.Encode(text)); } } return(TextPasteUtils.StringLiteralStrategy.Encode(text.Substring(0, idx)) + text.Substring(idx)); } return(TextPasteUtils.StringLiteralStrategy.Encode(text)); } else if (engine.IsInsideVerbatimString) { int idx = text.IndexOf('"'); if (idx > 0) { var o = offset; while (o < engine.Document.TextLength) { char ch = engine.Document.GetCharAt(o); engine.Push(ch); o++; if (!engine.IsInsideVerbatimString) { return(TextPasteUtils.VerbatimStringStrategy.Encode(text)); } } return(TextPasteUtils.VerbatimStringStrategy.Encode(text.Substring(0, idx)) + text.Substring(idx)); } return(TextPasteUtils.VerbatimStringStrategy.Encode(text)); } var line = engine.Document.GetLineByOffset(offset); var pasteAtLineStart = line.Offset == offset; var indentedText = new StringBuilder(); var curLine = new StringBuilder(); var clonedEngine = engine.Clone(); bool isNewLine = false, gotNewLine = false; for (int i = 0; i < text.Length; i++) { var ch = text[i]; if (clonedEngine.IsInsideVerbatimString || clonedEngine.IsInsideMultiLineComment) { clonedEngine.Push(ch); curLine.Append(ch); continue; } var delimiterLength = NewLine.GetDelimiterLength(ch, i + 1 < text.Length ? text[i + 1] : ' '); if (delimiterLength > 0) { isNewLine = true; if (gotNewLine || pasteAtLineStart) { if (curLine.Length > 0 || formattingOptions.EmptyLineFormatting == EmptyLineFormatting.Indent) { indentedText.Append(clonedEngine.ThisLineIndent); } } indentedText.Append(curLine); indentedText.Append(textEditorOptions.EolMarker); curLine.Length = 0; gotNewLine = true; i += delimiterLength - 1; // textEditorOptions.EolMarker[0] is the newLineChar used by the indentation engine. clonedEngine.Push(textEditorOptions.EolMarker[0]); } else { if (isNewLine) { if (ch == '\t' || ch == ' ') { clonedEngine.Push(ch); continue; } isNewLine = false; } curLine.Append(ch); clonedEngine.Push(ch); } if (clonedEngine.IsInsideVerbatimString || clonedEngine.IsInsideMultiLineComment && !(clonedEngine.LineBeganInsideVerbatimString || clonedEngine.LineBeganInsideMultiLineComment)) { if (gotNewLine) { if (curLine.Length > 0 || formattingOptions.EmptyLineFormatting == EmptyLineFormatting.Indent) { indentedText.Append(clonedEngine.ThisLineIndent); } } pasteAtLineStart = false; indentedText.Append(curLine); curLine.Length = 0; gotNewLine = false; continue; } } if (gotNewLine && (!pasteAtLineStart || curLine.Length > 0)) { indentedText.Append(clonedEngine.ThisLineIndent); } if (curLine.Length > 0) { indentedText.Append(curLine); } return(indentedText.ToString()); }
public void Push(char ch) { if (readPreprocessorExpression) { wordBuf.Append(ch); } if (inside.HasFlag(Inside.VerbatimString) && pc == '"' && ch != '"') { inside &= ~Inside.StringLiteral; } switch (ch) { case '#': if (IsLineStart) { inside = Inside.PreProcessor; } break; case '/': if (IsInStringOrChar || IsInPreProcessorComment) { break; } if (pc == '/') { if (inside.HasFlag(Inside.Comment)) { inside |= Inside.DocComment; } else { inside |= Inside.Comment; } } break; case '*': if (IsInStringOrChar || IsInComment || IsInPreProcessorComment) { break; } if (pc == '/') { inside |= Inside.MultiLineComment; } break; case ' ': currentIndent.Append(' '); break; case '\t': var nextTabStop = (col - 1 + textEditorOptions.IndentSize) / textEditorOptions.IndentSize; col = 1 + nextTabStop * textEditorOptions.IndentSize; currentIndent.Append('\t'); offset++; return; case '"': if (IsInComment || IsInPreProcessorComment) { break; } if (inside.HasFlag(Inside.StringLiteral)) { if (pc != '\\') { inside &= ~Inside.StringLiteral; } break; } if (pc == '@') { inside |= Inside.VerbatimString; } else { inside |= Inside.StringLiteral; } break; case '<': case '[': case '(': if (IsInComment || IsInStringOrChar || IsInPreProcessorComment) { break; } parenStack.Push(new TextLocation(line, col)); popNextParenBlock = true; indent.Push(IndentType.Block); break; case '>': case ']': case ')': if (IsInComment || IsInStringOrChar || IsInPreProcessorComment) { break; } if (popNextParenBlock && parenStack.Count > 0) { parenStack.Pop(); } if (indent.Count > 0) { indent.Pop(); } indent.ExtraSpaces = 0; break; case ',': if (IsInComment || IsInStringOrChar || IsInPreProcessorComment) { break; } if (parenStack.Count > 0 && parenStack.Peek().Line == line) { if (indent.Count > 0) { indent.Pop(); } popNextParenBlock = false; indent.ExtraSpaces = parenStack.Peek().Column - 1 - thisLineindent.CurIndent; } break; case '{': if (IsInComment || IsInStringOrChar || IsInPreProcessorComment) { break; } currentBody = nextBody; if (indent.Count > 0 && indent.Peek() == IndentType.Continuation) { indent.Pop(); } addContinuation = false; AddIndentation(currentBody); break; case '}': if (IsInComment || IsInStringOrChar || IsInPreProcessorComment) { break; } if (indentDelta.CurIndent > 0) { indentDelta.Pop(); if (indentDelta.Count > 0 && indentDelta.Peek() == IndentType.Continuation) { indentDelta.Pop(); } } else { if (thisLineindent.Count > 0) { thisLineindent.Pop(); } if (indent.Count > 0) { indent.Pop(); } } break; case ';': if (IsInComment || IsInStringOrChar || IsInPreProcessorComment) { break; } if (indent.Count > 0 && indent.Peek() == IndentType.Continuation) { indent.Pop(); } break; case '\'': if (IsInComment || inside.HasFlag(Inside.StringLiteral) || IsInPreProcessorComment) { break; } if (inside.HasFlag(Inside.CharLiteral)) { if (pc != '\\') { inside &= ~Inside.CharLiteral; } } else { inside &= Inside.CharLiteral; } break; default: var nl = NewLine.GetDelimiterLength(ch, pc); if (nl == 2) { break; } if (nl == 1) { if (readPreprocessorExpression) { if (!eval(wordBuf.ToString())) { inside |= Inside.PreProcessorComment; } } inside &= ~(Inside.Comment | Inside.String | Inside.CharLiteral | Inside.PreProcessor); CheckKeyword(wordBuf.ToString()); wordBuf.Length = 0; indent.Push(indentDelta); indentDelta = new Indent(textEditorOptions); if (addContinuation) { indent.Push(IndentType.Continuation); } thisLineindent = indent.Clone(); addContinuation = false; IsLineStart = true; readPreprocessorExpression = false; col = 1; line++; currentIndent.Length = 0; } break; } if (!IsInComment && !IsInStringOrChar && !readPreprocessorExpression) { if ((wordBuf.Length == 0 ? char.IsLetter(ch) : char.IsLetterOrDigit(ch)) || ch == '_') { wordBuf.Append(ch); } else { if (inside.HasFlag(Inside.PreProcessor)) { if (wordBuf.ToString() == "endif") { inside &= ~Inside.PreProcessorComment; } else if (wordBuf.ToString() == "if") { readPreprocessorExpression = true; } else if (wordBuf.ToString() == "elif") { inside &= ~Inside.PreProcessorComment; readPreprocessorExpression = true; } } else { CheckKeyword(wordBuf.ToString()); } wordBuf.Length = 0; } } if (addContinuation) { indent.Push(IndentType.Continuation); addContinuation = false; } IsLineStart &= ch == ' ' || ch == '\t' || NewLine.IsNewLine(ch); pc = ch; if (!NewLine.IsNewLine(ch)) { col++; } offset++; }
/// <inheritdoc /> string ITextPasteHandler.FormatPlainText(SourceText sourceText, int offset, string text, byte [] copyData) { if (copyData != null && copyData.Length == 1) { var strategy = TextPasteUtils.Strategies [(PasteStrategy)copyData [0]]; text = strategy.Decode(text); } engine.Update(sourceText, offset); if (engine.IsInsideStringLiteral) { int idx = text.IndexOf('"'); if (idx > 0) { var o = offset; while (o < sourceText.Length) { char ch = sourceText [o]; engine.Push(ch); if (NewLine.IsNewLine(ch)) { break; } o++; if (!engine.IsInsideStringLiteral) { return(TextPasteUtils.StringLiteralStrategy.Encode(text)); } } return(TextPasteUtils.StringLiteralStrategy.Encode(text.Substring(0, idx)) + text.Substring(idx)); } return(TextPasteUtils.StringLiteralStrategy.Encode(text)); } else if (engine.IsInsideVerbatimString) { int idx = text.IndexOf('"'); if (idx > 0) { var o = offset; while (o < sourceText.Length) { char ch = sourceText [o]; engine.Push(ch); o++; if (!engine.IsInsideVerbatimString) { return(TextPasteUtils.VerbatimStringStrategy.Encode(text)); } } return(TextPasteUtils.VerbatimStringStrategy.Encode(text.Substring(0, idx)) + text.Substring(idx)); } return(TextPasteUtils.VerbatimStringStrategy.Encode(text)); } // on the fly formatting is done in post formatting, if turned off just correct indenting. if (!InUnitTestMode && DefaultSourceEditorOptions.Instance.OnTheFlyFormatting) { return(text); } var line = sourceText.Lines.GetLineFromPosition(offset); var pasteAtLineStart = line.Start == offset; var indentedText = StringBuilderCache.Allocate(); var curLine = StringBuilderCache.Allocate(); var clonedEngine = engine.Clone(); bool isNewLine = false, gotNewLine = false; for (int i = 0; i < text.Length; i++) { var ch = text [i]; if (clonedEngine.IsInsideVerbatimString || clonedEngine.IsInsideMultiLineComment || clonedEngine.IsInsidePreprocessorComment) { clonedEngine.Push(ch); curLine.Append(ch); continue; } var delimiterLength = NewLine.GetDelimiterLength(ch, i + 1 < text.Length ? text [i + 1] : ' '); if (delimiterLength > 0) { isNewLine = true; if (gotNewLine || pasteAtLineStart) { if (curLine.Length > 0 /*|| formattingOptions.EmptyLineFormatting == EmptyLineFormatting.Indent*/) { indentedText.Append(clonedEngine.ThisLineIndent); } } indentedText.Append(curLine); var newLine = options.GetOption(FormattingOptions.NewLine, LanguageNames.CSharp); indentedText.Append(newLine); curLine.Length = 0; gotNewLine = true; i += delimiterLength - 1; // textEditorOptions.EolMarker[0] is the newLineChar used by the indentation engine. clonedEngine.Push(newLine [0]); } else { if (isNewLine) { if (ch == '\t' || ch == ' ') { clonedEngine.Push(ch); continue; } isNewLine = false; } curLine.Append(ch); clonedEngine.Push(ch); } if (clonedEngine.IsInsideVerbatimString || clonedEngine.IsInsideMultiLineComment && !(clonedEngine.LineBeganInsideVerbatimString || clonedEngine.LineBeganInsideMultiLineComment)) { if (gotNewLine) { if (curLine.Length > 0 /*|| formattingOptions.EmptyLineFormatting == EmptyLineFormatting.Indent*/) { indentedText.Append(clonedEngine.ThisLineIndent); } } pasteAtLineStart = false; indentedText.Append(curLine); curLine.Length = 0; gotNewLine = false; continue; } } if (gotNewLine && (!pasteAtLineStart || curLine.Length > 0)) { indentedText.Append(clonedEngine.ThisLineIndent); } if (curLine.Length > 0) { indentedText.Append(curLine); } StringBuilderCache.Free(curLine); return(StringBuilderCache.ReturnAndFree(indentedText)); }