mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-11 02:32:35 -05:00
Merge from vscode a234f13c45b40a0929777cb440ee011b7549eed2 (#8911)
* Merge from vscode a234f13c45b40a0929777cb440ee011b7549eed2 * update distro * fix layering * update distro * fix tests
This commit is contained in:
@@ -511,7 +511,93 @@ export class PieceTreeBase {
|
||||
}
|
||||
|
||||
public getLinesContent(): string[] {
|
||||
return this.getContentOfSubTree(this.root).split(/\r\n|\r|\n/);
|
||||
let lines: string[] = [];
|
||||
let linesLength = 0;
|
||||
let currentLine = '';
|
||||
let danglingCR = false;
|
||||
|
||||
this.iterate(this.root, node => {
|
||||
if (node === SENTINEL) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const piece = node.piece;
|
||||
let pieceLength = piece.length;
|
||||
if (pieceLength === 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const buffer = this._buffers[piece.bufferIndex].buffer;
|
||||
const lineStarts = this._buffers[piece.bufferIndex].lineStarts;
|
||||
|
||||
const pieceStartLine = piece.start.line;
|
||||
const pieceEndLine = piece.end.line;
|
||||
let pieceStartOffset = lineStarts[pieceStartLine] + piece.start.column;
|
||||
|
||||
if (danglingCR) {
|
||||
if (buffer.charCodeAt(pieceStartOffset) === CharCode.LineFeed) {
|
||||
// pretend the \n was in the previous piece..
|
||||
pieceStartOffset++;
|
||||
pieceLength--;
|
||||
}
|
||||
lines[linesLength++] = currentLine;
|
||||
currentLine = '';
|
||||
danglingCR = false;
|
||||
if (pieceLength === 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (pieceStartLine === pieceEndLine) {
|
||||
// this piece has no new lines
|
||||
if (!this._EOLNormalized && buffer.charCodeAt(pieceStartOffset + pieceLength - 1) === CharCode.CarriageReturn) {
|
||||
danglingCR = true;
|
||||
currentLine += buffer.substr(pieceStartOffset, pieceLength - 1);
|
||||
} else {
|
||||
currentLine += buffer.substr(pieceStartOffset, pieceLength);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// add the text before the first line start in this piece
|
||||
currentLine += (
|
||||
this._EOLNormalized
|
||||
? buffer.substring(pieceStartOffset, Math.max(pieceStartOffset, lineStarts[pieceStartLine + 1] - this._EOLLength))
|
||||
: buffer.substring(pieceStartOffset, lineStarts[pieceStartLine + 1]).replace(/(\r\n|\r|\n)$/, '')
|
||||
);
|
||||
lines[linesLength++] = currentLine;
|
||||
|
||||
for (let line = pieceStartLine + 1; line < pieceEndLine; line++) {
|
||||
currentLine = (
|
||||
this._EOLNormalized
|
||||
? buffer.substring(lineStarts[line], lineStarts[line + 1] - this._EOLLength)
|
||||
: buffer.substring(lineStarts[line], lineStarts[line + 1]).replace(/(\r\n|\r|\n)$/, '')
|
||||
);
|
||||
lines[linesLength++] = currentLine;
|
||||
}
|
||||
|
||||
if (!this._EOLNormalized && buffer.charCodeAt(lineStarts[pieceEndLine] + piece.end.column - 1) === CharCode.CarriageReturn) {
|
||||
danglingCR = true;
|
||||
if (piece.end.column === 0) {
|
||||
// The last line ended with a \r, let's undo the push, it will be pushed by next iteration
|
||||
linesLength--;
|
||||
} else {
|
||||
currentLine = buffer.substr(lineStarts[pieceEndLine], piece.end.column - 1);
|
||||
}
|
||||
} else {
|
||||
currentLine = buffer.substr(lineStarts[pieceEndLine], piece.end.column);
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
if (danglingCR) {
|
||||
lines[linesLength++] = currentLine;
|
||||
currentLine = '';
|
||||
}
|
||||
|
||||
lines[linesLength++] = currentLine;
|
||||
return lines;
|
||||
}
|
||||
|
||||
public getLength(): number {
|
||||
@@ -728,7 +814,7 @@ export class PieceTreeBase {
|
||||
// #endregion
|
||||
|
||||
// #region Piece Table
|
||||
insert(offset: number, value: string, eolNormalized: boolean = false): void {
|
||||
public insert(offset: number, value: string, eolNormalized: boolean = false): void {
|
||||
this._EOLNormalized = this._EOLNormalized && eolNormalized;
|
||||
this._lastVisitedLine.lineNumber = 0;
|
||||
this._lastVisitedLine.value = '';
|
||||
@@ -826,7 +912,7 @@ export class PieceTreeBase {
|
||||
this.computeBufferMetadata();
|
||||
}
|
||||
|
||||
delete(offset: number, cnt: number): void {
|
||||
public delete(offset: number, cnt: number): void {
|
||||
this._lastVisitedLine.lineNumber = 0;
|
||||
this._lastVisitedLine.value = '';
|
||||
|
||||
@@ -899,7 +985,7 @@ export class PieceTreeBase {
|
||||
this.computeBufferMetadata();
|
||||
}
|
||||
|
||||
insertContentToNodeLeft(value: string, node: TreeNode) {
|
||||
private insertContentToNodeLeft(value: string, node: TreeNode) {
|
||||
// we are inserting content to the beginning of node
|
||||
let nodesToDel: TreeNode[] = [];
|
||||
if (this.shouldCheckCRLF() && this.endWithCR(value) && this.startWithLF(node)) {
|
||||
@@ -934,7 +1020,7 @@ export class PieceTreeBase {
|
||||
this.deleteNodes(nodesToDel);
|
||||
}
|
||||
|
||||
insertContentToNodeRight(value: string, node: TreeNode) {
|
||||
private insertContentToNodeRight(value: string, node: TreeNode) {
|
||||
// we are inserting to the right of this node.
|
||||
if (this.adjustCarriageReturnFromNext(value, node)) {
|
||||
// move \n to the new node.
|
||||
@@ -952,9 +1038,9 @@ export class PieceTreeBase {
|
||||
this.validateCRLFWithPrevNode(newNode);
|
||||
}
|
||||
|
||||
positionInBuffer(node: TreeNode, remainder: number): BufferCursor;
|
||||
positionInBuffer(node: TreeNode, remainder: number, ret: BufferCursor): null;
|
||||
positionInBuffer(node: TreeNode, remainder: number, ret?: BufferCursor): BufferCursor | null {
|
||||
private positionInBuffer(node: TreeNode, remainder: number): BufferCursor;
|
||||
private positionInBuffer(node: TreeNode, remainder: number, ret: BufferCursor): null;
|
||||
private positionInBuffer(node: TreeNode, remainder: number, ret?: BufferCursor): BufferCursor | null {
|
||||
let piece = node.piece;
|
||||
let bufferIndex = node.piece.bufferIndex;
|
||||
let lineStarts = this._buffers[bufferIndex].lineStarts;
|
||||
@@ -1002,7 +1088,7 @@ export class PieceTreeBase {
|
||||
};
|
||||
}
|
||||
|
||||
getLineFeedCnt(bufferIndex: number, start: BufferCursor, end: BufferCursor): number {
|
||||
private getLineFeedCnt(bufferIndex: number, start: BufferCursor, end: BufferCursor): number {
|
||||
// we don't need to worry about start: abc\r|\n, or abc|\r, or abc|\n, or abc|\r\n doesn't change the fact that, there is one line break after start.
|
||||
// now let's take care of end: abc\r|\n, if end is in between \r and \n, we need to add line feed count by 1
|
||||
if (end.column === 0) {
|
||||
@@ -1032,18 +1118,18 @@ export class PieceTreeBase {
|
||||
}
|
||||
}
|
||||
|
||||
offsetInBuffer(bufferIndex: number, cursor: BufferCursor): number {
|
||||
private offsetInBuffer(bufferIndex: number, cursor: BufferCursor): number {
|
||||
let lineStarts = this._buffers[bufferIndex].lineStarts;
|
||||
return lineStarts[cursor.line] + cursor.column;
|
||||
}
|
||||
|
||||
deleteNodes(nodes: TreeNode[]): void {
|
||||
private deleteNodes(nodes: TreeNode[]): void {
|
||||
for (let i = 0; i < nodes.length; i++) {
|
||||
rbDelete(this, nodes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
createNewPieces(text: string): Piece[] {
|
||||
private createNewPieces(text: string): Piece[] {
|
||||
if (text.length > AverageBufferSize) {
|
||||
// the content is large, operations like substring, charCode becomes slow
|
||||
// so here we split it into smaller chunks, just like what we did for CR/LF normalization
|
||||
@@ -1128,11 +1214,11 @@ export class PieceTreeBase {
|
||||
return [newPiece];
|
||||
}
|
||||
|
||||
getLinesRawContent(): string {
|
||||
public getLinesRawContent(): string {
|
||||
return this.getContentOfSubTree(this.root);
|
||||
}
|
||||
|
||||
getLineRawContent(lineNumber: number, endOffset: number = 0): string {
|
||||
public getLineRawContent(lineNumber: number, endOffset: number = 0): string {
|
||||
let x = this.root;
|
||||
|
||||
let ret = '';
|
||||
@@ -1204,7 +1290,7 @@ export class PieceTreeBase {
|
||||
return ret;
|
||||
}
|
||||
|
||||
computeBufferMetadata() {
|
||||
private computeBufferMetadata() {
|
||||
let x = this.root;
|
||||
|
||||
let lfCnt = 1;
|
||||
@@ -1222,7 +1308,7 @@ export class PieceTreeBase {
|
||||
}
|
||||
|
||||
// #region node operations
|
||||
getIndexOf(node: TreeNode, accumulatedValue: number): { index: number, remainder: number } {
|
||||
private getIndexOf(node: TreeNode, accumulatedValue: number): { index: number, remainder: number } {
|
||||
let piece = node.piece;
|
||||
let pos = this.positionInBuffer(node, accumulatedValue);
|
||||
let lineCnt = pos.line - piece.start.line;
|
||||
@@ -1239,7 +1325,7 @@ export class PieceTreeBase {
|
||||
return { index: lineCnt, remainder: pos.column };
|
||||
}
|
||||
|
||||
getAccumulatedValue(node: TreeNode, index: number) {
|
||||
private getAccumulatedValue(node: TreeNode, index: number) {
|
||||
if (index < 0) {
|
||||
return 0;
|
||||
}
|
||||
@@ -1253,7 +1339,7 @@ export class PieceTreeBase {
|
||||
}
|
||||
}
|
||||
|
||||
deleteNodeTail(node: TreeNode, pos: BufferCursor) {
|
||||
private deleteNodeTail(node: TreeNode, pos: BufferCursor) {
|
||||
const piece = node.piece;
|
||||
const originalLFCnt = piece.lineFeedCnt;
|
||||
const originalEndOffset = this.offsetInBuffer(piece.bufferIndex, piece.end);
|
||||
@@ -1277,7 +1363,7 @@ export class PieceTreeBase {
|
||||
updateTreeMetadata(this, node, size_delta, lf_delta);
|
||||
}
|
||||
|
||||
deleteNodeHead(node: TreeNode, pos: BufferCursor) {
|
||||
private deleteNodeHead(node: TreeNode, pos: BufferCursor) {
|
||||
const piece = node.piece;
|
||||
const originalLFCnt = piece.lineFeedCnt;
|
||||
const originalStartOffset = this.offsetInBuffer(piece.bufferIndex, piece.start);
|
||||
@@ -1299,7 +1385,7 @@ export class PieceTreeBase {
|
||||
updateTreeMetadata(this, node, size_delta, lf_delta);
|
||||
}
|
||||
|
||||
shrinkNode(node: TreeNode, start: BufferCursor, end: BufferCursor) {
|
||||
private shrinkNode(node: TreeNode, start: BufferCursor, end: BufferCursor) {
|
||||
const piece = node.piece;
|
||||
const originalStartPos = piece.start;
|
||||
const originalEndPos = piece.end;
|
||||
@@ -1334,7 +1420,7 @@ export class PieceTreeBase {
|
||||
this.validateCRLFWithPrevNode(newNode);
|
||||
}
|
||||
|
||||
appendToNode(node: TreeNode, value: string): void {
|
||||
private appendToNode(node: TreeNode, value: string): void {
|
||||
if (this.adjustCarriageReturnFromNext(value, node)) {
|
||||
value += '\n';
|
||||
}
|
||||
@@ -1374,7 +1460,7 @@ export class PieceTreeBase {
|
||||
updateTreeMetadata(this, node, value.length, lf_delta);
|
||||
}
|
||||
|
||||
nodeAt(offset: number): NodePosition {
|
||||
private nodeAt(offset: number): NodePosition {
|
||||
let x = this.root;
|
||||
let cache = this._searchCache.get(offset);
|
||||
if (cache) {
|
||||
@@ -1409,7 +1495,7 @@ export class PieceTreeBase {
|
||||
return null!;
|
||||
}
|
||||
|
||||
nodeAt2(lineNumber: number, column: number): NodePosition {
|
||||
private nodeAt2(lineNumber: number, column: number): NodePosition {
|
||||
let x = this.root;
|
||||
let nodeStartOffset = 0;
|
||||
|
||||
@@ -1476,7 +1562,7 @@ export class PieceTreeBase {
|
||||
return null!;
|
||||
}
|
||||
|
||||
nodeCharCodeAt(node: TreeNode, offset: number): number {
|
||||
private nodeCharCodeAt(node: TreeNode, offset: number): number {
|
||||
if (node.piece.lineFeedCnt < 1) {
|
||||
return -1;
|
||||
}
|
||||
@@ -1485,7 +1571,7 @@ export class PieceTreeBase {
|
||||
return buffer.buffer.charCodeAt(newOffset);
|
||||
}
|
||||
|
||||
offsetOfNode(node: TreeNode): number {
|
||||
private offsetOfNode(node: TreeNode): number {
|
||||
if (!node) {
|
||||
return 0;
|
||||
}
|
||||
@@ -1504,11 +1590,11 @@ export class PieceTreeBase {
|
||||
// #endregion
|
||||
|
||||
// #region CRLF
|
||||
shouldCheckCRLF() {
|
||||
private shouldCheckCRLF() {
|
||||
return !(this._EOLNormalized && this._EOL === '\n');
|
||||
}
|
||||
|
||||
startWithLF(val: string | TreeNode): boolean {
|
||||
private startWithLF(val: string | TreeNode): boolean {
|
||||
if (typeof val === 'string') {
|
||||
return val.charCodeAt(0) === 10;
|
||||
}
|
||||
@@ -1532,7 +1618,7 @@ export class PieceTreeBase {
|
||||
return this._buffers[piece.bufferIndex].buffer.charCodeAt(startOffset) === 10;
|
||||
}
|
||||
|
||||
endWithCR(val: string | TreeNode): boolean {
|
||||
private endWithCR(val: string | TreeNode): boolean {
|
||||
if (typeof val === 'string') {
|
||||
return val.charCodeAt(val.length - 1) === 13;
|
||||
}
|
||||
@@ -1544,7 +1630,7 @@ export class PieceTreeBase {
|
||||
return this.nodeCharCodeAt(val, val.piece.length - 1) === 13;
|
||||
}
|
||||
|
||||
validateCRLFWithPrevNode(nextNode: TreeNode) {
|
||||
private validateCRLFWithPrevNode(nextNode: TreeNode) {
|
||||
if (this.shouldCheckCRLF() && this.startWithLF(nextNode)) {
|
||||
let node = nextNode.prev();
|
||||
if (this.endWithCR(node)) {
|
||||
@@ -1553,7 +1639,7 @@ export class PieceTreeBase {
|
||||
}
|
||||
}
|
||||
|
||||
validateCRLFWithNextNode(node: TreeNode) {
|
||||
private validateCRLFWithNextNode(node: TreeNode) {
|
||||
if (this.shouldCheckCRLF() && this.endWithCR(node)) {
|
||||
let nextNode = node.next();
|
||||
if (this.startWithLF(nextNode)) {
|
||||
@@ -1562,7 +1648,7 @@ export class PieceTreeBase {
|
||||
}
|
||||
}
|
||||
|
||||
fixCRLF(prev: TreeNode, next: TreeNode) {
|
||||
private fixCRLF(prev: TreeNode, next: TreeNode) {
|
||||
let nodesToDel: TreeNode[] = [];
|
||||
// update node
|
||||
let lineStarts = this._buffers[prev.piece.bufferIndex].lineStarts;
|
||||
@@ -1617,7 +1703,7 @@ export class PieceTreeBase {
|
||||
}
|
||||
}
|
||||
|
||||
adjustCarriageReturnFromNext(value: string, node: TreeNode): boolean {
|
||||
private adjustCarriageReturnFromNext(value: string, node: TreeNode): boolean {
|
||||
if (this.shouldCheckCRLF() && this.endWithCR(value)) {
|
||||
let nextNode = node.next();
|
||||
if (this.startWithLF(nextNode)) {
|
||||
@@ -1667,7 +1753,7 @@ export class PieceTreeBase {
|
||||
return callback(node) && this.iterate(node.right, callback);
|
||||
}
|
||||
|
||||
getNodeContent(node: TreeNode) {
|
||||
private getNodeContent(node: TreeNode) {
|
||||
if (node === SENTINEL) {
|
||||
return '';
|
||||
}
|
||||
@@ -1695,7 +1781,7 @@ export class PieceTreeBase {
|
||||
* /
|
||||
* z
|
||||
*/
|
||||
rbInsertRight(node: TreeNode | null, p: Piece): TreeNode {
|
||||
private rbInsertRight(node: TreeNode | null, p: Piece): TreeNode {
|
||||
let z = new TreeNode(p, NodeColor.Red);
|
||||
z.left = SENTINEL;
|
||||
z.right = SENTINEL;
|
||||
@@ -1727,7 +1813,7 @@ export class PieceTreeBase {
|
||||
* \
|
||||
* z
|
||||
*/
|
||||
rbInsertLeft(node: TreeNode | null, p: Piece): TreeNode {
|
||||
private rbInsertLeft(node: TreeNode | null, p: Piece): TreeNode {
|
||||
let z = new TreeNode(p, NodeColor.Red);
|
||||
z.left = SENTINEL;
|
||||
z.right = SENTINEL;
|
||||
@@ -1751,7 +1837,7 @@ export class PieceTreeBase {
|
||||
return z;
|
||||
}
|
||||
|
||||
getContentOfSubTree(node: TreeNode): string {
|
||||
private getContentOfSubTree(node: TreeNode): string {
|
||||
let str = '';
|
||||
|
||||
this.iterate(node, node => {
|
||||
|
||||
Reference in New Issue
Block a user