Merge from vscode 5b9869eb02fa4c96205a74d05cad9164dfd06d60 (#5607)

This commit is contained in:
Anthony Dresser
2019-05-24 12:20:30 -07:00
committed by GitHub
parent 361ada4963
commit bcc449b524
126 changed files with 3096 additions and 2255 deletions

View File

@@ -242,6 +242,9 @@ export class ContextView extends Disposable {
// if view intersects vertically with anchor, shift it horizontally
if (Range.intersects({ start: top, end: top + viewSizeHeight }, { start: verticalAnchor.offset, end: verticalAnchor.offset + verticalAnchor.size })) {
horizontalAnchor.size = around.width;
if (anchorAlignment === AnchorAlignment.RIGHT) {
horizontalAnchor.offset = around.left;
}
}
const left = layout(window.innerWidth, viewSizeWidth, horizontalAnchor);

View File

@@ -191,18 +191,19 @@ export class ActionRunner extends Disposable implements IActionRunner {
private _onDidRun = this._register(new Emitter<IRunEvent>());
readonly onDidRun: Event<IRunEvent> = this._onDidRun.event;
run(action: IAction, context?: any): Promise<any> {
async run(action: IAction, context?: any): Promise<any> {
if (!action.enabled) {
return Promise.resolve(null);
}
this._onDidBeforeRun.fire({ action: action });
return this.runAction(action, context).then((result: any) => {
try {
const result = await this.runAction(action, context);
this._onDidRun.fire({ action: action, result: result });
}, (error: any) => {
} catch (error) {
this._onDidRun.fire({ action: action, error: error });
});
}
}
protected runAction(action: IAction, context?: any): Promise<any> {

View File

@@ -362,6 +362,31 @@ export function matchesFuzzy2(pattern: string, word: string): IMatch[] | null {
return score ? createMatches(score) : null;
}
export function anyScore(pattern: string, lowPattern: string, _patternPos: number, word: string, lowWord: string, _wordPos: number): FuzzyScore {
const result = fuzzyScore(pattern, lowPattern, 0, word, lowWord, 0, true);
if (result) {
return result;
}
let matches = 0;
let score = 0;
let idx = _wordPos;
for (let patternPos = 0; patternPos < lowPattern.length && patternPos < _maxLen; ++patternPos) {
const wordPos = lowWord.indexOf(lowPattern.charAt(patternPos), idx);
if (wordPos >= 0) {
score += 1;
matches += 2 ** wordPos;
idx = wordPos + 1;
} else if (matches !== 0) {
// once we have started matching things
// we need to match the remaining pattern
// characters
break;
}
}
return [score, matches, _wordPos];
}
//#region --- fuzzyScore ---
export function createMatches(score: undefined | FuzzyScore): IMatch[] {
@@ -491,7 +516,7 @@ export namespace FuzzyScore {
/**
* No matches and value `-100`
*/
export const Default: [-100, 0, 0] = [-100, 0, 0];
export const Default: [-100, 0, 0] = <[-100, 0, 0]>Object.freeze([-100, 0, 0]);
export function isDefault(score?: FuzzyScore): score is [-100, 0, 0] {
return !score || (score[0] === -100 && score[1] === 0 && score[2] === 0);

View File

@@ -9,7 +9,8 @@ import * as objects from 'vs/base/common/objects';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { Event, Emitter } from 'vs/base/common/event';
import * as json from 'vs/base/common/json';
import { readlink, statLink } from 'vs/base/node/pfs';
import { statLink } from 'vs/base/node/pfs';
import { realpath } from 'vs/base/node/extpath';
import { watchFolder, watchFile } from 'vs/base/node/watcher';
export interface IConfigurationChangeEvent<T> {
@@ -130,7 +131,7 @@ export class ConfigWatcher<T> implements IConfigWatcher<T>, IDisposable {
private async handleSymbolicLink(): Promise<void> {
const { stat, isSymbolicLink } = await statLink(this._path);
if (isSymbolicLink && !stat.isDirectory()) {
const realPath = await readlink(this._path);
const realPath = await realpath(this._path);
this.watch(realPath, false);
}

View File

@@ -213,10 +213,6 @@ export function symlink(target: string, path: string, type?: string): Promise<vo
return promisify(fs.symlink)(target, path, type);
}
export function readlink(path: string): Promise<string> {
return promisify(fs.readlink)(path);
}
export function truncate(path: string, len: number): Promise<void> {
return promisify(fs.truncate)(path, len);
}

View File

@@ -554,10 +554,12 @@ export class SQLiteStorageDatabase implements IStorageDatabase {
return integrity;
}
private connect(path: string, retryOnBusy: boolean = true): Promise<IDatabaseConnection> {
private async connect(path: string, retryOnBusy: boolean = true): Promise<IDatabaseConnection> {
this.logger.trace(`[storage ${this.name}] open(${path}, retryOnBusy: ${retryOnBusy})`);
return this.doConnect(path).then(undefined, error => {
try {
return await this.doConnect(path);
} catch (error) {
this.logger.error(`[storage ${this.name}] open(): Unable to open DB due to ${error}`);
// SQLITE_BUSY should only arise if another process is locking the same DB we want
@@ -569,7 +571,9 @@ export class SQLiteStorageDatabase implements IStorageDatabase {
// In this case we simply wait for some time and retry once to establish the connection.
//
if (error.code === 'SQLITE_BUSY' && retryOnBusy) {
return timeout(SQLiteStorageDatabase.BUSY_OPEN_TIMEOUT).then(() => this.connect(path, false /* not another retry */));
await timeout(SQLiteStorageDatabase.BUSY_OPEN_TIMEOUT);
return this.connect(path, false /* not another retry */);
}
// Otherwise, best we can do is to recover from a backup if that exists, as such we
@@ -579,17 +583,19 @@ export class SQLiteStorageDatabase implements IStorageDatabase {
// The final fallback is to use an in-memory DB which should only happen if the target
// folder is really not writeable for us.
//
return unlink(path)
.then(() => renameIgnoreError(this.toBackupPath(path), path))
.then(() => this.doConnect(path))
.then(undefined, error => {
this.logger.error(`[storage ${this.name}] open(): Unable to use backup due to ${error}`);
try {
await unlink(path);
await renameIgnoreError(this.toBackupPath(path), path);
// In case of any error to open the DB, use an in-memory
// DB so that we always have a valid DB to talk to.
return this.doConnect(SQLiteStorageDatabase.IN_MEMORY_PATH);
});
});
return await this.doConnect(path);
} catch (error) {
this.logger.error(`[storage ${this.name}] open(): Unable to use backup due to ${error}`);
// In case of any error to open the DB, use an in-memory
// DB so that we always have a valid DB to talk to.
return this.doConnect(SQLiteStorageDatabase.IN_MEMORY_PATH);
}
}
}
private handleSQLiteError(connection: IDatabaseConnection, error: Error & { code?: string }, msg: string): void {

View File

@@ -9,20 +9,19 @@ import * as stream from 'vs/base/node/stream';
import { getPathFromAmdModule } from 'vs/base/common/amd';
suite('Stream', () => {
test('readToMatchingString - ANSI', function () {
test('readToMatchingString - ANSI', async () => {
const file = getPathFromAmdModule(require, './fixtures/file.css');
return stream.readToMatchingString(file, '\n', 10, 100).then((result: string) => {
// \r may be present on Windows
assert.equal(result.replace('\r', ''), '/*---------------------------------------------------------------------------------------------');
});
const result = await stream.readToMatchingString(file, '\n', 10, 100);
// \r may be present on Windows
assert.equal(result!.replace('\r', ''), '/*---------------------------------------------------------------------------------------------');
});
test('readToMatchingString - empty', function () {
test('readToMatchingString - empty', async () => {
const file = getPathFromAmdModule(require, './fixtures/empty.txt');
return stream.readToMatchingString(file, '\n', 10, 100).then((result: string) => {
assert.equal(result, null);
});
const result = await stream.readToMatchingString(file, '\n', 10, 100);
assert.equal(result, null);
});
});