mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-03-22 12:50:29 -04:00
Merge VS Code 1.21 source code (#1067)
* Initial VS Code 1.21 file copy with patches * A few more merges * Post npm install * Fix batch of build breaks * Fix more build breaks * Fix more build errors * Fix more build breaks * Runtime fixes 1 * Get connection dialog working with some todos * Fix a few packaging issues * Copy several node_modules to package build to fix loader issues * Fix breaks from master * A few more fixes * Make tests pass * First pass of license header updates * Second pass of license header updates * Fix restore dialog issues * Remove add additional themes menu items * fix select box issues where the list doesn't show up * formatting * Fix editor dispose issue * Copy over node modules to correct location on all platforms
This commit is contained in:
@@ -5,103 +5,210 @@
|
||||
'use strict';
|
||||
|
||||
import { ICompletionItem } from 'vs/editor/contrib/suggest/completionModel';
|
||||
import { LRUCache } from 'vs/base/common/map';
|
||||
import { LanguageIdentifier } from 'vs/editor/common/modes';
|
||||
import { LRUCache, TernarySearchTree } from 'vs/base/common/map';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { ITextModel } from 'vs/editor/common/model';
|
||||
import { IPosition } from 'vs/editor/common/core/position';
|
||||
import { RunOnceScheduler } from 'vs/base/common/async';
|
||||
|
||||
export class SuggestMemories {
|
||||
export abstract class Memory {
|
||||
|
||||
private readonly _storagePrefix = 'suggest/memories';
|
||||
private readonly _data = new Map<string, SuggestMemory>();
|
||||
abstract memorize(model: ITextModel, pos: IPosition, item: ICompletionItem): void;
|
||||
|
||||
constructor(
|
||||
@IStorageService private _storageService: IStorageService
|
||||
) {
|
||||
abstract select(model: ITextModel, pos: IPosition, items: ICompletionItem[]): number;
|
||||
|
||||
abstract toJSON(): object;
|
||||
|
||||
abstract fromJSON(data: object): void;
|
||||
}
|
||||
|
||||
export class NoMemory extends Memory {
|
||||
|
||||
memorize(model: ITextModel, pos: IPosition, item: ICompletionItem): void {
|
||||
// no-op
|
||||
}
|
||||
|
||||
select(model: ITextModel, pos: IPosition, items: ICompletionItem[]): number {
|
||||
return 0;
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
fromJSON() {
|
||||
//
|
||||
}
|
||||
}
|
||||
|
||||
remember({ language }: LanguageIdentifier, item: ICompletionItem): void {
|
||||
let memory = this._data.get(language);
|
||||
if (!memory) {
|
||||
memory = new SuggestMemory();
|
||||
this._data.set(language, memory);
|
||||
}
|
||||
memory.remember(item);
|
||||
this._storageService.store(`${this._storagePrefix}/${language}`, JSON.stringify(memory), StorageScope.WORKSPACE);
|
||||
export interface MemItem {
|
||||
type: string;
|
||||
insertText: string;
|
||||
touch: number;
|
||||
}
|
||||
|
||||
export class LRUMemory extends Memory {
|
||||
|
||||
private _cache = new LRUCache<string, MemItem>(300, .66);
|
||||
private _seq = 0;
|
||||
|
||||
memorize(model: ITextModel, pos: IPosition, item: ICompletionItem): void {
|
||||
const { label } = item.suggestion;
|
||||
const key = `${model.getLanguageIdentifier().language}/${label}`;
|
||||
this._cache.set(key, {
|
||||
touch: this._seq++,
|
||||
type: item.suggestion.type,
|
||||
insertText: undefined
|
||||
});
|
||||
}
|
||||
|
||||
select({ language }: LanguageIdentifier, items: ICompletionItem[], last: ICompletionItem): number {
|
||||
let memory = this._data.get(language);
|
||||
if (!memory) {
|
||||
const key: string = `${this._storagePrefix}/${language}`;
|
||||
const raw = this._storageService.get(key, StorageScope.WORKSPACE);
|
||||
if (raw) {
|
||||
try {
|
||||
const tuples = <[string, MemoryItem][]>JSON.parse(raw);
|
||||
memory = new SuggestMemory(tuples);
|
||||
last = undefined;
|
||||
this._data.set(language, memory);
|
||||
} catch (e) {
|
||||
this._storageService.remove(key, StorageScope.WORKSPACE);
|
||||
select(model: ITextModel, pos: IPosition, items: ICompletionItem[]): number {
|
||||
// in order of completions, select the first
|
||||
// that has been used in the past
|
||||
let { word } = model.getWordUntilPosition(pos);
|
||||
|
||||
let res = 0;
|
||||
let seq = -1;
|
||||
if (word.length === 0) {
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
const { suggestion } = items[i];
|
||||
const key = `${model.getLanguageIdentifier().language}/${suggestion.label}`;
|
||||
const item = this._cache.get(key);
|
||||
if (item && item.touch > seq && item.type === suggestion.type) {
|
||||
seq = item.touch;
|
||||
res = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (memory) {
|
||||
return memory.select(items, last);
|
||||
} else {
|
||||
return -1;
|
||||
return res;
|
||||
}
|
||||
|
||||
toJSON(): object {
|
||||
let data: [string, MemItem][] = [];
|
||||
this._cache.forEach((value, key) => {
|
||||
data.push([key, value]);
|
||||
});
|
||||
return data;
|
||||
}
|
||||
|
||||
fromJSON(data: [string, MemItem][]): void {
|
||||
this._cache.clear();
|
||||
let seq = 0;
|
||||
for (const [key, value] of data) {
|
||||
value.touch = seq;
|
||||
this._cache.set(key, value);
|
||||
}
|
||||
this._seq = this._cache.size;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export interface MemoryItem {
|
||||
type: string;
|
||||
insertText: string;
|
||||
}
|
||||
export class PrefixMemory extends Memory {
|
||||
|
||||
export class SuggestMemory {
|
||||
private _trie = TernarySearchTree.forStrings<MemItem>();
|
||||
private _seq = 0;
|
||||
|
||||
private readonly _memory = new LRUCache<string, MemoryItem>(400, 0.75);
|
||||
|
||||
constructor(tuples?: [string, MemoryItem][]) {
|
||||
if (tuples) {
|
||||
for (const [word, item] of tuples) {
|
||||
this._memory.set(word, item);
|
||||
}
|
||||
}
|
||||
memorize(model: ITextModel, pos: IPosition, item: ICompletionItem): void {
|
||||
const { word } = model.getWordUntilPosition(pos);
|
||||
const key = `${model.getLanguageIdentifier().language}/${word}`;
|
||||
this._trie.set(key, {
|
||||
type: item.suggestion.type,
|
||||
insertText: item.suggestion.insertText,
|
||||
touch: this._seq++
|
||||
});
|
||||
}
|
||||
|
||||
remember(item: ICompletionItem): void {
|
||||
if (item.word) {
|
||||
this._memory.set(item.word, { insertText: item.suggestion.insertText, type: item.suggestion.type });
|
||||
select(model: ITextModel, pos: IPosition, items: ICompletionItem[]): number {
|
||||
let { word } = model.getWordUntilPosition(pos);
|
||||
if (!word) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
select(items: ICompletionItem[], last: ICompletionItem): number {
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
if (items[i] === last) {
|
||||
// prefer the last selected item when
|
||||
// there is one
|
||||
return i;
|
||||
}
|
||||
if (items[i].word) {
|
||||
const item = this._memory.get(items[i].word);
|
||||
if (this._matches(item, items[i])) {
|
||||
let key = `${model.getLanguageIdentifier().language}/${word}`;
|
||||
let item = this._trie.get(key);
|
||||
if (!item) {
|
||||
item = this._trie.findSubstr(key);
|
||||
}
|
||||
if (item) {
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
let { type, insertText } = items[i].suggestion;
|
||||
if (type === item.type && insertText === item.insertText) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
private _matches(item: MemoryItem, candidate: ICompletionItem): boolean {
|
||||
return item && item.insertText === candidate.suggestion.insertText && item.type === candidate.suggestion.type;
|
||||
toJSON(): object {
|
||||
|
||||
let entries: [string, MemItem][] = [];
|
||||
this._trie.forEach((value, key) => entries.push([key, value]));
|
||||
|
||||
// sort by last recently used (touch), then
|
||||
// take the top 200 item and normalize their
|
||||
// touch
|
||||
entries
|
||||
.sort((a, b) => -(a[1].touch - b[1].touch))
|
||||
.forEach((value, i) => value[1].touch = i);
|
||||
|
||||
return entries.slice(0, 200);
|
||||
}
|
||||
|
||||
toJSON(): [string, MemoryItem][] {
|
||||
const tuples: [string, MemoryItem][] = [];
|
||||
this._memory.forEach((value, key) => tuples.push([key, value]));
|
||||
return tuples;
|
||||
fromJSON(data: [string, MemItem][]): void {
|
||||
this._trie.clear();
|
||||
if (data.length > 0) {
|
||||
this._seq = data[0][1].touch + 1;
|
||||
for (const [key, value] of data) {
|
||||
this._trie.set(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export type MemMode = 'first' | 'recentlyUsed' | 'recentlyUsedByPrefix';
|
||||
|
||||
export class SuggestMemories {
|
||||
|
||||
private readonly _storagePrefix = 'suggest/memories';
|
||||
|
||||
private _mode: MemMode;
|
||||
private _strategy: Memory;
|
||||
private _persistSoon: RunOnceScheduler;
|
||||
|
||||
constructor(
|
||||
mode: MemMode,
|
||||
@IStorageService private readonly _storageService: IStorageService
|
||||
) {
|
||||
this._persistSoon = new RunOnceScheduler(() => this._flush(), 3000);
|
||||
this.setMode(mode);
|
||||
}
|
||||
|
||||
setMode(mode: MemMode): void {
|
||||
if (this._mode === mode) {
|
||||
return;
|
||||
}
|
||||
this._mode = mode;
|
||||
this._strategy = mode === 'recentlyUsedByPrefix' ? new PrefixMemory() : mode === 'recentlyUsed' ? new LRUMemory() : new NoMemory();
|
||||
|
||||
try {
|
||||
const raw = this._storageService.get(`${this._storagePrefix}/${this._mode}`, StorageScope.WORKSPACE);
|
||||
this._strategy.fromJSON(JSON.parse(raw));
|
||||
} catch (e) {
|
||||
// things can go wrong with JSON...
|
||||
}
|
||||
}
|
||||
|
||||
memorize(model: ITextModel, pos: IPosition, item: ICompletionItem): void {
|
||||
this._strategy.memorize(model, pos, item);
|
||||
this._persistSoon.schedule();
|
||||
}
|
||||
|
||||
select(model: ITextModel, pos: IPosition, items: ICompletionItem[]): number {
|
||||
return this._strategy.select(model, pos, items);
|
||||
}
|
||||
|
||||
private _flush() {
|
||||
const raw = JSON.stringify(this._strategy);
|
||||
this._storageService.store(`${this._storagePrefix}/${this._mode}`, raw, StorageScope.WORKSPACE);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user