completionModel.ts 3.2 KB
Newer Older
1 2 3 4 5 6 7
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

'use strict';

A
Alex Dima 已提交
8 9
import {isFalsyOrEmpty} from 'vs/base/common/arrays';
import {assign} from 'vs/base/common/objects';
10
import URI from 'vs/base/common/uri';
A
Alex Dima 已提交
11 12 13 14 15
import {TPromise} from 'vs/base/common/winjs.base';
import {IPosition} from 'vs/editor/common/editorCommon';
import {ISuggestResult, ISuggestSupport, ISuggestion, ISuggestionFilter} from 'vs/editor/common/modes';
import {DefaultFilter, IMatch} from 'vs/editor/common/modes/modesFilters';
import {ISuggestResult2} from '../common/suggest';
16 17 18 19 20 21 22

export class CompletionItem {

	suggestion: ISuggestion;
	highlights: IMatch[];
	container: ISuggestResult;

23 24 25 26 27
	private _filter: ISuggestionFilter;
	private _support: ISuggestSupport;

	constructor(suggestion: ISuggestion, container: ISuggestResult2) {
		this._support = container.support;
28 29
		this.suggestion = suggestion;
		this.container = container;
30
		this._filter = container.support && container.support.getFilter() || DefaultFilter;
31 32
	}

A
Alex Dima 已提交
33
	resolveDetails(resource: URI, position: IPosition): TPromise<ISuggestion> {
34
		if (!this._support || typeof this._support.getSuggestionDetails !== 'function') {
35 36 37
			return TPromise.as(this.suggestion);
		}

38
		return this._support.getSuggestionDetails(resource, position, this.suggestion);
39 40 41 42 43 44
	}

	updateDetails(value: ISuggestion): void {
		this.suggestion = assign(this.suggestion, value);
	}

45 46 47
	updateHighlights(word: string): boolean {
		this.highlights = this._filter(word, this.suggestion);
		return !isFalsyOrEmpty(this.highlights);
48 49
	}

50 51 52
	static compare(item: CompletionItem, otherItem: CompletionItem): number {
		const suggestion = item.suggestion;
		const otherSuggestion = otherItem.suggestion;
53

54 55 56
		if (typeof suggestion.sortText === 'string' && typeof otherSuggestion.sortText === 'string') {
			const one = suggestion.sortText.toLowerCase();
			const other = otherSuggestion.sortText.toLowerCase();
57

58 59 60 61 62
			if (one < other) {
				return -1;
			} else if (one > other) {
				return 1;
			}
63 64
		}

65
		return suggestion.label.toLowerCase() < otherSuggestion.label.toLowerCase() ? -1 : 1;
66 67 68 69 70
	}
}

export class CompletionModel {

71 72 73
	private _currentWord: string;
	private _items: CompletionItem[] = [];
	private _filteredItems: CompletionItem[] = undefined;
74

75 76 77 78 79 80 81 82 83
	constructor(public raw: ISuggestResult2[], currentWord: string) {
		this._currentWord = currentWord;
		for (let container of raw) {
			for (let suggestion of container.suggestions) {
				this._items.push(new CompletionItem(suggestion, container));
			}
		}
		this._items.sort(CompletionItem.compare);
	}
84

85 86
	get currentWord(): string {
		return this._currentWord;
87 88
	}

89 90 91 92
	set currentWord(value: string) {
		if (this._currentWord !== value) {
			this._filteredItems = undefined;
			this._currentWord = value;
93
		}
94
	}
95

96 97 98 99 100 101 102 103
	get items(): CompletionItem[] {
		if (!this._filteredItems) {
			this._filteredItems = [];
			for (let item of this._items) {
				if (item.updateHighlights(this.currentWord)) {
					this._filteredItems.push(item);
				}
			}
104
		}
105
		return this._filteredItems;
106
	}
107

108
}