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())); }
public ITextBuffer CreateTextBuffer(IContentType contentType) { if (contentType == null) { throw new ArgumentNullException("contentType"); } return(Make(contentType, SimpleStringRebuilder.Create(String.Empty), false)); }
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)); } }
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)); } }
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)); } }
public ITextBuffer CreateTextBuffer() { return(Make(TextContentType, SimpleStringRebuilder.Create(String.Empty), false)); }
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); } }
/// <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))); }
/// <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))); }
/// <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))); }