private SimpleStringRebuilder(ITextStorage storage) : base(storage.Length, storage.LineBreaks.Length, 0) { _storage = storage; if (this.Length > 0) { _startsWithNewLine = storage.IsNewLine(_textSpanStart); _endsWithReturn = storage.IsReturn(this.TextSpanEnd - 1); } }
public static StringRebuilder Create(ITextStorage storage) { if (storage == null) { throw new ArgumentNullException("storage"); } return((storage.Length == 0) ? _empty : new SimpleStringRebuilder(storage)); }
private SimpleStringRebuilder(ITextStorage storage, int textSpanStart, int length, int lineBreakSpanStart, int lineBreakCount) : base(length, lineBreakCount, 0) { _storage = storage; _textSpanStart = textSpanStart; _lineBreakSpanStart = lineBreakSpanStart; if (this.Length > 0) { _startsWithNewLine = _storage.IsNewLine(_textSpanStart); _endsWithReturn = _storage.IsReturn(this.TextSpanEnd - 1); } }
public override ITextStorage Take( ITextStorage source) { if (!(source is StringStorage)) { Debug.Assert(false); throw new ArgumentException(); } return StringStorage.Take((StringStorage)source); }
public override void InsertSection(int insertLine, int insertChar, ITextStorage insert) { // TODO: optimize for copy/paste base.InsertSection(insertLine, insertChar, insert); }
public Exporter(IExercisesRepository exercisesRepository, IWorkoutsRepository workoutsRepository, ITextStorage textStorage) { _exercisesRepository = exercisesRepository; _workoutsRepository = workoutsRepository; _textStorage = textStorage; }
public MovieConsoleCreator(ITextStorage storage) { this.storage = storage; }
void ITextEditorChangeTracking.ReplacingRange( int startLine, int startChar, ITextStorage deleted, int replacedEndLine, int replacedEndCharPlusOne) { if (clearRedo) { textEdit.redo = null; } //SelectionUndoRecord selection = new SelectionUndoRecord(textEdit); //selection.next = records; //records = selection; ReplaceRangeUndoRecord newRange = new ReplaceRangeUndoRecord( startLine, startChar, deleted, replacedEndLine, replacedEndCharPlusOne); UndoRecord last = records; while ((last != null) && !(last is ReplaceRangeUndoRecord)) { last = last.Next; } if ((newRange.StartLine == newRange.EndLine) && (newRange.StartChar == newRange.EndCharPlusOne) && (newRange.StartLine == newRange.ReplacedEndLine) && (newRange.StartChar + 1 == newRange.ReplacedEndCharPlusOne)) { // if current is a keypress (single char insertion) try to coalesce with previous record ReplaceRangeUndoRecord lastRange = last != null ? (ReplaceRangeUndoRecord)last : null; if ((lastRange != null) && lastRange.Deleted.Empty && (lastRange.StartLine == lastRange.EndLine) && (lastRange.StartLine == newRange.StartLine) && (lastRange.ReplacedEndCharPlusOne == newRange.StartChar)) { lastRange.ReplacedEndCharPlusOne++; return; } } else if ((newRange.StartLine == newRange.EndLine) && (newRange.StartChar == newRange.EndCharPlusOne - 1) && (newRange.StartLine == newRange.ReplacedEndLine) && (newRange.StartChar == newRange.ReplacedEndCharPlusOne)) { // if current is a backspace/del (single char removal) try to coalesce with previous record ReplaceRangeUndoRecord lastRange = last != null ? (ReplaceRangeUndoRecord)last : null; if ((lastRange != null) && (lastRange.StartLine == lastRange.EndLine) && (lastRange.StartLine == newRange.StartLine) && (lastRange.StartChar == newRange.EndCharPlusOne)) { lastRange.StartChar--; lastRange.ReplacedEndCharPlusOne--; lastRange.Deleted.InsertSection(0, 0, newRange.Deleted); return; } else if ((lastRange != null) && (lastRange.StartLine == lastRange.EndLine) && (lastRange.StartChar == lastRange.ReplacedEndCharPlusOne) && (lastRange.StartLine == newRange.StartLine) && (lastRange.StartChar == newRange.StartChar)) { lastRange.Deleted.InsertSection(0, lastRange.Deleted[0].Length, newRange.Deleted); return; } } newRange.Next = records; records = newRange; }
public ITextStorage Copy( ITextStorage source) { TextStorage copy = NewStorage(); copy.CopyFrom(source); return copy; }
/* insert a storage block at the specified position into this storage block. */ /* note: there are (number of lines) - 1 line breaks */ public virtual void InsertSection( int insertLine, int insertChar, ITextStorage insert) { if ((insertLine < 0) || (insertLine >= GetLineCount())) { // Line position out of range Debug.Assert(false); throw new ArgumentException(); } if ((insertChar < 0) || (insertChar > GetLine(insertLine).Length)) { // Character position out of range Debug.Assert(false); throw new ArgumentException(); } /* check for special case where inertion only has 1 line */ int insertLines = insert.Count; if (insertLines == 1) { /* special case */ ITextLine origLine = GetLine(insertLine); SetLine( insertLine, factory.Combine( origLine, 0, insertChar, insert[0], origLine, insertChar, origLine.Length - insertChar)); } else { /* count characters for resize */ int charCount = 0; ITextLine origLine = GetLine(insertLine); /* create first composite line */ ITextLine insertStart = insert[0]; int insertStartLength = insertStart.Length; ITextLine compositeStart = factory.Combine( origLine, 0, insertChar, null, insertStart, 0, insertStartLength); charCount += insertStartLength; /* create second composite line */ ITextLine insertEnd = insert[insertLines - 1]; int insertEndLength = insertEnd.Length; ITextLine compositeEnd = factory.Combine( insertEnd, 0, insertEndLength, null, origLine, insertChar, origLine.Length - insertChar); charCount += insertEndLength; /* currently there is 1 line. that line will be replaced with composite */ /* start, then composite end will be inserted (+ 1), and then the middle */ /* lines will be inserted (+ (StuffLineCount - 2)). */ int insertedLineCount = 0; /* insert inner lines */ #if DEBUG const int BlockSize = 16; #else const int BlockSize = 4096; #endif // blocked loop reduces temporary memory demand at cost of multiple insertions int innerCount = insertLines - 2; for (int ii = 0; ii < innerCount; ii += BlockSize) { int c = Math.Min(BlockSize, innerCount - ii); ITextLine[] interiorLines = new ITextLine[c]; for (int i = 0; i < c; i++) { ITextLine toInsert = insert[i + ii + 1]; interiorLines[i] = factory.Ensure(toInsert); charCount += toInsert.Length; } InsertRange( ii + insertLine + 1/*skip start*/, interiorLines); } insertedLineCount += innerCount; /* insert last composite line */ Insert( (insertLine + 1/*skip start*/) + insertedLineCount, compositeEnd); insertedLineCount++; /* replace first line with first composite */ SetLine(insertLine, compositeStart); } modified = true; }
public void CopyFrom( ITextStorage source) { if (source.Count < 1) { Debug.Assert(false); throw new InvalidOperationException(); } MakeEmpty(); SetLine(0, factory.Ensure(source[0])); for (int i = 1; i < source.Count; i++) { Insert(i, factory.Ensure(source[i])); } this.modified = source.Modified; }
/// <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))); }
public override void Reload( ITextStorageFactory factory, ITextStorage storage) { ClearUndoRedo(); base.Reload(factory, storage); }
// TODO: make this work with complex scripts (currently too much Char.IsLetterOrDigit, etc) public bool IsMatch( ITextStorage pattern, bool caseSensitive, bool matchWholeWord, int startLine, int startChar) { if (pattern.Count == 1) { // within-line search case IDecodedTextLine decodedPattern = pattern[0].Decode_MustDispose(); IDecodedTextLine decodedStartLine = GetLine(startLine).Decode_MustDispose(); if (startChar + decodedPattern.Length > decodedStartLine.Length) { return false; } if (startChar != CurrentCultureIndexOf( decodedStartLine, decodedPattern, startChar, decodedPattern.Length, caseSensitive ? CompareOptions.None : CompareOptions.IgnoreCase)) { return false; } if (matchWholeWord) { if (Char.IsLetterOrDigit(decodedPattern[0])) { if ((startChar - 1 >= 0) && Char.IsLetterOrDigit(decodedStartLine[startChar - 1])) { return false; } } if (Char.IsLetterOrDigit(decodedPattern[decodedPattern.Length - 1])) { if ((startChar + decodedPattern.Length < decodedStartLine.Length) && Char.IsLetterOrDigit(decodedStartLine[startChar + decodedPattern.Length])) { return false; } } } } else { // multi-line search case if (startLine + pattern.Count - 1 >= this.Count) { return false; } // first line IDecodedTextLine decodedPatternFirstLine = pattern[0].Decode_MustDispose(); IDecodedTextLine decodedStartLine = GetLine(startLine).Decode_MustDispose(); if (startChar + decodedPatternFirstLine.Length != decodedStartLine.Length) { return false; } if (startChar != CurrentCultureIndexOf( decodedStartLine, decodedPatternFirstLine, startChar, decodedPatternFirstLine.Length, caseSensitive ? CompareOptions.None : CompareOptions.IgnoreCase)) { return false; } if (matchWholeWord) { if (Char.IsLetterOrDigit(decodedPatternFirstLine[0])) { if ((startChar - 1 >= 0) && Char.IsLetterOrDigit(decodedStartLine[startChar - 1])) { return false; } } } // interior lines for (int i = 1; i < pattern.Count - 1; i++) { IDecodedTextLine decodedPatternLine = pattern[i].Decode_MustDispose(); IDecodedTextLine decodedLine = GetLine(startLine + i).Decode_MustDispose(); if (!CurrentCultureEquals( decodedLine, decodedPatternLine, caseSensitive ? CompareOptions.None : CompareOptions.IgnoreCase)) { return false; } } // last line IDecodedTextLine decodedPatternLastLine = pattern[pattern.Count - 1].Decode_MustDispose(); IDecodedTextLine decodedLastLine = GetLine(startLine + pattern.Count - 1).Decode_MustDispose(); if (decodedLastLine.Length < decodedPatternLastLine.Length) { return false; } if (0 != CurrentCultureIndexOf( decodedLastLine, decodedPatternLastLine, 0, decodedPatternLastLine.Length, caseSensitive ? CompareOptions.None : CompareOptions.IgnoreCase)) { return false; } if (matchWholeWord) { if (Char.IsLetterOrDigit(decodedPatternLastLine[decodedPatternLastLine.Length - 1])) { if ((decodedPatternLastLine.Length < decodedLastLine.Length) && Char.IsLetterOrDigit(decodedLastLine[decodedPatternLastLine.Length])) { return false; } } } } return true; }
/* find the specified search string starting at the current selection. */ public bool Find( ITextStorage pattern, bool caseSensitive, bool matchWholeWord, bool wrap, bool up) { int line = !wrap ? SelectionStartLine : (!up ? 0 : this.Count - 1); int col; if (!wrap) { if (SelectionNonEmpty) { /* if there is a selection, assume it's from a previous search. we need */ /* to have + 1 so we don't find what we found again. */ col = !up ? SelectionStartChar + 1 : SelectionStartChar - 1; } else { /* if no selection, start search at current position. this lets us find */ /* patterns at the very beginning of the file. */ col = SelectionStartChar; } } else { col = !up ? 0 : GetLine(this.Count - 1).Length; } while (!up ? line < this.Count : line >= 0) { ITextLine testLine = GetLine(line); int colEnd = testLine.Length - pattern[0].Length; while (!up ? col <= colEnd : col >= 0) { if (IsMatch(pattern, caseSensitive, matchWholeWord, line, col)) { /* found it! */ SetSelection( line, col, line + pattern.Count - 1, (pattern.Count == 1 ? col : 0) + pattern[pattern.Count - 1].Length, SelectionStartIsActive); return true; } col = !up ? col + 1 : col - 1; } line = !up ? line + 1 : line - 1; col = !up ? 0 : (line >= 0 ? GetLine(line).Length - pattern[0].Length : Int32.MaxValue); } ErrorBeep(); /* selection not found */ return false; }
public abstract ITextStorage Take( ITextStorage source);
public MovieTranslator(ITextStorage storage) { this.storage = storage; }
public int StartChar; // hackable #endregion Fields #region Constructors public ReplaceRangeUndoRecord( int startLine, int startChar, ITextStorage deleted, int replacedEndLine, int replacedEndCharPlusOne) { this.StartLine = startLine; this.StartChar = startChar; this.Deleted = deleted; this.ReplacedEndLine = replacedEndLine; this.ReplacedEndCharPlusOne = replacedEndCharPlusOne; }