Example #1
0
        internal static StringRebuilder StringRebuilderFromSnapshotSpan(SnapshotSpan span)
        {
            TextSnapshot snapshot = span.Snapshot as TextSnapshot;

            if (snapshot != null)
            {
                return(snapshot.Content.Substring(span));
            }

            IProjectionSnapshot projectionSnapshot = span.Snapshot as IProjectionSnapshot;

            if (projectionSnapshot != null)
            {
                StringRebuilder content = SimpleStringRebuilder.Create(string.Empty);

                foreach (var childSpan in projectionSnapshot.MapToSourceSnapshots(span))
                {
                    content = content.Append(StringRebuilderFromSnapshotSpan(childSpan));
                }

                return(content);
            }

            //The we don't know what to do fallback. This should never be called unless someone provides a new snapshot
            //implementation.
            return(SimpleStringRebuilder.Create(span.GetText()));
        }
Example #2
0
 public ITextBuffer CreateTextBuffer(IContentType contentType)
 {
     if (contentType == null)
     {
         throw new ArgumentNullException("contentType");
     }
     return(Make(contentType, SimpleStringRebuilder.Create(String.Empty), false));
 }
Example #3
0
 public ITextBuffer CreateTextBuffer(string text, IContentType contentType, bool spurnGroup)
 {
     if (text == null)
     {
         throw new ArgumentNullException("text");
     }
     if (contentType == null)
     {
         throw new ArgumentNullException("contentType");
     }
     return(Make(contentType, SimpleStringRebuilder.Create(text), spurnGroup));
 }
 private static StringRebuilder ConsolidateOrBalanceTreeNode(StringRebuilder left, StringRebuilder right)
 {
     if ((left.Length + right.Length < TextModelOptions.StringRebuilderMaxCharactersToConsolidate) &&
         (left.LineBreakCount + right.LineBreakCount <= TextModelOptions.StringRebuilderMaxLinesToConsolidate))
     {
         //Consolidate the two rebuilders into a single simple string rebuilder
         return(SimpleStringRebuilder.Create(left, right));
     }
     else
     {
         return(BinaryStringRebuilder.BalanceTreeNode(left, right));
     }
 }
        /// <summary>
        /// Construct a new SimpleStringRebuilder that is a substring of another string rebuilder.
        /// </summary>
        private static SimpleStringRebuilder CreateSubstring(Span span, SimpleStringRebuilder simpleSource)
        {
            int firstLineNumber = simpleSource.GetLineNumberFromPosition(span.Start) + simpleSource._lineBreakSpanStart;
            int lastLineNumber  = simpleSource.GetLineNumberFromPosition(span.End) + simpleSource._lineBreakSpanStart;

            //Handle the special case where the end position falls in the middle of a linebreak.
            if ((lastLineNumber < simpleSource.LineBreakSpanEnd) &&
                (span.End > simpleSource._storage.LineBreaks.StartOfLineBreak(lastLineNumber) - simpleSource._textSpanStart))
            {
                ++lastLineNumber;
            }

            return(new SimpleStringRebuilder(simpleSource._storage, span.Start + simpleSource._textSpanStart, span.Length, firstLineNumber, lastLineNumber - firstLineNumber));
        }
        public override StringRebuilder Substring(Span span)
        {
            if (span.End > this.Length)
            {
                throw new ArgumentOutOfRangeException("span");
            }

            if (span.Length == this.Length)
            {
                return(this);
            }
            else if (span.Length == 0)
            {
                return(_empty);
            }
            else
            {
                return(SimpleStringRebuilder.CreateSubstring(span, this));
            }
        }
Example #7
0
        public static ChangeString CreateChangeString(IList <SnapshotSpan> sourceSpans, Span selected)
        {
            if (selected.Length == 0)
            {
                return(ChangeString.EmptyChangeString);
            }
            else if (selected.Length == 1)
            {
                return(ReferenceChangeString.CreateChangeString(sourceSpans[selected.Start]));
            }
            else
            {
                StringRebuilder builder = SimpleStringRebuilder.Create(String.Empty);
                for (int i = 0; (i < selected.Length); ++i)
                {
                    builder = builder.Insert(builder.Length, BufferFactoryService.StringRebuilderFromSnapshotSpan(sourceSpans[selected.Start + i]));
                }

                return(ReferenceChangeString.CreateChangeString(builder));
            }
        }
