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);
                        }
                    }
                }
            }
        }
Exemple #2
0
        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;
                    }
                }
            }
        }
Exemple #3
0
        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());
        }
Exemple #6
0
        /// <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++;
        }
Exemple #8
0
        /// <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));
        }