string GetIndentationString(int offset, DocumentLocation loc)
        {
            stateTracker.Update(Math.Min(data.Length, offset));
            DocumentLine line = data.Document.GetLine(loc.Line);

            if (line == null)
            {
                return("");
            }
            // Get context to the end of the line w/o changing the main engine's state
            var ctx = stateTracker.Clone();

            ctx.Update(line.Offset + line.Length);

//			int pos = line.Offset;
            string curIndent = line.GetIndentation(data.Document);
            int    nlwsp     = curIndent.Length;

//			int o = offset > pos + nlwsp ? offset - (pos + nlwsp) : 0;
            if (!stateTracker.LineBeganInsideMultiLineComment || (nlwsp < line.LengthIncludingDelimiter && data.Document.GetCharAt(line.Offset + nlwsp) == '*'))
            {
                return(ctx.ThisLineIndent);
            }
            return(curIndent);
        }
Esempio n. 2
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());
        }
Esempio n. 3
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));
        }
        void HandleTextPaste(int insertionOffset, string text, int insertedChars)
        {
            if (document.Editor.Options.IndentStyle == IndentStyle.None ||
                document.Editor.Options.IndentStyle == IndentStyle.Auto)
            {
                return;
            }

            // Just correct the start line of the paste operation - the text is already indented.
            var curLine       = Editor.GetLineByOffset(insertionOffset);
            var curLineOffset = curLine.Offset;

            stateTracker.Update(curLineOffset);
            if (!stateTracker.IsInsideOrdinaryCommentOrString)
            {
                // The Indent engine doesn't really handle pre processor directives very well.
                if (IsPreprocessorDirective(curLine))
                {
                    Editor.Replace(curLineOffset, curLine.Length, stateTracker.NextLineIndent + Editor.GetTextAt(curLine).TrimStart());
                }
                else
                {
                    int    pos       = curLineOffset;
                    string curIndent = curLine.GetIndentation(textEditorData.Document);
                    int    nlwsp     = curIndent.Length;

                    if (!stateTracker.LineBeganInsideMultiLineComment || (nlwsp < curLine.LengthIncludingDelimiter && textEditorData.Document.GetCharAt(curLineOffset + nlwsp) == '*'))
                    {
                        // Possibly replace the indent
                        stateTracker.Update(curLineOffset + curLine.Length);
                        string newIndent = stateTracker.ThisLineIndent;
                        if (newIndent != curIndent)
                        {
                            if (CompletionWindowManager.IsVisible)
                            {
                                if (pos < CompletionWindowManager.CodeCompletionContext.TriggerOffset)
                                {
                                    CompletionWindowManager.CodeCompletionContext.TriggerOffset -= nlwsp;
                                }
                            }
                            textEditorData.Replace(pos, nlwsp, newIndent);
                            textEditorData.Document.CommitLineUpdate(textEditorData.Caret.Line);
                        }
                    }
                }
            }
            textEditorData.FixVirtualIndentation();
        }