Example #8
0
        public ITextBuffer CreateTextBuffer(TextReader reader, IContentType contentType, long length, string traceId)
        {
            if (reader == null)
            {
                throw new ArgumentNullException("reader");
            }
            if (contentType == null)
            {
                throw new ArgumentNullException("contentType");
            }
            if (length > int.MaxValue)
            {
                throw new InvalidOperationException(Strings.FileTooLarge);
            }

            ITextStorageLoader loader;

            if (length < TextModelOptions.CompressedStorageFileSizeThreshold)
            {
                loader = new SimpleTextStorageLoader(reader, (int)length);
            }
            else
            {
                loader = new CompressedTextStorageLoader(reader, (int)length, traceId);
            }
            StringRebuilder content = SimpleStringRebuilder.Create(loader);

            ITextBuffer buffer = Make(contentType, content, false);

            if (!loader.HasConsistentLineEndings)
            {
                // leave a sign that line endings are inconsistent. This is rather nasty but for now
                // we don't want to pollute the API with this factoid
                buffer.Properties.AddProperty("InconsistentLineEndings", true);
            }
            // leave a similar sign about the longest line in the buffer.
            buffer.Properties.AddProperty("LongestLineLength", loader.LongestLineLength);
            return(buffer);
        }
        public static StringRebuilder Create(StringRebuilder left, StringRebuilder right)
        {
            if (left == null)
            {
                throw new ArgumentNullException("left");
            }
            if (right == null)
            {
                throw new ArgumentNullException("right");
            }

            if (left.Length == 0)
            {
                return(right);
            }
            else if (right.Length == 0)
            {
                return(left);
            }
            else if ((left.Length + right.Length < TextModelOptions.StringRebuilderMaxCharactersToConsolidate) &&
                     (left.LineBreakCount + right.LineBreakCount <= TextModelOptions.StringRebuilderMaxLinesToConsolidate))
            {
                //Consolidate the two rebuilders into a single simple string rebuilder
                return(SimpleStringRebuilder.Create(left, right));
            }
            else if (right.StartsWithNewLine && left.EndsWithReturn)
            {
                //Don't allow a line break to be broken across the seam
                return(BinaryStringRebuilder.Create(BinaryStringRebuilder.Create(left.Substring(new Span(0, left.Length - 1)),
                                                                                 _crlf),
                                                    right.Substring(Span.FromBounds(1, right.Length))));
            }
            else
            {
                return(BinaryStringRebuilder.BalanceStringRebuilder(left, right));
            }
        }
Example #10
0
 public ITextBuffer CreateTextBuffer()
 {
     return(Make(TextContentType, SimpleStringRebuilder.Create(String.Empty), false));
 }
Example #11
0
        public ReloadResult Reload(EditOptions options)
        {
            if (_isDisposed)
            {
                throw new ObjectDisposedException("ITextDocument");
            }
            if (_raisingDirtyStateChangedEvent || _raisingFileActionChangedEvent)
            {
                throw new InvalidOperationException();
            }

            var              beforeSnapshot = _textBuffer.CurrentSnapshot;
            Encoding         newEncoding    = null;
            FallbackDetector fallbackDetector;

            try
            {
                _reloadingFile = true;

                // Load the file and read the contents to the text buffer

                long fileSize;
                using (var stream = TextDocumentFactoryService.OpenFileGuts(_filePath, out _lastModifiedTimeUtc, out fileSize))
                {
                    // We want to use the encoding indicated by a BoM if one is present because
                    // VS9's editor did so. We can't let the StreamReader below detect
                    // the byte order marks because we still want to be able to detect the
                    // fallback condition.
                    bool unused;
                    newEncoding = EncodedStreamReader.CheckForBoM(stream, isStreamEmpty: out unused);

                    Debug.Assert(newEncoding == null || newEncoding.GetPreamble().Length > 0);

                    // TODO: Consider using the encoder detector extensions as well.

                    if (newEncoding == null)
                    {
                        newEncoding = this.Encoding;
                    }

                    fallbackDetector = new FallbackDetector(newEncoding.DecoderFallback);
                    var modifiedEncoding = (Encoding)newEncoding.Clone();
                    modifiedEncoding.DecoderFallback = fallbackDetector;

                    using (var streamReader = new StreamReader(stream, modifiedEncoding, detectEncodingFromByteOrderMarks: false))
                    {
                        TextBuffer concreteBuffer = _textBuffer as TextBuffer;
                        if (concreteBuffer != null)
                        {
                            ITextStorageLoader loader;
                            if (fileSize < TextModelOptions.CompressedStorageFileSizeThreshold)
                            {
                                loader = new SimpleTextStorageLoader(streamReader, (int)fileSize);
                            }
                            else
                            {
                                loader = new CompressedTextStorageLoader(streamReader, (int)fileSize, _filePath);
                            }
                            StringRebuilder newContent = SimpleStringRebuilder.Create(loader);
                            if (!loader.HasConsistentLineEndings)
                            {
                                // leave a sign that line endings are inconsistent. This is rather nasty but for now
                                // we don't want to pollute the API with this factoid.
                                concreteBuffer.Properties["InconsistentLineEndings"] = true;
                            }
                            else
                            {
                                // this covers a really obscure case where on initial load the file had inconsistent line
                                // endings, but the UI settings were such that it was ignored, and since then the file has
                                // acquired consistent line endings and the UI settings have also changed.
                                concreteBuffer.Properties.RemoveProperty("InconsistentLineEndings");
                            }
                            // leave a similar sign about the longest line in the buffer.
                            concreteBuffer.Properties["LongestLineLength"] = loader.LongestLineLength;

                            concreteBuffer.ReloadContent(newContent, options, editTag: this);
                        }
                        else
                        {
                            // we may hit this path if somebody mocks the text buffer in a test.
                            using (var edit = _textBuffer.CreateEdit(options, null, editTag: this))
                            {
                                if (edit.Replace(new Span(0, edit.Snapshot.Length), streamReader.ReadToEnd()))
                                {
                                    edit.Apply();
                                }
                                else
                                {
                                    edit.Cancel();
                                }
                            }
                        }
                        Debug.Assert(streamReader.CurrentEncoding.CodePage == newEncoding.CodePage);
                        Debug.Assert(streamReader.CurrentEncoding.GetPreamble().Length == newEncoding.GetPreamble().Length);
                    }
                }
            }
            finally
            {
                _reloadingFile = false;
            }

            //The snapshot on a reload will change even if the contents of the before & after files are identical (differences will simply find an
            //empty set of changes) so this test is a measure of whether of not the reload succeeded.
            if (beforeSnapshot.Version.Next != null)
            {
                // Update status
                // set the "clean" reiterated version number to the reiterated version number of the version immediately
                // after the before snapshot (which is the state of the buffer after loading the document but before any
                // subsequent edits made in the text buffer changed events).
                _cleanReiteratedVersion = beforeSnapshot.Version.Next.ReiteratedVersionNumber;

                // TODO: the following event really should be queued up through the buffer group so that it comes before
                // the text changed event (and any subsequent text changed event invoked from an event handler)
                RaiseFileActionChangedEvent(_lastModifiedTimeUtc, FileActionTypes.ContentLoadedFromDisk, _filePath);
                this.Encoding = newEncoding;
                return(fallbackDetector.FallbackOccurred ? ReloadResult.SucceededWithCharacterSubstitutions : ReloadResult.Succeeded);
            }
            else
            {
                return(ReloadResult.Aborted);
            }
        }
