private VisualTextLine GetPartialLineBeforeCollapse(IEnumerable <CharInfo> charInfos, VisualTextLine line, int startIndex, int count) { var collapseInfo = charInfos.First(info => !info.IsCharacter); var contents = line.RenderedText; var textBeforeCollapse = string.Empty; if (collapseInfo.PrevCharPosition.Column >= startIndex) { textBeforeCollapse = contents.Substring(startIndex, collapseInfo.PrevCharPosition.Column); } else { textBeforeCollapse = contents.Substring(startIndex); } var diff = 0; if (startIndex + count >= collapseInfo.NextCharPosition.Column) { diff = (startIndex + count) - collapseInfo.NextCharPosition.Column; } var textAfterCollapse = string.Join("", contents.Skip(collapseInfo.NextCharPosition.Column).Take(diff)); return(VisualTextLine.Create(textBeforeCollapse + textAfterCollapse, line.Index)); }
public VisualTextLine CollapseTextRange(TextRange area, IReadOnlyList <string> lines, ICollapseRepresentation collapseRepresentationAlgorithm) { var precedingText = new string(lines[area.StartPosition.Line].Take(area.StartPosition.Column).ToArray()); var followingText = new string(lines[area.EndPosition.Line].Skip(area.EndPosition.Column + 1).ToArray()); var collapsedLineIndex = area.StartPosition.Line; var middlePart = new List <string>(); var start = area.StartPosition.Line; var end = area.EndPosition.Line; if (start != end) { for (var i = start; i <= end; i++) { var currentLine = lines[i]; if (i == start) { currentLine = string.Join("", currentLine.Skip(area.StartPosition.Column)); } else if (i == end) { currentLine = string.Join("", currentLine.Take(area.EndPosition.Column + 1)); } middlePart.Add(currentLine); } } else { middlePart.Add(string.Join("", lines[start].Skip(area.StartPosition.Column).Take((1 + area.EndPosition.Column) - area.StartPosition.Column))); } return(VisualTextLine.Create(middlePart, precedingText, followingText, collapsedLineIndex, collapseRepresentationAlgorithm.GetCollapseRepresentation())); }
public ChangeInLinesInfo GetChangeInLines(IReadOnlyList <VisualTextLine> lines, TextRange range) { var orderedRanges = (new[] { range.StartPosition, range.EndPosition }).OrderBy(elem => elem.Line).ThenBy(elem => elem.Column).ToArray(); var pair = new TextRange { StartPosition = orderedRanges[0], EndPosition = orderedRanges[1] }; var rangeEnd = -1; if (pair.StartPosition.Line == pair.EndPosition.Line) { rangeEnd = pair.EndPosition.Line; } else { rangeEnd = pair.EndPosition.Line + 1; } var firstPart = Cut(lines[pair.StartPosition.Line], 0, pair.StartPosition.Column); var secondPart = Cut(lines[pair.EndPosition.Line], pair.EndPosition.Column); return(new ChangeInLinesInfo { LinesToChange = new Dictionary <TextPosition, VisualTextLine> { [new TextPosition(pair.StartPosition.Column, pair.StartPosition.Line)] = VisualTextLine.MergeLines(new[] { firstPart, secondPart }, firstPart.Index) }, LinesToRemove = Enumerable.Range(pair.StartPosition.Line, rangeEnd).ToList() }); }
public void TwoNonEmptyLinesEnteredBackspacePressedAtTheBeginningOfSecond_LineShouldBeEqualToText1Text2() { const string text1 = "asdf"; const string text2 = "zxcv"; var lines = new List <VisualTextLine> { VisualTextLine.Create(text1, 0), VisualTextLine.Create(text2, 1) }; var newLines = algorithm.GetChangeInLines(lines, new TextPosition(column: 0, line: 1), Key.Back); Assert.AreEqual(text1 + text2, newLines.LinesToChange.First().Value.GetStringContents()[0]); }
public void TwoNonEmptyLinesEnteredDelPressedAtTheEndOfFirstOne_LineShouldBeEqualToText1Text2() { const string text1 = "asdf"; const string text2 = "zxcv"; var lines = new List <VisualTextLine> { VisualTextLine.Create(text1, 0), VisualTextLine.Create(text2, 1) }; var newLines = algorithm.GetChangeInLines(lines, new TextPosition(column: 4, line: 0), Key.Delete); Assert.AreEqual(text1 + text2, newLines.LinesToChange.First().Value.GetStringContents()[0]); }
private void DrawLine(VisualTextLine line) { if (line.Index < visuals.Count) { visuals.Insert(line.Index, line); visuals.RemoveAt(line.Index + 1); line.Draw(); } else { visuals.Add(line); line.Draw(); } }
private ChangeInLinesInfo DeleteFromActiveLine(IReadOnlyList <VisualTextLine> lines, TextPosition startingTextPosition) { var currentLine = lines[startingTextPosition.Line]; var firstPart = Cut(currentLine, 0, startingTextPosition.Column); var secondPart = Cut(currentLine, startingTextPosition.Column + 1); var lineAfterRemove = VisualTextLine.MergeLines(new[] { firstPart, secondPart }, currentLine.Index); return(new ChangeInLinesInfo { LinesToChange = new Dictionary <TextPosition, VisualTextLine> { [new TextPosition(startingTextPosition.Column, startingTextPosition.Line)] = lineAfterRemove }, LinesToRemove = new int[0] }); }
public void CacheThreeSingleLines_ShouldCacheThreeLines() { collection.Add(VisualTextLine.Create("asdf", 0)); collection.Add(VisualTextLine.Create("{", 1)); collection.Add(VisualTextLine.Create("", 2)); collection.Add(VisualTextLine.Create("}", 3)); var cachedResult = collection.ConvertToCachedLines(3, 1); Assert.AreEqual(cachedResult.Count, 3); Assert.AreEqual(cachedResult[0].RenderedText, "{"); Assert.AreEqual(cachedResult[1].RenderedText, ""); Assert.AreEqual(cachedResult[2].RenderedText, "}"); }
public void OneNonEmptyLineEnteredText2SelectedBackspacePressed_LineShouldBeText1Text3() { const string text1 = "some "; const string text2 = "text"; const string text3 = " asdf"; var lines = new List <VisualTextLine> { VisualTextLine.Create(text1 + text2 + text3, 0) }; var newLines = algorithm.GetChangeInLines(lines, new TextRange { StartPosition = new TextPosition(column: 5, line: 0), EndPosition = new TextPosition(column: 9, line: 0) }); Assert.AreEqual(text1 + text3, newLines.LinesToChange.First().Value.GetStringContents()[0]); }
private ChangeInLinesInfo RemoveFromActiveLine(IReadOnlyList <VisualTextLine> lines, TextPosition startingTextPosition) { var currentLine = lines[startingTextPosition.Line]; var attachRest = startingTextPosition.Column < lines[startingTextPosition.Line].Length; var firstPart = Cut(currentLine, 0, startingTextPosition.Column - 1); var secondPart = attachRest ? Cut(currentLine, startingTextPosition.Column) : null; var lineAfterRemove = secondPart != null?VisualTextLine.MergeLines(new[] { firstPart, secondPart }, currentLine.Index) : firstPart; return(new ChangeInLinesInfo { LinesToChange = new Dictionary <TextPosition, VisualTextLine> { [new TextPosition(startingTextPosition.Column - 1, startingTextPosition.Line)] = lineAfterRemove }, LinesToRemove = new int[0] }); }
private void RedrawCollapsedLine(VisualTextLine collapsedLine, int line) { if (line >= visuals.Count) { visuals.Add(null); } else { visuals[line] = null; } visuals[line] = collapsedLine; collapsedLine.Draw(); }
public void FourCharactersEnteredSelectionForLastTwo_LineShouldBeText1() { const string text1 = "as"; const string text2 = "df"; var lines = new List <VisualTextLine> { VisualTextLine.Create(text1 + text2, 0) }; var newLines = algorithm.GetChangeInLines(lines, new TextRange { StartPosition = new TextPosition(column: 2, line: 0), EndPosition = new TextPosition(column: 4, line: 0) }); Assert.AreEqual(0, newLines.LinesToRemove.Count()); Assert.AreEqual(text1, newLines.LinesToChange.ElementAt(0).Value.GetStringContents()[0]); }
public void ThreeLinesEnteredBackspacePressedOnTheSecondOne_LinesShouldBeText1Text3AndLinesToRemoveShouldBeLast() { const string text1 = "a"; const string text2 = ""; const string text3 = "b"; var lines = new List <VisualTextLine> { VisualTextLine.Create(text1, 0), VisualTextLine.Create(text2, 1), VisualTextLine.Create(text3, 2) }; var newLines = algorithm.GetChangeInLines(lines, new TextPosition(column: 0, line: 1), Key.Back); Assert.IsTrue((new[] { 2 }).OrderBy(key => key).ToArray().SequenceEqual(newLines.LinesToRemove.ToArray())); Assert.AreEqual(text1, newLines.LinesToChange.First().Value.GetStringContents()[0]); Assert.AreEqual(text3, newLines.LinesToChange.Last().Value.GetStringContents()[0]); }
private VisualTextLine CutStandardLine(VisualTextLine line, int startIndex, int count) { var contents = line.GetStringContents()[0]; var newText = string.Empty; if (startIndex + count == line.Length) { newText = contents.Substring(startIndex); } else { newText = contents.Substring(startIndex, count - startIndex); } return(VisualTextLine.Create(newText, line.Index)); }
public void OneLineEnteredSelectionOfFourCharsDeletePressed_LineShouldBeText1Text3() { const string text1 = "asdf"; const string text2 = "qwer"; const string text3 = "zxcv"; var lines = new List <VisualTextLine> { VisualTextLine.Create(text1 + text2 + text3, 0) }; var newLines = algorithm.GetChangeInLines(lines, new TextRange { StartPosition = new TextPosition(column: 4, line: 0), EndPosition = new TextPosition(column: 8, line: 0) }); var removedLinesIndexes = newLines.LinesToRemove.ToArray(); Assert.AreEqual(0, removedLinesIndexes.Length); Assert.AreEqual(text1 + text3, newLines.LinesToChange.ElementAt(0).Value.GetStringContents()[0]); }
public void CacheCollapsedAndSingleLines_ShouldCacheThreeLines() { const string FirstLine = "asdf"; const string Collapse = "{...}"; const string LastLine = "zxcv"; collection.Add(VisualTextLine.Create(FirstLine, 0)); collection.Add(VisualTextLine.Create(new[] { "{", "", "}" }, "", "", 1, Collapse)); collection.Add(VisualTextLine.Create(LastLine, 2)); var cachedResult = collection.ConvertToCachedLines(3); Assert.AreEqual(cachedResult.Count, 3); Assert.AreEqual(cachedResult[0].RenderedText, FirstLine); Assert.AreEqual(cachedResult[1].RenderedText, Collapse); Assert.AreEqual(cachedResult[2].RenderedText, LastLine); }
public void ExpandText(FoldClickedMessage message) { var collapseIndex = message.AreaBeforeFolding.StartPosition.Line; var collapsedLineContent = ((VisualTextLine)visuals[collapseIndex]).GetStringContents(); var expandedLines = collapsedLineContent.Select((line, index) => VisualTextLine.Create(line, collapseIndex + index)).ToArray(); var linesToRedraw = collapsingAlgorithm.GetLinesToRedrawAfterExpand(visuals.ToEnumerableOf <VisualTextLine>().Where(line => line.Index > message.AreaBeforeFolding.StartPosition.Line), expandedLines.Length - 1); visuals.RemoveRange(collapseIndex, LinesCount - collapseIndex); foreach (var line in expandedLines) { visuals.Insert(line.Index, line); line.Draw(); } AddLines(linesToRedraw); UpdateSize(); }
private int[] GetCollapseSelectionRange(TextPosition clickPosition, VisualTextLine activeLine, int lineLength) { var startColumn = clickPosition.Column; var endColumn = clickPosition.Column; if (endColumn + 1 <= lineLength) { endColumn += 1; } else { startColumn -= 1; } // move left from current position for (var i = clickPosition.Column; i >= 0; i--) { var charInfo = activeLine.GetCharInfoAt(i); if (!charInfo.IsCharacter && !char.IsLetterOrDigit(charInfo.Text[0])) { startColumn = i; } else { break; } } // move right from current position for (var i = clickPosition.Column; i < lineLength; i++) { var charInfo = activeLine.GetCharInfoAt(i); if (!charInfo.IsCharacter && !char.IsLetterOrDigit(charInfo.Text[0])) { endColumn = i + 1; } else { break; } } return(new[] { startColumn, endColumn }); }
public void ThreeNonEmptyLinesEnteredBackspacePressedAtCharOneBeforeTheLastOneInTheLastLine_LinesShouldBeText4() { const string text1 = "some text"; const string text2 = ""; const string text3 = "totally unimportant text"; const string text4 = "text that stays"; var lines = new List <VisualTextLine> { VisualTextLine.Create(text1, 0), VisualTextLine.Create(text2, 1), VisualTextLine.Create(text3 + text4, 2) }; var newLines = algorithm.GetChangeInLines(lines, new TextRange { StartPosition = new TextPosition(column: 0, line: 0), EndPosition = new TextPosition(column: 24, line: 2) }); Assert.AreEqual(text4, newLines.LinesToChange.First().Value.GetStringContents()[0]); Assert.IsTrue((new[] { 0, 1, 2 }).OrderBy(key => key).ToArray().SequenceEqual(newLines.LinesToRemove.OrderBy(key => key).ToArray())); }
private ChangeInLinesInfo RemoveThisLine(IReadOnlyList <VisualTextLine> lines, TextPosition startingTextPosition) { var firstLine = lines[startingTextPosition.Line - 1]; var linesAffected = new List <KeyValuePair <TextPosition, VisualTextLine> > { new KeyValuePair <TextPosition, VisualTextLine>( new TextPosition(lines[startingTextPosition.Line - 1].Length, startingTextPosition.Line - 1), VisualTextLine.MergeLines(new[] { firstLine, lines[startingTextPosition.Line] }, firstLine.Index)) }; for (var i = startingTextPosition.Line + 1; i < lines.Count; i++) { linesAffected.Add(new KeyValuePair <TextPosition, VisualTextLine>(new TextPosition(0, i - 1), lines[i].CloneWithIndexChange(i - 1))); } return(new ChangeInLinesInfo { LinesToChange = linesAffected, LinesToRemove = new[] { lines.Count - 1 } }); }
public void FourLinesEnteredDeletePressedAtTheEndOfFirst_LinesShouldBeText1Text2Text3() { const string text1 = "asdf"; const string text2 = "zxcv"; const string text3 = "qwer"; var lines = new List <VisualTextLine> { VisualTextLine.Create(text1, 0), VisualTextLine.Create(string.Empty, 1), VisualTextLine.Create(text2, 2), VisualTextLine.Create(text3, 3) }; var newLines = algorithm.GetChangeInLines(lines, new TextPosition(column: 4, line: 0), Key.Delete); var removedLinesIndexes = newLines.LinesToRemove.ToArray(); Assert.AreEqual(text1, newLines.LinesToChange.First().Value.GetStringContents()[0]); Assert.AreEqual(text2, newLines.LinesToChange.ElementAt(1).Value.GetStringContents()[0]); Assert.AreEqual(text3, newLines.LinesToChange.ElementAt(2).Value.GetStringContents()[0]); Assert.AreEqual(1, removedLinesIndexes.Length); Assert.AreEqual(3, removedLinesIndexes[0]); }
public void TwoLinesEnteredSelectionInTheMiddleOfFirst_LinesShouldBeText1Text3Text4() { const string text1 = "as"; const string text2 = " df "; const string text3 = "qwer"; const string text4 = "zxcv"; var lines = new List <VisualTextLine> { VisualTextLine.Create(text1 + text2 + text3, 0), VisualTextLine.Create(text4, 1) }; var newLines = algorithm.GetChangeInLines(lines, new TextRange { StartPosition = new TextPosition(column: 2, line: 0), EndPosition = new TextPosition(column: 6, line: 0) }); var removedLineIndexes = newLines.LinesToRemove.ToArray(); Assert.AreEqual(0, removedLineIndexes.Length); Assert.AreEqual(1, newLines.LinesToChange.Count()); Assert.AreEqual(text1 + text3, newLines.LinesToChange.ElementAt(0).Value.GetStringContents()[0]); }
private ChangeInLinesInfo DeleteNextLine(IReadOnlyList <VisualTextLine> lines, TextPosition startingTextPosition) { var firstLine = lines[startingTextPosition.Line]; var secondLine = startingTextPosition.Line + 1 < lines.Count ? lines[startingTextPosition.Line + 1] : null; var linesToMerge = secondLine == null ? new[] { firstLine } : new[] { firstLine, secondLine }; var linesAffected = new List <KeyValuePair <TextPosition, VisualTextLine> > { new KeyValuePair <TextPosition, VisualTextLine>( new TextPosition(startingTextPosition.Column, startingTextPosition.Line), VisualTextLine.MergeLines(linesToMerge, firstLine.Index)) }; for (var i = startingTextPosition.Line + 2; i < lines.Count; i++) { linesAffected.Add(new KeyValuePair <TextPosition, VisualTextLine>(new TextPosition(0, i - 1), lines[i].CloneWithIndexChange(i - 1))); } return(new ChangeInLinesInfo { LinesToChange = linesAffected, LinesToRemove = new[] { lines.Count - 1 } }); }
private VisualTextLine Cut(VisualTextLine line, int startIndex, int?count = null) { var substringLength = count == null ? line.Length - startIndex : count.Value; if (line is CollapsedVisualTextLine) { var charInfos = Enumerable.Range(startIndex, substringLength).Select(index => line.GetCharInfoAt(index)); if (charInfos.Any(info => !info.IsCharacter)) { return(GetPartialLineBeforeCollapse(charInfos, line, startIndex, substringLength)); } else { return(GetPartialLineAfterCollapse(line, startIndex, substringLength)); } } else { return(CutStandardLine(line, startIndex, substringLength)); } }
public void FourLinesEnteredSelectionInbetweenDeletePressed_LinesShouldBeText1Text6() { const string text1 = "as"; const string text2 = "df"; const string text3 = "qwer"; const string text4 = "zxcv"; const string text5 = "fg"; const string text6 = "hj"; var lines = new List <VisualTextLine> { VisualTextLine.Create(text1 + text2, 0), VisualTextLine.Create(text3, 1), VisualTextLine.Create(text4, 2), VisualTextLine.Create(text5 + text6, 3) }; var newLines = algorithm.GetChangeInLines(lines, new TextRange { StartPosition = new TextPosition(column: 2, line: 0), EndPosition = new TextPosition(column: 2, line: 3) }); var removedLinesIndexes = newLines.LinesToRemove.ToArray(); Assert.AreEqual(4, removedLinesIndexes.Length); Assert.AreEqual(1, newLines.LinesToChange.Count()); Assert.AreEqual(text1 + text6, newLines.LinesToChange.ElementAt(0).Value.GetStringContents()[0]); }
private void InputText(string enteredText) { var newLines = updatingAlgorithm.GetChangeInLines(GetActualLines(), caretViewReader.CaretPosition, enteredText); DrawLines(newLines.Select(entry => VisualTextLine.Create(entry.Value, entry.Key))); }
public IEnumerable <VisualTextLine> GetLinesToRedrawAfterCollapse(IReadOnlyList <VisualTextLine> visuals, VisualTextLine collapsedLine, TextRange range) { var linesToRedraw = new List <VisualTextLine>(); if (range.StartPosition.Line == range.EndPosition.Line) { return(linesToRedraw); } var collapseEndLine = range.EndPosition.Line; for (int i = collapseEndLine + 1, newIndex = collapsedLine.Index + 1; i < visuals.Count; i++, newIndex++) { var line = visuals[i].CloneWithIndexChange(newIndex); linesToRedraw.Add(line); } return(linesToRedraw); }
public IEnumerable <VisualTextLine> ExpandTextRange(TextRange area, IEnumerable <string> lines) => lines.Skip(area.StartPosition.Line).Take(1 + area.EndPosition.Line - area.StartPosition.Line).Select((line, index) => VisualTextLine.Create(line, area.StartPosition.Line + index));
private VisualTextLine GetPartialLineAfterCollapse(VisualTextLine line, int startIndex, int count) { var firstPart = line.RenderedText.Substring(startIndex, count); return(VisualTextLine.Create(firstPart, line.Index)); }