public IDictionary<TextPosition, TextPosition> CreateFolds(string text, TextPosition position, IDictionary<TextPosition, TextPosition> foldingPositions) { if (text == GetOpeningTag()) { return CreateEmptyFold(position, foldingPositions); } return text == GetClosingTag() ? RebuildFolds(position, foldingPositions) : null; }
public void Deselect() { lastSelectionStart = null; lastSelectionEnd = null; isSelecting = false; visuals.Clear(); }
public TextPosition GetSelectionPosition(KeyEventArgs keyboardEvent) { TextPosition endingPosition = null; switch (keyboardEvent.Key) { case Key.Left: endingPosition = new TextPosition(column: caretViewReader.CaretPosition.Column - 1, line: caretViewReader.CaretPosition.Line); break; case Key.Home: endingPosition = new TextPosition(column: 0, line: caretViewReader.CaretPosition.Line); break; case Key.Right: endingPosition = new TextPosition(column: caretViewReader.CaretPosition.Column + 1, line: caretViewReader.CaretPosition.Line); break; case Key.End: endingPosition = new TextPosition(column: textViewReader.GetLineLength(caretViewReader.CaretPosition.Line), line: caretViewReader.CaretPosition.Line); break; case Key.Up: endingPosition = new TextPosition(column: caretViewReader.CaretPosition.Column, line: caretViewReader.CaretPosition.Line - 1); break; case Key.PageUp: endingPosition = new TextPosition(column: caretViewReader.CaretPosition.Column, line: caretViewReader.CaretPosition.Line - GlobalConstants.PageSize); break; case Key.Down: endingPosition = new TextPosition(column: caretViewReader.CaretPosition.Column, line: caretViewReader.CaretPosition.Line + 1); break; case Key.PageDown: endingPosition = new TextPosition(column: caretViewReader.CaretPosition.Column, line: caretViewReader.CaretPosition.Line + GlobalConstants.PageSize); break; } return endingPosition; }
private IEnumerable<PointsPair> GetSelectionPointsForward(TextPosition start, TextPosition end) { var pairs = new List<PointsPair>(); for (var i = start.Line; i <= end.Line; i++) { var tmpStartColumn = 0; var tmpStartLine = i; var tmpEndColumn = 0; var tmpEndLine = i; if (i == start.Line) { tmpStartColumn = start.Column; } var lineLen = textViewReader.GetLineLength(i); if (i == end.Line) { tmpEndColumn = end.Column > lineLen ? lineLen : end.Column; } else { tmpEndColumn = lineLen; } pairs.Add(new PointsPair { StartingPoint = (new TextPosition(column: tmpStartColumn, line: tmpStartLine)).GetPositionRelativeToParent(TextConfiguration.GetCharSize()) .AlignToVisualLineTop(TextConfiguration.GetCharSize()), EndingPoint = (new TextPosition(column: tmpEndColumn, line: tmpEndLine)).GetPositionRelativeToParent(TextConfiguration.GetCharSize()) .AlignToVisualLineBottom(TextConfiguration.GetCharSize()) }); } return pairs; }
public void Execute(object parameter) { var keyboardEvent = parameter as KeyEventArgs; var mouseEvent = parameter as MouseButtonEventArgs; TextPosition newPos = null; if (keyboardEvent != null) { newPos = caretView.GetNextPosition(keyboardEvent.Key); keyboardEvent.Handled = true; } else if (mouseEvent != null) { newPos = mouseEvent.GetPosition(caretView).GetDocumentPosition(TextConfiguration.GetCharSize()); } if (newPos == null) { return; } int column = -1, line = -1; if (newPos.Column > textViewReader.GetLineLength(newPos.Line)) { column = textViewReader.GetLineLength(newPos.Line); } if (newPos.Line >= textViewReader.LinesCount) { line = textViewReader.LinesCount - 1; } var moveDir = GetMoveDirection(newPos, caretView.CaretPosition); newPos = new TextPosition(column > -1 ? column : newPos.Column, line > -1 ? line : newPos.Line); newPos = textViewReader.AdjustStep(newPos, moveDir); caretView.MoveCursor(newPos); }
public ChangeInLinesInfo GetChangeInLines(IReadOnlyList<VisualTextLine> lines, TextPosition startingTextPosition, Key key) { if (key == Key.Delete) { var isStartEqToTextLen = startingTextPosition.Column == lines[startingTextPosition.Line].Length; if (isStartEqToTextLen && startingTextPosition.Line == lines.Count) { return new ChangeInLinesInfo { LinesToChange = new Dictionary<TextPosition, VisualTextLine>(), LinesToRemove = new int[0] }; } if (isStartEqToTextLen) { return DeleteNextLine(lines, startingTextPosition); } return DeleteFromActiveLine(lines, startingTextPosition); } var isStartEqZero = startingTextPosition.Column == 0; if (isStartEqZero && startingTextPosition.Line == 0) { return new ChangeInLinesInfo { LinesToChange = new Dictionary<TextPosition, VisualTextLine>(), LinesToRemove = new[] { startingTextPosition.Line } }; } if (isStartEqZero) { return RemoveThisLine(lines, startingTextPosition); } return RemoveFromActiveLine(lines, startingTextPosition); }
public TextPosition DeleteFolds(string text, TextPosition position, IDictionary<TextPosition, TextPosition> foldingPositions) { if (text == GetOpeningTag() || text == GetCollapsibleRepresentation()) { return position; } return text == GetClosingTag() ? DeleteFoldForClosePosition(position, foldingPositions) : null; }
private IReadOnlyDictionary<int, string> TabPressed(IReadOnlyList<string> lines, string text, TextPosition startingTextPosition) { var textBeforeCursorPosition = string.Concat(lines[startingTextPosition.Line].Take(startingTextPosition.Column)); var textAfterCursorPosition = string.Concat(lines[startingTextPosition.Line].Skip(startingTextPosition.Column)); return new Dictionary<int, string> { [startingTextPosition.Line] = textBeforeCursorPosition + new string(' ', TextProperties.Properties.TabSize) + textAfterCursorPosition }; }
public void Draw(TextPosition position) { var formattedText = GetFormattedText(Symbol, runProperties); var textLocation = new Point(position.Column * charSize.Width - charSize.Width / 2, position.Line * charSize.Height); using (var drawingContext = RenderOpen()) { drawingContext.DrawText(formattedText, textLocation); } }
public void Select(TextPosition position) { var selection = new VisualElement(); visuals.Clear(); SetSelectionState(position); selection.Draw(GetSelectionPoints(lastSelectionStart, lastSelectionEnd)); visuals.Add(selection); }
private IEnumerable<PointsPair> GetSelectionPoints(TextPosition start, TextPosition end) { visuals.Clear(); if (start.Line <= end.Line) { return GetSelectionPointsForward(start, end); } return GetSelectionPointsInverted(start, end); }
public TextPosition AdjustStep(TextPosition newPosition, CaretMoveDirection moveDirection) { var line = ((VisualTextLine)visuals[newPosition.Line]); var charInfo = line.RenderedText != string.Empty && newPosition.Column < GetLineLength(newPosition.Line) ? line.GetCharInfoAt(newPosition.Column) : null; if (charInfo != null) { return charInfo.IsCharacter ? newPosition : GetAdjustedPosition(charInfo, moveDirection); } return newPosition; }
public bool IsInTextRange(TextPosition position) { if (position.Column < 0 || position.Line < 0) { return false; } if (position.Line >= LinesCount) { return false; } return position.Column <= GetLineLength(position.Line); }
private void SetSelectionState(TextPosition position) { if (!isSelecting) { isSelecting = true; lastSelectionStart = position; lastSelectionEnd = lastSelectionStart; } else { lastSelectionEnd = position; } }
private IDictionary<TextPosition, TextPosition> CreateEmptyFold(TextPosition position, IDictionary<TextPosition, TextPosition> foldingPositions) { TextPosition outVal; foldingPositions.TryGetValue(position, out outVal); var tmpDict = new Dictionary<TextPosition, TextPosition>(foldingPositions); tmpDict[position] = outVal; return tmpDict; }
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 SelectionInfo LineSelection(MouseButtonEventArgs mouseEvent) { var clickPosition = mouseEvent.GetPosition(parent).GetDocumentPosition(TextConfiguration.GetCharSize()); var startPosition = new TextPosition(column: 0, line: clickPosition.Line); var endPosition = new TextPosition(column: textViewReader.GetLineLength(clickPosition.Line), line: clickPosition.Line); var cursorColumn = clickPosition.Line + 1 < textViewReader.LinesCount ? 0 : textViewReader.GetLineLength(clickPosition.Line); var cursorLine = clickPosition.Line + 1 < textViewReader.LinesCount ? clickPosition.Line + 1 : clickPosition.Line; return new SelectionInfo { StartPosition = startPosition, EndPosition = endPosition, CursorPosition = new TextPosition(column: cursorColumn, line: cursorLine) }; }
public IReadOnlyDictionary<int, string> GetChangeInLines(IReadOnlyList<string> lines, TextPosition startingTextPosition, string text) { var replacedText = SpecialCharsRegex.Replace(text, string.Empty); if (text == TextProperties.Properties.NEWLINE) { return LineAdded(lines, text, startingTextPosition); } else if (text == TextProperties.Properties.TAB) { return TabPressed(lines, text, startingTextPosition); } else if (replacedText.Length == 1) { return CharacterEntered(lines, replacedText, startingTextPosition); } else { return TextPasted(lines, text, startingTextPosition); } }
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 IReadOnlyDictionary<int, string> LineAdded(IReadOnlyList<string> lines, string text, TextPosition startingTextPosition) { var textBeforeCursorPosition = string.Concat(lines[startingTextPosition.Line].Take(startingTextPosition.Column)); var textAfterCursorPosition = string.Concat(lines[startingTextPosition.Line].Skip(startingTextPosition.Column)); var transformations = new Dictionary<int, string> { [startingTextPosition.Line] = textBeforeCursorPosition, [startingTextPosition.Line + 1] = textAfterCursorPosition }; for (var i = startingTextPosition.Line + 1; i < lines.Count; i++) { transformations[i + 1] = lines[i]; } return transformations; }
private Dictionary<TextPosition, TextPosition> UpdateFolds(Dictionary<TextPosition, TextPosition> newFolds, TextPosition keyToUpdate, TextPosition foldValue) { var nextPositions = newFolds.Where(kvp => kvp.Key > keyToUpdate).OrderBy(kvp => kvp.Key); var oldPosition = newFolds[keyToUpdate]; newFolds[keyToUpdate] = foldValue; foreach (var kvp in nextPositions) { var tmpPosition = kvp.Value; newFolds[kvp.Key] = oldPosition; oldPosition = tmpPosition; } return newFolds; }
private IDictionary<TextPosition, TextPosition> RebuildFolds(TextPosition position, IDictionary<TextPosition, TextPosition> foldingPositions) { var newFolds = new Dictionary<TextPosition, TextPosition>(foldingPositions); var candidates = foldingPositions.Where(kvp => position > kvp.Key && (kvp.Value == null || position < kvp.Value)); var closestCandidate = candidates.Max(kvp => kvp.Key); if (closestCandidate != null) { if (newFolds[closestCandidate] == null) { newFolds[closestCandidate] = position; } else { newFolds = UpdateFolds(newFolds, closestCandidate, position); } } return newFolds; }
private IReadOnlyDictionary<int, string> CharacterEntered(IReadOnlyList<string> lines, string text, TextPosition startingTextPosition) { var currentTextLine = new StringBuilder(); if (lines.Any()) { if (startingTextPosition.Column >= lines[startingTextPosition.Line].Length) { currentTextLine.Append(lines[startingTextPosition.Line]).Append(text); } else { currentTextLine.Append(lines[startingTextPosition.Line]).Insert(startingTextPosition.Column, text); } } else { currentTextLine.Append(text); } return new Dictionary<int, string> { [startingTextPosition.Line] = currentTextLine.ToString() }; }
public IEnumerable<string> GetTextPartsBetweenPositions(TextPosition startPosition, TextPosition endPosition) { var parts = visuals.ToEnumerableOf<VisualTextLine>().SelectMany(line => line.GetStringContents()).ToList(); if (parts.Count == 0) { return parts; } if (startPosition.Line == endPosition.Line) { parts[0] = string.Join("", parts[0].Skip(startPosition.Column).Take(endPosition.Column - startPosition.Column)); } else { parts[0] = parts[0].Substring(startPosition.Column); } var lastIndex = parts.Count - 1; var substringTo = endPosition.Column; if (startPosition.Line == endPosition.Line) { substringTo = endPosition.Column - startPosition.Column; } parts[lastIndex] = string.Join("", parts[lastIndex].Take(substringTo)); return parts; }
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 HandleTextRemove(TextPosition newPosition) => MoveCaret(newPosition);
public char GetCharAt(TextPosition position) { var info = ((VisualTextLine)visuals[position.Line]).GetCharInfoAt(position.Column); return info.IsCharacter ? info.Text[0] : default(char); }
public void MoveCursor(TextPosition newPos) => MoveCaret(newPos);
private TextPosition DeleteFoldForClosePosition(TextPosition position, IDictionary<TextPosition, TextPosition> foldingPositions) { var pair = foldingPositions.Where(kvp => kvp.Value == position).FirstOrDefault(); return pair.Key; }
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 } }; }