提交 9f7989d3 编写于 作者: J João Moreno

Merge pull request #1079 from joaomoreno/suggest

Suggest cleanup
......@@ -36,13 +36,11 @@ export class ArrayIterator<T> implements IIterator<T> {
export class MappedIterator<T, R> implements IIterator<R> {
constructor(private iterator: IIterator<T>, private fn: (item:T)=>R) {
constructor(protected iterator: IIterator<T>, protected fn: (item:T)=>R) {
// noop
}
public next(): R {
return this.fn(this.iterator.next());
}
next() { return this.fn(this.iterator.next()); }
}
export interface INavigator<T> extends IIterator<T> {
......@@ -52,3 +50,16 @@ export interface INavigator<T> extends IIterator<T> {
first(): T;
last(): T;
}
export class MappedNavigator<T, R> extends MappedIterator<T, R> implements INavigator<R> {
constructor(protected navigator: INavigator<T>, fn: (item:T)=>R) {
super(navigator, fn);
}
current() { return this.fn(this.navigator.current()); }
previous() { return this.fn(this.navigator.previous()); }
parent() { return this.fn(this.navigator.parent()); }
first() { return this.fn(this.navigator.first()); }
last() { return this.fn(this.navigator.last()); }
}
......@@ -11,6 +11,7 @@ import Events = require('vs/base/common/eventEmitter');
import Model = require('vs/base/parts/tree/common/treeModel');
import View = require('./treeView');
import _ = require('vs/base/parts/tree/common/tree');
import { INavigator, MappedNavigator } from 'vs/base/common/iterator';
export class TreeContext implements _.ITreeContext {
......@@ -165,6 +166,10 @@ export class Tree extends Events.EventEmitter implements _.ITree {
this.view.setScrollPosition(pos);
}
getContentHeight(): number {
return this.view.getTotalHeight();
}
public setHighlight(element?:any, eventPayload?:any):void {
this.model.setHighlight(element, eventPayload);
}
......@@ -306,6 +311,10 @@ export class Tree extends Events.EventEmitter implements _.ITree {
return this.view.withFakeRow(fn);
}
getNavigator(): INavigator<any> {
return new MappedNavigator(this.model.getNavigator(), i => i && i.getElement());
}
public dispose(): void {
if (this.model !== null) {
this.model.dispose();
......
......@@ -9,6 +9,7 @@ import Touch = require('vs/base/browser/touch');
import Events = require('vs/base/common/eventEmitter');
import Mouse = require('vs/base/browser/mouseEvent');
import Keyboard = require('vs/base/browser/keyboardEvent');
import { INavigator } from 'vs/base/common/iterator';
export interface ITree extends Events.IEventEmitter {
......@@ -132,6 +133,11 @@ export interface ITree extends Events.IEventEmitter {
*/
setScrollPosition(pos: number): void;
/**
* Returns the total height of the tree's content.
*/
getContentHeight(): number;
/**
* Sets the tree's highlight to be the given element.
* Provide no arguments and it clears the tree's highlight.
......@@ -309,6 +315,12 @@ export interface ITree extends Events.IEventEmitter {
*/
withFakeRow(fn:(container:HTMLElement)=>any):any;
/**
* Returns a navigator which allows to discover the visible and
* expanded elements in the tree.
*/
getNavigator(): INavigator<any>;
/**
* Disposes the tree
*/
......
......@@ -458,7 +458,7 @@ export class Item extends Events.EventEmitter {
public getHierarchy(): Item[] {
var result: Item[] = [];
var node = this;
var node: Item = this;
do {
result.push(node);
......
......@@ -409,7 +409,7 @@ export interface ISuggestionFilter {
(word: string, suggestion: ISuggestion): IMatch[];
}
export interface ISuggestionSorter {
export interface ISuggestionCompare {
(one: ISuggestion, other: ISuggestion): number;
}
......@@ -429,7 +429,7 @@ export interface ISuggestSupport {
getSuggestionDetails?:(resource:URI, position:EditorCommon.IPosition, suggestion:ISuggestion)=>TPromise<ISuggestion>;
getFilter():ISuggestionFilter;
getSorter?():ISuggestionSorter;
getSorter?():ISuggestionCompare;
getTriggerCharacters():string[];
shouldShowEmptySuggestionList():boolean;
shouldAutotriggerSuggest(context:ILineContext, offset:number, triggeredByCharacter:string):boolean;
......
......@@ -25,15 +25,11 @@ export var ContiguousSubString: ISuggestionFilter = wrapBaseFilter(Filters.match
// Combined Filters
export function or(first: ISuggestionFilter, second: ISuggestionFilter): ISuggestionFilter {
return (word: string, suggestion: ISuggestion): Filters.IMatch[] => {
return first(word, suggestion) || second(word, suggestion);
};
return (word, suggestion) => first(word, suggestion) || second(word, suggestion);
}
export function and(first: ISuggestionFilter, second: ISuggestionFilter): ISuggestionFilter {
return (word: string, suggestion: ISuggestion): Filters.IMatch[] => {
return first(word, suggestion) && second(word, suggestion);
};
return (word, suggestion) => first(word, suggestion) && second(word, suggestion);
}
export var DefaultFilter = or(or(Prefix, CamelCase), ContiguousSubString);
\ No newline at end of file
......@@ -776,7 +776,7 @@ export class SuggestSupport extends AbstractSupport implements Modes.ISuggestSup
return DefaultFilter;
}
public getSorter(): Modes.ISuggestionSorter {
public getSorter(): Modes.ISuggestionCompare {
return (one, other) => {
if (this.sortByType.length > 0) {
var oneTypeIndex = this.sortByType.indexOf(one.type);
......
......@@ -26,43 +26,31 @@
line-height: 1.3em;
}
.monaco-editor .suggest-widget > .message {
padding-left: 22px;
opacity: 0.7;
}
.monaco-editor .suggest-widget > .tree {
height: 100%;
width: 100%;
}
.monaco-editor .suggest-widget .monaco-tree .monaco-tree-row > .content {
-mox-box-sizing: border-box;
box-sizing: border-box;
line-height: 1.2em;
padding: 2px 10px 2px 2px;
padding: 2px 10px 2px 22px;
background-repeat: no-repeat;
background-position: 2px 2px;
white-space: nowrap;
}
.monaco-editor .suggest-widget .monaco-tree .monaco-tree-row > .content > * {
float: left;
}
.monaco-editor .suggest-widget .monaco-tree .monaco-tree-row > .content:after {
content:"";
clear: both;
display: block;
visibility: hidden;
height: 0;
}
.monaco-editor .suggest-widget .monaco-tree .monaco-tree-row > .content .text {
width: -webkit-calc(100% - 16px);
width: -moz-calc(100% - 16px);
width: -ms-calc(100% - 16px);
width: -o-calc(100% - 16px);
width: calc(100% - 16px);
overflow: hidden;
text-overflow: ellipsis;
padding-left: 6px;
-webkit-box-sizing: border-box;
-o-box-sizing: border-box;
-moz-box-sizing: border-box;
-ms-box-sizing: border-box;
box-sizing: border-box;
}
.monaco-editor .suggest-widget .monaco-tree .monaco-tree-row > .content .docs {
display: none;
max-height: 3.4em;
......@@ -79,15 +67,11 @@
opacity: 1;
}
.monaco-editor .suggest-widget .monaco-tree .monaco-tree-row > .content .monaco-highlighted-label .highlight {
.monaco-editor .suggest-widget:not(.frozen) .monaco-tree .monaco-tree-row > .content .monaco-highlighted-label .highlight {
font-weight: bold;
color: #186B9E;
}
.monaco-editor .suggest-widget.empty .monaco-tree .monaco-tree-row > .content .monaco-highlighted-label .highlight {
background-color: inherit;
}
.monaco-editor .suggest-widget .monaco-tree .monaco-tree-row > .content .type-label {
display: none;
margin-left: 0.8em;
......@@ -95,17 +79,19 @@
color: #0035DD;
}
.monaco-editor .suggest-widget .monaco-tree .monaco-tree-row.fake > .content .type-label,
.monaco-editor .suggest-widget .monaco-tree .monaco-tree-row.focused > .content .type-label {
display: inline;
}
.monaco-editor .suggest-widget .monaco-tree .monaco-tree-row.fake > .content .docs,
.monaco-editor .suggest-widget .monaco-tree .monaco-tree-row.focused > .content .docs {
display: block;
}
.monaco-editor .suggest-widget .monaco-tree .monaco-tree-row > .content .icon {
position: absolute;
display: block;
left: 1px;
top: 2px;
background-image: url('symbol-sprite.svg');
background-repeat: no-repeat;
height: 16px;
......@@ -150,14 +136,10 @@
border: 1px solid rgb(69, 69, 69);
}
.monaco-editor.vs-dark .suggest-widget .monaco-tree .monaco-tree-row > .content .monaco-highlighted-label .highlight {
.monaco-editor.vs-dark .suggest-widget:not(.frozen) .monaco-tree .monaco-tree-row > .content .monaco-highlighted-label .highlight {
color: #219AE4;
}
.monaco-editor.vs-dark .suggest-widget.empty .monaco-tree .monaco-tree-row > .content .monaco-highlighted-label .highlight {
color: inherit;
}
.monaco-editor.vs-dark .suggest-widget .monaco-tree .monaco-tree-row > .content .docs {
color: #C07A7A;
}
......@@ -195,14 +177,10 @@
border: 2px solid #6FC3DF;
}
.monaco-editor.hc-black .suggest-widget .monaco-tree .monaco-tree-row > .content .monaco-highlighted-label .highlight {
.monaco-editor.hc-black .suggest-widget:not(.frozen) .monaco-tree .monaco-tree-row > .content .monaco-highlighted-label .highlight {
color: #219AE4;
}
.monaco-editor.hc-black .suggest-widget.empty .monaco-tree .monaco-tree-row > .content .monaco-highlighted-label .highlight {
color: inherit;
}
.monaco-editor.hc-black .suggest-widget .monaco-tree .monaco-tree-row > .content .docs {
color: #C07A7A;
}
......
......@@ -7,22 +7,22 @@
import nls = require('vs/nls');
import Lifecycle = require('vs/base/common/lifecycle');
import Snippet = require('vs/editor/contrib/snippet/common/snippet');
import SuggestWidget = require('./suggestWidget');
import SuggestModel = require('./suggestModel');
import { SuggestWidget } from './suggestWidget';
import { SuggestModel } from './suggestModel';
import Errors = require('vs/base/common/errors');
import {TPromise} from 'vs/base/common/winjs.base';
import {EditorBrowserRegistry} from 'vs/editor/browser/editorBrowserExtensions';
import {CommonEditorRegistry, ContextKey, EditorActionDescriptor} from 'vs/editor/common/editorCommonExtensions';
import {EditorAction, Behaviour} from 'vs/editor/common/editorAction';
import { TPromise } from 'vs/base/common/winjs.base';
import { EditorBrowserRegistry } from 'vs/editor/browser/editorBrowserExtensions';
import { CommonEditorRegistry, ContextKey, EditorActionDescriptor } from 'vs/editor/common/editorCommonExtensions';
import { EditorAction, Behaviour } from 'vs/editor/common/editorAction';
import EditorBrowser = require('vs/editor/browser/editorBrowser');
import EditorCommon = require('vs/editor/common/editorCommon');
import Modes = require('vs/editor/common/modes');
import EventEmitter = require('vs/base/common/eventEmitter');
import {IKeybindingService, IKeybindingContextKey} from 'vs/platform/keybinding/common/keybindingService';
import {ITelemetryService} from 'vs/platform/telemetry/common/telemetry';
import {SuggestRegistry, ACCEPT_SELECTED_SUGGESTION_CMD, CONTEXT_SUGGEST_WIDGET_VISIBLE} from 'vs/editor/contrib/suggest/common/suggest';
import {INullService} from 'vs/platform/instantiation/common/instantiation';
import {KeyMod, KeyCode} from 'vs/base/common/keyCodes';
import { IKeybindingService, IKeybindingContextKey } from 'vs/platform/keybinding/common/keybindingService';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { SuggestRegistry, ACCEPT_SELECTED_SUGGESTION_CMD, CONTEXT_SUGGEST_WIDGET_VISIBLE } from 'vs/editor/contrib/suggest/common/suggest';
import { IInstantiationService, INullService } from 'vs/platform/instantiation/common/instantiation';
import { KeyMod, KeyCode } from 'vs/base/common/keyCodes';
export class SuggestController implements EditorCommon.IEditorContribution {
static ID = 'editor.contrib.suggestController';
......@@ -31,32 +31,25 @@ export class SuggestController implements EditorCommon.IEditorContribution {
return <SuggestController>editor.getContribution(SuggestController.ID);
}
private editor:EditorBrowser.ICodeEditor;
private model:SuggestModel.SuggestModel;
private suggestWidget: SuggestWidget.SuggestWidget;
private toDispose: Lifecycle.IDisposable[];
private model: SuggestModel;
private widget: SuggestWidget;
private triggerCharacterListeners: Function[];
private suggestWidgetVisible: IKeybindingContextKey<boolean>;
private toDispose: Lifecycle.IDisposable[];
constructor(editor:EditorBrowser.ICodeEditor, @IKeybindingService keybindingService: IKeybindingService, @ITelemetryService telemetryService: ITelemetryService) {
this.editor = editor;
constructor(
private editor:EditorBrowser.ICodeEditor,
@IKeybindingService keybindingService: IKeybindingService,
@IInstantiationService instantiationService: IInstantiationService
) {
this.suggestWidgetVisible = keybindingService.createKey(CONTEXT_SUGGEST_WIDGET_VISIBLE, false);
this.model = new SuggestModel.SuggestModel(this.editor, (snippet:Snippet.CodeSnippet, overwriteBefore:number, overwriteAfter:number) => {
Snippet.get(this.editor).run(snippet, overwriteBefore, overwriteAfter);
});
this.suggestWidget = new SuggestWidget.SuggestWidget(this.editor, telemetryService, keybindingService, () => {
this.suggestWidgetVisible.set(true);
}, () => {
this.suggestWidgetVisible.reset();
});
this.suggestWidget.setModel(this.model);
this.model = new SuggestModel(this.editor);
this.widget = instantiationService.createInstance(SuggestWidget, this.editor, this.model);
this.triggerCharacterListeners = [];
this.toDispose = [];
this.toDispose.push(this.widget.onDidVisibilityChange(visible => visible ? this.suggestWidgetVisible.set(true) : this.suggestWidgetVisible.reset()));
this.toDispose.push(editor.addListener2(EditorCommon.EventType.ConfigurationChanged, () => this.update()));
this.toDispose.push(editor.addListener2(EditorCommon.EventType.ModelChanged, () => this.update()));
this.toDispose.push(editor.addListener2(EditorCommon.EventType.ModelModeChanged, () => this.update()));
......@@ -67,6 +60,9 @@ export class SuggestController implements EditorCommon.IEditorContribution {
}));
this.toDispose.push(SuggestRegistry.onDidChange(this.update, this));
// TODO@Joao: what is this?
this.toDispose.push(this.model.onDidAccept(e => Snippet.get(this.editor).run(e.snippet, e.overwriteBefore, e.overwriteAfter)));
this.update();
}
......@@ -78,12 +74,12 @@ export class SuggestController implements EditorCommon.IEditorContribution {
this.toDispose = Lifecycle.disposeAll(this.toDispose);
this.triggerCharacterListeners = Lifecycle.cAll(this.triggerCharacterListeners);
if (this.suggestWidget) {
this.suggestWidget.destroy();
this.suggestWidget = null;
if (this.widget) {
this.widget.dispose();
this.widget = null;
}
if (this.model) {
this.model.destroy();
this.model.dispose();
this.model = null;
}
}
......@@ -160,38 +156,38 @@ export class SuggestController implements EditorCommon.IEditorContribution {
}
public acceptSelectedSuggestion(): void {
if (this.suggestWidget) {
this.suggestWidget.acceptSelectedSuggestion();
if (this.widget) {
this.widget.acceptSelectedSuggestion();
}
}
public hideSuggestWidget(): void {
if (this.suggestWidget) {
this.suggestWidget.cancel();
if (this.widget) {
this.widget.cancel();
}
}
public selectNextSuggestion(): void {
if (this.suggestWidget) {
this.suggestWidget.selectNext();
if (this.widget) {
this.widget.selectNext();
}
}
public selectNextPageSuggestion(): void {
if (this.suggestWidget) {
this.suggestWidget.selectNextPage();
if (this.widget) {
this.widget.selectNextPage();
}
}
public selectPrevSuggestion(): void {
if (this.suggestWidget) {
this.suggestWidget.selectPrevious();
if (this.widget) {
this.widget.selectPrevious();
}
}
public selectPrevPageSuggestion(): void {
if (this.suggestWidget) {
this.suggestWidget.selectPreviousPage();
if (this.widget) {
this.widget.selectPreviousPage();
}
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册