mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-10 10:12:34 -05:00
Merge VS Code 1.31.1 (#4283)
This commit is contained in:
@@ -145,7 +145,7 @@ export class EditStack {
|
||||
this.pushStackElement();
|
||||
}
|
||||
|
||||
public pushEditOperation(beforeCursorState: Selection[], editOperations: IIdentifiedSingleEditOperation[], cursorStateComputer: ICursorStateComputer): Selection[] | null {
|
||||
public pushEditOperation(beforeCursorState: Selection[], editOperations: IIdentifiedSingleEditOperation[], cursorStateComputer: ICursorStateComputer | null): Selection[] | null {
|
||||
// No support for parallel universes :(
|
||||
this.future = [];
|
||||
|
||||
@@ -174,7 +174,7 @@ export class EditStack {
|
||||
return stackElement!.afterCursorState;
|
||||
}
|
||||
|
||||
private static _computeCursorState(cursorStateComputer: ICursorStateComputer, inverseEditOperations: IIdentifiedSingleEditOperation[]): Selection[] | null {
|
||||
private static _computeCursorState(cursorStateComputer: ICursorStateComputer | null, inverseEditOperations: IIdentifiedSingleEditOperation[]): Selection[] | null {
|
||||
try {
|
||||
return cursorStateComputer ? cursorStateComputer(inverseEditOperations) : null;
|
||||
} catch (e) {
|
||||
|
||||
@@ -189,6 +189,12 @@ export function guessIndentation(source: ITextBuffer, defaultTabSize: number, de
|
||||
}
|
||||
});
|
||||
|
||||
// Let a tabSize of 2 win even if it is not the maximum
|
||||
// (only in case 4 was guessed)
|
||||
if (tabSize === 4 && spacesDiffCount[4] > 0 && spacesDiffCount[2] > 0 && spacesDiffCount[2] >= spacesDiffCount[4] / 2) {
|
||||
tabSize = 2;
|
||||
}
|
||||
|
||||
|
||||
// console.log('--------------------------');
|
||||
// console.log('linesIndentedWithTabsCount: ' + linesIndentedWithTabsCount + ', linesIndentedWithSpacesCount: ' + linesIndentedWithSpacesCount);
|
||||
|
||||
@@ -464,11 +464,9 @@ export function nodeAcceptEdit(node: IntervalNode, start: number, end: number, t
|
||||
const deltaColumn = (insertingCnt - deletingCnt);
|
||||
if (!startDone) {
|
||||
node.start = Math.max(0, nodeStart + deltaColumn);
|
||||
startDone = true;
|
||||
}
|
||||
if (!endDone) {
|
||||
node.end = Math.max(0, nodeEnd + deltaColumn);
|
||||
endDone = true;
|
||||
}
|
||||
|
||||
if (node.start > node.end) {
|
||||
|
||||
@@ -60,8 +60,7 @@ export class MirrorTextModel {
|
||||
|
||||
// Update my lines
|
||||
const changes = e.changes;
|
||||
for (let i = 0, len = changes.length; i < len; i++) {
|
||||
const change = changes[i];
|
||||
for (const change of changes) {
|
||||
this._acceptDeleteRange(change.range);
|
||||
this._acceptInsertText(new Position(change.range.startLineNumber, change.range.startColumn), change.text);
|
||||
}
|
||||
|
||||
@@ -242,7 +242,7 @@ class PieceTreeSearchCache {
|
||||
|
||||
public valdiate(offset: number) {
|
||||
let hasInvalidVal = false;
|
||||
let tmp: (CacheEntry | null)[] = this._cache;
|
||||
let tmp: Array<CacheEntry | null> = this._cache;
|
||||
for (let i = 0; i < tmp.length; i++) {
|
||||
let nodePos = tmp[i]!;
|
||||
if (nodePos.node.parent === null || nodePos.nodeStartOffset >= offset) {
|
||||
@@ -254,8 +254,7 @@ class PieceTreeSearchCache {
|
||||
|
||||
if (hasInvalidVal) {
|
||||
let newArr: CacheEntry[] = [];
|
||||
for (let i = 0; i < tmp.length; i++) {
|
||||
const entry = tmp[i];
|
||||
for (const entry of tmp) {
|
||||
if (entry !== null) {
|
||||
newArr.push(entry);
|
||||
}
|
||||
@@ -1042,7 +1041,7 @@ export class PieceTreeBase {
|
||||
while (text.length > AverageBufferSize) {
|
||||
const lastChar = text.charCodeAt(AverageBufferSize - 1);
|
||||
let splitText;
|
||||
if (lastChar === CharCode.CarriageReturn || (lastChar >= 0xd800 && lastChar <= 0xdbff)) {
|
||||
if (lastChar === CharCode.CarriageReturn || (lastChar >= 0xD800 && lastChar <= 0xDBFF)) {
|
||||
// last character is \r or a high surrogate => keep it back
|
||||
splitText = text.substring(0, AverageBufferSize - 1);
|
||||
text = text.substring(AverageBufferSize - 1);
|
||||
|
||||
@@ -103,7 +103,7 @@ export class PieceTreeTextBufferBuilder implements ITextBufferBuilder {
|
||||
}
|
||||
|
||||
const lastChar = chunk.charCodeAt(chunk.length - 1);
|
||||
if (lastChar === CharCode.CarriageReturn || (lastChar >= 0xd800 && lastChar <= 0xdbff)) {
|
||||
if (lastChar === CharCode.CarriageReturn || (lastChar >= 0xD800 && lastChar <= 0xDBFF)) {
|
||||
// last character is \r or a high surrogate => keep it back
|
||||
this._acceptChunk1(chunk.substr(0, chunk.length - 1), false);
|
||||
this._hasPreviousChar = true;
|
||||
|
||||
@@ -315,6 +315,7 @@ export class TextModel extends Disposable implements model.ITextModel {
|
||||
|
||||
this._resetTokenizationState();
|
||||
this.emitModelTokensChangedEvent({
|
||||
tokenizationSupportChanged: true,
|
||||
ranges: [{
|
||||
fromLineNumber: 1,
|
||||
toLineNumber: this.getLineCount()
|
||||
@@ -1166,7 +1167,7 @@ export class TextModel extends Disposable implements model.ITextModel {
|
||||
}
|
||||
}
|
||||
|
||||
public pushEditOperations(beforeCursorState: Selection[], editOperations: model.IIdentifiedSingleEditOperation[], cursorStateComputer: model.ICursorStateComputer): Selection[] | null {
|
||||
public pushEditOperations(beforeCursorState: Selection[], editOperations: model.IIdentifiedSingleEditOperation[], cursorStateComputer: model.ICursorStateComputer | null): Selection[] | null {
|
||||
try {
|
||||
this._onDidChangeDecorations.beginDeferredEmit();
|
||||
this._eventEmitter.beginDeferredEmit();
|
||||
@@ -1177,7 +1178,7 @@ export class TextModel extends Disposable implements model.ITextModel {
|
||||
}
|
||||
}
|
||||
|
||||
private _pushEditOperations(beforeCursorState: Selection[], editOperations: model.IIdentifiedSingleEditOperation[], cursorStateComputer: model.ICursorStateComputer): Selection[] | null {
|
||||
private _pushEditOperations(beforeCursorState: Selection[], editOperations: model.IIdentifiedSingleEditOperation[], cursorStateComputer: model.ICursorStateComputer | null): Selection[] | null {
|
||||
if (this._options.trimAutoWhitespace && this._trimAutoWhitespaceLines) {
|
||||
// Go through each saved line number and insert a trim whitespace edit
|
||||
// if it is safe to do so (no conflicts with other edits).
|
||||
@@ -1760,42 +1761,41 @@ export class TextModel extends Disposable implements model.ITextModel {
|
||||
|
||||
public tokenizeViewport(startLineNumber: number, endLineNumber: number): void {
|
||||
if (!this._tokens.tokenizationSupport) {
|
||||
// nothing to do
|
||||
return;
|
||||
}
|
||||
|
||||
// we tokenize `this._tokens.inValidLineStartIndex` lines in around 20ms so it's a good baseline.
|
||||
const contextBefore = Math.floor(this._tokens.inValidLineStartIndex * 0.3);
|
||||
startLineNumber = Math.max(1, startLineNumber - contextBefore);
|
||||
startLineNumber = Math.max(1, startLineNumber);
|
||||
endLineNumber = Math.min(this.getLineCount(), endLineNumber);
|
||||
|
||||
if (endLineNumber <= this._tokens.inValidLineStartIndex) {
|
||||
// nothing to do
|
||||
return;
|
||||
}
|
||||
|
||||
if (startLineNumber <= this._tokens.inValidLineStartIndex) {
|
||||
// tokenization has reached the viewport start...
|
||||
this.forceTokenization(endLineNumber);
|
||||
return;
|
||||
}
|
||||
|
||||
const eventBuilder = new ModelTokensChangedEventBuilder();
|
||||
let nonWhitespaceColumn = this.getLineFirstNonWhitespaceColumn(startLineNumber);
|
||||
let fakeLines: string[] = [];
|
||||
let i = startLineNumber - 1;
|
||||
let initialState: IState | null = null;
|
||||
if (nonWhitespaceColumn > 0) {
|
||||
while (nonWhitespaceColumn > 0 && i >= 1) {
|
||||
let newNonWhitespaceIndex = this.getLineFirstNonWhitespaceColumn(i);
|
||||
for (let i = startLineNumber - 1; nonWhitespaceColumn > 0 && i >= 1; i--) {
|
||||
let newNonWhitespaceIndex = this.getLineFirstNonWhitespaceColumn(i);
|
||||
|
||||
if (newNonWhitespaceIndex === 0) {
|
||||
i--;
|
||||
continue;
|
||||
if (newNonWhitespaceIndex === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (newNonWhitespaceIndex < nonWhitespaceColumn) {
|
||||
initialState = this._tokens._getState(i - 1);
|
||||
if (initialState) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (newNonWhitespaceIndex < nonWhitespaceColumn) {
|
||||
initialState = this._tokens._getState(i - 1);
|
||||
if (initialState) {
|
||||
break;
|
||||
}
|
||||
fakeLines.push(this.getLineContent(i));
|
||||
nonWhitespaceColumn = newNonWhitespaceIndex;
|
||||
}
|
||||
|
||||
i--;
|
||||
fakeLines.push(this.getLineContent(i));
|
||||
nonWhitespaceColumn = newNonWhitespaceIndex;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1813,19 +1813,16 @@ export class TextModel extends Disposable implements model.ITextModel {
|
||||
}
|
||||
}
|
||||
|
||||
const contextAfter = Math.floor(this._tokens.inValidLineStartIndex * 0.4);
|
||||
endLineNumber = Math.min(this.getLineCount(), endLineNumber + contextAfter);
|
||||
const eventBuilder = new ModelTokensChangedEventBuilder();
|
||||
for (let i = startLineNumber; i <= endLineNumber; i++) {
|
||||
let text = this.getLineContent(i);
|
||||
let r = this._tokens._tokenizeText(this._buffer, text, state);
|
||||
if (r) {
|
||||
this._tokens._setTokens(this._tokens.languageIdentifier.id, i - 1, text.length, r.tokens);
|
||||
/*
|
||||
* we think it's valid and give it a state but we don't update `_invalidLineStartIndex` then the top-to-bottom tokenization
|
||||
* goes through the viewport, it can skip them if they already have correct tokens and state, and the lines after the viewport
|
||||
* can still be tokenized.
|
||||
*/
|
||||
this._tokens._setIsInvalid(i - 1, false);
|
||||
|
||||
// We cannot trust these states/tokens to be valid!
|
||||
// (see https://github.com/Microsoft/vscode/issues/67607)
|
||||
this._tokens._setIsInvalid(i - 1, true);
|
||||
this._tokens._setState(i - 1, state);
|
||||
state = r.endState.clone();
|
||||
eventBuilder.registerChangedTokens(i);
|
||||
@@ -1840,6 +1837,17 @@ export class TextModel extends Disposable implements model.ITextModel {
|
||||
}
|
||||
}
|
||||
|
||||
public flushTokens(): void {
|
||||
this._resetTokenizationState();
|
||||
this.emitModelTokensChangedEvent({
|
||||
tokenizationSupportChanged: false,
|
||||
ranges: [{
|
||||
fromLineNumber: 1,
|
||||
toLineNumber: this.getLineCount()
|
||||
}]
|
||||
});
|
||||
}
|
||||
|
||||
public forceTokenization(lineNumber: number): void {
|
||||
if (lineNumber < 1 || lineNumber > this.getLineCount()) {
|
||||
throw new Error('Illegal value for lineNumber');
|
||||
@@ -1915,6 +1923,7 @@ export class TextModel extends Disposable implements model.ITextModel {
|
||||
this._resetTokenizationState();
|
||||
|
||||
this.emitModelTokensChangedEvent({
|
||||
tokenizationSupportChanged: true,
|
||||
ranges: [{
|
||||
fromLineNumber: 1,
|
||||
toLineNumber: this.getLineCount()
|
||||
|
||||
@@ -82,6 +82,7 @@ export interface IModelDecorationsChangedEvent {
|
||||
* An event describing that some ranges of lines have been tokenized (their tokens have changed).
|
||||
*/
|
||||
export interface IModelTokensChangedEvent {
|
||||
readonly tokenizationSupportChanged: boolean;
|
||||
readonly ranges: {
|
||||
/**
|
||||
* The start of the range (inclusive)
|
||||
|
||||
@@ -154,7 +154,7 @@ class ModelLineTokens {
|
||||
|
||||
let fromTokenIndex = LineTokens.findIndexInTokensArray(tokens, chIndex);
|
||||
if (fromTokenIndex > 0) {
|
||||
const fromTokenStartOffset = (fromTokenIndex > 0 ? tokens[(fromTokenIndex - 1) << 1] : 0);
|
||||
const fromTokenStartOffset = tokens[(fromTokenIndex - 1) << 1];
|
||||
if (fromTokenStartOffset === chIndex) {
|
||||
fromTokenIndex--;
|
||||
}
|
||||
@@ -500,6 +500,7 @@ export class ModelTokensChangedEventBuilder {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
tokenizationSupportChanged: false,
|
||||
ranges: this._ranges
|
||||
};
|
||||
}
|
||||
|
||||
@@ -17,11 +17,11 @@ export const USUAL_WORD_SEPARATORS = '`~!#$%^&*()-=+[{]}\\|;:\'",.<>/?';
|
||||
*/
|
||||
function createWordRegExp(allowInWords: string = ''): RegExp {
|
||||
let source = '(-?\\d*\\.\\d\\w*)|([^';
|
||||
for (let i = 0; i < USUAL_WORD_SEPARATORS.length; i++) {
|
||||
if (allowInWords.indexOf(USUAL_WORD_SEPARATORS[i]) >= 0) {
|
||||
for (const sep of USUAL_WORD_SEPARATORS) {
|
||||
if (allowInWords.indexOf(sep) >= 0) {
|
||||
continue;
|
||||
}
|
||||
source += '\\' + USUAL_WORD_SEPARATORS[i];
|
||||
source += '\\' + sep;
|
||||
}
|
||||
source += '\\s]+)';
|
||||
return new RegExp(source, 'g');
|
||||
@@ -42,6 +42,9 @@ export function ensureValidWordDefinition(wordDefinition?: RegExp | null): RegEx
|
||||
if (wordDefinition.multiline) {
|
||||
flags += 'm';
|
||||
}
|
||||
if ((wordDefinition as any).unicode) {
|
||||
flags += 'u';
|
||||
}
|
||||
result = new RegExp(wordDefinition.source, flags);
|
||||
} else {
|
||||
result = wordDefinition;
|
||||
@@ -58,10 +61,6 @@ function getWordAtPosFast(column: number, wordDefinition: RegExp, text: string,
|
||||
|
||||
let pos = column - 1 - textOffset;
|
||||
let start = text.lastIndexOf(' ', pos - 1) + 1;
|
||||
let end = text.indexOf(' ', pos);
|
||||
if (end === -1) {
|
||||
end = text.length;
|
||||
}
|
||||
|
||||
wordDefinition.lastIndex = start;
|
||||
let match: RegExpMatchArray | null;
|
||||
|
||||
Reference in New Issue
Block a user