Ejemplo n.º 1
0
        /// <inheritdoc />
        /// <remarks>
        ///     If the <paramref name="position"/> is negative, the engine will
        ///     update to: document.TextLength + (offset % document.TextLength+1)
        ///     Otherwise it will update to: offset % document.TextLength+1
        /// </remarks>
        public void Update(int position)
        {
            const int BUFFER_SIZE = 2000;

            if (currentEngine.Offset == position)
            {
                //positions match, nothing to be done
                return;
            }
            else if (currentEngine.Offset > position)
            {
                //moving backwards, so reset from previous saved location
                ResetEngineToPosition(position);
            }

            // get the engine caught up
            int nextSave = (cachedEngines.Count == 0) ? BUFFER_SIZE : cachedEngines.Peek().Offset + BUFFER_SIZE;

            if (currentEngine.Offset + 1 == position)
            {
                char ch = currentEngine.Document.GetCharAt(currentEngine.Offset);
                currentEngine.Push(ch);
                if (currentEngine.Offset == nextSave)
                {
                    cachedEngines.Push(currentEngine.Clone());
                }
            }
            else
            {
                //bulk copy characters in case buffer is unmanaged
                //(faster if we reduce managed/unmanaged transitions)
                while (currentEngine.Offset < position)
                {
                    int endCut = currentEngine.Offset + BUFFER_SIZE;
                    if (endCut > position)
                    {
                        endCut = position;
                    }
                    string buffer = currentEngine.Document.GetText(currentEngine.Offset, endCut - currentEngine.Offset);
                    foreach (char ch in buffer)
                    {
                        currentEngine.Push(ch);
                        //ConsoleWrite ("pushing character '{0}'", ch);
                        if (currentEngine.Offset == nextSave)
                        {
                            cachedEngines.Push(currentEngine.Clone());
                            nextSave += BUFFER_SIZE;
                        }
                    }
                }
            }
        }
        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);
        }
        void DoReSmartIndent(int cursor)
        {
            if (stateTracker.LineBeganInsideVerbatimString || stateTracker.LineBeganInsideMultiLineComment)
            {
                return;
            }
            DocumentLine line = textEditorData.Document.GetLineByOffset(cursor);

//			stateTracker.UpdateEngine (line.Offset);
            // Get context to the end of the line w/o changing the main engine's state
            var ctx = stateTracker.Clone();

            for (int max = cursor; max < line.EndOffset; max++)
            {
                ctx.Push(textEditorData.Document.GetCharAt(max));
            }
            int    pos       = line.Offset;
            string curIndent = line.GetIndentation(textEditorData.Document);
            int    nlwsp     = curIndent.Length;
            int    offset    = cursor > pos + nlwsp ? cursor - (pos + nlwsp) : 0;

            if (!stateTracker.LineBeganInsideMultiLineComment || (nlwsp < line.LengthIncludingDelimiter && textEditorData.Document.GetCharAt(line.Offset + nlwsp) == '*'))
            {
                // Possibly replace the indent
                string newIndent       = ctx.ThisLineIndent;
                int    newIndentLength = newIndent.Length;
                if (newIndent != curIndent)
                {
                    if (CompletionWindowManager.IsVisible)
                    {
                        if (pos < CompletionWindowManager.CodeCompletionContext.TriggerOffset)
                        {
                            CompletionWindowManager.CodeCompletionContext.TriggerOffset -= nlwsp;
                        }
                    }

                    newIndentLength = textEditorData.Replace(pos, nlwsp, newIndent);
                    textEditorData.Document.CommitLineUpdate(textEditorData.Caret.Line);
                    // Engine state is now invalid
                    stateTracker.Update(pos);
                    CompletionWindowManager.HideWindow();
                }
                pos += newIndentLength;
            }
            else
            {
                pos += curIndent.Length;
            }

            pos += offset;

            textEditorData.FixVirtualIndentation();
        }
Ejemplo n.º 4
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());
        }
Ejemplo n.º 5
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));
        }