public override void DoOn() { ViReceiverData startData = this.startData; this.startData = null; if (controller.macrosExecutor != null && controller.macrosExecutor.lastCommand != null && startData != null) { controller.macrosExecutor.lastCommand.startData = startData; } foreach (Selection selection in controller.Selections) { selection.SetEmpty(); } if (startData != null) { ClipboardExecutor.viLastInputChars = startData.inputChars; if (startData.action == 'o' || startData.action == 'O') { for (int i = startData.forcedInput ? 0 : 1; i < startData.count; i++) { if (i > 0) { controller.InsertLineBreak(); } foreach (char c in startData.inputChars) { ProcessInputChar(c); } } } else { for (int i = startData.forcedInput ? 0 : 1; i < startData.count; i++) { foreach (char c in startData.inputChars) { ProcessInputChar(c); } } } } controller.processor.ResetCommandsBatching(); if (offsetOnStart) { for (int i = 0; i < lines.selections.Count; i++) { Selection selection = lines.selections[i]; if (selection.Empty) { Place place = lines.PlaceOf(selection.caret); if (place.iChar > 0) { selection.anchor--; selection.caret--; if (selection.preferredPos > 0) { selection.preferredPos--; } } } } } }
public void RemoveText(int index, int count) { if (index < 0 || index + count > charsCount) { throw new IndexOutOfRangeException("text index=" + index + ", count=" + count + " is out of [0, " + charsCount + "]"); } if (count == 0) { return; } int blockI; int blockIChar; Place place = PlaceOf(index, out blockI, out blockIChar); LineBlock block = blocks[blockI]; int startJ = place.iLine - block.offset; Line start = block.array[startJ]; if (place.iChar + count <= start.charsCount) { start.Chars_RemoveRange(place.iChar, count); start.cachedText = null; start.cachedSize = -1; start.endState = null; start.wwSizeX = 0; block.valid = 0; block.wwSizeX = 0; int startCharsCount = start.charsCount; bool mergeNext = true; if (startCharsCount == 1 && start.chars[0].c == '\n') { mergeNext = false; if (place.iLine > 0) { Line prev; if (startJ - 1 >= 0) { prev = block.array[startJ - 1]; } else { block = blocks[blockI - 1]; block.valid = 0; block.wwSizeX = 0; prev = block.array[block.count - 1]; } if (prev.chars[prev.charsCount - 1].c == '\r') { RemoveValueAt(place.iLine); prev.Chars_Add(new Char('\n')); prev.cachedText = null; prev.cachedSize = -1; prev.endState = null; prev.wwSizeX = 0; } } } else if (startCharsCount > 0) { char c = start.chars[startCharsCount - 1].c; mergeNext = c != '\n' && c != '\r'; } if (mergeNext && place.iLine + 1 < valuesCount) { Line line = startJ + 1 < block.count ? block.array[startJ + 1] : blocks[blockI + 1].array[0]; start.Chars_AddRange(line); RemoveValueAt(place.iLine + 1); } } else { LineBlock prevBlock = block; int prevBlockI = blockI; block.valid = 0; block.wwSizeX = 0; int lineJ = startJ; int k = start.charsCount - place.iChar; int countToRemove = -1; Line line = start; while (k < count) { lineJ++; ++countToRemove; if (lineJ >= block.count) { blockI++; block = blocks[blockI]; lineJ = 0; } line = block.array[lineJ]; k += line.charsCount; } Line end = line; start.Chars_RemoveRange(place.iChar, start.charsCount - place.iChar); // fails start.cachedText = null; start.cachedSize = -1; start.endState = null; start.wwSizeX = 0; end.Chars_RemoveRange(0, count + end.charsCount - k); end.cachedText = null; end.cachedSize = -1; end.wwSizeX = 0; end.Chars_ReduceBuffer(); start.Chars_AddRange(end); int removeStart = place.iLine + 1; int startCharsCount = start.charsCount; bool mergeNext = true; if (startCharsCount == 1 && start.chars[0].c == '\n') { mergeNext = false; if (place.iLine > 0) { Line prev; if (startJ - 1 >= 0) { prev = prevBlock.array[startJ - 1]; } else { prevBlock = blocks[prevBlockI - 1]; prevBlock.valid = 0; prevBlock.wwSizeX = 0; prev = prevBlock.array[prevBlock.count - 1]; } if (prev.chars[prev.charsCount - 1].c == '\r') { --removeStart; ++countToRemove; prev.Chars_Add(new Char('\n')); prev.cachedText = null; prev.cachedSize = -1; prev.endState = null; prev.wwSizeX = 0; } } } else if (startCharsCount > 0) { char c = start.chars[startCharsCount - 1].c; mergeNext = c != '\n' && c != '\r'; } if (mergeNext && block.offset + lineJ + 1 < valuesCount) { Line next = lineJ + 1 < block.count ? block.array[lineJ + 1] : blocks[blockI + 1].array[0]; start.Chars_AddRange(next); ++countToRemove; } ++countToRemove; RemoveValuesRange(removeStart, countToRemove); } start.Chars_ReduceBuffer(); charsCount -= count; size = null; wwSizeX = 0; ResetTextCache(); if (hook != null) { hook.RemoveText(index, count); } if (hook2 != null) { hook2.RemoveText(index, count); } }
public Pos UniversalPosOf(Place place) { return(wordWrap ? wwValidator.PosOf(place) : PosOf(place)); }
public void InsertText(int index, string text) { if (index < 0 || index > charsCount) { throw new IndexOutOfRangeException( "text index=" + index + ", count=" + text.Length + " is out of [0, " + charsCount + "]"); } if (text.Length == 0) { return; } int blockI; int blockIChar; Place place = PlaceOf(index, out blockI, out blockIChar); LineBlock block = blocks[blockI]; int startJ = place.iLine - block.offset; Line start = block.array[startJ]; if (place.iChar == start.charsCount - 1 && start.charsCount >= 2 && start.chars[start.charsCount - 2].c == '\r' && start.chars[start.charsCount - 1].c == '\n') { start.Chars_RemoveAt(start.charsCount - 1); start.cachedText = null; start.cachedSize = -1; start.endState = null; start.wwSizeX = 0; block.valid = 0; block.wwSizeX = 0; start = NewLine("\n", 0, 1); place.iLine++; place.iChar = 0; InsertValue(place.iLine, start); } if (text.IndexOf('\n') == -1 && text.IndexOf('\r') == -1) { start.Chars_InsertRange(place.iChar, text); start.cachedText = null; start.cachedSize = -1; start.endState = null; start.wwSizeX = 0; block.valid = 0; block.wwSizeX = 0; } else { int textLength = text.Length; int lineStart = 0; List <Line> lines = new List <Line>(); for (int i = 0; i < textLength; i++) { char c = text[i]; if (c == '\r') { if (i + 1 < textLength && text[i + 1] == '\n') { i++; } lines.Add(NewLine(text, lineStart, i + 1 - lineStart)); lineStart = i + 1; } else if (c == '\n') { lines.Add(NewLine(text, lineStart, i + 1 - lineStart)); lineStart = i + 1; } } lines.Add(NewLine(text, lineStart, textLength - lineStart)); Line line0 = lines[0]; line0.Chars_InsertRange(0, start, 0, place.iChar); line0.cachedText = null; line0.cachedSize = -1; line0.wwSizeX = 0; if (place.iLine > 0 && line0.charsCount > 0 && line0.chars[0].c == '\n') { int prevBlockI = GetBlockIndex(place.iLine - 1); LineBlock prevBlock = blocks[prevBlockI]; Line prev = prevBlock.array[place.iLine - 1 - prevBlock.offset]; if (prev.chars[prev.charsCount - 1].c == '\r') { line0.Chars_RemoveAt(0); prev.Chars_Add(new Char('\n')); prev.cachedText = null; prev.cachedSize = -1; prev.endState = null; prev.wwSizeX = 0; prevBlock.valid = 0; prevBlock.wwSizeX = 0; if (line0.charsCount == 0) { lines.RemoveAt(0); } } } Line line1 = lines[lines.Count - 1]; line1.Chars_AddRange(start, place.iChar, start.charsCount - place.iChar); line1.cachedText = null; line1.cachedSize = -1; line1.wwSizeX = 0; if (line1.charsCount == 1 && line1.chars[0].c == '\n' && lines.Count > 1) { Line prevLine1 = lines[lines.Count - 2]; if (prevLine1.chars[prevLine1.charsCount - 1].c == '\r') { prevLine1.Chars_Add(new Char('\n')); lines.RemoveAt(lines.Count - 1); } } RemoveValueAt(place.iLine); InsertValuesRange(place.iLine, lines.ToArray()); } charsCount += text.Length; size = null; wwSizeX = 0; ResetTextCache(); if (hook != null) { hook.InsertText(index, text); } if (hook2 != null) { hook2.InsertText(index, text); } }