diff options
Diffstat (limited to 'src/CellBuffer.cxx')
| -rw-r--r-- | src/CellBuffer.cxx | 500 | 
1 files changed, 159 insertions, 341 deletions
diff --git a/src/CellBuffer.cxx b/src/CellBuffer.cxx index bd124d011..7096d4419 100644 --- a/src/CellBuffer.cxx +++ b/src/CellBuffer.cxx @@ -14,6 +14,8 @@  #include "Scintilla.h"  #include "SVector.h" +#include "SplitVector.h" +#include "Partitioning.h"  #include "CellBuffer.h"  MarkerHandleSet::MarkerHandleSet() { @@ -30,7 +32,7 @@ MarkerHandleSet::~MarkerHandleSet() {  	root = 0;  } -int MarkerHandleSet::Length() { +int MarkerHandleSet::Length() const {  	int c = 0;  	MarkerHandleNumber *mhn = root;  	while (mhn) { @@ -40,7 +42,7 @@ int MarkerHandleSet::Length() {  	return c;  } -int MarkerHandleSet::NumberFromHandle(int handle) { +int MarkerHandleSet::NumberFromHandle(int handle) const {  	MarkerHandleNumber *mhn = root;  	while (mhn) {  		if (mhn->handle == handle) { @@ -51,7 +53,7 @@ int MarkerHandleSet::NumberFromHandle(int handle) {  	return - 1;  } -int MarkerHandleSet::MarkValue() { +int MarkerHandleSet::MarkValue() const {  	unsigned int m = 0;  	MarkerHandleNumber *mhn = root;  	while (mhn) { @@ -61,7 +63,7 @@ int MarkerHandleSet::MarkValue() {  	return m;  } -bool MarkerHandleSet::Contains(int handle) { +bool MarkerHandleSet::Contains(int handle) const {  	MarkerHandleNumber *mhn = root;  	while (mhn) {  		if (mhn->handle == handle) { @@ -90,7 +92,7 @@ void MarkerHandleSet::RemoveHandle(int handle) {  		if (mhn->handle == handle) {  			*pmhn = mhn->next;  			delete mhn; -			return ; +			return;  		}  		pmhn = &((*pmhn)->next);  	} @@ -121,210 +123,154 @@ void MarkerHandleSet::CombineWith(MarkerHandleSet *other) {  	other->root = 0;  } -LineVector::LineVector() { -	linesData = 0; -	lines = 0; -	size = 0; -	levels = 0; -	sizeLevels = 0; +LineVector::LineVector() : starts(256) {  	handleCurrent = 1; -	growSize = 1000;  	Init();  }  LineVector::~LineVector() { -	for (int line = 0; line < lines; line++) { -		delete linesData[line].handleSet; -		linesData[line].handleSet = 0; +	starts.DeleteAll(); +	for (int line = 0; line < markers.Length(); line++) { +		delete markers[line]; +		markers[line] = 0;  	} -	delete []linesData; -	linesData = 0; -	delete []levels; -	levels = 0; +	markers.DeleteAll(); +	levels.DeleteAll();  }  void LineVector::Init() { -	for (int line = 0; line < lines; line++) { -		delete linesData[line].handleSet; -		linesData[line].handleSet = 0; +	starts.DeleteAll(); +	for (int line = 0; line < markers.Length(); line++) { +		delete markers[line]; +		markers[line] = 0;  	} -	delete []linesData; -	linesData = new LineData[static_cast<int>(growSize)]; -	size = growSize; -	lines = 1; -	delete []levels; -	levels = 0; -	sizeLevels = 0; -} - -void LineVector::Expand(int sizeNew) { -	LineData *linesDataNew = new LineData[sizeNew]; -	if (linesDataNew) { -		for (int i = 0; i < size; i++) -			linesDataNew[i] = linesData[i]; -		// Do not delete handleSets here as they are transferred to new linesData -		delete []linesData; -		linesData = linesDataNew; -		size = sizeNew; -	} else { -		Platform::DebugPrintf("No memory available\n"); -		// TODO: Blow up -	} - +	markers.DeleteAll(); +	levels.DeleteAll();  }  void LineVector::ExpandLevels(int sizeNew) { -	if (sizeNew == -1) -		sizeNew = size; -	int *levelsNew = new int[sizeNew]; -	if (levelsNew) { -		int i = 0; -		for (; i < sizeLevels; i++) -			levelsNew[i] = levels[i]; -		for (; i < sizeNew; i++) -			levelsNew[i] = SC_FOLDLEVELBASE; -		delete []levels; -		levels = levelsNew; -		sizeLevels = sizeNew; -	} else { -		Platform::DebugPrintf("No memory available\n"); -		// TODO: Blow up -	} - +	levels.InsertValue(levels.Length(), sizeNew - levels.Length(), SC_FOLDLEVELBASE);  }  void LineVector::ClearLevels() { -	delete []levels; -	levels = 0; -	sizeLevels = 0; -} - -void LineVector::InsertValue(int pos, int value) { -	//Platform::DebugPrintf("InsertValue[%d] = %d\n", pos, value); -	if ((lines + 2) >= size) { -		if (growSize * 6 < size) -			growSize *= 2; -		Expand(size + growSize); -		if (levels) { -			ExpandLevels(size + growSize); -		} -	} -	lines++; -	for (int i = lines; i > pos; i--) { -		linesData[i] = linesData[i - 1]; -	} -	linesData[pos].startPosition = value; -	linesData[pos].handleSet = 0; -	if (levels) { -		for (int j = lines; j > pos; j--) { -			levels[j] = levels[j - 1]; +	levels.DeleteAll(); +} + +int LineVector::SetLevel(int line, int level) { +	int prev = 0; +	if ((line >= 0) && (line < Lines())) { +		if (!levels.Length()) { +			ExpandLevels(Lines() + 1);  		} -		if (pos == 0) { -			levels[pos] = SC_FOLDLEVELBASE; -		} else if (pos == (lines - 1)) {	// Last line will not be a folder -			levels[pos] = SC_FOLDLEVELBASE; -		} else { -			levels[pos] = levels[pos - 1] & ~SC_FOLDLEVELWHITEFLAG; +		prev = levels[line]; +		if (prev != level) { +			levels[line] = level;  		}  	} +	return prev;  } -void LineVector::SetValue(int pos, int value) { -	//Platform::DebugPrintf("SetValue[%d] = %d\n", pos, value); -	if ((pos + 2) >= size) { -		//Platform::DebugPrintf("Resize %d %d\n", size,pos); -		Expand(pos + growSize); -		//Platform::DebugPrintf("end Resize %d %d\n", size,pos); -		lines = pos; -		if (levels) { -			ExpandLevels(pos + growSize); +int LineVector::GetLevel(int line) { +	if (levels.Length() && (line >= 0) && (line < Lines())) { +		return levels[line]; +	} else { +		return SC_FOLDLEVELBASE; +	} +} + +void LineVector::InsertText(int line, int delta) { +	starts.InsertText(line, delta); +} + +void LineVector::InsertLine(int line, int position) { +	starts.InsertPartition(line, position); +	if (markers.Length()) { +		markers.Insert(line, 0); +	} +	if (levels.Length()) { +		int level = SC_FOLDLEVELBASE; +		if ((line > 0) && (line < Lines())) { +			level = levels[line-1] & ~SC_FOLDLEVELWHITEFLAG;  		} +		levels.InsertValue(line, 1, level);  	} -	linesData[pos].startPosition = value;  } -void LineVector::Remove(int pos) { -	//Platform::DebugPrintf("Remove %d\n", pos); +void LineVector::SetLineStart(int line, int position) { +	starts.SetPartitionStartPosition(line, position); +} + +void LineVector::RemoveLine(int line) { +	starts.RemovePartition(line);  	// Retain the markers from the deleted line by oring them into the previous line -	if (pos > 0) { -		MergeMarkers(pos - 1); -	} -	for (int i = pos; i < lines; i++) { -		linesData[i] = linesData[i + 1]; +	if (markers.Length()) { +		if (line > 0) { +			MergeMarkers(line - 1); +		} +		markers.Delete(line);  	} -	if (levels) { +	if (levels.Length()) {  		// Move up following lines but merge header flag from this line  		// to line before to avoid a temporary disappearence causing expansion. -		int firstHeader = levels[pos] & SC_FOLDLEVELHEADERFLAG; -		for (int j = pos; j < lines; j++) { -			levels[j] = levels[j + 1]; -		} -		if (pos > 0) -			levels[pos-1] |= firstHeader; +		int firstHeader = levels[line] & SC_FOLDLEVELHEADERFLAG; +		levels.Delete(line); +		if (line > 0) +			levels[line-1] |= firstHeader;  	} -	lines--;  }  int LineVector::LineFromPosition(int pos) { -	//Platform::DebugPrintf("LineFromPostion %d lines=%d end = %d\n", pos, lines, linesData[lines].startPosition); -	if (lines == 0) +	return starts.PartitionFromPosition(pos); +} + +int LineVector::MarkValue(int line) { +	if (markers.Length() && markers.ValueAt(line)) +		return markers.ValueAt(line)->MarkValue(); +	else  		return 0; -	//Platform::DebugPrintf("LineFromPosition %d\n", pos); -	if (pos >= linesData[lines].startPosition) -		return lines - 1; -	int lower = 0; -	int upper = lines; -	do { -		int middle = (upper + lower + 1) / 2; 	// Round high -		if (pos < linesData[middle].startPosition) { -			upper = middle - 1; -		} else { -			lower = middle; -		} -	} while (lower < upper); -	//Platform::DebugPrintf("LineFromPostion %d %d %d\n", pos, lower, linesData[lower].startPosition, linesData[lower > 1 ? lower - 1 : 0].startPosition); -	return lower;  }  int LineVector::AddMark(int line, int markerNum) {  	handleCurrent++; -	if (!linesData[line].handleSet) { +	if (!markers.Length()) { +		// No existing markers so allocate one element per line +		markers.InsertValue(0, Lines(), 0); +	} +	if (!markers[line]) {  		// Need new structure to hold marker handle -		linesData[line].handleSet = new MarkerHandleSet; -		if (!linesData[line].handleSet) +		markers[line] = new MarkerHandleSet(); +		if (!markers[line])  			return - 1;  	} -	linesData[line].handleSet->InsertHandle(handleCurrent, markerNum); +	markers[line]->InsertHandle(handleCurrent, markerNum);  	return handleCurrent;  }  void LineVector::MergeMarkers(int pos) { -	if (linesData[pos + 1].handleSet != NULL) { -		if (linesData[pos].handleSet == NULL ) -			linesData[pos].handleSet = new MarkerHandleSet; -		linesData[pos].handleSet->CombineWith(linesData[pos + 1].handleSet); -		delete linesData[pos + 1].handleSet; -		linesData[pos + 1].handleSet = NULL; +	if (markers[pos + 1] != NULL) { +		if (markers[pos] == NULL) +			markers[pos] = new MarkerHandleSet; +		markers[pos]->CombineWith(markers[pos + 1]); +		delete markers[pos + 1]; +		markers[pos + 1] = NULL;  	}  }  void LineVector::DeleteMark(int line, int markerNum, bool all) { -	if (linesData[line].handleSet) { +	if (markers.Length() && markers[line]) {  		if (markerNum == -1) { -			delete linesData[line].handleSet; -			linesData[line].handleSet = 0; +			delete markers[line]; +			markers[line] = NULL;  		} else { -			bool performedDeletion = -				linesData[line].handleSet->RemoveNumber(markerNum); +			bool performedDeletion = markers[line]->RemoveNumber(markerNum);  			while (all && performedDeletion) { -				performedDeletion = -					linesData[line].handleSet->RemoveNumber(markerNum); +				performedDeletion = markers[line]->RemoveNumber(markerNum);  			} -			if (linesData[line].handleSet->Length() == 0) { -				delete linesData[line].handleSet; -				linesData[line].handleSet = 0; +			if (markers[line]->Length() == 0) { +				delete markers[line]; +				markers[line] = NULL;  			}  		}  	} @@ -333,23 +279,25 @@ void LineVector::DeleteMark(int line, int markerNum, bool all) {  void LineVector::DeleteMarkFromHandle(int markerHandle) {  	int line = LineFromHandle(markerHandle);  	if (line >= 0) { -		linesData[line].handleSet->RemoveHandle(markerHandle); -		if (linesData[line].handleSet->Length() == 0) { -			delete linesData[line].handleSet; -			linesData[line].handleSet = 0; +		markers[line]->RemoveHandle(markerHandle); +		if (markers[line]->Length() == 0) { +			delete markers[line]; +			markers[line] = NULL;  		}  	}  }  int LineVector::LineFromHandle(int markerHandle) { -	for (int line = 0; line < lines; line++) { -		if (linesData[line].handleSet) { -			if (linesData[line].handleSet->Contains(markerHandle)) { -				return line; +	if (markers.Length()) { +		for (int line = 0; line < Lines(); line++) { +			if (markers[line]) { +				if (markers[line]->Contains(markerHandle)) { +					return line; +				}  			}  		}  	} -	return - 1; +	return -1;  }  Action::Action() { @@ -437,7 +385,7 @@ void UndoHistory::EnsureUndoRoom() {  		int lenActionsNew = lenActions * 2;  		Action *actionsNew = new Action[lenActionsNew];  		if (!actionsNew) -			return ; +			return;  		for (int act = 0; act <= currentAction; act++)  			actionsNew[act].Grab(&actions[act]);  		delete []actions; @@ -488,7 +436,7 @@ void UndoHistory::AppendAction(actionType at, int position, char *data, int leng  					currentAction++;  				}  			} else { -				//Platform::DebugPrintf("action coalesced\n"); +				// Action coalesced.  			}  		} else { @@ -603,91 +551,12 @@ void UndoHistory::CompletedRedoStep() {  	currentAction++;  } -CellBuffer::CellBuffer(int initialLength) { -	body = new char[initialLength]; -	size = initialLength; -	length = 0; -	part1len = 0; -	gaplen = initialLength; -	part2body = body + gaplen; +CellBuffer::CellBuffer() {  	readOnly = false;  	collectingUndo = true; -	growSize = 4000;  }  CellBuffer::~CellBuffer() { -	delete []body; -	body = 0; -} - -void CellBuffer::GapTo(int position) { -	if (position == part1len) -		return ; -	if (position < part1len) { -		int diff = part1len - position; -		//Platform::DebugPrintf("Move gap backwards to %d diff = %d part1len=%d length=%d \n", position,diff, part1len, length); -		for (int i = 0; i < diff; i++) -			body[part1len + gaplen - i - 1] = body[part1len - i - 1]; -	} else {	// position > part1len -		int diff = position - part1len; -		//Platform::DebugPrintf("Move gap forwards to %d diff =%d\n", position,diff); -		for (int i = 0; i < diff; i++) -			body[part1len + i] = body[part1len + gaplen + i]; -	} -	part1len = position; -	part2body = body + gaplen; -} - -void CellBuffer::RoomFor(int insertionLength) { -	//Platform::DebugPrintf("need room %d %d\n", gaplen, insertionLength); -	if (gaplen <= insertionLength) { -		//Platform::DebugPrintf("need room %d %d\n", gaplen, insertionLength); -		if (growSize * 6 < size) -			growSize *= 2; -		int newSize = size + insertionLength + growSize; -		Allocate(newSize); -	} -} - -// To make it easier to write code that uses ByteAt, a position outside the range of the buffer -// can be retrieved. All characters outside the range have the value '\0'. -char CellBuffer::ByteAt(int position) { -	if (position < part1len) { -		if (position < 0) { -			return '\0'; -		} else { -			return body[position]; -		} -	} else { -		if (position >= length) { -			return '\0'; -		} else { -			return part2body[position]; -		} -	} -} - -void CellBuffer::SetByteAt(int position, char ch) { - -	if (position < 0) { -		//Platform::DebugPrintf("Bad position %d\n",position); -		return ; -	} -	if (position >= length + 11) { -		Platform::DebugPrintf("Very Bad position %d of %d\n", position, length); -		//exit(2); -		return ; -	} -	if (position >= length) { -		//Platform::DebugPrintf("Bad position %d of %d\n",position,length); -		return ; -	} - -	if (position < part1len) { -		body[position] = ch; -	} else { -		part2body[position] = ch; -	}  }  char CellBuffer::CharAt(int position) { @@ -696,20 +565,19 @@ char CellBuffer::CharAt(int position) {  void CellBuffer::GetCharRange(char *buffer, int position, int lengthRetrieve) {  	if (lengthRetrieve < 0) -		return ; +		return;  	if (position < 0) -		return ; +		return;  	int bytePos = position * 2; -	if ((bytePos + lengthRetrieve * 2) > length) { +	if ((bytePos + lengthRetrieve * 2) > body.Length()) {  		Platform::DebugPrintf("Bad GetCharRange %d for %d of %d\n", bytePos, -		                      lengthRetrieve, length); -		return ; +		                      lengthRetrieve, body.Length()); +		return;  	} -	GapTo(0); 	// Move the buffer so its easy to subscript into it -	char *pb = part2body + bytePos; +	int i = bytePos;  	while (lengthRetrieve--) { -		*buffer++ = *pb; -		pb += 2; +		*buffer++ = body.ValueAt(i); +		i += 2;  	}  } @@ -740,7 +608,7 @@ bool CellBuffer::SetStyleAt(int position, char style, char mask) {  	style &= mask;  	char curVal = ByteAt(position * 2 + 1);  	if ((curVal & mask) != style) { -		SetByteAt(position*2 + 1, static_cast<char>((curVal & ~mask) | style)); +		body.SetValueAt(position*2 + 1, static_cast<char>((curVal & ~mask) | style));  		return true;  	} else {  		return false; @@ -751,11 +619,11 @@ bool CellBuffer::SetStyleFor(int position, int lengthStyle, char style, char mas  	int bytePos = position * 2 + 1;  	bool changed = false;  	PLATFORM_ASSERT(lengthStyle == 0 || -		(lengthStyle > 0 && lengthStyle + position < length)); +		(lengthStyle > 0 && lengthStyle + position < body.Length()));  	while (lengthStyle--) {  		char curVal = ByteAt(bytePos);  		if ((curVal & mask) != style) { -			SetByteAt(bytePos, static_cast<char>((curVal & ~mask) | style)); +			body.SetValueAt(bytePos, static_cast<char>((curVal & ~mask) | style));  			changed = true;  		}  		bytePos += 2; @@ -783,38 +651,29 @@ const char *CellBuffer::DeleteChars(int position, int deleteLength, bool &startS  }  int CellBuffer::ByteLength() { -	return length; +	return body.Length();  }  int CellBuffer::Length() {  	return ByteLength() / 2;  } +  void CellBuffer::Allocate(int newSize) { -	if (newSize > length) { -		GapTo(length); -		char *newBody = new char[newSize]; -		memcpy(newBody, body, length); -		delete []body; -		body = newBody; -		gaplen += newSize - size; -		part2body = body + gaplen; -		size = newSize; -	} +	body.ReAllocate(newSize);  }  int CellBuffer::Lines() { -	//Platform::DebugPrintf("Lines = %d\n", lv.lines); -	return lv.lines; +	return lv.Lines();  }  int CellBuffer::LineStart(int line) {  	if (line < 0)  		return 0; -	else if (line > lv.lines) +	else if (line >= Lines())  		return Length();  	else -		return lv.linesData[line].startPosition; +		return lv.LineStart(line);  }  bool CellBuffer::IsReadOnly() { @@ -834,14 +693,14 @@ bool CellBuffer::IsSavePoint() {  }  int CellBuffer::AddMark(int line, int markerNum) { -	if ((line >= 0) && (line < lv.lines)) { +	if ((line >= 0) && (line < Lines())) {  		return lv.AddMark(line, markerNum);  	}  	return - 1;  }  void CellBuffer::DeleteMark(int line, int markerNum) { -	if ((line >= 0) && (line < lv.lines)) { +	if ((line >= 0) && (line < Lines())) {  		lv.DeleteMark(line, markerNum, false);  	}  } @@ -851,13 +710,13 @@ void CellBuffer::DeleteMarkFromHandle(int markerHandle) {  }  int CellBuffer::GetMark(int line) { -	if ((line >= 0) && (line < lv.lines) && (lv.linesData[line].handleSet)) -		return lv.linesData[line].handleSet->MarkValue(); +	if ((line >= 0) && (line < Lines())) +		return lv.MarkValue(line);  	return 0;  }  void CellBuffer::DeleteAllMarks(int markerNum) { -	for (int line = 0; line < lv.lines; line++) { +	for (int line = 0; line < Lines(); line++) {  		lv.DeleteMark(line, markerNum, true);  	}  } @@ -869,51 +728,38 @@ int CellBuffer::LineFromHandle(int markerHandle) {  // Without undo  void CellBuffer::BasicInsertString(int position, char *s, int insertLength) { -	//Platform::DebugPrintf("Inserting at %d for %d\n", position, insertLength);  	if (insertLength == 0) -		return ; +		return;  	PLATFORM_ASSERT(insertLength > 0); -	RoomFor(insertLength); -	GapTo(position); -	memcpy(body + part1len, s, insertLength); -	length += insertLength; -	part1len += insertLength; -	gaplen -= insertLength; -	part2body = body + gaplen; +	body.InsertFromArray(position, s, 0, insertLength);  	int lineInsert = lv.LineFromPosition(position / 2) + 1;  	// Point all the lines after the insertion point further along in the buffer -	for (int lineAfter = lineInsert; lineAfter <= lv.lines; lineAfter++) { -		lv.linesData[lineAfter].startPosition += insertLength / 2; -	} +	lv.InsertText(lineInsert-1, insertLength / 2);  	char chPrev = ' ';  	if ((position - 2) >= 0)  		chPrev = ByteAt(position - 2);  	char chAfter = ' '; -	if ((position + insertLength) < length) +	if ((position + insertLength) < body.Length())  		chAfter = ByteAt(position + insertLength);  	if (chPrev == '\r' && chAfter == '\n') { -		//Platform::DebugPrintf("Splitting a crlf pair at %d\n", lineInsert);  		// Splitting up a crlf pair at position -		lv.InsertValue(lineInsert, position / 2); +		lv.InsertLine(lineInsert, position / 2);  		lineInsert++;  	}  	char ch = ' ';  	for (int i = 0; i < insertLength; i += 2) {  		ch = s[i];  		if (ch == '\r') { -			//Platform::DebugPrintf("Inserting cr at %d\n", lineInsert); -			lv.InsertValue(lineInsert, (position + i) / 2 + 1); +			lv.InsertLine(lineInsert, (position + i) / 2 + 1);  			lineInsert++;  		} else if (ch == '\n') {  			if (chPrev == '\r') { -				//Platform::DebugPrintf("Patching cr before lf at %d\n", lineInsert-1);  				// Patch up what was end of line -				lv.SetValue(lineInsert - 1, (position + i) / 2 + 1); +				lv.SetLineStart(lineInsert - 1, (position + i) / 2 + 1);  			} else { -				//Platform::DebugPrintf("Inserting lf at %d\n", lineInsert); -				lv.InsertValue(lineInsert, (position + i) / 2 + 1); +				lv.InsertLine(lineInsert, (position + i) / 2 + 1);  				lineInsert++;  			}  		} @@ -922,44 +768,37 @@ void CellBuffer::BasicInsertString(int position, char *s, int insertLength) {  	// Joining two lines where last insertion is cr and following text starts with lf  	if (chAfter == '\n') {  		if (ch == '\r') { -			//Platform::DebugPrintf("Joining cr before lf at %d\n", lineInsert-1);  			// End of line already in buffer so drop the newly created one -			lv.Remove(lineInsert - 1); +			lv.RemoveLine(lineInsert - 1);  		}  	}  }  void CellBuffer::BasicDeleteChars(int position, int deleteLength) { -	//Platform::DebugPrintf("Deleting at %d for %d\n", position, deleteLength);  	if (deleteLength == 0) -		return ; +		return; -	if ((position == 0) && (deleteLength == length)) { +	if ((position == 0) && (deleteLength == body.Length())) {  		// If whole buffer is being deleted, faster to reinitialise lines data  		// than to delete each line. -		//printf("Whole buffer being deleted\n");  		lv.Init();  	} else {  		// Have to fix up line positions before doing deletion as looking at text in buffer  		// to work out which lines have been removed  		int lineRemove = lv.LineFromPosition(position / 2) + 1; -		// Point all the lines after the insertion point further along in the buffer -		for (int lineAfter = lineRemove; lineAfter <= lv.lines; lineAfter++) { -			lv.linesData[lineAfter].startPosition -= deleteLength / 2; -		} +		lv.InsertText(lineRemove-1, - (deleteLength / 2));  		char chPrev = ' ';  		if (position >= 2)  			chPrev = ByteAt(position - 2);  		char chBefore = chPrev;  		char chNext = ' '; -		if (position < length) +		if (position < body.Length())  			chNext = ByteAt(position);  		bool ignoreNL = false;  		if (chPrev == '\r' && chNext == '\n') { -			//Platform::DebugPrintf("Deleting lf after cr, move line end to cr at %d\n", lineRemove);  			// Move back one -			lv.SetValue(lineRemove, position / 2); +			lv.SetLineStart(lineRemove, position / 2);  			lineRemove++;  			ignoreNL = true; 	// First \n is not real deletion  		} @@ -967,20 +806,17 @@ void CellBuffer::BasicDeleteChars(int position, int deleteLength) {  		char ch = chNext;  		for (int i = 0; i < deleteLength; i += 2) {  			chNext = ' '; -			if ((position + i + 2) < length) +			if ((position + i + 2) < body.Length())  				chNext = ByteAt(position + i + 2); -			//Platform::DebugPrintf("Deleting %d %x\n", i, ch);  			if (ch == '\r') {  				if (chNext != '\n') { -					//Platform::DebugPrintf("Removing cr end of line\n"); -					lv.Remove(lineRemove); +					lv.RemoveLine(lineRemove);  				}  			} else if (ch == '\n') {  				if (ignoreNL) {  					ignoreNL = false; 	// Further \n are real deletions  				} else { -					//Platform::DebugPrintf("Removing lf end of line\n"); -					lv.Remove(lineRemove); +					lv.RemoveLine(lineRemove);  				}  			} @@ -989,19 +825,15 @@ void CellBuffer::BasicDeleteChars(int position, int deleteLength) {  		// May have to fix up end if last deletion causes cr to be next to lf  		// or removes one of a crlf pair  		char chAfter = ' '; -		if ((position + deleteLength) < length) +		if ((position + deleteLength) < body.Length())  			chAfter = ByteAt(position + deleteLength);  		if (chBefore == '\r' && chAfter == '\n') { -			//d.printf("Joining cr before lf at %d\n", lineRemove);  			// Using lineRemove-1 as cr ended line before start of deletion -			lv.Remove(lineRemove - 1); -			lv.SetValue(lineRemove - 1, position / 2 + 1); +			lv.RemoveLine(lineRemove - 1); +			lv.SetLineStart(lineRemove - 1, position / 2 + 1);  		}  	} -	GapTo(position); -	length -= deleteLength; -	gaplen += deleteLength; -	part2body = body + gaplen; +	body.DeleteRange(position, deleteLength);  }  bool CellBuffer::SetUndoCollection(bool collectUndo) { @@ -1097,25 +929,11 @@ int CellBuffer::GetMaxLineState() {  }  int CellBuffer::SetLevel(int line, int level) { -	int prev = 0; -	if ((line >= 0) && (line < lv.lines)) { -		if (!lv.levels) { -			lv.ExpandLevels(); -		} -		prev = lv.levels[line]; -		if (lv.levels[line] != level) { -			lv.levels[line] = level; -		} -	} -	return prev; +	return lv.SetLevel(line, level);  }  int CellBuffer::GetLevel(int line) { -	if (lv.levels && (line >= 0) && (line < lv.lines)) { -		return lv.levels[line]; -	} else { -		return SC_FOLDLEVELBASE; -	} +	return lv.GetLevel(line);  }  void CellBuffer::ClearLevels() {  | 
