mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-14 18:46:34 -05:00
Merge from vscode 7eaf220cafb9d9e901370ffce02229171cbf3ea6
This commit is contained in:
committed by
Anthony Dresser
parent
39d9eed585
commit
a63578e6f7
@@ -590,17 +590,6 @@ export function asArray<T>(x: T | T[]): T[] {
|
||||
return Array.isArray(x) ? x : [x];
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use `Array.from` or `[...iter]`
|
||||
*/
|
||||
export function toArray<T>(iterable: IterableIterator<T>): T[] {
|
||||
const result: T[] = [];
|
||||
for (let element of iterable) {
|
||||
result.push(element);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export function getRandomElement<T>(arr: T[]): T | undefined {
|
||||
return arr[Math.floor(Math.random() * arr.length)];
|
||||
}
|
||||
|
||||
@@ -170,6 +170,25 @@ export class Sequencer {
|
||||
}
|
||||
}
|
||||
|
||||
export class SequencerByKey<TKey> {
|
||||
|
||||
private promiseMap = new Map<TKey, Promise<any>>();
|
||||
|
||||
queue<T>(key: TKey, promiseTask: ITask<Promise<T>>): Promise<T> {
|
||||
const runningPromise = this.promiseMap.get(key) ?? Promise.resolve();
|
||||
const newPromise = runningPromise
|
||||
.catch(() => { })
|
||||
.then(promiseTask)
|
||||
.finally(() => {
|
||||
if (this.promiseMap.get(key) === newPromise) {
|
||||
this.promiseMap.delete(key);
|
||||
}
|
||||
});
|
||||
this.promiseMap.set(key, newPromise);
|
||||
return newPromise;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A helper to delay execution of a task that is being requested often.
|
||||
*
|
||||
|
||||
@@ -499,7 +499,11 @@ export function markdownUnescapeCodicons(text: string): string {
|
||||
return text.replace(markdownUnescapeCodiconsRegex, (match, escaped, codicon) => escaped ? match : `$(${codicon})`);
|
||||
}
|
||||
|
||||
const renderCodiconsRegex = /(\\)?\$\((([a-z0-9\-]+?)(?:~([a-z0-9\-]*?))?)\)/gi;
|
||||
export const renderCodiconsRegex = /(\\)?\$\((([a-z0-9\-]+?)(?:~([a-z0-9\-]*?))?)\)/gi;
|
||||
|
||||
/**
|
||||
* @deprecated Use `renderCodiconsAsElement` instead
|
||||
*/
|
||||
export function renderCodicons(text: string): string {
|
||||
return text.replace(renderCodiconsRegex, (_, escaped, codicon, name, animation) => {
|
||||
// If the class for codicons is changed, it should also be updated in src\vs\base\browser\markdownRenderer.ts
|
||||
|
||||
@@ -142,7 +142,7 @@ export function isUNC(path: string): boolean {
|
||||
// Reference: https://en.wikipedia.org/wiki/Filename
|
||||
const WINDOWS_INVALID_FILE_CHARS = /[\\/:\*\?"<>\|]/g;
|
||||
const UNIX_INVALID_FILE_CHARS = /[\\/]/g;
|
||||
const WINDOWS_FORBIDDEN_NAMES = /^(con|prn|aux|clock\$|nul|lpt[0-9]|com[0-9])$/i;
|
||||
const WINDOWS_FORBIDDEN_NAMES = /^(con|prn|aux|clock\$|nul|lpt[0-9]|com[0-9])(\.(.*?))?$/i;
|
||||
export function isValidBasename(name: string | null | undefined, isWindowsOS: boolean = isWindows): boolean {
|
||||
const invalidFileChars = isWindowsOS ? WINDOWS_INVALID_FILE_CHARS : UNIX_INVALID_FILE_CHARS;
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { compareAnything } from 'vs/base/common/comparers';
|
||||
import { matchesPrefix, IMatch, isUpper, fuzzyScore, createMatches as createFuzzyMatches, matchesStrictPrefix } from 'vs/base/common/filters';
|
||||
import { matchesPrefix, IMatch, isUpper, fuzzyScore, createMatches as createFuzzyMatches } from 'vs/base/common/filters';
|
||||
import { sep } from 'vs/base/common/path';
|
||||
import { isWindows, isLinux } from 'vs/base/common/platform';
|
||||
import { stripWildcards, equalsIgnoreCase } from 'vs/base/common/strings';
|
||||
@@ -369,9 +369,8 @@ export interface IItemAccessor<T> {
|
||||
}
|
||||
|
||||
const PATH_IDENTITY_SCORE = 1 << 18;
|
||||
const LABEL_PREFIX_SCORE_MATCHCASE = 1 << 17;
|
||||
const LABEL_PREFIX_SCORE_IGNORECASE = 1 << 16;
|
||||
const LABEL_SCORE_THRESHOLD = 1 << 15;
|
||||
const LABEL_PREFIX_SCORE_THRESHOLD = 1 << 17;
|
||||
const LABEL_SCORE_THRESHOLD = 1 << 16;
|
||||
|
||||
export function scoreItemFuzzy<T>(item: T, query: IPreparedQuery, fuzzy: boolean, accessor: IItemAccessor<T>, cache: FuzzyScorerCache): IItemScore {
|
||||
if (!item || !query.normalized) {
|
||||
@@ -460,20 +459,33 @@ function doScoreItemFuzzyMultiple(label: string, description: string | undefined
|
||||
|
||||
function doScoreItemFuzzySingle(label: string, description: string | undefined, path: string | undefined, query: IPreparedQueryPiece, preferLabelMatches: boolean, fuzzy: boolean): IItemScore {
|
||||
|
||||
// Prefer label matches if told so
|
||||
if (preferLabelMatches) {
|
||||
|
||||
// Treat prefix matches on the label highest
|
||||
const prefixLabelMatchIgnoreCase = matchesPrefix(query.normalized, label);
|
||||
if (prefixLabelMatchIgnoreCase) {
|
||||
const prefixLabelMatchStrictCase = matchesStrictPrefix(query.normalized, label);
|
||||
return { score: prefixLabelMatchStrictCase ? LABEL_PREFIX_SCORE_MATCHCASE : LABEL_PREFIX_SCORE_IGNORECASE, labelMatch: prefixLabelMatchStrictCase || prefixLabelMatchIgnoreCase };
|
||||
}
|
||||
|
||||
// Second, score fuzzy
|
||||
// Prefer label matches if told so or we have no description
|
||||
if (preferLabelMatches || !description) {
|
||||
const [labelScore, labelPositions] = scoreFuzzy(label, query.normalized, query.normalizedLowercase, fuzzy);
|
||||
if (labelScore) {
|
||||
return { score: labelScore + LABEL_SCORE_THRESHOLD, labelMatch: createMatches(labelPositions) };
|
||||
|
||||
// If we have a prefix match on the label, we give a much
|
||||
// higher baseScore to elevate these matches over others
|
||||
// This ensures that typing a file name wins over results
|
||||
// that are present somewhere in the label, but not the
|
||||
// beginning.
|
||||
const labelPrefixMatch = matchesPrefix(query.normalized, label);
|
||||
let baseScore: number;
|
||||
if (labelPrefixMatch) {
|
||||
baseScore = LABEL_PREFIX_SCORE_THRESHOLD;
|
||||
|
||||
// We give another boost to labels that are short, e.g. given
|
||||
// files "window.ts" and "windowActions.ts" and a query of
|
||||
// "window", we want "window.ts" to receive a higher score.
|
||||
// As such we compute the percentage the query has within the
|
||||
// label and add that to the baseScore.
|
||||
const prefixLengthBoost = Math.round((query.normalized.length / label.length) * 100);
|
||||
baseScore += prefixLengthBoost;
|
||||
} else {
|
||||
baseScore = LABEL_SCORE_THRESHOLD;
|
||||
}
|
||||
|
||||
return { score: baseScore + labelScore, labelMatch: labelPrefixMatch || createMatches(labelPositions) };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -600,46 +612,19 @@ export function compareItemsByFuzzyScore<T>(itemA: T, itemB: T, query: IPrepared
|
||||
}
|
||||
}
|
||||
|
||||
// 2.) prefer label prefix matches (match case)
|
||||
if (scoreA === LABEL_PREFIX_SCORE_MATCHCASE || scoreB === LABEL_PREFIX_SCORE_MATCHCASE) {
|
||||
if (scoreA !== scoreB) {
|
||||
return scoreA === LABEL_PREFIX_SCORE_MATCHCASE ? -1 : 1;
|
||||
}
|
||||
|
||||
const labelA = accessor.getItemLabel(itemA) || '';
|
||||
const labelB = accessor.getItemLabel(itemB) || '';
|
||||
|
||||
// prefer shorter names when both match on label prefix
|
||||
if (labelA.length !== labelB.length) {
|
||||
return labelA.length - labelB.length;
|
||||
}
|
||||
}
|
||||
|
||||
// 3.) prefer label prefix matches (ignore case)
|
||||
if (scoreA === LABEL_PREFIX_SCORE_IGNORECASE || scoreB === LABEL_PREFIX_SCORE_IGNORECASE) {
|
||||
if (scoreA !== scoreB) {
|
||||
return scoreA === LABEL_PREFIX_SCORE_IGNORECASE ? -1 : 1;
|
||||
}
|
||||
|
||||
const labelA = accessor.getItemLabel(itemA) || '';
|
||||
const labelB = accessor.getItemLabel(itemB) || '';
|
||||
|
||||
// prefer shorter names when both match on label prefix
|
||||
if (labelA.length !== labelB.length) {
|
||||
return labelA.length - labelB.length;
|
||||
}
|
||||
}
|
||||
|
||||
// 4.) matches on label are considered higher compared to label+description matches
|
||||
// 2.) matches on label are considered higher compared to label+description matches
|
||||
if (scoreA > LABEL_SCORE_THRESHOLD || scoreB > LABEL_SCORE_THRESHOLD) {
|
||||
if (scoreA !== scoreB) {
|
||||
return scoreA > scoreB ? -1 : 1;
|
||||
}
|
||||
|
||||
// prefer more compact matches over longer in label
|
||||
const comparedByMatchLength = compareByMatchLength(itemScoreA.labelMatch, itemScoreB.labelMatch);
|
||||
if (comparedByMatchLength !== 0) {
|
||||
return comparedByMatchLength;
|
||||
// prefer more compact matches over longer in label (unless this is a prefix match where
|
||||
// longer prefix matches are actually preferred)
|
||||
if (scoreA < LABEL_PREFIX_SCORE_THRESHOLD && scoreB < LABEL_PREFIX_SCORE_THRESHOLD) {
|
||||
const comparedByMatchLength = compareByMatchLength(itemScoreA.labelMatch, itemScoreB.labelMatch);
|
||||
if (comparedByMatchLength !== 0) {
|
||||
return comparedByMatchLength;
|
||||
}
|
||||
}
|
||||
|
||||
// prefer shorter labels over longer labels
|
||||
@@ -650,12 +635,12 @@ export function compareItemsByFuzzyScore<T>(itemA: T, itemB: T, query: IPrepared
|
||||
}
|
||||
}
|
||||
|
||||
// 5.) compare by score in label+description
|
||||
// 3.) compare by score in label+description
|
||||
if (scoreA !== scoreB) {
|
||||
return scoreA > scoreB ? -1 : 1;
|
||||
}
|
||||
|
||||
// 6.) scores are identical: prefer matches in label over non-label matches
|
||||
// 4.) scores are identical: prefer matches in label over non-label matches
|
||||
const itemAHasLabelMatches = Array.isArray(itemScoreA.labelMatch) && itemScoreA.labelMatch.length > 0;
|
||||
const itemBHasLabelMatches = Array.isArray(itemScoreB.labelMatch) && itemScoreB.labelMatch.length > 0;
|
||||
if (itemAHasLabelMatches && !itemBHasLabelMatches) {
|
||||
@@ -664,14 +649,14 @@ export function compareItemsByFuzzyScore<T>(itemA: T, itemB: T, query: IPrepared
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 7.) scores are identical: prefer more compact matches (label and description)
|
||||
// 5.) scores are identical: prefer more compact matches (label and description)
|
||||
const itemAMatchDistance = computeLabelAndDescriptionMatchDistance(itemA, itemScoreA, accessor);
|
||||
const itemBMatchDistance = computeLabelAndDescriptionMatchDistance(itemB, itemScoreB, accessor);
|
||||
if (itemAMatchDistance && itemBMatchDistance && itemAMatchDistance !== itemBMatchDistance) {
|
||||
return itemBMatchDistance > itemAMatchDistance ? -1 : 1;
|
||||
}
|
||||
|
||||
// 8.) scores are identical: start to use the fallback compare
|
||||
// 6.) scores are identical: start to use the fallback compare
|
||||
return fallbackCompare(itemA, itemB, query, accessor);
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ export class MarkdownString implements IMarkdownString {
|
||||
// escape markdown syntax tokens: http://daringfireball.net/projects/markdown/syntax#backslash
|
||||
this._value += (this._supportThemeIcons ? escapeCodicons(value) : value)
|
||||
.replace(/[\\`*_{}[\]()#+\-.!]/g, '\\$&')
|
||||
.replace('\n', '\n\n');
|
||||
.replace(/\n/g, '\n\n');
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import { VSBuffer } from 'vs/base/common/buffer';
|
||||
import { regExpFlags } from 'vs/base/common/strings';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { URI, UriComponents } from 'vs/base/common/uri';
|
||||
|
||||
export function stringify(obj: any): string {
|
||||
return JSON.stringify(obj, replacer);
|
||||
@@ -33,7 +33,15 @@ function replacer(key: string, value: any): any {
|
||||
return value;
|
||||
}
|
||||
|
||||
export function revive(obj: any, depth = 0): any {
|
||||
|
||||
type Deserialize<T> = T extends UriComponents ? URI
|
||||
: T extends object
|
||||
? Revived<T>
|
||||
: T;
|
||||
|
||||
export type Revived<T> = { [K in keyof T]: Deserialize<T[K]> };
|
||||
|
||||
export function revive<T = any>(obj: any, depth = 0): Revived<T> {
|
||||
if (!obj || depth > 200) {
|
||||
return obj;
|
||||
}
|
||||
@@ -41,15 +49,15 @@ export function revive(obj: any, depth = 0): any {
|
||||
if (typeof obj === 'object') {
|
||||
|
||||
switch ((<MarshalledObject>obj).$mid) {
|
||||
case 1: return URI.revive(obj);
|
||||
case 2: return new RegExp(obj.source, obj.flags);
|
||||
case 1: return <any>URI.revive(obj);
|
||||
case 2: return <any>new RegExp(obj.source, obj.flags);
|
||||
}
|
||||
|
||||
if (
|
||||
obj instanceof VSBuffer
|
||||
|| obj instanceof Uint8Array
|
||||
) {
|
||||
return obj;
|
||||
return <any>obj;
|
||||
}
|
||||
|
||||
if (Array.isArray(obj)) {
|
||||
|
||||
@@ -33,7 +33,7 @@ export interface ReadableStreamEvents<T> {
|
||||
|
||||
/**
|
||||
* A interface that emulates the API shape of a node.js readable
|
||||
* stream for use in desktop and web environments.
|
||||
* stream for use in native and web environments.
|
||||
*/
|
||||
export interface ReadableStream<T> extends ReadableStreamEvents<T> {
|
||||
|
||||
@@ -60,7 +60,7 @@ export interface ReadableStream<T> extends ReadableStreamEvents<T> {
|
||||
|
||||
/**
|
||||
* A interface that emulates the API shape of a node.js readable
|
||||
* for use in desktop and web environments.
|
||||
* for use in native and web environments.
|
||||
*/
|
||||
export interface Readable<T> {
|
||||
|
||||
@@ -73,7 +73,7 @@ export interface Readable<T> {
|
||||
|
||||
/**
|
||||
* A interface that emulates the API shape of a node.js writeable
|
||||
* stream for use in desktop and web environments.
|
||||
* stream for use in native and web environments.
|
||||
*/
|
||||
export interface WriteableStream<T> extends ReadableStream<T> {
|
||||
|
||||
|
||||
@@ -258,14 +258,12 @@ export type UriDto<T> = { [K in keyof T]: T[K] extends URI
|
||||
/**
|
||||
* Mapped-type that replaces all occurrences of URI with UriComponents and
|
||||
* drops all functions.
|
||||
* todo@joh use toJSON-results
|
||||
*/
|
||||
export type Dto<T> = { [K in keyof T]: T[K] extends URI
|
||||
? UriComponents
|
||||
: T[K] extends Function
|
||||
? never
|
||||
: UriDto<T[K]> };
|
||||
|
||||
export type Dto<T> = T extends { toJSON(): infer U }
|
||||
? U
|
||||
: T extends object
|
||||
? { [k in keyof T]: Dto<T[k]>; }
|
||||
: T;
|
||||
|
||||
export function NotImplementedProxy<T>(name: string): { new(): T } {
|
||||
return <any>class {
|
||||
|
||||
Reference in New Issue
Block a user