Example #12
0
 /// <summary>
 /// Create a new StringRebuilder equivalent to replacing a contiguous span of characters
 /// with different text.
 /// </summary>
 /// <param name="span">
 /// Span of text in this <see cref="StringRebuilder"/> to replace.
 /// </param>
 /// <param name="text">
 /// The new text to replace the old.
 /// </param>
 /// <returns>
 /// A new string rebuilder containing the replacement.
 /// </returns>
 /// <remarks>
 /// <para>this <see cref="StringRebuilder"/> is not modified.</para>
 /// <para>This operation can be performed simultaneously on multiple threads.</para>
 /// </remarks>
 /// <exception cref="ArgumentOutOfRangeException"><paramref name="span"/>.End is greater than <see cref="Length"/>.</exception>
 /// <exception cref="ArgumentNullException"><paramref name="text"/> is null.</exception>
 public StringRebuilder Replace(Span span, string text)
 {
     return(this.Replace(span, SimpleStringRebuilder.Create(text)));
 }
Example #13
0
 /// <summary>
 /// Create a new StringRebuilder equivalent to inserting storage into this <see cref="StringRebuilder"/>.
 /// </summary>
 /// <param name="position">Position at which to insert.</param>
 /// <param name="storage">Storage containing text to insert.</param>
 /// <returns>A new StringRebuilder containing the insertion.</returns>
 /// <remarks>
 /// <para>this <see cref="StringRebuilder"/> is not modified.</para>
 /// <para>This operation can be performed simultaneously on multiple threads.</para>
 /// </remarks>
 /// <exception cref="ArgumentOutOfRangeException"><paramref name="position"/> is less than zero or greater than <see cref="Length"/>.</exception>
 /// <exception cref="ArgumentNullException"><paramref name="storage"/> is null.</exception>
 public StringRebuilder Insert(int position, ITextStorage storage)
 {
     return(this.Insert(position, SimpleStringRebuilder.Create(storage)));
 }
Example #14
0
 /// <summary>
 /// Create a new StringRebuilder equivalent to inserting text into this <see cref="StringRebuilder"/>.
 /// </summary>
 /// <param name="position">Position at which to insert.</param>
 /// <param name="text">Text to insert.</param>
 /// <returns>A new StringRebuilder containing the insertion.</returns>
 /// <remarks>
 /// <para>this <see cref="StringRebuilder"/> is not modified.</para>
 /// <para>This operation can be performed simultaneously on multiple threads.</para>
 /// </remarks>
 /// <exception cref="ArgumentOutOfRangeException"><paramref name="position"/> is less than zero or greater than <see cref="Length"/>.</exception>
 /// <exception cref="ArgumentNullException"><paramref name="text"/> is null.</exception>
 public StringRebuilder Insert(int position, string text)
 {
     return(this.Insert(position, SimpleStringRebuilder.Create(text)));
 }