src/vs/editor/common/model/pieceTreeTextBuffer/pieceTreeBase.ts/PieceTreeBase/fixCRLF
class PieceTreeBase:	private fixCRLF(prev: TreeNode, next: TreeNode) {
		const nodesToDel: TreeNode[] = [];
		// update node
		const lineStarts = this._buffers[prev.piece.bufferIndex].lineStarts;
		let newEnd: BufferCursor;
		if (prev.piece.end.column === 0) {
			// it means, last line ends with \r, not \r\n
			newEnd = { line: prev.piece.end.line - 1, column: lineStarts[prev.piece.end.line] - lineStarts[prev.piece.end.line - 1] - 1 };
		} else {
			// \r\n
			newEnd = { line: prev.piece.end.line, column: prev.piece.end.column - 1 };
		}

		const prevNewLength = prev.piece.length - 1;
		const prevNewLFCnt = prev.piece.lineFeedCnt - 1;
		prev.piece = new Piece(
			prev.piece.bufferIndex,
			prev.piece.start,
			newEnd,
			prevNewLFCnt,
			prevNewLength
		);

		updateTreeMetadata(this, prev, - 1, -1);
		if (prev.piece.length === 0) {
			nodesToDel.push(prev);
		}

		// update nextNode
		const newStart: BufferCursor = { line: next.piece.start.line + 1, column: 0 };
		const newLength = next.piece.length - 1;
		const newLineFeedCnt = this.getLineFeedCnt(next.piece.bufferIndex, newStart, next.piece.end);
		next.piece = new Piece(
			next.piece.bufferIndex,
			newStart,
			next.piece.end,
			newLineFeedCnt,
			newLength
		);

		updateTreeMetadata(this, next, - 1, -1);
		if (next.piece.length === 0) {
			nodesToDel.push(next);
		}

		// create new piece which contains \r\n
		const pieces = this.createNewPieces('\r\n');
		this.rbInsertRight(prev, pieces[0]);
		// delete empty nodes

		for (let i = 0; i < nodesToDel.length; i++) {
			rbDelete(this, nodesToDel[i]);
		}
	}