diff --git a/build/lib/monaco-editor.d.ts b/build/lib/monaco-editor.d.ts index fbec661b33d..58ef1c4f44b 100644 --- a/build/lib/monaco-editor.d.ts +++ b/build/lib/monaco-editor.d.ts @@ -1,18 +1,15 @@ -// Some types were replaced with `any` to introduce cut-off points -// in order to not bring in our entire TypeScript universe - -declare module Monaco.Editor { +declare module monaco.editor { export function create(domElement: HTMLElement, options: IEditorConstructionOptions, services?: any): ICodeEditor; export function createDiffEditor(domElement: HTMLElement, options: IDiffEditorConstructionOptions, services?: any): IDiffEditor; - export function createModel(value:string, mode:string|IMonarchLanguage|IMode, associatedResource?:any|string): IModel; + export function createModel(value: string, mode: string | ILanguage | IMode, associatedResource?: any | string): IModel; export function getOrCreateMode(modeId: string): TPromise; - export function createCustomMode(description:IMonarchLanguage): TPromise; + export function createCustomMode(description: ILanguage): TPromise; export function colorize(text: string, modeId: string, options: IColorizerOptions): TPromise; export function colorizeElement(domNode: HTMLElement, options: IColorizerElementOptions): TPromise; - export function colorizeLine(line: string, tokens: Editor.ILineToken[], tabSize?: number): string; - export function colorizeModelLine(model: Editor.IModel, lineNumber: number, tabSize?: number): string; - export function registerWorkerParticipant(modeId:string, moduleName:string, ctorName:string): void; + export function colorizeLine(line: string, tokens: ViewLineToken[], tabSize?: number): string; + export function colorizeModelLine(model: IModel, lineNumber: number, tabSize?: number): string; + export function registerWorkerParticipant(modeId: string, moduleName: string, ctorName: string): void; export function configureMode(modeId: string, options: any): void; export interface IColorizerOptions { @@ -25,4228 +22,4219 @@ declare module Monaco.Editor { } export interface IEditorConstructionOptions extends ICodeEditorWidgetCreationOptions { - value?:string; + value?: string; /** * A mode name (such as text/javascript, etc.) or an IMonarchLanguage */ - mode?:any; - enableTelemetry?:boolean; + mode?: any; + enableTelemetry?: boolean; } export interface IDiffEditorConstructionOptions extends IDiffEditorOptions { } +} + +declare module monaco { + + interface Thenable { + /** + * Attaches callbacks for the resolution and/or rejection of the Promise. + * @param onfulfilled The callback to execute when the Promise is resolved. + * @param onrejected The callback to execute when the Promise is rejected. + * @returns A Promise for the completion of which ever callback is executed. + */ + then(onfulfilled?: (value: R) => TResult | Thenable, onrejected?: (reason: any) => TResult | Thenable): Thenable; + then(onfulfilled?: (value: R) => TResult | Thenable, onrejected?: (reason: any) => void): Thenable; + } export interface IDisposable { dispose(): void; } - export interface Event { - (listener: (e: T) => any, thisArgs?: any, disposables?: IDisposable[]): IDisposable; + export interface IEvent { + (listener: (e: T) => any, thisArg?: any): IDisposable; } -// ======================================================================== -// vs/base/common/winjs.base.d.ts -// ======================================================================== + export class Emitter { + constructor(); + event: IEvent; + fire(event?: T): void; + dispose(): void; + } -export interface ProgressCallback { - (progress: any): any; -} -export interface TPromise { - then(success?: (value: V) => TPromise, error?: (err: any) => TPromise, progress?: ProgressCallback): TPromise; - then(success?: (value: V) => TPromise, error?: (err: any) => U, progress?: ProgressCallback): TPromise; - then(success?: (value: V) => U, error?: (err: any) => TPromise, progress?: ProgressCallback): TPromise; - then(success?: (value: V) => U, error?: (err: any) => U, progress?: ProgressCallback): TPromise; + // --- Generic promise + export interface TValueCallback { + (value: T): void; + } - done(success?: (value: V) => void , error?: (err: any) => any, progress?: ProgressCallback): void; - cancel(): void; + + export interface ProgressCallback { + (progress: any): any; + } + + + export class TPromise { + + constructor(init: (complete: TValueCallback, error: (err: any) => void, progress: ProgressCallback) => void, oncancel?: any); + + public then(success?: (value: V) => TPromise, error?: (err: any) => TPromise, progress?: ProgressCallback): TPromise; + public then(success?: (value: V) => TPromise, error?: (err: any) => TPromise | U, progress?: ProgressCallback): TPromise; + public then(success?: (value: V) => TPromise, error?: (err: any) => U, progress?: ProgressCallback): TPromise; + public then(success?: (value: V) => TPromise, error?: (err: any) => void, progress?: ProgressCallback): TPromise; + public then(success?: (value: V) => TPromise | U, error?: (err: any) => TPromise, progress?: ProgressCallback): TPromise; + public then(success?: (value: V) => TPromise | U, error?: (err: any) => TPromise | U, progress?: ProgressCallback): TPromise; + public then(success?: (value: V) => TPromise | U, error?: (err: any) => U, progress?: ProgressCallback): TPromise; + public then(success?: (value: V) => TPromise | U, error?: (err: any) => void, progress?: ProgressCallback): TPromise; + public then(success?: (value: V) => U, error?: (err: any) => TPromise, progress?: ProgressCallback): TPromise; + public then(success?: (value: V) => U, error?: (err: any) => TPromise | U, progress?: ProgressCallback): TPromise; + public then(success?: (value: V) => U, error?: (err: any) => U, progress?: ProgressCallback): TPromise; + public then(success?: (value: V) => U, error?: (err: any) => void, progress?: ProgressCallback): TPromise; + + public done(success?: (value: V) => void, error?: (err: any) => any, progress?: ProgressCallback): void; + public cancel(): void; + + public static as(value: ValueType): TPromise; + public static is(value: any): value is TPromise; + public static timeout(delay: number): TPromise; + public static join(promises: TPromise[]): TPromise; + public static join(promises: Thenable[]): Thenable; + public static join(promises: { [n: string]: TPromise }): TPromise<{ [n: string]: ValueType }>; + public static any(promises: TPromise[]): TPromise<{ key: string; value: TPromise; }>; + public static wrapError(error: any): TPromise; + } + + /** + * Uniform Resource Identifier (Uri) http://tools.ietf.org/html/rfc3986. + * This class is a simple parser which creates the basic component paths + * (http://tools.ietf.org/html/rfc3986#section-3) with minimal validation + * and encoding. + * + * foo://example.com:8042/over/there?name=ferret#nose + * \_/ \______________/\_________/ \_________/ \__/ + * | | | | | + * scheme authority path query fragment + * | _____________________|__ + * / \ / \ + * urn:example:animal:ferret:nose + * + * + */ + export class Uri { + private static _empty; + private static _slash; + private static _regexp; + private static _driveLetterPath; + private static _upperCaseDrive; + private _scheme; + private _authority; + private _path; + private _query; + private _fragment; + private _formatted; + private _fsPath; + constructor(); + /** + * scheme is the 'http' part of 'http://www.msft.com/some/path?query#fragment'. + * The part before the first colon. + */ + scheme: string; + /** + * authority is the 'www.msft.com' part of 'http://www.msft.com/some/path?query#fragment'. + * The part between the first double slashes and the next slash. + */ + authority: string; + /** + * path is the '/some/path' part of 'http://www.msft.com/some/path?query#fragment'. + */ + path: string; + /** + * query is the 'query' part of 'http://www.msft.com/some/path?query#fragment'. + */ + query: string; + /** + * fragment is the 'fragment' part of 'http://www.msft.com/some/path?query#fragment'. + */ + fragment: string; + /** + * Returns a string representing the corresponding file system path of this Uri. + * Will handle UNC paths and normalize windows drive letters to lower-case. Also + * uses the platform specific path separator. Will *not* validate the path for + * invalid characters and semantics. Will *not* look at the scheme of this Uri. + */ + fsPath: string; + with(scheme: string, authority: string, path: string, query: string, fragment: string): Uri; + withScheme(value: string): Uri; + withAuthority(value: string): Uri; + withPath(value: string): Uri; + withQuery(value: string): Uri; + withFragment(value: string): Uri; + static parse(value: string): Uri; + static file(path: string): Uri; + private static _parseComponents(value); + static create(scheme?: string, authority?: string, path?: string, query?: string, fragment?: string): Uri; + private static _validate(ret); + /** + * + * @param skipEncoding Do not encode the result, default is `false` + */ + toString(skipEncoding?: boolean): string; + private static _asFormatted(uri, skipEncoding); + toJSON(): any; + static revive(data: any): Uri; + } + + export interface IEmitterEvent { + getType(): string; + getData(): any; + } + + export interface ListenerCallback { + (value: any): void; + } + + export interface IBulkListenerCallback { + (value: IEmitterEvent[]): void; + } + + export interface ListenerUnbind { + (): void; + } + + export interface IEventEmitter extends IDisposable { + addListener(eventType: string, listener: ListenerCallback): ListenerUnbind; + addListener2(eventType: string, listener: ListenerCallback): IDisposable; + addOneTimeListener(eventType: string, listener: ListenerCallback): ListenerUnbind; + addBulkListener(listener: IBulkListenerCallback): ListenerUnbind; + addBulkListener2(listener: IBulkListenerCallback): IDisposable; + addEmitter(eventEmitter: IEventEmitter, emitterType?: string): ListenerUnbind; + addEmitter2(eventEmitter: IEventEmitter, emitterType?: string): IDisposable; + addEmitterTypeListener(eventType: string, emitterType: string, listener: ListenerCallback): ListenerUnbind; + emit(eventType: string, data?: any): void; + } + + + /** + * Virtual Key Codes, the value does not hold any inherent meaning. + * Inspired somewhat from https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx + * But these are "more general", as they should work across browsers & OS`s. + */ + export enum KeyCode { + /** + * Placed first to cover the 0 value of the enum. + */ + Unknown = 0, + Backspace = 1, + Tab = 2, + Enter = 3, + Shift = 4, + Ctrl = 5, + Alt = 6, + PauseBreak = 7, + CapsLock = 8, + Escape = 9, + Space = 10, + PageUp = 11, + PageDown = 12, + End = 13, + Home = 14, + LeftArrow = 15, + UpArrow = 16, + RightArrow = 17, + DownArrow = 18, + Insert = 19, + Delete = 20, + KEY_0 = 21, + KEY_1 = 22, + KEY_2 = 23, + KEY_3 = 24, + KEY_4 = 25, + KEY_5 = 26, + KEY_6 = 27, + KEY_7 = 28, + KEY_8 = 29, + KEY_9 = 30, + KEY_A = 31, + KEY_B = 32, + KEY_C = 33, + KEY_D = 34, + KEY_E = 35, + KEY_F = 36, + KEY_G = 37, + KEY_H = 38, + KEY_I = 39, + KEY_J = 40, + KEY_K = 41, + KEY_L = 42, + KEY_M = 43, + KEY_N = 44, + KEY_O = 45, + KEY_P = 46, + KEY_Q = 47, + KEY_R = 48, + KEY_S = 49, + KEY_T = 50, + KEY_U = 51, + KEY_V = 52, + KEY_W = 53, + KEY_X = 54, + KEY_Y = 55, + KEY_Z = 56, + Meta = 57, + ContextMenu = 58, + F1 = 59, + F2 = 60, + F3 = 61, + F4 = 62, + F5 = 63, + F6 = 64, + F7 = 65, + F8 = 66, + F9 = 67, + F10 = 68, + F11 = 69, + F12 = 70, + F13 = 71, + F14 = 72, + F15 = 73, + F16 = 74, + F17 = 75, + F18 = 76, + F19 = 77, + NumLock = 78, + ScrollLock = 79, + /** + * Used for miscellaneous characters; it can vary by keyboard. + * For the US standard keyboard, the ';:' key + */ + US_SEMICOLON = 80, + /** + * For any country/region, the '+' key + * For the US standard keyboard, the '=+' key + */ + US_EQUAL = 81, + /** + * For any country/region, the ',' key + * For the US standard keyboard, the ',<' key + */ + US_COMMA = 82, + /** + * For any country/region, the '-' key + * For the US standard keyboard, the '-_' key + */ + US_MINUS = 83, + /** + * For any country/region, the '.' key + * For the US standard keyboard, the '.>' key + */ + US_DOT = 84, + /** + * Used for miscellaneous characters; it can vary by keyboard. + * For the US standard keyboard, the '/?' key + */ + US_SLASH = 85, + /** + * Used for miscellaneous characters; it can vary by keyboard. + * For the US standard keyboard, the '`~' key + */ + US_BACKTICK = 86, + /** + * Used for miscellaneous characters; it can vary by keyboard. + * For the US standard keyboard, the '[{' key + */ + US_OPEN_SQUARE_BRACKET = 87, + /** + * Used for miscellaneous characters; it can vary by keyboard. + * For the US standard keyboard, the '\|' key + */ + US_BACKSLASH = 88, + /** + * Used for miscellaneous characters; it can vary by keyboard. + * For the US standard keyboard, the ']}' key + */ + US_CLOSE_SQUARE_BRACKET = 89, + /** + * Used for miscellaneous characters; it can vary by keyboard. + * For the US standard keyboard, the ''"' key + */ + US_QUOTE = 90, + /** + * Used for miscellaneous characters; it can vary by keyboard. + */ + OEM_8 = 91, + /** + * Either the angle bracket key or the backslash key on the RT 102-key keyboard. + */ + OEM_102 = 92, + NUMPAD_0 = 93, + NUMPAD_1 = 94, + NUMPAD_2 = 95, + NUMPAD_3 = 96, + NUMPAD_4 = 97, + NUMPAD_5 = 98, + NUMPAD_6 = 99, + NUMPAD_7 = 100, + NUMPAD_8 = 101, + NUMPAD_9 = 102, + NUMPAD_MULTIPLY = 103, + NUMPAD_ADD = 104, + NUMPAD_SEPARATOR = 105, + NUMPAD_SUBTRACT = 106, + NUMPAD_DECIMAL = 107, + NUMPAD_DIVIDE = 108, + /** + * Placed last to cover the length of the enum. + */ + MAX_VALUE = 109, + } + + export class KeyMod { + static CtrlCmd: number; + static Shift: number; + static Alt: number; + static WinCtrl: number; + static chord(firstPart: number, secondPart: number): number; + } + + export interface IHTMLContentElementCode { + language: string; + value: string; + } + + export interface IHTMLContentElement { + /** + * supports **bold**, __italics__, and [[actions]] + */ + formattedText?: string; + text?: string; + className?: string; + style?: string; + customStyle?: any; + tagName?: string; + children?: IHTMLContentElement[]; + isText?: boolean; + role?: string; + markdown?: string; + code?: IHTMLContentElementCode; + } + + + export interface IAction extends IDisposable { + id: string; + label: string; + tooltip: string; + class: string; + enabled: boolean; + checked: boolean; + run(event?: any): TPromise; + } + + + export interface IKeyboardEvent { + browserEvent: Event; + target: HTMLElement; + ctrlKey: boolean; + shiftKey: boolean; + altKey: boolean; + metaKey: boolean; + keyCode: KeyCode; + clone(): IKeyboardEvent; + asKeybinding(): number; + equals(keybinding: number): boolean; + preventDefault(): void; + stopPropagation(): void; + } + + export interface IMouseEvent { + browserEvent: MouseEvent; + leftButton: boolean; + middleButton: boolean; + rightButton: boolean; + target: HTMLElement; + detail: number; + posx: number; + posy: number; + ctrlKey: boolean; + shiftKey: boolean; + altKey: boolean; + metaKey: boolean; + timestamp: number; + preventDefault(): void; + stopPropagation(): void; + } + + export interface IPlatformServices { + } + + export interface IInstantiationService { + } + + export interface IConstructorSignature1 { + new (context: IPlatformServices, first: A1): T; + } + + export interface IConstructorSignature2 { + new (context: IPlatformServices, first: A1, second: A2): T; + } } - -// ======================================================================== -// vs/base/common/eventEmitter.ts -// ======================================================================== - -export interface IEmitterEvent { - getType():string; - getData():any; -} - -export interface ListenerCallback { - (value:any):void; -} - -export interface IBulkListenerCallback { - (value:IEmitterEvent[]):void; -} - -export interface ListenerUnbind { - ():void; -} - -export interface IEventEmitter { - addListener(eventType:string, listener:ListenerCallback):ListenerUnbind; - addOneTimeListener(eventType:string, listener:ListenerCallback):ListenerUnbind; - addBulkListener(listener:IBulkListenerCallback):ListenerUnbind; - addEmitter(eventEmitter:IEventEmitter, emitterType?:string):ListenerUnbind; - addEmitterTypeListener(eventType:string, emitterType:string, listener:ListenerCallback):ListenerUnbind; - emit(eventType:string, data?:any):void; - dispose(): void; -} - - - -// ======================================================================== -// vs/base/common/htmlContent.ts -// ======================================================================== - -export interface IHTMLContentElement { - formattedText?:string; - text?: string; - className?: string; - style?: string; - customStyle?: any; - tagName?: string; - children?: IHTMLContentElement[]; - code?: { language: string; value: string; }; - isText?: boolean; - role?: string; -} - -// ======================================================================== -// vs/platform/services.ts -// ======================================================================== - - -export interface IPlatformServices { -} - -export interface IInstantiationService { -} - -export interface IConstructorSignature1 { - new(context:IPlatformServices, first:A1):T; -} - -export interface IConstructorSignature2 { - new(context:IPlatformServices, first:A1, second:A2):T; -} - -// ======================================================================== -// vs/editor/common/modes/monarch/monarchTypes.ts -// ======================================================================== +declare module monaco.editor { /** * A Monarch language definition */ - export interface IMonarchLanguage { - // required - name: string; // unique name to identify the language - mimeTypes: string[]; // associated mime types, for example ['text/x-koka'] - tokenizer: Object; // map from string to ILanguageRule[] - - // optional - displayName?: string; // nice display name - fileExtensions?: string[]; // file extensions associated with this language - ignoreCase?: boolean; // is the language case insensitive? - lineComment?: string; // used to insert/delete line comments in the editor - blockCommentStart?: string; // used to insert/delete block comments in the editor + export interface ILanguage { + /** + * unique name to identify the language. + */ + name: string; + /** + * map from string to ILanguageRule[] + */ + tokenizer: Object; + /** + * nice display name + */ + displayName?: string; + /** + * is the language case insensitive? + */ + ignoreCase?: boolean; + /** + * used to insert/delete line comments in the editor + */ + lineComment?: string; + /** + * used to insert/delete block comments in the editor + */ + blockCommentStart?: string; + /** + * used to insert/delete block comments in the editor + */ blockCommentEnd?: string; - defaultToken?: string; // if no match in the tokenizer assign this token class (default 'source') - brackets?: IMonarchLanguageBracket[]; // for example [['{','}','delimiter.curly']] - - // advanced - start?: string; // start symbol in the tokenizer (by default the first entry is used) - tokenPostfix?: string; // attach this to every token class (by default '.' + name) - autoClosingPairs?: string[][]; // for example [['"','"']] - nonWordTokens?: string[]; // token classes that are not words, for example ['delimiter','delimiter.curly'] - wordDefinition?: RegExp; // word definition regular expression - outdentTriggers?: string; // characters that could potentially cause outdentation - autoComplete?: IMonarchLanguageAutoComplete[]; // autocompletion rules - autoIndent?: IMonarchLanguageAutoIndent[]; // autoindentation rules - noindentBrackets?: string /* || RegExp */; // suppress auto indentation for certain brackets, for example /[()<>]/ - - // worker - workerScriptPath?: string; // path to worker script - - // hidden? - editorOptions?: Object; - logConsole?: string; + /** + * if no match in the tokenizer assign this token class (default 'source') + */ + defaultToken?: string; + /** + * for example [['{','}','delimiter.curly']] + */ + brackets?: ILanguageBracket[]; + /** + * start symbol in the tokenizer (by default the first entry is used) + */ + start?: string; + /** + * attach this to every token class (by default '.' + name) + */ + tokenPostfix?: string; + /** + * for example [['"','"']] + */ + autoClosingPairs?: string[][]; + /** + * word definition regular expression + */ + wordDefinition?: RegExp; + /** + * characters that could potentially cause outdentation + */ + outdentTriggers?: string; } /** * This interface can be shortened as an array, ie. ['{','}','delimiter.curly'] */ - export interface IMonarchLanguageBracket { - open: string; // open bracket - close: string; // closeing bracket - token: string; // token class - } - - export interface IMonarchLanguageAutoComplete { - triggers: string; // characters that trigger auto completion rules - match: string /* || RegExp */; // autocomplete if this matches - complete: string; // complete with this string - } - - export interface IMonarchLanguageAutoIndent { - match: string /* || RegExp */; // auto indent if this matches on enter - matchAfter: string /* || RegExp */; // and auto-outdent if this matches on the next line + export interface ILanguageBracket { + /** + * open bracket + */ + open: string; + /** + * closeing bracket + */ + close: string; + /** + * token class + */ + token: string; } - // ======================================================================== - // vs/editor/common/modes.ts - // ======================================================================== - - export interface IState { - clone():IState; - equals(other:IState):boolean; - getMode():IMode; - getStateData(): IState; - setStateData(state:IState):void; + export class ModeTransition { + _modeTransitionBrand: void; + startIndex: number; + mode: IMode; + constructor(startIndex: number, mode: IMode); + static findIndexInSegmentsArray(arr: ModeTransition[], desiredIndex: number): number; + static create(modeTransitions: IModeTransition[]): ModeTransition[]; } + + + /** + * Interface used for tokenization + */ export interface IToken { - startIndex:number; - type:string; - bracket:number; + startIndex: number; + type: string; } + export interface IModeTransition { startIndex: number; mode: IMode; } - export interface ILineTokens { - tokens: IToken[]; - actualStopOffset: number; - endState: IState; - modeTransitions: IModeTransition[]; - } + export interface ILineContext { getLineContent(): string; - modeTransitions: IModeTransition[]; - + modeTransitions: ModeTransition[]; getTokenCount(): number; - getTokenStartIndex(tokenIndex:number): number; - getTokenType(tokenIndex:number): string; - getTokenBracket(tokenIndex:number): number; - getTokenText(tokenIndex:number): string; - getTokenEndIndex(tokenIndex:number): number; - findIndexOfOffset(offset:number): number; + getTokenStartIndex(tokenIndex: number): number; + getTokenType(tokenIndex: number): string; + getTokenText(tokenIndex: number): string; + getTokenEndIndex(tokenIndex: number): number; + findIndexOfOffset(offset: number): number; } + export interface IMode { } - // ======================================================================== - // vs/editor/common/ts - // ======================================================================== - -/** - * A position in the editor. This interface is suitable for serialization. - */ -export interface IPosition { - /** - * line number (starts at 1) - */ - lineNumber:number; - /** - * column (the first character in a line is between column 1 and column 2) - */ - column:number; -} - -/** - * A position in the editor. - */ -export interface IEditorPosition extends IPosition { - /** - * Test if this position equals other position - */ - equals(other:IPosition): boolean; - /** - * Test if this position is before other position. If the two positions are equal, the result will be false. - */ - isBefore(other:IPosition): boolean; - /** - * Test if this position is before other position. If the two positions are equal, the result will be true. - */ - isBeforeOrEqual(other:IPosition): boolean; - /** - * Clone this position. - */ - clone(): IEditorPosition; -} - -/** - * A range in the editor. This interface is suitable for serialization. - */ -export interface IRange { - /** - * Line number on which the range starts (starts at 1). - */ - startLineNumber:number; - /** - * Column on which the range starts in line `startLineNumber` (starts at 1). - */ - startColumn:number; - /** - * Line number on which the range ends. - */ - endLineNumber:number; - /** - * Column on which the range ends in line `endLineNumber`. - */ - endColumn:number; -} - -/** - * A range in the editor. - */ -export interface IEditorRange extends IRange { - /** - * Test if this range is empty. - */ - isEmpty(): boolean; - collapseToStart():IEditorRange; - /** - * Test if position is in this range. If the position is at the edges, will return true. - */ - containsPosition(position:IPosition): boolean; - /** - * Test if range is in this range. If the range is equal to this range, will return true. - */ - containsRange(range:IRange): boolean; - /** - * A reunion of the two ranges. The smallest position will be used as the start point, and the largest one as the end point. - */ - plusRange(range:IRange): IEditorRange; - /** - * A intersection of the two ranges. - */ - intersectRanges(range:IRange): IEditorRange; - /** - * Test if this range equals other. - */ - equalsRange(other:IRange): boolean; - /** - * Return the end position (which will be after or equal to the start position) - */ - getEndPosition(): IEditorPosition; - /** - * Create a new range using this range's start position, and using endLineNumber and endColumn as the end position. - */ - setEndPosition(endLineNumber: number, endColumn: number): IEditorRange; - /** - * Return the start position (which will be before or equal to the end position) - */ - getStartPosition(): IEditorPosition; - /** - * Create a new range using this range's end position, and using startLineNumber and startColumn as the start position. - */ - setStartPosition(startLineNumber: number, startColumn: number): IEditorRange; - /** - * Clone this range. - */ - cloneRange(): IEditorRange; - /** - * Transform to a user presentable string representation. - */ - toString(): string; -} - -/** - * A selection in the editor. - * The selection is a range that has an orientation. - */ -export interface ISelection { - /** - * The line number on which the selection has started. - */ - selectionStartLineNumber: number; - /** - * The column on `selectionStartLineNumber` where the selection has started. - */ - selectionStartColumn: number; - /** - * The line number on which the selection has ended. - */ - positionLineNumber: number; - /** - * The column on `positionLineNumber` where the selection has ended. - */ - positionColumn: number; -} - -/** - * The direction of a selection. - */ -export enum SelectionDirection { - /** - * The selection starts above where it ends. - */ - LTR, - /** - * The selection starts below where it ends. - */ - RTL -} - -/** - * A selection in the editor. - */ -export interface IEditorSelection extends ISelection, IEditorRange { - /** - * Test if equals other selection. - */ - equalsSelection(other:ISelection): boolean; - /** - * Clone this selection. - */ - clone(): IEditorSelection; - /** - * Get directions (LTR or RTL). - */ - getDirection(): SelectionDirection; - /** - * Create a new selection with a different `positionLineNumber` and `positionColumn`. - */ - setEndPosition(endLineNumber: number, endColumn: number): IEditorSelection; - /** - * Create a new selection with a different `selectionStartLineNumber` and `selectionStartColumn`. - */ - setStartPosition(startLineNumber: number, startColumn: number): IEditorSelection; -} - -/** - * Configuration options for editor scrollbars - */ -export interface IEditorScrollbarOptions { - /** - * The size of arrows (if displayed). - * Defaults to 11. - */ - arrowSize?:number; - /** - * Render vertical scrollbar. - * Accepted values: 'auto', 'visible', 'hidden'. - * Defaults to 'auto'. - */ - vertical?:string; - /** - * Render horizontal scrollbar. - * Accepted values: 'auto', 'visible', 'hidden'. - * Defaults to 'auto'. - */ - horizontal?:string; - /** - * Cast horizontal and vertical shadows when the content is scrolled. - * Defaults to false. - */ - useShadows?:boolean; - /** - * Render arrows at the top and bottom of the vertical scrollbar. - * Defaults to false. - */ - verticalHasArrows?:boolean; - /** - * Render arrows at the left and right of the horizontal scrollbar. - * Defaults to false. - */ - horizontalHasArrows?:boolean; - /** - * Listen to mouse wheel events and react to them by scrolling. - * Defaults to true. - */ - handleMouseWheel?: boolean; - /** - * Height in pixels for the horizontal scrollbar. - * Defaults to 10 (px). - */ - horizontalScrollbarSize?: number; - /** - * Width in pixels for the vertical scrollbar. - * Defaults to 10 (px). - */ - verticalScrollbarSize?: number; - verticalSliderSize?: number; - horizontalSliderSize?: number; -} - -export enum WrappingIndent { - None = 0, - Same = 1, - Indent = 2 -} - -export function wrappingIndentFromString(wrappingIndent:string): WrappingIndent; - -/** - * Configuration options for the editor. - */ -export interface IEditorOptions { - experimentalScreenReader?: boolean; - ariaLabel?: string; - /** - * Render vertical lines at the specified columns. - * Defaults to empty array. - */ - rulers?: number[]; - /** - * A string containing the word separators used when doing word navigation. - * Defaults to `~!@#$%^&*()-=+[{]}\\|;:\'",.<>/? - */ - wordSeparators?: string; - /** - * Control the rendering of line numbers. - * If it is a function, it will be invoked when rendering a line number and the return value will be rendered. - * Otherwise, if it is a truey, line numbers will be rendered normally (equivalent of using an identity function). - * Otherwise, line numbers will not be rendered. - * Defaults to true. - */ - lineNumbers?:any; - /** - * Should the corresponding line be selected when clicking on the line number? - * Defaults to true. - */ - selectOnLineNumbers?:boolean; - /** - * Control the width of line numbers, by reserving horizontal space for rendering at least an amount of digits. - * Defaults to 5. - */ - lineNumbersMinChars?:number; - /** - * Enable the rendering of the glyph margin. - * Defaults to false. - */ - glyphMargin?:boolean; - /** - * The width reserved for line decorations (in px). - * Line decorations are placed between line numbers and the editor content. - * Defaults to 10. - */ - lineDecorationsWidth?:number; - /** - * When revealing the cursor, a virtual padding (px) is added to the cursor, turning it into a rectangle. - * This virtual padding ensures that the cursor gets revealed before hitting the edge of the viewport. - * Defaults to 30 (px). - */ - revealHorizontalRightPadding?:number; - /** - * Render the editor selection with rounded borders. - * Defaults to true. - */ - roundedSelection?:boolean; - /** - * Theme to be used for rendering. Consists of two parts, the UI theme and the syntax theme, - * separated by a space. - * The current available UI themes are: 'vs' (default), 'vs-dark', 'hc-black' - * The syntax themes are contributed. The default is 'default-theme' - */ - theme?:string; - /** - * Should the editor be read only. - * Defaults to false. - */ - readOnly?:boolean; - /** - * Control the behavior and rendering of the scrollbars. - */ - scrollbar?:IEditorScrollbarOptions; - /** - * The number of vertical lanes the overview ruler should render. - * Defaults to 2. - */ - overviewRulerLanes?:number; - /** - * Control the cursor blinking animation. - * Defaults to 'blink'. - */ - cursorBlinking?:string; - /** - * Control the cursor style, either 'block' or 'line'. - * Defaults to 'line'. - */ - cursorStyle?:string; - /** - * Enable font ligatures. - * Defaults to false. - */ - fontLigatures?:boolean; - /** - * Should the cursor be hidden in the overview ruler. - * Defaults to false. - */ - hideCursorInOverviewRuler?:boolean; - /** - * Enable that scrolling can go one screen size after the last line. - * Defaults to true. - */ - scrollBeyondLastLine?:boolean; - /** - * Enable that the editor will install an interval to check if its container dom node size has changed. - * Enabling this might have a severe performance impact. - * Defaults to false. - */ - automaticLayout?:boolean; - /** - * Control the wrapping strategy of the editor. - * Using -1 means no wrapping whatsoever. - * Using 0 means viewport width wrapping (ajusts with the resizing of the editor). - * Using a positive number means wrapping after a fixed number of characters. - * Defaults to 300. - */ - wrappingColumn?:number; - /** - * Control indentation of wrapped lines. Can be: 'none', 'same' or 'indent'. - * Defaults to 'none'. - */ - wrappingIndent?: string; - /** - * Configure word wrapping characters. A break will be introduced before these characters. - * Defaults to '{([+'. - */ - wordWrapBreakBeforeCharacters?: string; - /** - * Configure word wrapping characters. A break will be introduced after these characters. - * Defaults to ' \t})]?|&,;'. - */ - wordWrapBreakAfterCharacters?: string; - /** - * Configure word wrapping characters. A break will be introduced after these characters only if no `wordWrapBreakBeforeCharacters` or `wordWrapBreakAfterCharacters` were found. - * Defaults to '.'. - */ - wordWrapBreakObtrusiveCharacters?: string; - -// autoSize?:boolean; - /** - * Control what pressing Tab does. - * If it is false, pressing Tab or Shift-Tab will be handled by the editor. - * If it is true, pressing Tab or Shift-Tab will move the browser focus. - * Defaults to false. - */ - tabFocusMode?:boolean; - - /** - * Performance guard: Stop tokenizing a line after x characters. - * Defaults to 10000 if wrappingColumn is -1. Defaults to -1 if wrappingColumn is >= 0. - * Use -1 to never stop tokenization. - */ - stopLineTokenizationAfter?:number; - /** - * Performance guard: Stop rendering a line after x characters. - * Defaults to 10000 if wrappingColumn is -1. Defaults to -1 if wrappingColumn is >= 0. - * Use -1 to never stop rendering - */ - stopRenderingLineAfter?:number; - /** - * Performance guard: Force viewport width wrapping if more than half of the - * characters in a model are on lines of length >= `longLineBoundary`. - * Defaults to 300. - */ - longLineBoundary?:number; - /** - * Performance guard: Tokenize in the background if the [wrapped] lines count is above - * this number. If the [wrapped] lines count is below this number, then the view will - * always force tokenization before rendering. - * Defaults to 1000. - */ - forcedTokenizationBoundary?:number; - /** - * Enable hover. - * Defaults to true. - */ - hover?:boolean; - /** - * Enable custom contextmenu. - * Defaults to true. - */ - contextmenu?:boolean; - /** - * A multiplier to be used on the `deltaX` and `deltaY` of mouse wheel scroll events. - * Defaults to 1. - */ - mouseWheelScrollSensitivity?: number; - /** - * Enable quick suggestions (shaddow suggestions) - * Defaults to true. - */ - quickSuggestions?:boolean; - /** - * Quick suggestions show delay (in ms) - * Defaults to 500 (ms) - */ - quickSuggestionsDelay?:number; - /** - * Render icons in suggestions box. - * Defaults to true. - */ - iconsInSuggestions?:boolean; - /** - * Enable auto closing brackets. - * Defaults to true. - */ - autoClosingBrackets?:boolean; - /** - * Enable format on type. - * Defaults to false. - */ - formatOnType?:boolean; - /** - * Enable the suggestion box to pop-up on trigger characters. - * Defaults to true. - */ - suggestOnTriggerCharacters?:boolean; - /** - * Enable selection highlight. - * Defaults to true. - */ - selectionHighlight?:boolean; - /** - * Show lines before classes and methods (based on outline info). - * Defaults to false. - */ - outlineMarkers?: boolean; - /** - * Show reference infos (a.k.a. code lenses) for modes that support it - * Defaults to true. - */ - referenceInfos?: boolean; - /** - * Enable code folding - * Defaults to true. - */ - folding?: boolean; - /** - * Enable rendering of leading whitespace. - * Defaults to false. - */ - renderWhitespace?: boolean; - /** - * Tab size in spaces. This is used for rendering and for editing. - * 'auto' means the model attached to the editor will be scanned and this property will be guessed. - * Defaults to 4. - */ - tabSize?:any; - /** - * Insert spaces instead of tabs when indenting or when auto-indenting. - * 'auto' means the model attached to the editor will be scanned and this property will be guessed. - * Defaults to true. - */ - insertSpaces?:any; - /** - * The font family - */ - fontFamily?: string; - /** - * The font size - */ - fontSize?: number; - /** - * The line height - */ - lineHeight?: number; -} - -/** - * Configuration options for the diff editor. - */ -export interface IDiffEditorOptions extends IEditorOptions { - /** - * Allow the user to resize the diff editor split view. - * Defaults to true. - */ - enableSplitViewResizing?: boolean; - /** - * Render the differences in two side-by-side editors. - * Defaults to true. - */ - renderSideBySide?: boolean; - /** - * Compute the diff by ignoring leading/trailing whitespace - * Defaults to true. - */ - ignoreTrimWhitespace?: boolean; -} - -/** - * Internal indentation options (computed) for the editor. - */ -export interface IInternalIndentationOptions { - /** - * Tab size in spaces. This is used for rendering and for editing. - */ - tabSize:number; - /** - * Insert spaces instead of tabs when indenting or when auto-indenting. - */ - insertSpaces:boolean; -} - -export interface IInternalEditorScrollbarOptions { - arrowSize:number; - vertical:string; - horizontal:string; - useShadows:boolean; - verticalHasArrows:boolean; - horizontalHasArrows:boolean; - handleMouseWheel: boolean; - horizontalScrollbarSize: number; - horizontalSliderSize: number; - verticalScrollbarSize: number; - verticalSliderSize: number; - mouseWheelScrollSensitivity: number; -} - -export interface IEditorWrappingInfo { - isViewportWrapping: boolean; - wrappingColumn: number; -} - -/** - * Internal configuration options (transformed or computed) for the editor. - */ -export interface IInternalEditorOptions { - experimentalScreenReader: boolean; - rulers: number[]; - wordSeparators: string; - ariaLabel: string; - - // ---- Options that are transparent - get no massaging - lineNumbers:any; - selectOnLineNumbers:boolean; - glyphMargin:boolean; - revealHorizontalRightPadding:number; - roundedSelection:boolean; - theme:string; - readOnly:boolean; - scrollbar:IInternalEditorScrollbarOptions; - overviewRulerLanes:number; - cursorBlinking:string; - cursorStyle:string; - fontLigatures:boolean; - hideCursorInOverviewRuler:boolean; - scrollBeyondLastLine:boolean; - wrappingIndent: string; - wordWrapBreakBeforeCharacters: string; - wordWrapBreakAfterCharacters: string; - wordWrapBreakObtrusiveCharacters: string; - tabFocusMode:boolean; - stopLineTokenizationAfter:number; - stopRenderingLineAfter: number; - longLineBoundary:number; - forcedTokenizationBoundary:number; - - // ---- Options that are transparent - get no massaging - hover:boolean; - contextmenu:boolean; - quickSuggestions:boolean; - quickSuggestionsDelay:number; - iconsInSuggestions:boolean; - autoClosingBrackets:boolean; - formatOnType:boolean; - suggestOnTriggerCharacters:boolean; - selectionHighlight:boolean; - outlineMarkers: boolean; - referenceInfos: boolean; - folding: boolean; - renderWhitespace: boolean; - - // ---- Options that are computed - - layoutInfo: IEditorLayoutInfo; - - stylingInfo: IEditorStyling; - - wrappingInfo: IEditorWrappingInfo; - - indentInfo: IInternalIndentationOptions; - - /** - * Computed width of the container of the editor in px. - */ - observedOuterWidth:number; - /** - * Computed height of the container of the editor in px. - */ - observedOuterHeight:number; - /** - * Computed line height (deduced from theme and CSS) in px. - */ - lineHeight:number; - /** - * Computed page size (deduced from editor size) in lines. - */ - pageSize:number; - /** - * Computed width of 'm' (deduced from theme and CSS) in px. - */ - typicalHalfwidthCharacterWidth:number; - /** - * Computed width of fullwidth 'm' (U+FF4D) - */ - typicalFullwidthCharacterWidth:number; - /** - * Computed font size. - */ - fontSize:number; -} - -/** - * An event describing that the configuration of the editor has changed. - */ -export interface IConfigurationChangedEvent { - experimentalScreenReader: boolean; - rulers: boolean; - wordSeparators: boolean; - ariaLabel: boolean; - - // ---- Options that are transparent - get no massaging - lineNumbers: boolean; - selectOnLineNumbers: boolean; - glyphMargin: boolean; - revealHorizontalRightPadding: boolean; - roundedSelection: boolean; - theme: boolean; - readOnly: boolean; - scrollbar: boolean; - overviewRulerLanes: boolean; - cursorBlinking: boolean; - cursorStyle: boolean; - fontLigatures: boolean; - hideCursorInOverviewRuler: boolean; - scrollBeyondLastLine: boolean; - wrappingIndent: boolean; - wordWrapBreakBeforeCharacters: boolean; - wordWrapBreakAfterCharacters: boolean; - wordWrapBreakObtrusiveCharacters: boolean; - tabFocusMode: boolean; - stopLineTokenizationAfter: boolean; - stopRenderingLineAfter: boolean; - longLineBoundary: boolean; - forcedTokenizationBoundary: boolean; - - // ---- Options that are transparent - get no massaging - hover: boolean; - contextmenu: boolean; - quickSuggestions: boolean; - quickSuggestionsDelay: boolean; - iconsInSuggestions: boolean; - autoClosingBrackets: boolean; - formatOnType: boolean; - suggestOnTriggerCharacters: boolean; - selectionHighlight: boolean; - outlineMarkers: boolean; - referenceInfos: boolean; - folding: boolean; - renderWhitespace: boolean; - - // ---- Options that are computed - layoutInfo: boolean; - stylingInfo: boolean; - wrappingInfo: boolean; - indentInfo: boolean; - observedOuterWidth: boolean; - observedOuterHeight: boolean; - lineHeight: boolean; - pageSize: boolean; - typicalHalfwidthCharacterWidth: boolean; - typicalFullwidthCharacterWidth: boolean; - fontSize: boolean; -} - -/** - * An event describing that one or more supports of a mode have changed. - */ -export interface IModeSupportChangedEvent { - tokenizationSupport:boolean; - occurrencesSupport:boolean; - declarationSupport:boolean; - typeDeclarationSupport:boolean; - navigateTypesSupport:boolean; - referenceSupport:boolean; - suggestSupport:boolean; - parameterHintsSupport:boolean; - extraInfoSupport:boolean; - outlineSupport:boolean; - logicalSelectionSupport:boolean; - formattingSupport:boolean; - inplaceReplaceSupport:boolean; - emitOutputSupport:boolean; - linkSupport:boolean; - configSupport:boolean; - quickFixSupport: boolean; - codeLensSupport: boolean; - richEditSupport: boolean; -} - -/** - * Vertical Lane in the overview ruler of the editor. - */ -export enum OverviewRulerLane { - Left = 1, - Center = 2, - Right = 4, - Full = 7 -} - -/** - * Options for rendering a model decoration in the overview ruler. - */ -export interface IModelDecorationOverviewRulerOptions { - /** - * CSS color to render in the overview ruler. - * e.g.: rgba(100, 100, 100, 0.5) - */ - color: string; - /** - * CSS color to render in the overview ruler. - * e.g.: rgba(100, 100, 100, 0.5) - */ - darkColor: string; - /** - * The position in the overview ruler. - */ - position: OverviewRulerLane; -} - -/** - * Options for a model decoration. - */ -export interface IModelDecorationOptions { - /** - * Customize the growing behaviour of the decoration when typing at the edges of the decoration. - * Defaults to TrackedRangeStickiness.AlwaysGrowsWhenTypingAtEdges - */ - stickiness?:TrackedRangeStickiness; - /** - * CSS class name describing the decoration. - */ - className?:string; - /** - * Message to be rendered when hovering over the decoration. - */ - hoverMessage?:string; - /** - * Array of IHTMLContentElements to render as the decoration message. - */ - htmlMessage?:IHTMLContentElement[]; - /** - * Should the decoration expand to encompass a whole line. - */ - isWholeLine?:boolean; - /** - * @deprecated : Use `overviewRuler` instead - */ - showInOverviewRuler?:string; - /** - * If set, render this decoration in the overview ruler. - */ - overviewRuler?:IModelDecorationOverviewRulerOptions; - /** - * If set, the decoration will be rendered in the glyph margin with this CSS class name. - */ - glyphMarginClassName?:string; - /** - * If set, the decoration will be rendered in the lines decorations with this CSS class name. - */ - linesDecorationsClassName?:string; - /** - * If set, the decoration will be rendered inline with the text with this CSS class name. - * Please use this only for CSS rules that must impact the text. For example, use `className` - * to have a background color decoration. - */ - inlineClassName?:string; -} - -/** - * New model decorations. - */ -export interface IModelDeltaDecoration { - /** - * Range that this decoration covers. - */ - range: IRange; - /** - * Options associated with this decoration. - */ - options: IModelDecorationOptions; -} - -/** - * A tracked range in the model. - */ -export interface IModelTrackedRange { - /** - * Identifier for a tracked range - */ - id: string; - /** - * Range that this tracked range covers - */ - range: IRange; -} - -/** - * A decoration in the model. - */ -export interface IModelDecoration { - /** - * Identifier for a decoration. - */ - id: string; - /** - * Identifier for a decoration's owener. - */ - ownerId: number; - /** - * Range that this decoration covers. - */ - range: IRange; - /** - * Options associated with this decoration. - */ - options: IModelDecorationOptions; -} - -/** - * An accessor that can add, change or remove model decorations. - */ -export interface IModelDecorationsChangeAccessor { - /** - * Add a new decoration. - * @param range Range that this decoration covers. - * @param options Options associated with this decoration. - * @return An unique identifier associated with this decoration. - */ - addDecoration(range:IRange, options:IModelDecorationOptions): string; - /** - * Change the range that an existing decoration covers. - * @param id The unique identifier associated with the decoration. - * @param newRange The new range that this decoration covers. - */ - changeDecoration(id:string, newRange:IRange): void; - /** - * Change the options associated with an existing decoration. - * @param id The unique identifier associated with the decoration. - * @param newOptions The new options associated with this decoration. - */ - changeDecorationOptions(id: string, newOptions:IModelDecorationOptions): void; - /** - * Remove an existing decoration. - * @param id The unique identifier associated with the decoration. - */ - removeDecoration(id:string): void; - /** - * Perform a minimum ammount of operations, in order to transform the decorations - * identified by `oldDecorations` to the decorations described by `newDecorations` - * and returns the new identifiers associated with the resulting decorations. - * - * @param oldDecorations Array containing previous decorations identifiers. - * @param newDecorations Array describing what decorations should result after the call. - * @return An array containing the new decorations identifiers. - */ - deltaDecorations(oldDecorations:string[], newDecorations:IModelDeltaDecoration[]): string[]; -} - -/** - * Word inside a model. - */ -export interface IWordAtPosition { - /** - * The word. - */ - word: string; - /** - * The column where the word starts. - */ - startColumn: number; - /** - * The column where the word ends. - */ - endColumn: number; -} - -/** - * Range of a word inside a model. - */ -export interface IWordRange { - /** - * The column where the word starts. - */ - start:number; - /** - * The column where the word ends. - */ - end:number; -} - -export interface ITokenInfo { - token: IToken; - lineNumber: number; - startColumn: number; - endColumn: number; -} - -export interface ITokenIterator { - hasNext(): boolean; - next(): ITokenInfo; - hasPrev(): boolean; - prev(): ITokenInfo; -} - -/** - * End of line character preference. - */ -export enum EndOfLinePreference { - /** - * Use the end of line character identified in the text buffer. - */ - TextDefined = 0, - /** - * Use line feed (\n) as the end of line character. - */ - LF = 1, - /** - * Use carriage return and line feed (\r\n) as the end of line character. - */ - CRLF = 2 -} - -/** - * The default end of line to use when instantiating models. - */ -export enum DefaultEndOfLine { - /** - * Use line feed (\n) as the end of line character. - */ - LF = 1, - /** - * Use carriage return and line feed (\r\n) as the end of line character. - */ - CRLF = 2 -} - -/** - * End of line character preference. - */ -export enum EndOfLineSequence { - /** - * Use line feed (\n) as the end of line character. - */ - LF = 0, - /** - * Use carriage return and line feed (\r\n) as the end of line character. - */ - CRLF = 1 -} - -/** - * The result of a matchBracket operation. - */ -export interface IMatchBracketResult { - /** - * The two ranges describing matching brackets, or null - */ - brackets:IEditorRange[]; - /** - * Indicates that the bracket match result is not accurate because the search - * hit some untokenized lines. - */ - isAccurate:boolean; -} - -/** - * A read-only line marker in the model. - */ -export interface IReadOnlyLineMarker { - id: string; - column: number; -} - -/** - * And identifier for a single edit operation. - */ -export interface ISingleEditOperationIdentifier { - /** - * Identifier major - */ - major:number; - /** - * Identifier minor - */ - minor:number; -} - -/** - * A builder and helper for edit operations for a command. - */ -export interface IEditOperationBuilder { - /** - * Add a new edit operation (a replace operation). - * @param range The range to replace (delete). May be empty to represent a simple insert. - * @param text The text to replace with. May be null to represent a simple delete. - */ - addEditOperation(range:IEditorRange, text:string): void; - - /** - * Track `selection` when applying edit operations. - * A best effort will be made to not grow/expand the selection. - * An empty selection will clamp to a nearby character. - * @param selection The selection to track. - * @param trackPreviousOnEmpty If set, and the selection is empty, indicates whether the selection - * should clamp to the previous or the next character. - * @return A unique identifer. - */ - trackSelection(selection:IEditorSelection, trackPreviousOnEmpty?:boolean): string; -} - -/** - * A helper for computing cursor state after a command. - */ -export interface ICursorStateComputerData { - /** - * Get the inverse edit operations of the added edit operations. - */ - getInverseEditOperations(): IIdentifiedSingleEditOperation[]; - /** - * Get a previously tracked selection. - * @param id The unique identifier returned by `trackSelection`. - * @return The selection. - */ - getTrackedSelection(id:string): IEditorSelection; -} - -/** - * A command that modifies text / cursor state on a model. - */ -export interface ICommand { - /** - * Get the edit operations needed to execute this command. - * @param model The model the command will execute on. - * @param builder A helper to collect the needed edit operations and to track selections. - */ - getEditOperations(model:ITokenizedModel, builder:IEditOperationBuilder): void; - /** - * Compute the cursor state after the edit operations were applied. - * @param model The model the commad has executed on. - * @param helper A helper to get inverse edit operations and to get previously tracked selections. - * @return The cursor state after the command executed. - */ - computeCursorState(model:ITokenizedModel, helper:ICursorStateComputerData): IEditorSelection; -} - -/** - * A single edit operation, that acts as a simple replace. - * i.e. Replace text at `range` with `text` in model. - */ -export interface ISingleEditOperation { - /** - * The range to replace. This can be empty to emulate a simple insert. - */ - range: IRange; - /** - * The text to replace with. This can be null to emulate a simple delete. - */ - text: string; - /** - * This indicates that this operation has "insert" semantics. - * i.e. forceMoveMarkers = true => if `range` is collapsed, all markers at the position will be moved. - */ - forceMoveMarkers?: boolean; -} - -/** - * A single edit operation, that has an identifier. - */ -export interface IIdentifiedSingleEditOperation { - /** - * An identifier associated with this single edit operation. - */ - identifier: ISingleEditOperationIdentifier; - /** - * The range to replace. This can be empty to emulate a simple insert. - */ - range: IEditorRange; - /** - * The text to replace with. This can be null to emulate a simple delete. - */ - text: string; - /** - * This indicates that this operation has "insert" semantics. - * i.e. forceMoveMarkers = true => if `range` is collapsed, all markers at the position will be moved. - */ - forceMoveMarkers: boolean; -} - - -/** - * A callback that can compute the cursor state after applying a series of edit operations. - */ -export interface ICursorStateComputer { - /** - * A callback that can compute the resulting cursors state after some edit operations have been executed. - */ - (inverseEditOperations:IIdentifiedSingleEditOperation[]): IEditorSelection[]; -} - -/** - * A token on a line. - */ -export interface ILineToken { - startIndex: number; - type: string; -} - -export interface ITokensInflatorMap { - _inflate:string[]; - _deflate: { [token:string]:number; }; -} - -export interface ILineTokensBinaryEncoding { - START_INDEX_MASK: number; - TYPE_MASK: number; - START_INDEX_OFFSET: number; - TYPE_OFFSET: number; - - deflateArr(map:ITokensInflatorMap, tokens:IToken[]): number[]; - inflate(map:ITokensInflatorMap, binaryEncodedToken:number): IToken; - getStartIndex(binaryEncodedToken:number): number; - getType(map:ITokensInflatorMap, binaryEncodedToken:number): string; - inflateArr(map:ITokensInflatorMap, binaryEncodedTokens:number[]): IToken[]; - findIndexOfOffset(binaryEncodedTokens:number[], offset:number): number; - sliceAndInflate(map:ITokensInflatorMap, binaryEncodedTokens:number[], startOffset:number, endOffset:number, deltaStartIndex:number): IToken[]; -} -export var LineTokensBinaryEncoding:ILineTokensBinaryEncoding; - -/** - * A list of tokens on a line. - */ -export interface ILineTokens { - /** - * Get the binary representation of tokens. - */ - getBinaryEncodedTokens(): number[]; - - /** - * A map to help decoding the token type. - */ - getBinaryEncodedTokensMap(): ITokensInflatorMap; - - getTokenCount(): number; - getTokenStartIndex(tokenIndex:number): number; - getTokenType(tokenIndex:number): string; - getTokenEndIndex(tokenIndex:number, textLength:number): number; - - /** - * Check if tokens have changed. This is called by the view to validate rendered lines - * and decide which lines need re-rendering. - */ - equals(other:ILineTokens): boolean; - - /** - * Find the token containing offset `offset`. - * For example, with the following tokens [0, 5), [5, 9), [9, infinity) - * Searching for 0, 1, 2, 3 or 4 will return 0. - * Searching for 5, 6, 7 or 8 will return 1. - * Searching for 9, 10, 11, ... will return 2. - * @param offset The search offset - * @return The index of the token containing the offset. - */ - findIndexOfOffset(offset:number): number; -} - -/** - * Result for a ITextModel.guessIndentation - */ -export interface IGuessedIndentation { - /** - * If indentation is based on spaces (`insertSpaces` = true), then what is the number of spaces that make an indent? - */ - tabSize: number; - /** - * Is indentation based on spaces? - */ - insertSpaces: boolean; -} - -/** - * A textual read-only model. - */ -export interface ITextModel { - - /** - * Get the current version id of the model. - * Anytime a change happens to the model (even undo/redo), - * the version id is incremented. - */ - getVersionId(): number; - - /** - * Get the alternative version id of the model. - * This alternative version id is not always incremented, - * it will return the same values in the case of undo-redo. - */ - getAlternativeVersionId(): number; - - /** - * Replace the entire text buffer value contained in this model. - */ - setValue(newValue:string): void; - - /** - * Get the text stored in this model. - * @param eol The end of line character preference. Defaults to `EndOfLinePreference.TextDefined`. - * @param preserverBOM Preserve a BOM character if it was detected when the model was constructed. - * @return The text. - */ - getValue(eol?:EndOfLinePreference, preserveBOM?:boolean): string; - - getValueLength(eol?:EndOfLinePreference, preserveBOM?:boolean): number; - - toRawText(): IRawText; - - /** - * Get the text in a certain range. - * @param range The range describing what text to get. - * @param eol The end of line character preference. This will only be used for multiline ranges. Defaults to `EndOfLinePreference.TextDefined`. - * @return The text. - */ - getValueInRange(range:IRange, eol?:EndOfLinePreference): string; - - /** - * Get the length of text in a certain range. - * @param range The range describing what text length to get. - * @return The text length. - */ - getValueLengthInRange(range:IRange): number; - - /** - * Splits characters in two buckets. First bucket (A) is of characters that - * sit in lines with length < `longLineBoundary`. Second bucket (B) is of - * characters that sit in lines with length >= `longLineBoundary`. - * If count(B) > count(A) return true. Returns false otherwise. - */ - isDominatedByLongLines(longLineBoundary:number): boolean; - - /** - * Guess the text indentation. - * @param defaultTabSize The tab size to use if `insertSpaces` is false. - * If `insertSpaces` is true, then `tabSize` is relevant. - * If `insertSpaces` is false, then `tabSize` is `defaultTabSize`. - */ - guessIndentation(defaultTabSize:number): IGuessedIndentation; - - /** - * Get the number of lines in the model. - */ - getLineCount(): number; - - /** - * Get the text for a certain line. - */ - getLineContent(lineNumber:number): string; - - /** - * Get the text for all lines. - */ - getLinesContent(): string[]; - - /** - * Get the end of line character predominantly used in the text buffer. - * @return EOL char sequence (e.g.: '\n' or '\r\n'). - */ - getEOL(): string; - - setEOL(eol: EndOfLineSequence): void; - - /** - * Get the minimum legal column for line at `lineNumber` - */ - getLineMinColumn(lineNumber:number): number; - - /** - * Get the maximum legal column for line at `lineNumber` - */ - getLineMaxColumn(lineNumber:number): number; - - /** - * Returns the column before the first non whitespace character for line at `lineNumber`. - * Returns 0 if line is empty or contains only whitespace. - */ - getLineFirstNonWhitespaceColumn(lineNumber:number): number; - - /** - * Returns the column after the last non whitespace character for line at `lineNumber`. - * Returns 0 if line is empty or contains only whitespace. - */ - getLineLastNonWhitespaceColumn(lineNumber:number): number; - - /** - * Create a valid position, - */ - validatePosition(position:IPosition): IEditorPosition; - - /** - * Advances the given position by the given offest (negative offsets are also accepted) - * and returns it as a new valid position. - * - * If the offset and position are such that their combination goes beyond the beginning or - * end of the model, throws an exception. - * - * If the ofsset is such that the new position would be in the middle of a multi-byte - * line terminator, throws an exception. - */ - modifyPosition(position: IPosition, offset: number): IEditorPosition; - - /** - * Create a valid range. - */ - validateRange(range:IRange): IEditorRange; - - /** - * Get a range covering the entire model - */ - getFullModelRange(): IEditorRange; - - /** - * Returns iff the model was disposed or not. - */ - isDisposed(): boolean; -} - -export interface IRichEditBracket { - modeId: string; - open: string; - close: string; - forwardRegex: RegExp; - reversedRegex: RegExp; -} - -export interface IFoundBracket { - range: IEditorRange; - open: string; - close: string; - isOpen: boolean; -} - -/** - * A model that is tokenized. - */ -export interface ITokenizedModel extends ITextModel { - - /** - * Set the value at which to stop tokenization. - * The default is 10000. - */ - setStopLineTokenizationAfter(stopLineTokenizationAfter:number): void; - - /** - * Tokenize if necessary and get the tokens for the line `lineNumber`. - * @param lineNumber The line number - * @param inaccurateTokensAcceptable Are inaccurate tokens acceptable? Defaults to false - */ - getLineTokens(lineNumber:number, inaccurateTokensAcceptable?:boolean): ILineTokens; - - /** - * Tokenize if necessary and get the tokenization result for the line `lineNumber`, as returned by the language mode. - */ - getLineContext(lineNumber:number): ILineContext; - - /*package*/_getLineModeTransitions(lineNumber:number): IModeTransition[]; - - /** - * Replace the entire text buffer value contained in this model. - * Optionally, the language mode of the model can be changed. - * This call clears all of the undo / redo stack, - * removes all decorations or tracked ranges, emits a - * ModelContentChanged(ModelContentChangedFlush) event and - * unbinds the mirror model from the previous mode to the new - * one if the mode has changed. - */ - setValue(newValue:string, newMode?:IMode): void; - - /** - * Get the current language mode associated with the model. - */ - getMode(): IMode; - - /** - * Set the current language mode associated with the model. - */ - setMode(newMode:IMode): void; - setMode(newModePromise:TPromise): void; - /** - * A mode can be currently pending loading if a promise is used when constructing a model or calling setMode(). - * - * If there is no currently pending loading mode, then the result promise will complete immediately. - * Otherwise, the result will complete once the currently pending loading mode is loaded. - */ - whenModeIsReady(): TPromise; - - /** - * Returns the true (inner-most) language mode at a given position. - */ - getModeAtPosition(lineNumber:number, column:number): IMode; - - /** - * Get the word under or besides `position`. - * @param position The position to look for a word. - * @param skipSyntaxTokens Ignore syntax tokens, as identified by the mode. - * @return The word under or besides `position`. Might be null. - */ - getWordAtPosition(position:IPosition): IWordAtPosition; - - /** - * Get the word under or besides `position` trimmed to `position`.column - * @param position The position to look for a word. - * @param skipSyntaxTokens Ignore syntax tokens, as identified by the mode. - * @return The word under or besides `position`. Will never be null. - */ - getWordUntilPosition(position:IPosition): IWordAtPosition; - - /** - * Get the words on line `lineNumber`. - * @param lineNumber The lineNumber - * @param skipSyntaxTokens Ignore syntax tokens, as identified by the mode. - * @return All the words on the line. - */ - getWords(lineNumber:number): IWordRange[]; - - /** - * Returns an iterator that can be used to read - * next and previous tokens from the provided position. - * The iterator is made available through the callback - * function and can't be used afterwards. - */ - tokenIterator(position: IPosition, callback: (it: ITokenIterator) =>any): any; - - /** - * Find the matching bracket of `request` up, counting brackets. - * @param request The bracket we're searching for - * @param position The position at which to start the search. - * @return The range of the matching bracket, or null if the bracket match was not found. - */ - findMatchingBracketUp(bracket:string, position:IPosition): IEditorRange; - - /** - * Find the first bracket in the model before `position`. - * @param position The position at which to start the search. - * @return The info for the first bracket before `position`, or null if there are no more brackets before `positions`. - */ - findPrevBracket(position:IPosition): IFoundBracket; - - /** - * Find the first bracket in the model after `position`. - * @param position The position at which to start the search. - * @return The info for the first bracket after `position`, or null if there are no more brackets after `positions`. - */ - findNextBracket(position:IPosition): IFoundBracket; - - /** - * Given a `position`, if the position is on top or near a bracket, - * find the matching bracket of that bracket and return the ranges of both brackets. - * @param position The position at which to look for a bracket. - */ - matchBracket(position:IPosition, inaccurateResultAcceptable?:boolean): IMatchBracketResult; - - /** - * No mode supports allowed on this model because it is simply too large. - * (even tokenization would cause too much memory pressure) - */ - isTooLargeForHavingAMode(): boolean; - - /** - * Only basic mode supports allowed on this model because it is simply too large. - * (tokenization is allowed and other basic supports) - */ - isTooLargeForHavingARichMode(): boolean; -} - -/** - * A model that can track markers. - */ -export interface ITextModelWithMarkers extends ITextModel { - /*package*/_addMarker(lineNumber:number, column:number, stickToPreviousCharacter:boolean): string; - /*package*/_changeMarker(id:string, newLineNumber:number, newColumn:number): void; - /*package*/_changeMarkerStickiness(id:string, newStickToPreviousCharacter:boolean): void; - /*package*/_getMarker(id:string): IEditorPosition; - /*package*/_removeMarker(id:string): void; - /*package*/_getLineMarkers(lineNumber: number): IReadOnlyLineMarker[]; -} - -/** - * A map of changed ranges used during the model internal processing - */ -export interface IChangedTrackedRanges { - [key:string]:IRange; -} - -export enum TrackedRangeStickiness { - AlwaysGrowsWhenTypingAtEdges = 0, - NeverGrowsWhenTypingAtEdges = 1, - GrowsOnlyWhenTypingBefore = 2, - GrowsOnlyWhenTypingAfter = 3, -} - -/** - * A model that can track ranges. - */ -export interface ITextModelWithTrackedRanges extends ITextModel { - /** - * Start tracking a range (across edit operations). - * @param range The range to start tracking. - * @param stickiness The behaviour when typing at the edges of the range. - * @return A unique identifier for the tracked range. - */ - addTrackedRange(range:IRange, stickiness:TrackedRangeStickiness): string; - - /** - * Change the range of a tracked range. - * @param id The id of the tracked range, as returned by a `addTrackedRange` call. - * @param newRange The new range of the tracked range. - */ - changeTrackedRange(id:string, newRange:IRange): void; - - /** - * Change the stickiness (behaviour when typing at the edges of the range) for a tracked range. - * @param id The id of the tracked range, as returned by a `addTrackedRange` call. - * @param newStickiness The new behaviour when typing at the edges of the range. - */ - changeTrackedRangeStickiness(id:string, newStickiness:TrackedRangeStickiness): void; - - /** - * Remove a tracked range. - * @param id The id of the tracked range, as returned by a `addTrackedRaneg` call. - */ - removeTrackedRange(id:string): void; - - /** - * Get the range of a tracked range. - * @param id The id of the tracked range, as returned by a `addTrackedRaneg` call. - */ - getTrackedRange(id:string): IEditorRange; - - /** - * Gets all the tracked ranges for the lines between `startLineNumber` and `endLineNumber` as an array. - * @param startLineNumber The start line number - * @param endLineNumber The end line number - * @return An array with the tracked ranges - */ - getLinesTrackedRanges(startLineNumber:number, endLineNumber:number): IModelTrackedRange[]; -} - -/** - * A model that can have decorations. - */ -export interface ITextModelWithDecorations { - /** - * Change the decorations. The callback will be called with a change accessor - * that becomes invalid as soon as the callback finishes executing. - * This allows for all events to be queued up until the change - * is completed. Returns whatever the callback returns. - * @param ownerId Identifies the editor id in which these decorations should appear. If no `ownerId` is provided, the decorations will appear in all editors that attach this model. - */ - changeDecorations(callback: (changeAccessor:IModelDecorationsChangeAccessor)=>any, ownerId?:number): any; - - /** - * Perform a minimum ammount of operations, in order to transform the decorations - * identified by `oldDecorations` to the decorations described by `newDecorations` - * and returns the new identifiers associated with the resulting decorations. - * - * @param oldDecorations Array containing previous decorations identifiers. - * @param newDecorations Array describing what decorations should result after the call. - * @param ownerId Identifies the editor id in which these decorations should appear. If no `ownerId` is provided, the decorations will appear in all editors that attach this model. - * @return An array containing the new decorations identifiers. - */ - deltaDecorations(oldDecorations:string[], newDecorations:IModelDeltaDecoration[], ownerId?:number): string[]; - - /** - * Remove all decorations that have been added with this specific ownerId. - * @param ownerId The owner id to search for. - */ - removeAllDecorationsWithOwnerId(ownerId:number): void; - - /** - * Get the options associated with a decoration. - * @param id The decoration id. - * @return The decoration options or null if the decoration was not found. - */ - getDecorationOptions(id:string): IModelDecorationOptions; - - /** - * Get the range associated with a decoration. - * @param id The decoration id. - * @return The decoration range or null if the decoration was not found. - */ - getDecorationRange(id:string): IEditorRange; - - /** - * Gets all the decorations for the line `lineNumber` as an array. - * @param lineNumber The line number - * @param ownerId If set, it will ignore decorations belonging to other owners. - * @param filterOutValidation If set, it will ignore decorations specific to validation (i.e. warnings, errors). - * @return An array with the decorations - */ - getLineDecorations(lineNumber:number, ownerId?:number, filterOutValidation?:boolean): IModelDecoration[]; - - /** - * Gets all the decorations for the lines between `startLineNumber` and `endLineNumber` as an array. - * @param startLineNumber The start line number - * @param endLineNumber The end line number - * @param ownerId If set, it will ignore decorations belonging to other owners. - * @param filterOutValidation If set, it will ignore decorations specific to validation (i.e. warnings, errors). - * @return An array with the decorations - */ - getLinesDecorations(startLineNumber:number, endLineNumber:number, ownerId?:number, filterOutValidation?:boolean): IModelDecoration[]; - - /** - * Gets all the deocorations in a range as an array. Only `startLineNumber` and `endLineNumber` from `range` are used for filtering. - * So for now it returns all the decorations on the same line as `range`. - * @param range The range to search in - * @param ownerId If set, it will ignore decorations belonging to other owners. - * @param filterOutValidation If set, it will ignore decorations specific to validation (i.e. warnings, errors). - * @return An array with the decorations - */ - getDecorationsInRange(range:IRange, ownerId?:number, filterOutValidation?:boolean): IModelDecoration[]; - - /** - * Gets all the decorations as an array. - * @param ownerId If set, it will ignore decorations belonging to other owners. - * @param filterOutValidation If set, it will ignore decorations specific to validation (i.e. warnings, errors). - */ - getAllDecorations(ownerId?:number, filterOutValidation?:boolean): IModelDecoration[]; -} - -/** - * An editable text model. - */ -export interface IEditableTextModel extends ITextModelWithMarkers { - /** - * Push a stack element onto the undo stack. This acts as an undo/redo point. - * The idea is to use `pushEditOperations` to edit the model and then to - * `pushStackElement` to create an undo/redo stop point. - */ - pushStackElement(): void; - - /** - * Push edit operations, basically editing the model. This is the preferred way - * of editing the model. The edit operations will land on the undo stack. - * @param beforeCursorState The cursor state before the edit operaions. This cursor state will be returned when `undo` or `redo` are invoked. - * @param editOperations The edit operations. - * @param cursorStateComputer A callback that can compute the resulting cursors state after the edit operations have been executed. - * @return The cursor state returned by the `cursorStateComputer`. - */ - pushEditOperations(beforeCursorState:IEditorSelection[], editOperations:IIdentifiedSingleEditOperation[], cursorStateComputer:ICursorStateComputer): IEditorSelection[]; - - /** - * Edit the model without adding the edits to the undo stack. - * This can have dire consequences on the undo stack! See @pushEditOperations for the preferred way. - * @param operations The edit operations. - * @return The inverse edit operations, that, when applied, will bring the model back to the previous state. - */ - applyEdits(operations:IIdentifiedSingleEditOperation[]): IIdentifiedSingleEditOperation[]; - - /** - * Undo edit operations until the first previous stop point created by `pushStackElement`. - * The inverse edit operations will be pushed on the redo stack. - */ - undo(): IEditorSelection[]; - - /** - * Redo edit operations until the next stop point created by `pushStackElement`. - * The inverse edit operations will be pushed on the undo stack. - */ - redo(): IEditorSelection[]; - - /** - * Set an editable range on the model. - */ - setEditableRange(range:IRange): void; - - /** - * Check if the model has an editable range. - */ - hasEditableRange(): boolean; - - /** - * Get the editable range on the model. - */ - getEditableRange(): IEditorRange; -} - -/** - * A model. - */ -export interface IModel extends IEditableTextModel, ITextModelWithMarkers, ITokenizedModel, ITextModelWithTrackedRanges, ITextModelWithDecorations, IEventEmitter, IEditorModel { - /** - * A unique identifier associated with this model. - */ - id: string; - - /** - * Destroy this model. This will unbind the model from the mode - * and make all necessary clean-up to release this object to the GC. - */ - destroy(): void; - - /** - * Gets the resource associated with this editor model. - */ - getAssociatedResource(): any;//URI; - - /** - * Search the model. - * @param searchString The string used to search. If it is a regular expression, set `isRegex` to true. - * @param searchOnlyEditableRange Limit the searching to only search inside the editable range of the model. - * @param isRegex Used to indicate that `searchString` is a regular expression. - * @param matchCase Force the matching to match lower/upper case exactly. - * @param wholeWord Force the matching to match entire words only. - * @param limitResultCount Limit the number of results - * @return The ranges where the matches are. It is empty if not matches have been found. - */ - findMatches(searchString:string, searchOnlyEditableRange:boolean, isRegex:boolean, matchCase:boolean, wholeWord:boolean, limitResultCount?:number): IEditorRange[]; - /** - * Search the model. - * @param searchString The string used to search. If it is a regular expression, set `isRegex` to true. - * @param searchScope Limit the searching to only search inside this range. - * @param isRegex Used to indicate that `searchString` is a regular expression. - * @param matchCase Force the matching to match lower/upper case exactly. - * @param wholeWord Force the matching to match entire words only. - * @param limitResultCount Limit the number of results - * @return The ranges where the matches are. It is empty if no matches have been found. - */ - findMatches(searchString:string, searchScope:IRange, isRegex:boolean, matchCase:boolean, wholeWord:boolean, limitResultCount?:number): IEditorRange[]; - /** - * Search the model for the next match. Loops to the beginning of the model if needed. - * @param searchString The string used to search. If it is a regular expression, set `isRegex` to true. - * @param searchStart Start the searching at the specified position. - * @param isRegex Used to indicate that `searchString` is a regular expression. - * @param matchCase Force the matching to match lower/upper case exactly. - * @param wholeWord Force the matching to match entire words only. - * @return The range where the next match is. It is null if no next match has been found. - */ - findNextMatch(searchString:string, searchStart:IPosition, isRegex:boolean, matchCase:boolean, wholeWord:boolean): IEditorRange; - /** - * Search the model for the previous match. Loops to the end of the model if needed. - * @param searchString The string used to search. If it is a regular expression, set `isRegex` to true. - * @param searchStart Start the searching at the specified position. - * @param isRegex Used to indicate that `searchString` is a regular expression. - * @param matchCase Force the matching to match lower/upper case exactly. - * @param wholeWord Force the matching to match entire words only. - * @return The range where the previous match is. It is null if no previous match has been found. - */ - findPreviousMatch(searchString:string, searchStart:IPosition, isRegex:boolean, matchCase:boolean, wholeWord:boolean): IEditorRange; - - /** - * Replace the entire text buffer value contained in this model. - * Optionally, the language mode of the model can be changed. - * This call clears all of the undo / redo stack, - * removes all decorations or tracked ranges, emits a - * ModelContentChanged(ModelContentChangedFlush) event and - * unbinds the mirror model from the previous mode to the new - * one if the mode has changed. - */ - setValue(newValue:string, newMode?:IMode): void; - setValue(newValue:string, newModePromise:TPromise): void; - - onBeforeAttached(): void; - - onBeforeDetached(): void; - - getModeId(): string; - - /** - * Returns iff this model is attached to an editor or not. - */ - isAttachedToEditor(): boolean; -} - -export interface IRangeWithText { - text:string; - range:IRange; -} - -export interface IMirrorModel extends IEventEmitter, ITokenizedModel { - getEmbeddedAtPosition(position:IPosition): IMirrorModel; - getAllEmbedded(): IMirrorModel[]; - - getAssociatedResource(): any;//URI; - - getOffsetFromPosition(position:IPosition): number; - getPositionFromOffset(offset:number): IPosition; - getOffsetAndLengthFromRange(range:IRange): {offset:number; length:number;}; - getRangeFromOffsetAndLength(offset:number, length:number): IRange; - getLineStart(lineNumber:number): number; - - getAllWordsWithRange(): IRangeWithText[]; - getAllUniqueWords(skipWordOnce?:string): string[]; -} - -/** - * An event describing that the current mode associated with a model has changed. - */ -export interface IModelModeChangedEvent { - /** - * Previous mode - */ - oldMode:IMode; - /** - * New mode - */ - newMode:IMode; -} - -/** - * An event describing a change in the text of a model. - */ -export interface IModelContentChangedEvent2 { - /** - * The range that got replaced. - */ - range: IRange; - /** - * The length of the range that got replaced. - */ - rangeLength: number; - /** - * The new text for the range. - */ - text: string; - /** - * The end-of-line character. - */ - eol: string; - /** - * The new version id the model has transitioned to. - */ - versionId: number; - /** - * Flag that indicates that this event was generated while undoing. - */ - isUndoing: boolean; - /** - * Flag that indicates that this event was generated while redoing. - */ - isRedoing: boolean; -} -/** - * An event describing a change in the text of a model. - */ -export interface IModelContentChangedEvent { - /** - * The event type. It can be used to detect the actual event type: - * EventType.ModelContentChangedFlush => IModelContentChangedFlushEvent - * EventType.ModelContentChangedLinesDeleted => IModelContentChangedLineChangedEvent - * EventType.ModelContentChangedLinesInserted => IModelContentChangedLinesDeletedEvent - * EventType.ModelContentChangedLineChanged => IModelContentChangedLinesInsertedEvent - */ - changeType: string; - /** - * The new version id the model has transitioned to. - */ - versionId: number; - /** - * Flag that indicates that this event was generated while undoing. - */ - isUndoing: boolean; - /** - * Flag that indicates that this event was generated while redoing. - */ - isRedoing: boolean; -} -export interface IRawText { - length: number; - lines: string[]; - BOM: string; - EOL: string; - defaultEOL: DefaultEndOfLine; -} -/** - * An event describing that a model has been reset to a new value. - */ -export interface IModelContentChangedFlushEvent extends IModelContentChangedEvent { - /** - * The new text content of the model. - */ - detail: IRawText; -} -/** - * An event describing that a line has changed in a model. - */ -export interface IModelContentChangedLineChangedEvent extends IModelContentChangedEvent { - /** - * The line that has changed. - */ - lineNumber: number; - /** - * The new value of the line. - */ - detail: string; -} -/** - * An event describing that line(s) have been deleted in a model. - */ -export interface IModelContentChangedLinesDeletedEvent extends IModelContentChangedEvent { - /** - * At what line the deletion began (inclusive). - */ - fromLineNumber: number; - /** - * At what line the deletion stopped (inclusive). - */ - toLineNumber: number; -} -/** - * An event describing that line(s) have been inserted in a model. - */ -export interface IModelContentChangedLinesInsertedEvent extends IModelContentChangedEvent { - /** - * Before what line did the insertion begin - */ - fromLineNumber: number; - /** - * `toLineNumber` - `fromLineNumber` + 1 denotes the number of lines that were inserted - */ - toLineNumber: number; - /** - * The text that was inserted - */ - detail: string; -} -/** - * Decoration data associated with a model decorations changed event. - */ -export interface IModelDecorationsChangedEventDecorationData { - id:string; - ownerId:number; - range:IRange; - isForValidation:boolean; - options:IModelDecorationOptions; -} -/** - * An event describing that model decorations have changed. - */ -export interface IModelDecorationsChangedEvent { - /** - * A summary with ids of decorations that have changed. - */ - ids:string[]; - /** - * Lists of details - */ - addedOrChangedDecorations:IModelDecorationsChangedEventDecorationData[]; - removedDecorations:string[]; - oldOptions:{[decorationId:string]:IModelDecorationOptions;}; - oldRanges:{[decorationId:string]:IRange;}; -} -/** - * An event describing that a range of lines has been tokenized - */ -export interface IModelTokensChangedEvent { - /** - * The start of the range (inclusive) - */ - fromLineNumber:number; - /** - * The end of the range (inclusive) - */ - toLineNumber:number; -} -/** - * An event describing that the cursor position has changed. - */ -export interface ICursorPositionChangedEvent { - /** - * Primary cursor's position. - */ - position:IEditorPosition; - /** - * Primary cursor's view position - */ - viewPosition:IEditorPosition; - /** - * Secondary cursors' position. - */ - secondaryPositions:IEditorPosition[]; - /** - * Secondary cursors' view position. - */ - secondaryViewPositions:IEditorPosition[]; - /** - * Reason. - */ - reason:string; - /** - * Source of the call that caused the event. - */ - source:string; - /** - * Is the primary cursor in the editable range? - */ - isInEditableRange:boolean; -} -/** - * An event describing that the cursor selection has changed. - */ -export interface ICursorSelectionChangedEvent { - /** - * The primary selection. - */ - selection:IEditorSelection; - /** - * The primary selection in view coordinates. - */ - viewSelection:IEditorSelection; - /** - * The secondary selections. - */ - secondarySelections:IEditorSelection[]; - /** - * The secondary selections in view coordinates. - */ - secondaryViewSelections:IEditorSelection[]; - /** - * Source of the call that caused the event. - */ - source:string; - /** - * Reason. - */ - reason:string; -} -export enum VerticalRevealType { - Simple = 0, - Center = 1, - CenterIfOutsideViewport = 2 -} -/** - * An event describing a request to reveal a specific range in the view of the editor. - */ -export interface ICursorRevealRangeEvent { - /** - * Range to be reavealed. - */ - range:IEditorRange; - /** - * View range to be reavealed. - */ - viewRange:IEditorRange; - - verticalType: VerticalRevealType; - /** - * If true: there should be a horizontal & vertical revealing - * If false: there should be just a vertical revealing - */ - revealHorizontal:boolean; -} - -export interface ICursorScrollRequestEvent { - deltaLines: number; -} - -export interface IModelChangedEvent { - oldModelUrl: string; - newModelUrl: string; -} - -export interface IEditorWhitespace { - id:number; - afterLineNumber:number; - heightInLines:number; -} - -/** - * A description for the overview ruler position. - */ -export interface IOverviewRulerPosition { - /** - * Width of the overview ruler - */ - width:number; - /** - * Height of the overview ruler - */ - height:number; - /** - * Top position for the overview ruler - */ - top:number; - /** - * Right position for the overview ruler - */ - right:number; -} - -/** - * The internal layout details of the editor. - */ -export interface IEditorLayoutInfo { - /** - * Full editor width. - */ - width:number; - /** - * Full editor height. - */ - height:number; - - /** - * Left position for the glyph margin. - */ - glyphMarginLeft:number; - /** - * The width of the glyph margin. - */ - glyphMarginWidth:number; - /** - * The height of the glyph margin. - */ - glyphMarginHeight:number; - - /** - * Left position for the line numbers. - */ - lineNumbersLeft:number; - /** - * The width of the line numbers. - */ - lineNumbersWidth:number; - /** - * The height of the line numbers. - */ - lineNumbersHeight:number; - - /** - * Left position for the line decorations. - */ - decorationsLeft:number; - /** - * The width of the line decorations. - */ - decorationsWidth:number; - /** - * The height of the line decorations. - */ - decorationsHeight:number; - - /** - * Left position for the content (actual text) - */ - contentLeft:number; - /** - * The width of the content (actual text) - */ - contentWidth:number; - /** - * The height of the content (actual height) - */ - contentHeight:number; - - /** - * The width of the vertical scrollbar. - */ - verticalScrollbarWidth:number; - /** - * The height of the horizontal scrollbar. - */ - horizontalScrollbarHeight:number; - - /** - * The position of the overview ruler. - */ - overviewRuler:IOverviewRulerPosition; -} - -/** - * Options for creating the editor. - */ -export interface ICodeEditorWidgetCreationOptions extends IEditorOptions { - model?:IModel; -} - -/** - * An editor model. - */ -export interface IEditorModel { -} -/** - * An editor view state. - */ -export interface IEditorViewState { -} -export interface IDimension { - width:number; - height:number; -} -/** - * Conditions describing action enablement - */ -export interface IActionEnablement { - /** - * The action is enabled only if text in the editor is focused (e.g. blinking cursor). - * Warning: This condition will be disabled if the action is marked to be displayed in the context menu - * Defaults to false. - */ - textFocus?: boolean; - /** - * The action is enabled only if the editor or its widgets have focus (e.g. focus is in find widget). - * Defaults to false. - */ - widgetFocus?: boolean; - /** - * The action is enabled only if the editor is not in read only mode. - * Defaults to false. - */ - writeableEditor?: boolean; - /** - * The action is enabled only if the cursor position is over tokens of a certain kind. - * Defaults to no tokens required. - */ - tokensAtPosition?: string[]; - /** - * The action is enabled only if the cursor position is over a word (i.e. not whitespace). - * Defaults to false. - */ - wordAtPosition?: boolean; -} - -/** - * A (serializable) state of the cursors. - */ -export interface ICursorState { - inSelectionMode:boolean; - selectionStart:IPosition; - position:IPosition; -} -/** - * A (serializable) state of the view. - */ -export interface IViewState { - scrollTop: number; - scrollTopWithoutViewZones: number; - scrollLeft: number; -} -/** - * A (serializable) state of the code editor. - */ -export interface ICodeEditorViewState extends IEditorViewState { - cursorState:ICursorState[]; - viewState:IViewState; - contributionsState: {[id:string]:any}; -} - -/** - * Type of hit element with the mouse in the editor. - */ -export enum MouseTargetType { - /** - * Mouse is on top of an unknown element. - */ - UNKNOWN, - /** - * Mouse is on top of the textarea used for input. - */ - TEXTAREA, - /** - * Mouse is on top of the glyph margin - */ - GUTTER_GLYPH_MARGIN, - /** - * Mouse is on top of the line numbers - */ - GUTTER_LINE_NUMBERS, - /** - * Mouse is on top of the line decorations - */ - GUTTER_LINE_DECORATIONS, - /** - * Mouse is on top of the whitespace left in the gutter by a view zone. - */ - GUTTER_VIEW_ZONE, - /** - * Mouse is on top of text in the content. - */ - CONTENT_TEXT, - /** - * Mouse is on top of empty space in the content (e.g. after line text or below last line) - */ - CONTENT_EMPTY, - /** - * Mouse is on top of a view zone in the content. - */ - CONTENT_VIEW_ZONE, - /** - * Mouse is on top of a content widget. - */ - CONTENT_WIDGET, - /** - * Mouse is on top of the decorations overview ruler. - */ - OVERVIEW_RULER, - /** - * Mouse is on top of a scrollbar. - */ - SCROLLBAR, - /** - * Mouse is on top of an overlay widget. - */ - OVERLAY_WIDGET -} - -/** - * A model for the diff editor. - */ -export interface IDiffEditorModel extends IEditorModel { - /** - * Original model. - */ - original: IModel; - /** - * Modified model. - */ - modified: IModel; -} -/** - * (Serializable) View state for the diff editor. - */ -export interface IDiffEditorViewState extends IEditorViewState { - original: ICodeEditorViewState; - modified: ICodeEditorViewState; -} -/** - * A change - */ -export interface IChange { - originalStartLineNumber:number; - originalEndLineNumber:number; - modifiedStartLineNumber:number; - modifiedEndLineNumber:number; -} -/** - * A character level change. - */ -export interface ICharChange extends IChange { - originalStartColumn:number; - originalEndColumn:number; - modifiedStartColumn:number; - modifiedEndColumn:number; -} -/** - * A line change - */ -export interface ILineChange extends IChange { - charChanges:ICharChange[]; -} -/** - * Information about a line in the diff editor - */ -export interface IDiffLineInformation { - equivalentLineNumber: number; -} - -export const KEYBINDING_CONTEXT_EDITOR_TEXT_FOCUS: string; -export const KEYBINDING_CONTEXT_EDITOR_FOCUS: string; -export const KEYBINDING_CONTEXT_EDITOR_TAB_MOVES_FOCUS: string; -export const KEYBINDING_CONTEXT_EDITOR_HAS_MULTIPLE_SELECTIONS: string; -export const KEYBINDING_CONTEXT_EDITOR_HAS_NON_EMPTY_SELECTION: string; -export const KEYBINDING_CONTEXT_EDITOR_LANGUAGE_ID: string; -export const SHOW_ACCESSIBILITY_HELP_ACTION_ID: string; - -export interface IDispatcherEvent { - getSource(): string; - getData(): any; -} - -export interface IHandler { - (e:IDispatcherEvent): boolean; -} - -export interface IHandlerDispatcher { - setHandler(handlerId:string, handlerCallback:IHandler): void; - clearHandlers(): void; - trigger(source:string, handlerId:string, payload:any): boolean; -} - -export interface IEditorStyling { - editorClassName: string; - fontFamily: string; - fontSize: number; - lineHeight: number; -} - -export interface IConfiguration { - onDidChange: Event; - - editor:IInternalEditorOptions; - - setLineCount(lineCount:number): void; - - handlerDispatcher: IHandlerDispatcher; - - getIndentationOptions(): IInternalIndentationOptions; - getOneIndent(): string; - normalizeIndentation(str:string): string; -} - -// --- view - -export interface IViewLineTokens { - getTokens(): ILineToken[]; - getFauxIndentLength(): number; - getTextLength(): number; - equals(other:IViewLineTokens): boolean; - findIndexOfOffset(offset:number): number; -} - -export interface IViewModelDecorationsResolver { - getDecorations(): IModelDecoration[]; - getInlineDecorations(lineNumber: number): IModelDecoration[]; -} - -export interface IViewEventBus { - emit(eventType:string, data?:any): void; -} - -export interface IWhitespaceManager { - /** - * Reserve rendering space. - * @param height is specified in pixels. - * @return an identifier that can be later used to remove or change the whitespace. - */ - addWhitespace(afterLineNumber:number, ordinal:number, height:number): number; - - /** - * Change the properties of a whitespace. - * @param height is specified in pixels. - */ - changeWhitespace(id:number, newAfterLineNumber:number, newHeight:number): boolean; - - /** - * Remove rendering space - */ - removeWhitespace(id:number): boolean; - - /** - * Get the layout information for whitespaces currently in the viewport - */ - getWhitespaceViewportData(): IViewWhitespaceViewportData[]; - - getWhitespaces(): IEditorWhitespace[]; -} - -export interface IViewModel extends IEventEmitter, IDisposable { - - getLineCount(): number; - getLineContent(lineNumber:number): string; - getLineMinColumn(lineNumber:number): number; - getLineMaxColumn(lineNumber:number): number; - getLineFirstNonWhitespaceColumn(lineNumber:number): number; - getLineLastNonWhitespaceColumn(lineNumber:number): number; - getLineTokens(lineNumber:number): IViewLineTokens; - getDecorationsResolver(startLineNumber:number, endLineNumber:number): IViewModelDecorationsResolver; - getLineRenderLineNumber(lineNumber:number): string; - getAllDecorations(): IModelDecoration[]; - getEOL(): string; - getValueInRange(range:IRange, eol:EndOfLinePreference): string; - dispose(): void; - - getSelections(): IEditorSelection[]; - - getModelLineContent(modelLineNumber:number): string; - getModelLineMaxColumn(modelLineNumber:number): number; - validateModelPosition(position:IPosition): IEditorPosition; - convertViewPositionToModelPosition(viewLineNumber:number, viewColumn:number): IEditorPosition; - convertViewRangeToModelRange(viewRange:IRange): IEditorRange; - convertModelPositionToViewPosition(modelLineNumber:number, modelColumn:number): IEditorPosition; - convertModelSelectionToViewSelection(modelSelection:IEditorSelection): IEditorSelection; - modelPositionIsVisible(position:IPosition): boolean; -} - -export interface IViewEventNames { - ModelFlushedEvent: string; - LinesDeletedEvent: string; - LinesInsertedEvent: string; - LineChangedEvent: string; - TokensChangedEvent: string; - DecorationsChangedEvent: string; - CursorPositionChangedEvent: string; - CursorSelectionChangedEvent: string; - RevealRangeEvent: string; - LineMappingChangedEvent: string; -} - -export var ViewEventNames : { - ModelFlushedEvent: string; - LinesDeletedEvent: string; - LinesInsertedEvent: string; - LineChangedEvent: string; - TokensChangedEvent: string; - DecorationsChangedEvent: string; - CursorPositionChangedEvent: string; - CursorSelectionChangedEvent: string; - RevealRangeEvent: string; - LineMappingChangedEvent: string; - ScrollRequestEvent: string; -}; - -export interface IScrollEvent { - vertical: boolean; - horizontal: boolean; - scrollTop:number; - scrollLeft:number; -} - -export interface IViewLinesDeletedEvent { - /** - * At what line the deletion began (inclusive). - */ - fromLineNumber: number; - /** - * At what line the deletion stopped (inclusive). - */ - toLineNumber: number; -} - -export interface IViewLinesInsertedEvent { - /** - * Before what line did the insertion begin - */ - fromLineNumber: number; - /** - * `toLineNumber` - `fromLineNumber` + 1 denotes the number of lines that were inserted - */ - toLineNumber: number; -} - -export interface IViewLineChangedEvent { - /** - * The line that has changed. - */ - lineNumber: number; -} - -export interface IViewTokensChangedEvent { - /** - * Start line number of range - */ - fromLineNumber: number; - /** - * End line number of range - */ - toLineNumber: number; -} - -export interface IViewDecorationsChangedEvent { - /** - * signals that at least one inline decoration has changed - */ - inlineDecorationsChanged: boolean; -} - -export interface IViewCursorPositionChangedEvent { - /** - * Primary cursor's position. - */ - position: IEditorPosition; - /** - * Secondary cursors' position. - */ - secondaryPositions: IEditorPosition[]; - /** - * Is the primary cursor in the editable range? - */ - isInEditableRange: boolean; -} - -export interface IViewCursorSelectionChangedEvent { - /** - * The primary selection. - */ - selection: IEditorSelection; - /** - * The secondary selections. - */ - secondarySelections: IEditorSelection[]; -} - -export interface IViewRevealRangeEvent { - /** - * Range to be reavealed. - */ - range: IEditorRange; - - verticalType: VerticalRevealType; - /** - * If true: there should be a horizontal & vertical revealing - * If false: there should be just a vertical revealing - */ - revealHorizontal: boolean; -} - -export interface IViewScrollRequestEvent { - deltaLines: number; -} - -export interface IViewWhitespaceViewportData { - id:number; - afterLineNumber:number; - verticalOffset:number; - height:number; -} - -export interface IViewLinesViewportData { - viewportTop: number; - viewportHeight: number; - - bigNumbersDelta: number; - - visibleRangesDeltaTop:number; - /** - * The line number at which to start rendering (inclusive). - */ - startLineNumber:number; - /** - * The line number at which to end rendering (inclusive). - */ - endLineNumber:number; - /** - * relativeVerticalOffset[i] is the gap that must be left between line at - * i - 1 + `startLineNumber` and i + `startLineNumber`. - */ - relativeVerticalOffset:number[]; - /** - * The viewport as a range (`startLineNumber`,1) -> (`endLineNumber`,maxColumn(`endLineNumber`)). - */ - visibleRange:IEditorRange; - - getInlineDecorationsForLineInViewport(lineNumber:number): IModelDecoration[]; - getDecorationsInViewport(): IModelDecoration[]; -} - -export interface IViewport { - top: number; - left: number; - width: number; - height: number; -} - -/** - * Description of an action contribution - */ -export interface IActionDescriptor { - /** - * An unique identifier of the contributed action. - */ - id: string; - /** - * A label of the action that will be presented to the user. - */ - label: string; - /** - * An array of keybindings for the action. - */ - keybindings?: number[]; - keybindingContext: string; - /** - * A set of enablement conditions. - */ - enablement?: IActionEnablement; - /** - * Control if the action should show up in the context menu and where. - * Built-in groups: - * 1_goto/* => e.g. 1_goto/1_peekDefinition - * 2_change/* => e.g. 2_change/2_format - * 3_edit/* => e.g. 3_edit/1_copy - * 4_tools/* => e.g. 4_tools/1_commands - * You can also create your own group. - * Defaults to null (don't show in context menu). - */ - contextMenuGroupId?: string; - /** - * Method that will be executed when the action is triggered. - * @param editor The editor instance is passed in as a convinience - */ - run:(editor:ICommonCodeEditor)=>TPromise; -} - -/** - * Data associated with an editor action contribution - */ -export interface IEditorActionDescriptorData { - id:string; - label:string; -} - -export type IEditorActionContributionCtor = IConstructorSignature2; - -export type ICommonEditorContributionCtor = IConstructorSignature1; - -/** - * An editor contribution descriptor that will be used to construct editor contributions - */ -export interface ICommonEditorContributionDescriptor { - /** - * Create an instance of the contribution - */ - createInstance(instantiationService:IInstantiationService, editor:ICommonCodeEditor): IEditorContribution; -} - -/** - * An editor. - */ -export interface IEditor extends IEventEmitter { - - getId(): string; - - /** - * Get the editor type. Current supported types: - * EditorType.ICodeEditor => ICodeEditor; - * EditorType.IDiffEditor => IDiffEditor; - * This is to avoid an instanceof check - */ - getEditorType(): string; - - /** - * Destroy the editor. - */ - destroy(): void; - - /** - * Update the editor's options after the editor has been created. - */ - updateOptions(newOptions: IEditorOptions): void; - - /** - * Indicates that the editor becomes visible. - */ - onVisible(): void; - - /** - * Indicates that the editor becomes hidden. - */ - onHide(): void; - - /** - * Instructs the editor to remeasure its container. This method should - * be called when the container of the editor gets resized. - */ - layout(dimension?:IDimension): void; - - /** - * Brings browser focus to the editor - */ - focus(): void; - - /** - * Returns true if this editor has keyboard focus. - */ - isFocused(): boolean; - - /** - * Add a new action to this editor. - */ - addAction(descriptor:IActionDescriptor): void; - - /** - * Returns all actions associated with this editor. - */ - getActions(): any[];//IAction[]; - - /** - * Saves current view state of the editor in a serializable object. - */ - saveViewState(): IEditorViewState; - - /** - * Restores the view state of the editor from a serializable object generated by `saveViewState`. - */ - restoreViewState(state: IEditorViewState): void; - - /** - * Given a position, returns a column number that takes tab-widths into account. - */ - getVisibleColumnFromPosition(position:IPosition): number; - - /** - * Returns the primary position of the cursor. - */ - getPosition(): IEditorPosition; - - /** - * Set the primary position of the cursor. This will remove any secondary cursors. - * @param position New primary cursor's position - */ - setPosition(position:IPosition): void; - - /** - * Scroll vertically as necessary and reveal a line. - */ - revealLine(lineNumber: number): void; - - /** - * Scroll vertically as necessary and reveal a line centered vertically. - */ - revealLineInCenter(lineNumber: number): void; - - /** - * Scroll vertically as necessary and reveal a line centered vertically only if it lies outside the viewport. - */ - revealLineInCenterIfOutsideViewport(lineNumber: number): void; - - /** - * Scroll vertically or horizontally as necessary and reveal a position. - */ - revealPosition(position: IPosition): void; - - /** - * Scroll vertically or horizontally as necessary and reveal a position centered vertically. - */ - revealPositionInCenter(position: IPosition): void; - - /** - * Scroll vertically or horizontally as necessary and reveal a position centered vertically only if it lies outside the viewport. - */ - revealPositionInCenterIfOutsideViewport(position: IPosition): void; - - /** - * Returns the primary selection of the editor. - */ - getSelection(): IEditorSelection; - - /** - * Returns all the selections of the editor. - */ - getSelections(): IEditorSelection[]; - - /** - * Set the primary selection of the editor. This will remove any secondary cursors. - * @param selection The new selection - */ - setSelection(selection:IRange): void; - setSelection(selection:IEditorRange): void; - setSelection(selection:ISelection): void; - setSelection(selection:IEditorSelection): void; - - /** - * Set the selections for all the cursors of the editor. - * Cursors will be removed or added, as necessary. - */ - setSelections(selections:ISelection[]): void; - - /** - * Scroll vertically as necessary and reveal lines. - */ - revealLines(startLineNumber: number, endLineNumber: number): void; - - /** - * Scroll vertically as necessary and reveal lines centered vertically. - */ - revealLinesInCenter(lineNumber: number, endLineNumber: number): void; - - /** - * Scroll vertically as necessary and reveal lines centered vertically only if it lies outside the viewport. - */ - revealLinesInCenterIfOutsideViewport(lineNumber: number, endLineNumber: number): void; - - /** - * Scroll vertically or horizontally as necessary and reveal a range. - */ - revealRange(range: IRange): void; - - /** - * Scroll vertically or horizontally as necessary and reveal a range centered vertically. - */ - revealRangeInCenter(range: IRange): void; - - /** - * Scroll vertically or horizontally as necessary and reveal a range centered vertically only if it lies outside the viewport. - */ - revealRangeInCenterIfOutsideViewport(range: IRange): void; - - - /** - * Directly trigger a handler or an editor action. - * @param source The source of the call. - * @param handlerId The id of the handler or the id of a contribution. - * @param payload Extra data to be sent to the handler. - */ - trigger(source:string, handlerId:string, payload:any): void; - - /** - * Gets the current model attached to this editor. - */ - getModel(): IEditorModel; - - /** - * Sets the current model attached to this editor. - * If the previous model was created by the editor via the value key in the options - * literal object, it will be destroyed. Otherwise, if the previous model was set - * via setModel, or the model key in the options literal object, the previous model - * will not be destroyed. - * It is safe to call setModel(null) to simply detach the current model from the editor. - */ - setModel(model:IEditorModel): void; - - /** - * Change the decorations. All decorations added through this changeAccessor - * will get the ownerId of the editor (meaning they will not show up in other - * editors). - * @see IModel.changeDecorations - */ - changeDecorations(callback: (changeAccessor:IModelDecorationsChangeAccessor)=>any): any; -} - -export interface ICodeEditorState { - validate(editor:ICommonCodeEditor): boolean; -} - -export enum CodeEditorStateFlag { - Value, - Selection, - Position, - Scroll -} - -/** - * An editor contribution that gets created every time a new editor gets created and gets disposed when the editor gets disposed. - */ -export interface IEditorContribution { - /** - * Get a unique identifier for this contribution. - */ - getId(): string; - /** - * Dispose this contribution. - */ - dispose(): void; - /** - * Store view state. - */ - saveViewState?(): any; - /** - * Restore view state. - */ - restoreViewState?(state: any): void; -} - -export type MarkedString = string | { language: string; value: string }; - -export interface IThemeDecorationRenderOptions { - backgroundColor?: string; - - outlineColor?: string; - outlineStyle?: string; - outlineWidth?: string; - - borderColor?: string; - borderRadius?: string; - borderSpacing?: string; - borderStyle?: string; - borderWidth?: string; - - textDecoration?: string; - cursor?: string; - color?: string; - letterSpacing?: string; - - gutterIconPath?: string; - - overviewRulerColor?: string; -} - -export interface IDecorationRenderOptions extends IThemeDecorationRenderOptions { - isWholeLine?: boolean; - overviewRulerLane?: OverviewRulerLane; - - light?: IThemeDecorationRenderOptions; - dark?: IThemeDecorationRenderOptions; -} - -export interface IRangeWithMessage { - range: IRange; - hoverMessage?: IHTMLContentElement[]; -} - -export interface ICommonCodeEditor extends IEditor { - - /** - * Get a contribution of this editor. - * @id Unique identifier of the contribution. - * @return The contribution or null if contribution not found. - */ - getContribution(id: string): IEditorContribution; - - captureState(...flags:CodeEditorStateFlag[]): ICodeEditorState; - - /** - * Type the getModel() of IEditor. - */ - getModel(): IModel; - - /** - * Returns the current editor's configuration - */ - getConfiguration(): IInternalEditorOptions; - - /** - * Returns the 'raw' editor's configuration, as it was applied over the defaults, but without any computed members. - */ - getRawConfiguration(): IEditorOptions; - - /** - * Computed indentation options. - * If either one of the `tabSize` and `insertSpaces` options is set to 'auto', this is computed based on the current attached model. - * Otherwise, they are equal to `tabSize` and `insertSpaces`. - */ - getIndentationOptions(): IInternalIndentationOptions; - - /** - * Normalize whitespace using the editor's whitespace specific settings - */ - normalizeIndentation(str: string): string; - - /** - * Get value of the current model attached to this editor. - * @see IModel.getValue - */ - getValue(options?: { preserveBOM: boolean; lineEnding: string; }): string; - - /** - * Set the value of the current model attached to this editor. - * @see IModel.setValue - */ - setValue(newValue: string): void; - - /** - * Change the scrollTop of the editor's viewport. - */ - setScrollTop(newScrollTop: number): void; - /** - * Get the scrollTop of the editor's viewport. - */ - getScrollTop(): number; - - /** - * Change the scrollLeft of the editor's viewport. - */ - setScrollLeft(newScrollLeft: number): void; - /** - * Get the scrollLeft of the editor's viewport. - */ - getScrollLeft(): number; - - /** - * Get the scrollWidth of the editor's viewport. - */ - getScrollWidth(): number; - - /** - * Get the scrollHeight of the editor's viewport. - */ - getScrollHeight(): number; - - /** - * Get an action that is a contribution to this editor. - * @id Unique identifier of the contribution. - * @return The action or null if action not found. - */ - getAction(id: string): any;//IAction; - - /** - * Execute a command on the editor. - * @param source The source of the call. - * @param command The command to execute - */ - executeCommand(source: string, command: ICommand): boolean; - - /** - * Execute a command on the editor. - * @param source The source of the call. - * @param command The command to execute - */ - executeEdits(source: string, edits: IIdentifiedSingleEditOperation[]): boolean; - - /** - * Execute multiple (concommitent) commands on the editor. - * @param source The source of the call. - * @param command The commands to execute - */ - executeCommands(source: string, commands: ICommand[]): boolean; - - /** - * Get all the decorations on a line (filtering out decorations from other editors). - */ - getLineDecorations(lineNumber: number): IModelDecoration[]; - - /** - * All decorations added through this call wii get the ownerId of this editor. - * @see IModel.deltaDecorations - */ - deltaDecorations(oldDecorations: string[], newDecorations: IModelDeltaDecoration[]): string[]; - - setDecorations(decorationTypeKey: string, ranges:IRangeWithMessage[]): void; - - removeDecorations(decorationTypeKey:string): void; - - /** - * Get the layout info for the editor. - */ - getLayoutInfo(): IEditorLayoutInfo; - - /** - * Prevent the editor from sending a widgetFocusLost event, - * set it in a state where it believes that focus is in one of its widgets. - * Use this method with care and always add a matching `endForcedWidgetFocus` - */ - beginForcedWidgetFocus(): void; - - /** - * End the preventing of sending a widgetFocusLost event. - */ - endForcedWidgetFocus(): void; - - /** - * This listener is notified when a keypress produces a visible character. - * The callback should not do operations on the view, as the view might not be updated to reflect previous typed characters. - * @param character Character to listen to. - * @param callback Function to call when `character` is typed. - */ - addTypingListener(character: string, callback: () => void): ListenerUnbind; - -} - -export interface ICommonDiffEditor extends IEditor { - /** - * Type the getModel() of IEditor. - */ - getModel(): IDiffEditorModel; - - getOriginalEditor(): ICommonCodeEditor; - getModifiedEditor(): ICommonCodeEditor; - - getLineChanges(): ILineChange[]; - - /** - * Get information based on computed diff about a line number from the original model. - * If the diff computation is not finished or the model is missing, will return null. - */ - getDiffLineInformationForOriginal(lineNumber:number): IDiffLineInformation; - /** - * Get information based on computed diff about a line number from the modified model. - * If the diff computation is not finished or the model is missing, will return null. - */ - getDiffLineInformationForModified(lineNumber:number): IDiffLineInformation; - - /** - * @see ICodeEditor.getValue - */ - getValue(options?:{ preserveBOM:boolean; lineEnding:string; }): string; - - /** - * Returns whether the diff editor is ignoring trim whitespace or not. - */ - ignoreTrimWhitespace: boolean; - /** - * Returns whether the diff editor is rendering side by side or not. - */ - renderSideBySide: boolean; -} - -export var EditorType : { - ICodeEditor: string; - IDiffEditor: string; -}; - -export var ClassName : { - EditorWarningDecoration: string; - EditorErrorDecoration: string; -}; - -export var EventType : { - Disposed: string; - - ConfigurationChanged: string; - - ModelDispose: string; - - ModelChanged: string; - - ModelTokensChanged: string; - ModelModeChanged: string; - ModelModeSupportChanged: string; - ModelContentChanged: string; - ModelContentChanged2: string; - ModelContentChangedFlush: string; - ModelContentChangedLinesDeleted: string; - ModelContentChangedLinesInserted: string; - ModelContentChangedLineChanged: string; - - EditorTextBlur: string; - EditorTextFocus: string; - EditorFocus: string; - EditorBlur: string; - - ModelDecorationsChanged: string; - - CursorPositionChanged: string; - CursorSelectionChanged: string; - CursorRevealRange: string; - CursorScrollRequest: string; - - ViewFocusGained: string; - ViewFocusLost: string; - ViewFocusChanged: string; - ViewScrollWidthChanged: string; - ViewScrollHeightChanged: string; - ViewScrollChanged: string; - ViewZonesChanged: string; - - ViewLayoutChanged: string; - - ContextMenu: string; - MouseDown: string; - MouseUp: string; - MouseMove: string; - MouseLeave: string; - KeyDown: string; - KeyUp: string; - - EditorLayout: string; - - DiffUpdated: string; -}; - -export var Handler : { - ExecuteCommand: string; - ExecuteCommands: string; - - CursorLeft: string; - CursorLeftSelect: string; - CursorWordLeft: string; - CursorWordLeftSelect: string; - - CursorRight: string; - CursorRightSelect: string; - CursorWordRight: string; - CursorWordRightSelect: string; - - CursorUp: string; - CursorUpSelect: string; - CursorDown: string; - CursorDownSelect: string; - - CursorPageUp: string; - CursorPageUpSelect: string; - CursorPageDown: string; - CursorPageDownSelect: string; - - CursorHome: string; - CursorHomeSelect: string; - - CursorEnd: string; - CursorEndSelect: string; - - ExpandLineSelection: string; - - CursorTop: string; - CursorTopSelect: string; - CursorBottom: string; - CursorBottomSelect: string; - - AddCursorDown: string; - AddCursorUp: string; - CursorUndo: string; - MoveTo: string; - MoveToSelect: string; - ColumnSelect: string; - CreateCursor: string; - LastCursorMoveToSelect: string; - - JumpToBracket: string; - - Type: string; - ReplacePreviousChar: string; - Paste: string; - - Tab: string; - Indent: string; - Outdent: string; - - DeleteLeft: string; - DeleteRight: string; - DeleteWordLeft: string; - DeleteWordRight: string; - DeleteAllLeft: string; - DeleteAllRight: string; - - Enter: string; - RemoveSecondaryCursors: string; - CancelSelection: string; - - Cut: string; - - Undo: string; - Redo: string; - - WordSelect: string; - WordSelectDrag: string; - LastCursorWordSelect: string; - - LineSelect: string; - LineSelectDrag: string; - LastCursorLineSelect: string; - LastCursorLineSelectDrag: string; - LineInsertBefore: string; - LineInsertAfter: string; - LineBreakInsert: string; - - SelectAll: string; - - ScrollLineUp: string; - ScrollLineDown: string; - - ScrollPageUp: string; - ScrollPageDown: string; -}; - -export class VisibleRange { - - public top:number; - public left:number; - public width:number; - - constructor(top:number, left:number, width:number); -} - -export class HorizontalRange { - - public left: number; - public width: number; - - constructor(left:number, width:number); -} - -export class LineVisibleRanges { - - public lineNumber: number; - public ranges: HorizontalRange[]; - - constructor(lineNumber:number, ranges:HorizontalRange[]); -} - - // ======================================================================== - // vs/editor/browser/editorBrowser.ts - // ======================================================================== - -export interface IDynamicViewOverlay extends IDisposable { - shouldCallRender2(ctx:IRenderingContext): boolean; - render2(lineNumber:number): string[]; -} - -export interface IContentWidgetData { - widget: IContentWidget; - position: IContentWidgetPosition; -} - -export interface IOverlayWidgetData { - widget: IOverlayWidget; - position: IOverlayWidgetPosition; -} - -export interface ICodeEditorHelper { - getScrollTop(): number; - setScrollTop(scrollTop:number): void; - getScrollLeft(): number; - setScrollLeft(scrollLeft:number): void; - getScrollHeight(): number; - getScrollWidth(): number; - getVerticalOffsetForPosition(lineNumber:number, column:number): number; - delegateVerticalScrollbarMouseDown(browserEvent:MouseEvent): void; - getOffsetForColumn(lineNumber:number, column:number): number; -} - -export interface IKeyboardHandlerHelper { - viewDomNode:HTMLElement; - textArea:HTMLTextAreaElement; - visibleRangeForPositionRelativeToEditor(lineNumber:number, column:number): VisibleRange; -} - -export interface IPointerHandlerHelper { - viewDomNode:HTMLElement; - linesContentDomNode:HTMLElement; - - focusTextArea(): void; - isDirty(): boolean; - - getScrollTop(): number; - setScrollTop(scrollTop:number): void; - getScrollLeft(): number; - setScrollLeft(scrollLeft:number): void; - - isAfterLines(verticalOffset:number): boolean; - getLineNumberAtVerticalOffset(verticalOffset: number): number; - getVerticalOffsetForLineNumber(lineNumber: number): number; - getWhitespaceAtVerticalOffset(verticalOffset:number): IViewWhitespaceViewportData; - shouldSuppressMouseDownOnViewZone(viewZoneId:number): boolean; - - /** - * Decode an Editor.IPosition from a rendered dom node - */ - getPositionFromDOMInfo(spanNode:HTMLElement, offset:number): IPosition; - - visibleRangeForPosition2(lineNumber:number, column:number): VisibleRange; - getLineWidth(lineNumber:number): number; -} - -export interface IView extends IDisposable { - domNode: HTMLElement; - - getInternalEventBus(): IEventEmitter; - - createOverviewRuler(cssClassName:string, minimumHeight:number, maximumHeight:number): IOverviewRuler; - getCodeEditorHelper(): ICodeEditorHelper; - - getCenteredRangeInViewport(): IEditorRange; - - change(callback:(changeAccessor:IViewZoneChangeAccessor) => any): boolean; - getWhitespaces(): IEditorWhitespace[]; - renderOnce(callback:() => any): any; - - render(now:boolean): void; - - focus(): void; - isFocused(): boolean; - - saveState(): IViewState; - restoreState(state:IViewState): void; - - addContentWidget(widgetData: IContentWidgetData): void; - layoutContentWidget(widgetData: IContentWidgetData): void; - removeContentWidget(widgetData: IContentWidgetData): void; - - addOverlayWidget(widgetData: IOverlayWidgetData): void; - layoutOverlayWidget(widgetData: IOverlayWidgetData): void; - removeOverlayWidget(widgetData: IOverlayWidgetData): void; -} - -export interface IViewZoneData { - viewZoneId: number; - positionBefore:IEditorPosition; - positionAfter:IEditorPosition; - position: IEditorPosition; - afterLineNumber: number; -} - -export interface IMouseDispatchData { - position: IEditorPosition; - /** - * Desired mouse column (e.g. when position.column gets clamped to text length -- clicking after text on a line). - */ - mouseColumn: number; - startedOnLineNumbers: boolean; - - inSelectionMode: boolean; - mouseDownCount: number; - altKey: boolean; - ctrlKey: boolean; - metaKey: boolean; - shiftKey: boolean; -} - -export interface IViewController { - dispatchMouse(data:IMouseDispatchData); - - moveTo(source:string, position:IEditorPosition): void; - - paste(source:string, text:string, pasteOnNewLine:boolean): void; - type(source: string, text: string): void; - replacePreviousChar(source: string, text: string, replaceCharCnt:number): void; - cut(source:string): void; - - // emitKeyDown(e:IKeyboardEvent): void; - // emitKeyUp(e:IKeyboardEvent): void; - emitContextMenu(e:IEditorMouseEvent): void; - emitMouseMove(e:IEditorMouseEvent): void; - emitMouseLeave(e:IEditorMouseEvent): void; - emitMouseUp(e:IEditorMouseEvent): void; - emitMouseDown(e:IEditorMouseEvent): void; -} - -export var ClassNames : { - TEXTAREA_COVER: string; - TEXTAREA: string; - LINES_CONTENT: string; - OVERFLOW_GUARD: string; - VIEW_LINES: string; - VIEW_LINE: string; - SCROLLABLE_ELEMENT: string; - CONTENT_WIDGETS: string; - OVERFLOWING_CONTENT_WIDGETS: string; - OVERLAY_WIDGETS: string; - MARGIN_VIEW_OVERLAYS: string; - LINE_NUMBERS: string; - GLYPH_MARGIN: string; - SCROLL_DECORATION: string; - VIEW_CURSORS_LAYER: string; - VIEW_ZONES: string; -}; - -export interface IRestrictedRenderingContext { - linesViewportData:IViewLinesViewportData; - - scrollWidth:number; - scrollHeight:number; - - visibleRange:IEditorRange; - bigNumbersDelta:number; - - viewportTop:number; - viewportWidth:number; - viewportHeight:number; - viewportLeft:number; - - getScrolledTopFromAbsoluteTop(absoluteTop:number): number; - getViewportVerticalOffsetForLineNumber(lineNumber:number): number; - lineIsVisible(lineNumber:number): boolean; - - getDecorationsInViewport(): IModelDecoration[]; -} - -export interface IRenderingContext extends IRestrictedRenderingContext { - - linesVisibleRangesForRange(range:IRange, includeNewLines:boolean): LineVisibleRanges[]; - - visibleRangeForPosition(position:IPosition): VisibleRange; -} - -export interface IViewEventHandler { - handleEvents(events:IEmitterEvent[]): void; -} - -export interface IViewportInfo { - visibleRange: IEditorRange; - width:number; - height:number; - deltaTop:number; - deltaLeft:number; -} - -export interface IViewPart extends IDisposable { - onBeforeForcedLayout(): void; - onReadAfterForcedLayout(ctx:IRenderingContext): void; - onWriteAfterForcedLayout(): void; -} - -// --- end View Event Handlers & Parts - -export interface IViewContext { - - addEventHandler(eventHandler:IViewEventHandler): void; - removeEventHandler(eventHandler:IViewEventHandler): void; - - configuration:IConfiguration; - model: IViewModel; - privateViewEventBus:IViewEventBus; -} - -export interface ILayoutProvider extends IVerticalLayoutProvider, IScrollingProvider { - - dispose():void; - - getCenteredViewLineNumberInViewport(): number; - - getCurrentViewport(): IViewport; - - onMaxLineWidthChanged(width:number): void; - - saveState(): IViewState; - restoreState(state:IViewState): void; -} - -export interface IScrollingProvider { - - getOverviewRulerInsertData(): { parent: HTMLElement; insertBefore: HTMLElement; }; - getScrollbarContainerDomNode(): HTMLElement; - delegateVerticalScrollbarMouseDown(browserEvent:MouseEvent): void; - - // This is for the glyphs, line numbers, etc. - getScrolledTopFromAbsoluteTop(top:number): number; - - getScrollHeight(): number; - getScrollWidth(): number; - getScrollLeft(): number; - setScrollLeft(scrollLeft:number): void; - getScrollTop(): number; - setScrollTop(scrollTop:number): void; -} - -export interface IVerticalLayoutProvider { - - /** - * Compute vertical offset (top) of line number - */ - getVerticalOffsetForLineNumber(lineNumber:number): number; - - /** - * Returns the height in pixels for `lineNumber`. - */ - heightInPxForLine(lineNumber:number): number; - - /** - * Return line number at `verticalOffset` or closest line number - */ - getLineNumberAtVerticalOffset(verticalOffset:number): number; - - /** - * Compute content height (including one extra scroll page if necessary) - */ - getTotalHeight(): number; - - /** - * Compute the lines that need to be rendered in the current viewport position. - */ - getLinesViewportData(): IViewLinesViewportData; -} - -/** - * A view zone is a full horizontal rectangle that 'pushes' text down. - * The editor reserves space for view zones when rendering. - */ -export interface IViewZone { - /** - * The line number after which this zone should appear. - * Use 0 to place a view zone before the first line number. - */ - afterLineNumber:number; - /** - * The column after which this zone should appear. - * If not set, the maxLineColumn of `afterLineNumber` will be used. - */ - afterColumn?:number; - /** - * Suppress mouse down events. - * If set, the editor will attach a mouse down listener to the view zone and .preventDefault on it. - * Defaults to false - */ - suppressMouseDown?:boolean; - /** - * The height in lines of the view zone. - * If specified, `heightInPx` will be used instead of this. - * If neither `heightInPx` nor `heightInLines` is specified, a default of `heightInLines` = 1 will be chosen. - */ - heightInLines?:number; - /** - * The height in px of the view zone. - * If this is set, the editor will give preference to it rather than `heightInLines` above. - * If neither `heightInPx` nor `heightInLines` is specified, a default of `heightInLines` = 1 will be chosen. - */ - heightInPx?: number; - /** - * The dom node of the view zone - */ - domNode:HTMLElement; - /** - * Callback which gives the relative top of the view zone as it appears (taking scrolling into account). - */ - onDomNodeTop?:(top: number) =>void; - /** - * Callback which gives the height in pixels of the view zone. - */ - onComputedHeight?:(height: number) =>void; -} -/** - * An accessor that allows for zones to be added or removed. - */ -export interface IViewZoneChangeAccessor { - /** - * Create a new view zone. - * @param zone Zone to create - * @return A unique identifier to the view zone. - */ - addZone(zone: IViewZone): number; - /** - * Remove a zone - * @param id A unique identifier to the view zone, as returned by the `addZone` call. - */ - removeZone(id: number): void; - /** - * Change a zone's position. - * The editor will rescan the `afterLineNumber` and `afterColumn` properties of a view zone. - */ - layoutZone(id: number): void; -} - -/** - * A positioning preference for rendering content widgets. - */ -export enum ContentWidgetPositionPreference { - /** - * Place the content widget exactly at a position - */ - EXACT, - /** - * Place the content widget above a position - */ - ABOVE, - /** - * Place the content widget below a position - */ - BELOW -} -/** - * A position for rendering content widgets. - */ -export interface IContentWidgetPosition { - /** - * Desired position for the content widget. - * `preference` will also affect the placement. - */ - position: IPosition; - /** - * Placement preference for position, in order of preference. - */ - preference: ContentWidgetPositionPreference[]; -} -/** - * A content widget renders inline with the text and can be easily placed 'near' an editor position. - */ -export interface IContentWidget { - /** - * Render this content widget in a location where it could overflow the editor's view dom node. - */ - allowEditorOverflow?: boolean; - /** - * Get a unique identifier of the content widget. - */ - getId(): string; - /** - * Get the dom node of the content widget. - */ - getDomNode(): HTMLElement; - /** - * Get the placement of the content widget. - * If null is returned, the content widget will be placed off screen. - */ - getPosition(): IContentWidgetPosition; -} - -/** - * A positioning preference for rendering overlay widgets. - */ -export enum OverlayWidgetPositionPreference { - /** - * Position the overlay widget in the top right corner - */ - TOP_RIGHT_CORNER, - - /** - * Position the overlay widget in the bottom right corner - */ - BOTTOM_RIGHT_CORNER, - - /** - * Position the overlay widget in the top center - */ - TOP_CENTER -} -/** - * A position for rendering overlay widgets. - */ -export interface IOverlayWidgetPosition { - /** - * The position preference for the overlay widget. - */ - preference: OverlayWidgetPositionPreference; -} -/** - * An overlay widgets renders on top of the text. - */ -export interface IOverlayWidget { - /** - * Get a unique identifier of the overlay widget. - */ - getId(): string; - /** - * Get the dom node of the overlay widget. - */ - getDomNode(): HTMLElement; - /** - * Get the placement of the overlay widget. - * If null is returned, the overlay widget is responsible to place itself. - */ - getPosition(): IOverlayWidgetPosition; -} - -/** - * Target hit with the mouse in the editor. - */ -export interface IMouseTarget { - /** - * The target element - */ - element: Element; - /** - * The target type - */ - type: MouseTargetType; - /** - * The 'approximate' editor position - */ - position: IEditorPosition; - /** - * Desired mouse column (e.g. when position.column gets clamped to text length -- clicking after text on a line). - */ - mouseColumn: number; - /** - * The 'approximate' editor range - */ - range: IEditorRange; - /** - * Some extra detail. - */ - detail: any; -} -/** - * A mouse event originating from the editor. - */ -export interface IEditorMouseEvent { - //event: IMouseEvent; - target: IMouseTarget; -} - -export type ISimpleEditorContributionCtor = IConstructorSignature1; - -/** - * An editor contribution descriptor that will be used to construct editor contributions - */ -export interface IEditorContributionDescriptor { - /** - * Create an instance of the contribution - */ - createInstance(instantiationService:IInstantiationService, editor:ICodeEditor): IEditorContribution; -} - -/** - * A zone in the overview ruler - */ -export interface IOverviewRulerZone { - startLineNumber: number; - endLineNumber: number; - forceHeight?: number; - color: string; - darkColor: string; - position: OverviewRulerLane; -} -/** - * An overview ruler - */ -export interface IOverviewRuler { - getDomNode(): HTMLElement; - dispose(): void; - setZones(zones:IOverviewRulerZone[]): void; - setLayout(position:IOverviewRulerPosition): void; -} -/** - * A rich code editor. - */ -export interface ICodeEditor extends ICommonCodeEditor { - - /** - * Returns the editor's dom node - */ - getDomNode(): HTMLElement; - - /** - * Add a content widget. Widgets must have unique ids, otherwise they will be overwritten. - */ - addContentWidget(widget: IContentWidget): void; - /** - * Layout/Reposition a content widget. This is a ping to the editor to call widget.getPosition() - * and update appropiately. - */ - layoutContentWidget(widget: IContentWidget): void; - /** - * Remove a content widget. - */ - removeContentWidget(widget: IContentWidget): void; - - /** - * Add an overlay widget. Widgets must have unique ids, otherwise they will be overwritten. - */ - addOverlayWidget(widget: IOverlayWidget): void; - /** - * Layout/Reposition an overlay widget. This is a ping to the editor to call widget.getPosition() - * and update appropiately. - */ - layoutOverlayWidget(widget: IOverlayWidget): void; - /** - * Remove an overlay widget. - */ - removeOverlayWidget(widget: IOverlayWidget): void; - - /** - * Change the view zones. View zones are lost when a new model is attached to the editor. - */ - changeViewZones(callback: (accessor: IViewZoneChangeAccessor) => void): void; - - /** - * Returns the range that is currently centered in the view port. - */ - getCenteredRangeInViewport(): IEditorRange; - - /** - * Get the view zones. - */ - getWhitespaces(): IEditorWhitespace[]; - - /** - * Get the horizontal position (left offset) for the column w.r.t to the beginning of the line. - * This method works only if the line `lineNumber` is currently rendered (in the editor's viewport). - * Use this method with caution. - */ - getOffsetForColumn(lineNumber: number, column: number): number; - - /** - * Force an editor render now. - */ - render(): void; - - /** - * Get the vertical position (top offset) for the line w.r.t. to the first line. - */ - getTopForLineNumber(lineNumber: number): number; - - /** - * Get the vertical position (top offset) for the position w.r.t. to the first line. - */ - getTopForPosition(lineNumber: number, column: number): number; - - /** - * Get the visible position for `position`. - * The result position takes scrolling into account and is relative to the top left corner of the editor. - * Explanation 1: the results of this method will change for the same `position` if the user scrolls the editor. - * Explanation 2: the results of this method will not change if the container of the editor gets repositioned. - * Warning: the results of this method are innacurate for positions that are outside the current editor viewport. - */ - getScrolledVisiblePosition(position: IPosition): { top: number; left: number; height: number; }; - - /** - * Set the model ranges that will be hidden in the view. - */ - setHiddenAreas(ranges:IRange[]): void; -} - -/** - * A rich diff editor. - */ -export interface IDiffEditor extends ICommonDiffEditor { - /** - * @see ICodeEditor.getDomNode - */ - getDomNode(): HTMLElement; -} - + export enum ScrollbarVisibility { + Auto = 1, + Hidden = 2, + Visible = 3, + } + + /** + * A token on a line. + */ + export class ViewLineToken { + _viewLineTokenBrand: void; + startIndex: number; + type: string; + constructor(startIndex: number, type: string); + equals(other: ViewLineToken): boolean; + static findIndexInSegmentsArray(arr: ViewLineToken[], desiredIndex: number): number; + static equalsArray(a: ViewLineToken[], b: ViewLineToken[]): boolean; + } + + + /** + * A position in the editor. This interface is suitable for serialization. + */ + export interface IPosition { + /** + * line number (starts at 1) + */ + lineNumber: number; + /** + * column (the first character in a line is between column 1 and column 2) + */ + column: number; + } + + /** + * A position in the editor. + */ + export interface IEditorPosition extends IPosition { + /** + * Test if this position equals other position + */ + equals(other: IPosition): boolean; + /** + * Test if this position is before other position. If the two positions are equal, the result will be false. + */ + isBefore(other: IPosition): boolean; + /** + * Test if this position is before other position. If the two positions are equal, the result will be true. + */ + isBeforeOrEqual(other: IPosition): boolean; + /** + * Clone this position. + */ + clone(): IEditorPosition; + } + + /** + * A range in the editor. This interface is suitable for serialization. + */ + export interface IRange { + /** + * Line number on which the range starts (starts at 1). + */ + startLineNumber: number; + /** + * Column on which the range starts in line `startLineNumber` (starts at 1). + */ + startColumn: number; + /** + * Line number on which the range ends. + */ + endLineNumber: number; + /** + * Column on which the range ends in line `endLineNumber`. + */ + endColumn: number; + } + + /** + * A range in the editor. + */ + export interface IEditorRange extends IRange { + /** + * Test if this range is empty. + */ + isEmpty(): boolean; + collapseToStart(): IEditorRange; + /** + * Test if position is in this range. If the position is at the edges, will return true. + */ + containsPosition(position: IPosition): boolean; + /** + * Test if range is in this range. If the range is equal to this range, will return true. + */ + containsRange(range: IRange): boolean; + /** + * A reunion of the two ranges. The smallest position will be used as the start point, and the largest one as the end point. + */ + plusRange(range: IRange): IEditorRange; + /** + * A intersection of the two ranges. + */ + intersectRanges(range: IRange): IEditorRange; + /** + * Test if this range equals other. + */ + equalsRange(other: IRange): boolean; + /** + * Return the end position (which will be after or equal to the start position) + */ + getEndPosition(): IEditorPosition; + /** + * Create a new range using this range's start position, and using endLineNumber and endColumn as the end position. + */ + setEndPosition(endLineNumber: number, endColumn: number): IEditorRange; + /** + * Return the start position (which will be before or equal to the end position) + */ + getStartPosition(): IEditorPosition; + /** + * Create a new range using this range's end position, and using startLineNumber and startColumn as the start position. + */ + setStartPosition(startLineNumber: number, startColumn: number): IEditorRange; + /** + * Clone this range. + */ + cloneRange(): IEditorRange; + /** + * Transform to a user presentable string representation. + */ + toString(): string; + } + + /** + * A selection in the editor. + * The selection is a range that has an orientation. + */ + export interface ISelection { + /** + * The line number on which the selection has started. + */ + selectionStartLineNumber: number; + /** + * The column on `selectionStartLineNumber` where the selection has started. + */ + selectionStartColumn: number; + /** + * The line number on which the selection has ended. + */ + positionLineNumber: number; + /** + * The column on `positionLineNumber` where the selection has ended. + */ + positionColumn: number; + } + + /** + * The direction of a selection. + */ + export enum SelectionDirection { + /** + * The selection starts above where it ends. + */ + LTR = 0, + /** + * The selection starts below where it ends. + */ + RTL = 1, + } + + /** + * A selection in the editor. + */ + export interface IEditorSelection extends ISelection, IEditorRange { + /** + * Test if equals other selection. + */ + equalsSelection(other: ISelection): boolean; + /** + * Clone this selection. + */ + clone(): IEditorSelection; + /** + * Get directions (LTR or RTL). + */ + getDirection(): SelectionDirection; + /** + * Create a new selection with a different `positionLineNumber` and `positionColumn`. + */ + setEndPosition(endLineNumber: number, endColumn: number): IEditorSelection; + /** + * Create a new selection with a different `selectionStartLineNumber` and `selectionStartColumn`. + */ + setStartPosition(startLineNumber: number, startColumn: number): IEditorSelection; + } + + /** + * Configuration options for editor scrollbars + */ + export interface IEditorScrollbarOptions { + /** + * The size of arrows (if displayed). + * Defaults to 11. + */ + arrowSize?: number; + /** + * Render vertical scrollbar. + * Accepted values: 'auto', 'visible', 'hidden'. + * Defaults to 'auto'. + */ + vertical?: string; + /** + * Render horizontal scrollbar. + * Accepted values: 'auto', 'visible', 'hidden'. + * Defaults to 'auto'. + */ + horizontal?: string; + /** + * Cast horizontal and vertical shadows when the content is scrolled. + * Defaults to false. + */ + useShadows?: boolean; + /** + * Render arrows at the top and bottom of the vertical scrollbar. + * Defaults to false. + */ + verticalHasArrows?: boolean; + /** + * Render arrows at the left and right of the horizontal scrollbar. + * Defaults to false. + */ + horizontalHasArrows?: boolean; + /** + * Listen to mouse wheel events and react to them by scrolling. + * Defaults to true. + */ + handleMouseWheel?: boolean; + /** + * Height in pixels for the horizontal scrollbar. + * Defaults to 10 (px). + */ + horizontalScrollbarSize?: number; + /** + * Width in pixels for the vertical scrollbar. + * Defaults to 10 (px). + */ + verticalScrollbarSize?: number; + verticalSliderSize?: number; + horizontalSliderSize?: number; + } + + export enum WrappingIndent { + None = 0, + Same = 1, + Indent = 2, + } + + /** + * Configuration options for the editor. + */ + export interface IEditorOptions { + experimentalScreenReader?: boolean; + ariaLabel?: string; + /** + * Render vertical lines at the specified columns. + * Defaults to empty array. + */ + rulers?: number[]; + /** + * A string containing the word separators used when doing word navigation. + * Defaults to `~!@#$%^&*()-=+[{]}\\|;:\'",.<>/? + */ + wordSeparators?: string; + /** + * Enable Linux primary clipboard. + * Defaults to true. + */ + selectionClipboard?: boolean; + /** + * Control the rendering of line numbers. + * If it is a function, it will be invoked when rendering a line number and the return value will be rendered. + * Otherwise, if it is a truey, line numbers will be rendered normally (equivalent of using an identity function). + * Otherwise, line numbers will not be rendered. + * Defaults to true. + */ + lineNumbers?: any; + /** + * Should the corresponding line be selected when clicking on the line number? + * Defaults to true. + */ + selectOnLineNumbers?: boolean; + /** + * Control the width of line numbers, by reserving horizontal space for rendering at least an amount of digits. + * Defaults to 5. + */ + lineNumbersMinChars?: number; + /** + * Enable the rendering of the glyph margin. + * Defaults to false. + */ + glyphMargin?: boolean; + /** + * The width reserved for line decorations (in px). + * Line decorations are placed between line numbers and the editor content. + * Defaults to 10. + */ + lineDecorationsWidth?: number; + /** + * When revealing the cursor, a virtual padding (px) is added to the cursor, turning it into a rectangle. + * This virtual padding ensures that the cursor gets revealed before hitting the edge of the viewport. + * Defaults to 30 (px). + */ + revealHorizontalRightPadding?: number; + /** + * Render the editor selection with rounded borders. + * Defaults to true. + */ + roundedSelection?: boolean; + /** + * Theme to be used for rendering. Consists of two parts, the UI theme and the syntax theme, + * separated by a space. + * The current available UI themes are: 'vs' (default), 'vs-dark', 'hc-black' + * The syntax themes are contributed. The default is 'default-theme' + */ + theme?: string; + /** + * Should the editor be read only. + * Defaults to false. + */ + readOnly?: boolean; + /** + * Control the behavior and rendering of the scrollbars. + */ + scrollbar?: IEditorScrollbarOptions; + /** + * The number of vertical lanes the overview ruler should render. + * Defaults to 2. + */ + overviewRulerLanes?: number; + /** + * Control the cursor blinking animation. + * Defaults to 'blink'. + */ + cursorBlinking?: string; + /** + * Control the cursor style, either 'block' or 'line'. + * Defaults to 'line'. + */ + cursorStyle?: string; + /** + * Enable font ligatures. + * Defaults to false. + */ + fontLigatures?: boolean; + /** + * Should the cursor be hidden in the overview ruler. + * Defaults to false. + */ + hideCursorInOverviewRuler?: boolean; + /** + * Enable that scrolling can go one screen size after the last line. + * Defaults to true. + */ + scrollBeyondLastLine?: boolean; + /** + * Enable that the editor will install an interval to check if its container dom node size has changed. + * Enabling this might have a severe performance impact. + * Defaults to false. + */ + automaticLayout?: boolean; + /** + * Control the wrapping strategy of the editor. + * Using -1 means no wrapping whatsoever. + * Using 0 means viewport width wrapping (ajusts with the resizing of the editor). + * Using a positive number means wrapping after a fixed number of characters. + * Defaults to 300. + */ + wrappingColumn?: number; + /** + * Control indentation of wrapped lines. Can be: 'none', 'same' or 'indent'. + * Defaults to 'none'. + */ + wrappingIndent?: string; + /** + * Configure word wrapping characters. A break will be introduced before these characters. + * Defaults to '{([+'. + */ + wordWrapBreakBeforeCharacters?: string; + /** + * Configure word wrapping characters. A break will be introduced after these characters. + * Defaults to ' \t})]?|&,;'. + */ + wordWrapBreakAfterCharacters?: string; + /** + * Configure word wrapping characters. A break will be introduced after these characters only if no `wordWrapBreakBeforeCharacters` or `wordWrapBreakAfterCharacters` were found. + * Defaults to '.'. + */ + wordWrapBreakObtrusiveCharacters?: string; + /** + * Control what pressing Tab does. + * If it is false, pressing Tab or Shift-Tab will be handled by the editor. + * If it is true, pressing Tab or Shift-Tab will move the browser focus. + * Defaults to false. + */ + tabFocusMode?: boolean; + /** + * Performance guard: Stop rendering a line after x characters. + * Defaults to 10000 if wrappingColumn is -1. Defaults to -1 if wrappingColumn is >= 0. + * Use -1 to never stop rendering + */ + stopRenderingLineAfter?: number; + /** + * Enable hover. + * Defaults to true. + */ + hover?: boolean; + /** + * Enable custom contextmenu. + * Defaults to true. + */ + contextmenu?: boolean; + /** + * A multiplier to be used on the `deltaX` and `deltaY` of mouse wheel scroll events. + * Defaults to 1. + */ + mouseWheelScrollSensitivity?: number; + /** + * Enable quick suggestions (shaddow suggestions) + * Defaults to true. + */ + quickSuggestions?: boolean; + /** + * Quick suggestions show delay (in ms) + * Defaults to 500 (ms) + */ + quickSuggestionsDelay?: number; + /** + * Render icons in suggestions box. + * Defaults to true. + */ + iconsInSuggestions?: boolean; + /** + * Enable auto closing brackets. + * Defaults to true. + */ + autoClosingBrackets?: boolean; + /** + * Enable format on type. + * Defaults to false. + */ + formatOnType?: boolean; + /** + * Enable the suggestion box to pop-up on trigger characters. + * Defaults to true. + */ + suggestOnTriggerCharacters?: boolean; + /** + * Accept suggestions on ENTER. + * Defaults to true. + */ + acceptSuggestionOnEnter?: boolean; + /** + * Enable selection highlight. + * Defaults to true. + */ + selectionHighlight?: boolean; + /** + * Show lines before classes and methods (based on outline info). + * Defaults to false. + */ + outlineMarkers?: boolean; + /** + * Show reference infos (a.k.a. code lenses) for modes that support it + * Defaults to true. + */ + referenceInfos?: boolean; + /** + * Enable code folding + * Defaults to true. + */ + folding?: boolean; + /** + * Enable rendering of leading whitespace. + * Defaults to false. + */ + renderWhitespace?: boolean; + /** + * Enable rendering of indent guides. + * Defaults to true. + */ + indentGuides?: boolean; + /** + * Inserting and deleting whitespace follows tab stops. + */ + useTabStops?: boolean; + /** + * The font family + */ + fontFamily?: string; + /** + * The font size + */ + fontSize?: number; + /** + * The line height + */ + lineHeight?: number; + } + + /** + * Configuration options for the diff editor. + */ + export interface IDiffEditorOptions extends IEditorOptions { + /** + * Allow the user to resize the diff editor split view. + * Defaults to true. + */ + enableSplitViewResizing?: boolean; + /** + * Render the differences in two side-by-side editors. + * Defaults to true. + */ + renderSideBySide?: boolean; + /** + * Compute the diff by ignoring leading/trailing whitespace + * Defaults to true. + */ + ignoreTrimWhitespace?: boolean; + /** + * Original model should be editable? + * Defaults to false. + */ + originalEditable?: boolean; + } + + export class InternalEditorScrollbarOptions { + _internalEditorScrollbarOptionsBrand: void; + arrowSize: number; + vertical: ScrollbarVisibility; + horizontal: ScrollbarVisibility; + useShadows: boolean; + verticalHasArrows: boolean; + horizontalHasArrows: boolean; + handleMouseWheel: boolean; + horizontalScrollbarSize: number; + horizontalSliderSize: number; + verticalScrollbarSize: number; + verticalSliderSize: number; + mouseWheelScrollSensitivity: number; + constructor(source: { + arrowSize: number; + vertical: ScrollbarVisibility; + horizontal: ScrollbarVisibility; + useShadows: boolean; + verticalHasArrows: boolean; + horizontalHasArrows: boolean; + handleMouseWheel: boolean; + horizontalScrollbarSize: number; + horizontalSliderSize: number; + verticalScrollbarSize: number; + verticalSliderSize: number; + mouseWheelScrollSensitivity: number; + }); + equals(other: InternalEditorScrollbarOptions): boolean; + clone(): InternalEditorScrollbarOptions; + } + + export class EditorWrappingInfo { + _editorWrappingInfoBrand: void; + isViewportWrapping: boolean; + wrappingColumn: number; + wrappingIndent: WrappingIndent; + wordWrapBreakBeforeCharacters: string; + wordWrapBreakAfterCharacters: string; + wordWrapBreakObtrusiveCharacters: string; + constructor(source: { + isViewportWrapping: boolean; + wrappingColumn: number; + wrappingIndent: WrappingIndent; + wordWrapBreakBeforeCharacters: string; + wordWrapBreakAfterCharacters: string; + wordWrapBreakObtrusiveCharacters: string; + }); + equals(other: EditorWrappingInfo): boolean; + clone(): EditorWrappingInfo; + } + + export class InternalEditorViewOptions { + _internalEditorViewOptionsBrand: void; + theme: string; + canUseTranslate3d: boolean; + experimentalScreenReader: boolean; + rulers: number[]; + ariaLabel: string; + lineNumbers: any; + selectOnLineNumbers: boolean; + glyphMargin: boolean; + revealHorizontalRightPadding: number; + roundedSelection: boolean; + overviewRulerLanes: number; + cursorBlinking: string; + cursorStyle: TextEditorCursorStyle; + hideCursorInOverviewRuler: boolean; + scrollBeyondLastLine: boolean; + editorClassName: string; + stopRenderingLineAfter: number; + renderWhitespace: boolean; + indentGuides: boolean; + scrollbar: InternalEditorScrollbarOptions; + constructor(source: { + theme: string; + canUseTranslate3d: boolean; + experimentalScreenReader: boolean; + rulers: number[]; + ariaLabel: string; + lineNumbers: any; + selectOnLineNumbers: boolean; + glyphMargin: boolean; + revealHorizontalRightPadding: number; + roundedSelection: boolean; + overviewRulerLanes: number; + cursorBlinking: string; + cursorStyle: TextEditorCursorStyle; + hideCursorInOverviewRuler: boolean; + scrollBeyondLastLine: boolean; + editorClassName: string; + stopRenderingLineAfter: number; + renderWhitespace: boolean; + indentGuides: boolean; + scrollbar: InternalEditorScrollbarOptions; + }); + private static _toSortedIntegerArray(source); + private static _numberArraysEqual(a, b); + equals(other: InternalEditorViewOptions): boolean; + createChangeEvent(newOpts: InternalEditorViewOptions): IViewConfigurationChangedEvent; + clone(): InternalEditorViewOptions; + } + + export interface IViewConfigurationChangedEvent { + theme: boolean; + canUseTranslate3d: boolean; + experimentalScreenReader: boolean; + rulers: boolean; + ariaLabel: boolean; + lineNumbers: boolean; + selectOnLineNumbers: boolean; + glyphMargin: boolean; + revealHorizontalRightPadding: boolean; + roundedSelection: boolean; + overviewRulerLanes: boolean; + cursorBlinking: boolean; + cursorStyle: boolean; + hideCursorInOverviewRuler: boolean; + scrollBeyondLastLine: boolean; + editorClassName: boolean; + stopRenderingLineAfter: boolean; + renderWhitespace: boolean; + indentGuides: boolean; + scrollbar: boolean; + } + + export class EditorContribOptions { + selectionClipboard: boolean; + hover: boolean; + contextmenu: boolean; + quickSuggestions: boolean; + quickSuggestionsDelay: number; + iconsInSuggestions: boolean; + formatOnType: boolean; + suggestOnTriggerCharacters: boolean; + acceptSuggestionOnEnter: boolean; + selectionHighlight: boolean; + outlineMarkers: boolean; + referenceInfos: boolean; + folding: boolean; + constructor(source: { + selectionClipboard: boolean; + hover: boolean; + contextmenu: boolean; + quickSuggestions: boolean; + quickSuggestionsDelay: number; + iconsInSuggestions: boolean; + formatOnType: boolean; + suggestOnTriggerCharacters: boolean; + acceptSuggestionOnEnter: boolean; + selectionHighlight: boolean; + outlineMarkers: boolean; + referenceInfos: boolean; + folding: boolean; + }); + equals(other: EditorContribOptions): boolean; + clone(): EditorContribOptions; + } + + /** + * Internal configuration options (transformed or computed) for the editor. + */ + export class InternalEditorOptions { + _internalEditorOptionsBrand: void; + lineHeight: number; + readOnly: boolean; + wordSeparators: string; + autoClosingBrackets: boolean; + useTabStops: boolean; + tabFocusMode: boolean; + layoutInfo: EditorLayoutInfo; + fontInfo: FontInfo; + viewInfo: InternalEditorViewOptions; + wrappingInfo: EditorWrappingInfo; + contribInfo: EditorContribOptions; + constructor(source: { + lineHeight: number; + readOnly: boolean; + wordSeparators: string; + autoClosingBrackets: boolean; + useTabStops: boolean; + tabFocusMode: boolean; + layoutInfo: EditorLayoutInfo; + fontInfo: FontInfo; + viewInfo: InternalEditorViewOptions; + wrappingInfo: EditorWrappingInfo; + contribInfo: EditorContribOptions; + }); + equals(other: InternalEditorOptions): boolean; + createChangeEvent(newOpts: InternalEditorOptions): IConfigurationChangedEvent; + clone(): InternalEditorOptions; + } + + /** + * An event describing that the configuration of the editor has changed. + */ + export interface IConfigurationChangedEvent { + lineHeight: boolean; + readOnly: boolean; + wordSeparators: boolean; + autoClosingBrackets: boolean; + useTabStops: boolean; + tabFocusMode: boolean; + layoutInfo: boolean; + fontInfo: boolean; + viewInfo: IViewConfigurationChangedEvent; + wrappingInfo: boolean; + contribInfo: boolean; + } + + /** + * An event describing that one or more supports of a mode have changed. + */ + export interface IModeSupportChangedEvent { + tokenizationSupport: boolean; + richEditSupport: boolean; + } + + /** + * Vertical Lane in the overview ruler of the editor. + */ + export enum OverviewRulerLane { + Left = 1, + Center = 2, + Right = 4, + Full = 7, + } + + /** + * Options for rendering a model decoration in the overview ruler. + */ + export interface IModelDecorationOverviewRulerOptions { + /** + * CSS color to render in the overview ruler. + * e.g.: rgba(100, 100, 100, 0.5) + */ + color: string; + /** + * CSS color to render in the overview ruler. + * e.g.: rgba(100, 100, 100, 0.5) + */ + darkColor: string; + /** + * The position in the overview ruler. + */ + position: OverviewRulerLane; + } + + /** + * Options for a model decoration. + */ + export interface IModelDecorationOptions { + /** + * Customize the growing behaviour of the decoration when typing at the edges of the decoration. + * Defaults to TrackedRangeStickiness.AlwaysGrowsWhenTypingAtEdges + */ + stickiness?: TrackedRangeStickiness; + /** + * CSS class name describing the decoration. + */ + className?: string; + /** + * Message to be rendered when hovering over the decoration. + */ + hoverMessage?: string; + /** + * Array of IHTMLContentElements to render as the decoration message. + */ + htmlMessage?: IHTMLContentElement[]; + /** + * Should the decoration expand to encompass a whole line. + */ + isWholeLine?: boolean; + /** + * @deprecated : Use `overviewRuler` instead + */ + showInOverviewRuler?: string; + /** + * If set, render this decoration in the overview ruler. + */ + overviewRuler?: IModelDecorationOverviewRulerOptions; + /** + * If set, the decoration will be rendered in the glyph margin with this CSS class name. + */ + glyphMarginClassName?: string; + /** + * If set, the decoration will be rendered in the lines decorations with this CSS class name. + */ + linesDecorationsClassName?: string; + /** + * If set, the decoration will be rendered inline with the text with this CSS class name. + * Please use this only for CSS rules that must impact the text. For example, use `className` + * to have a background color decoration. + */ + inlineClassName?: string; + } + + /** + * New model decorations. + */ + export interface IModelDeltaDecoration { + /** + * Range that this decoration covers. + */ + range: IRange; + /** + * Options associated with this decoration. + */ + options: IModelDecorationOptions; + } + + /** + * A tracked range in the model. + */ + export interface IModelTrackedRange { + /** + * Identifier for a tracked range + */ + id: string; + /** + * Range that this tracked range covers + */ + range: IEditorRange; + } + + /** + * A decoration in the model. + */ + export interface IModelDecoration { + /** + * Identifier for a decoration. + */ + id: string; + /** + * Identifier for a decoration's owener. + */ + ownerId: number; + /** + * Range that this decoration covers. + */ + range: IEditorRange; + /** + * Options associated with this decoration. + */ + options: IModelDecorationOptions; + } + + /** + * An accessor that can add, change or remove model decorations. + */ + export interface IModelDecorationsChangeAccessor { + /** + * Add a new decoration. + * @param range Range that this decoration covers. + * @param options Options associated with this decoration. + * @return An unique identifier associated with this decoration. + */ + addDecoration(range: IRange, options: IModelDecorationOptions): string; + /** + * Change the range that an existing decoration covers. + * @param id The unique identifier associated with the decoration. + * @param newRange The new range that this decoration covers. + */ + changeDecoration(id: string, newRange: IRange): void; + /** + * Change the options associated with an existing decoration. + * @param id The unique identifier associated with the decoration. + * @param newOptions The new options associated with this decoration. + */ + changeDecorationOptions(id: string, newOptions: IModelDecorationOptions): void; + /** + * Remove an existing decoration. + * @param id The unique identifier associated with the decoration. + */ + removeDecoration(id: string): void; + /** + * Perform a minimum ammount of operations, in order to transform the decorations + * identified by `oldDecorations` to the decorations described by `newDecorations` + * and returns the new identifiers associated with the resulting decorations. + * + * @param oldDecorations Array containing previous decorations identifiers. + * @param newDecorations Array describing what decorations should result after the call. + * @return An array containing the new decorations identifiers. + */ + deltaDecorations(oldDecorations: string[], newDecorations: IModelDeltaDecoration[]): string[]; + } + + /** + * Word inside a model. + */ + export interface IWordAtPosition { + /** + * The word. + */ + word: string; + /** + * The column where the word starts. + */ + startColumn: number; + /** + * The column where the word ends. + */ + endColumn: number; + } + + /** + * Range of a word inside a model. + */ + export interface IWordRange { + /** + * The index where the word starts. + */ + start: number; + /** + * The index where the word ends. + */ + end: number; + } + + export interface ITokenInfo { + token: IToken; + lineNumber: number; + startColumn: number; + endColumn: number; + } + + export interface ITokenIterator { + hasNext(): boolean; + next(): ITokenInfo; + hasPrev(): boolean; + prev(): ITokenInfo; + } + + /** + * End of line character preference. + */ + export enum EndOfLinePreference { + /** + * Use the end of line character identified in the text buffer. + */ + TextDefined = 0, + /** + * Use line feed (\n) as the end of line character. + */ + LF = 1, + /** + * Use carriage return and line feed (\r\n) as the end of line character. + */ + CRLF = 2, + } + + /** + * The default end of line to use when instantiating models. + */ + export enum DefaultEndOfLine { + /** + * Use line feed (\n) as the end of line character. + */ + LF = 1, + /** + * Use carriage return and line feed (\r\n) as the end of line character. + */ + CRLF = 2, + } + + /** + * End of line character preference. + */ + export enum EndOfLineSequence { + /** + * Use line feed (\n) as the end of line character. + */ + LF = 0, + /** + * Use carriage return and line feed (\r\n) as the end of line character. + */ + CRLF = 1, + } + + /** + * A read-only line marker in the model. + */ + export interface IReadOnlyLineMarker { + id: string; + column: number; + } + + /** + * And identifier for a single edit operation. + */ + export interface ISingleEditOperationIdentifier { + /** + * Identifier major + */ + major: number; + /** + * Identifier minor + */ + minor: number; + } + + /** + * A builder and helper for edit operations for a command. + */ + export interface IEditOperationBuilder { + /** + * Add a new edit operation (a replace operation). + * @param range The range to replace (delete). May be empty to represent a simple insert. + * @param text The text to replace with. May be null to represent a simple delete. + */ + addEditOperation(range: IEditorRange, text: string): void; + /** + * Track `selection` when applying edit operations. + * A best effort will be made to not grow/expand the selection. + * An empty selection will clamp to a nearby character. + * @param selection The selection to track. + * @param trackPreviousOnEmpty If set, and the selection is empty, indicates whether the selection + * should clamp to the previous or the next character. + * @return A unique identifer. + */ + trackSelection(selection: IEditorSelection, trackPreviousOnEmpty?: boolean): string; + } + + /** + * A helper for computing cursor state after a command. + */ + export interface ICursorStateComputerData { + /** + * Get the inverse edit operations of the added edit operations. + */ + getInverseEditOperations(): IIdentifiedSingleEditOperation[]; + /** + * Get a previously tracked selection. + * @param id The unique identifier returned by `trackSelection`. + * @return The selection. + */ + getTrackedSelection(id: string): IEditorSelection; + } + + /** + * A command that modifies text / cursor state on a model. + */ + export interface ICommand { + /** + * Get the edit operations needed to execute this command. + * @param model The model the command will execute on. + * @param builder A helper to collect the needed edit operations and to track selections. + */ + getEditOperations(model: ITokenizedModel, builder: IEditOperationBuilder): void; + /** + * Compute the cursor state after the edit operations were applied. + * @param model The model the commad has executed on. + * @param helper A helper to get inverse edit operations and to get previously tracked selections. + * @return The cursor state after the command executed. + */ + computeCursorState(model: ITokenizedModel, helper: ICursorStateComputerData): IEditorSelection; + } + + /** + * A single edit operation, that acts as a simple replace. + * i.e. Replace text at `range` with `text` in model. + */ + export interface ISingleEditOperation { + /** + * The range to replace. This can be empty to emulate a simple insert. + */ + range: IRange; + /** + * The text to replace with. This can be null to emulate a simple delete. + */ + text: string; + /** + * This indicates that this operation has "insert" semantics. + * i.e. forceMoveMarkers = true => if `range` is collapsed, all markers at the position will be moved. + */ + forceMoveMarkers?: boolean; + } + + /** + * A single edit operation, that has an identifier. + */ + export interface IIdentifiedSingleEditOperation { + /** + * An identifier associated with this single edit operation. + */ + identifier: ISingleEditOperationIdentifier; + /** + * The range to replace. This can be empty to emulate a simple insert. + */ + range: IEditorRange; + /** + * The text to replace with. This can be null to emulate a simple delete. + */ + text: string; + /** + * This indicates that this operation has "insert" semantics. + * i.e. forceMoveMarkers = true => if `range` is collapsed, all markers at the position will be moved. + */ + forceMoveMarkers: boolean; + /** + * This indicates that this operation is inserting automatic whitespace + * that can be removed on next model edit operation if `config.trimAutoWhitespace` is true. + */ + isAutoWhitespaceEdit?: boolean; + } + + /** + * A callback that can compute the cursor state after applying a series of edit operations. + */ + export interface ICursorStateComputer { + /** + * A callback that can compute the resulting cursors state after some edit operations have been executed. + */ + (inverseEditOperations: IIdentifiedSingleEditOperation[]): IEditorSelection[]; + } + + /** + * A list of tokens on a line. + */ + export interface ILineTokens { + getTokenCount(): number; + getTokenStartIndex(tokenIndex: number): number; + getTokenType(tokenIndex: number): string; + getTokenEndIndex(tokenIndex: number, textLength: number): number; + /** + * Check if tokens have changed. This is called by the view to validate rendered lines + * and decide which lines need re-rendering. + */ + equals(other: ILineTokens): boolean; + /** + * Find the token containing offset `offset`. + * For example, with the following tokens [0, 5), [5, 9), [9, infinity) + * Searching for 0, 1, 2, 3 or 4 will return 0. + * Searching for 5, 6, 7 or 8 will return 1. + * Searching for 9, 10, 11, ... will return 2. + * @param offset The search offset + * @return The index of the token containing the offset. + */ + findIndexOfOffset(offset: number): number; + sliceAndInflate(startOffset: number, endOffset: number, deltaStartIndex: number): ViewLineToken[]; + inflate(): ViewLineToken[]; + } + + export interface ITextModelResolvedOptions { + tabSize: number; + insertSpaces: boolean; + defaultEOL: DefaultEndOfLine; + trimAutoWhitespace: boolean; + } + + export interface ITextModelCreationOptions { + tabSize: number; + insertSpaces: boolean; + detectIndentation: boolean; + trimAutoWhitespace: boolean; + defaultEOL: DefaultEndOfLine; + } + + export interface ITextModelUpdateOptions { + tabSize?: number; + insertSpaces?: boolean; + trimAutoWhitespace?: boolean; + } + + export interface IModelOptionsChangedEvent { + tabSize: boolean; + insertSpaces: boolean; + trimAutoWhitespace: boolean; + } + + /** + * A textual read-only model. + */ + export interface ITextModel { + getOptions(): ITextModelResolvedOptions; + /** + * Get the current version id of the model. + * Anytime a change happens to the model (even undo/redo), + * the version id is incremented. + */ + getVersionId(): number; + /** + * Get the alternative version id of the model. + * This alternative version id is not always incremented, + * it will return the same values in the case of undo-redo. + */ + getAlternativeVersionId(): number; + /** + * Replace the entire text buffer value contained in this model. + */ + setValue(newValue: string): void; + /** + * Get the text stored in this model. + * @param eol The end of line character preference. Defaults to `EndOfLinePreference.TextDefined`. + * @param preserverBOM Preserve a BOM character if it was detected when the model was constructed. + * @return The text. + */ + getValue(eol?: EndOfLinePreference, preserveBOM?: boolean): string; + getValueLength(eol?: EndOfLinePreference, preserveBOM?: boolean): number; + toRawText(): IRawText; + equals(other: IRawText): boolean; + /** + * Get the text in a certain range. + * @param range The range describing what text to get. + * @param eol The end of line character preference. This will only be used for multiline ranges. Defaults to `EndOfLinePreference.TextDefined`. + * @return The text. + */ + getValueInRange(range: IRange, eol?: EndOfLinePreference): string; + /** + * Get the length of text in a certain range. + * @param range The range describing what text length to get. + * @return The text length. + */ + getValueLengthInRange(range: IRange): number; + /** + * Splits characters in two buckets. First bucket (A) is of characters that + * sit in lines with length < `LONG_LINE_BOUNDARY`. Second bucket (B) is of + * characters that sit in lines with length >= `LONG_LINE_BOUNDARY`. + * If count(B) > count(A) return true. Returns false otherwise. + */ + isDominatedByLongLines(): boolean; + /** + * Get the number of lines in the model. + */ + getLineCount(): number; + /** + * Get the text for a certain line. + */ + getLineContent(lineNumber: number): string; + /** + * Get the text for all lines. + */ + getLinesContent(): string[]; + /** + * Get the end of line character predominantly used in the text buffer. + * @return EOL char sequence (e.g.: '\n' or '\r\n'). + */ + getEOL(): string; + setEOL(eol: EndOfLineSequence): void; + /** + * Get the minimum legal column for line at `lineNumber` + */ + getLineMinColumn(lineNumber: number): number; + /** + * Get the maximum legal column for line at `lineNumber` + */ + getLineMaxColumn(lineNumber: number): number; + /** + * Returns the column before the first non whitespace character for line at `lineNumber`. + * Returns 0 if line is empty or contains only whitespace. + */ + getLineFirstNonWhitespaceColumn(lineNumber: number): number; + /** + * Returns the column after the last non whitespace character for line at `lineNumber`. + * Returns 0 if line is empty or contains only whitespace. + */ + getLineLastNonWhitespaceColumn(lineNumber: number): number; + /** + * Create a valid position, + */ + validatePosition(position: IPosition): IEditorPosition; + /** + * Advances the given position by the given offest (negative offsets are also accepted) + * and returns it as a new valid position. + * + * If the offset and position are such that their combination goes beyond the beginning or + * end of the model, throws an exception. + * + * If the ofsset is such that the new position would be in the middle of a multi-byte + * line terminator, throws an exception. + */ + modifyPosition(position: IPosition, offset: number): IEditorPosition; + /** + * Create a valid range. + */ + validateRange(range: IRange): IEditorRange; + /** + * Get a range covering the entire model + */ + getFullModelRange(): IEditorRange; + /** + * Returns iff the model was disposed or not. + */ + isDisposed(): boolean; + /** + * No mode supports allowed on this model because it is simply too large. + * (even tokenization would cause too much memory pressure) + */ + isTooLargeForHavingAMode(): boolean; + /** + * Only basic mode supports allowed on this model because it is simply too large. + * (tokenization is allowed and other basic supports) + */ + isTooLargeForHavingARichMode(): boolean; + } + + export interface IReadOnlyModel extends ITextModel { + /** + * Gets the resource associated with this editor model. + */ + uri: Uri; + getModeId(): string; + /** + * Get the word under or besides `position`. + * @param position The position to look for a word. + * @param skipSyntaxTokens Ignore syntax tokens, as identified by the mode. + * @return The word under or besides `position`. Might be null. + */ + getWordAtPosition(position: IPosition): IWordAtPosition; + /** + * Get the word under or besides `position` trimmed to `position`.column + * @param position The position to look for a word. + * @param skipSyntaxTokens Ignore syntax tokens, as identified by the mode. + * @return The word under or besides `position`. Will never be null. + */ + getWordUntilPosition(position: IPosition): IWordAtPosition; + } + + export interface IRichEditBracket { + modeId: string; + open: string; + close: string; + forwardRegex: RegExp; + reversedRegex: RegExp; + } + + export interface IFoundBracket { + range: IEditorRange; + open: string; + close: string; + isOpen: boolean; + } + + /** + * A model that is tokenized. + */ + export interface ITokenizedModel extends ITextModel { + /** + * Tokenize if necessary and get the tokens for the line `lineNumber`. + * @param lineNumber The line number + * @param inaccurateTokensAcceptable Are inaccurate tokens acceptable? Defaults to false + */ + getLineTokens(lineNumber: number, inaccurateTokensAcceptable?: boolean): ILineTokens; + /** + * Tokenize if necessary and get the tokenization result for the line `lineNumber`, as returned by the language mode. + */ + getLineContext(lineNumber: number): ILineContext; + _getLineModeTransitions(lineNumber: number): IModeTransition[]; + /** + * Replace the entire text buffer value contained in this model. + * Optionally, the language mode of the model can be changed. + * This call clears all of the undo / redo stack, + * removes all decorations or tracked ranges, emits a + * ModelContentChanged(ModelContentChangedFlush) event and + * unbinds the mirror model from the previous mode to the new + * one if the mode has changed. + */ + setValue(newValue: string, newMode?: IMode): void; + /** + * Get the current language mode associated with the model. + */ + getMode(): IMode; + /** + * Set the current language mode associated with the model. + */ + setMode(newMode: IMode): void; + setMode(newModePromise: TPromise): void; + /** + * A mode can be currently pending loading if a promise is used when constructing a model or calling setMode(). + * + * If there is no currently pending loading mode, then the result promise will complete immediately. + * Otherwise, the result will complete once the currently pending loading mode is loaded. + */ + whenModeIsReady(): TPromise; + /** + * Returns the true (inner-most) language mode at a given position. + */ + getModeAtPosition(lineNumber: number, column: number): IMode; + /** + * Get the word under or besides `position`. + * @param position The position to look for a word. + * @param skipSyntaxTokens Ignore syntax tokens, as identified by the mode. + * @return The word under or besides `position`. Might be null. + */ + getWordAtPosition(position: IPosition): IWordAtPosition; + /** + * Get the word under or besides `position` trimmed to `position`.column + * @param position The position to look for a word. + * @param skipSyntaxTokens Ignore syntax tokens, as identified by the mode. + * @return The word under or besides `position`. Will never be null. + */ + getWordUntilPosition(position: IPosition): IWordAtPosition; + /** + * Returns an iterator that can be used to read + * next and previous tokens from the provided position. + * The iterator is made available through the callback + * function and can't be used afterwards. + */ + tokenIterator(position: IPosition, callback: (it: ITokenIterator) => any): any; + /** + * Find the matching bracket of `request` up, counting brackets. + * @param request The bracket we're searching for + * @param position The position at which to start the search. + * @return The range of the matching bracket, or null if the bracket match was not found. + */ + findMatchingBracketUp(bracket: string, position: IPosition): IEditorRange; + /** + * Given a `position`, if the position is on top or near a bracket, + * find the matching bracket of that bracket and return the ranges of both brackets. + * @param position The position at which to look for a bracket. + */ + matchBracket(position: IPosition): [IEditorRange, IEditorRange]; + } + + /** + * A model that can track markers. + */ + export interface ITextModelWithMarkers extends ITextModel { + _addMarker(lineNumber: number, column: number, stickToPreviousCharacter: boolean): string; + _changeMarker(id: string, newLineNumber: number, newColumn: number): void; + _changeMarkerStickiness(id: string, newStickToPreviousCharacter: boolean): void; + _getMarker(id: string): IEditorPosition; + _removeMarker(id: string): void; + _getLineMarkers(lineNumber: number): IReadOnlyLineMarker[]; + } + + /** + * A map of changed ranges used during the model internal processing + */ + export interface IChangedTrackedRanges { + [key: string]: IRange; + } + + export enum TrackedRangeStickiness { + AlwaysGrowsWhenTypingAtEdges = 0, + NeverGrowsWhenTypingAtEdges = 1, + GrowsOnlyWhenTypingBefore = 2, + GrowsOnlyWhenTypingAfter = 3, + } + + /** + * A model that can track ranges. + */ + export interface ITextModelWithTrackedRanges extends ITextModel { + /** + * Start tracking a range (across edit operations). + * @param range The range to start tracking. + * @param stickiness The behaviour when typing at the edges of the range. + * @return A unique identifier for the tracked range. + */ + addTrackedRange(range: IRange, stickiness: TrackedRangeStickiness): string; + /** + * Change the range of a tracked range. + * @param id The id of the tracked range, as returned by a `addTrackedRange` call. + * @param newRange The new range of the tracked range. + */ + changeTrackedRange(id: string, newRange: IRange): void; + /** + * Change the stickiness (behaviour when typing at the edges of the range) for a tracked range. + * @param id The id of the tracked range, as returned by a `addTrackedRange` call. + * @param newStickiness The new behaviour when typing at the edges of the range. + */ + changeTrackedRangeStickiness(id: string, newStickiness: TrackedRangeStickiness): void; + /** + * Remove a tracked range. + * @param id The id of the tracked range, as returned by a `addTrackedRaneg` call. + */ + removeTrackedRange(id: string): void; + /** + * Get the range of a tracked range. + * @param id The id of the tracked range, as returned by a `addTrackedRaneg` call. + */ + getTrackedRange(id: string): IEditorRange; + /** + * Gets all the tracked ranges for the lines between `startLineNumber` and `endLineNumber` as an array. + * @param startLineNumber The start line number + * @param endLineNumber The end line number + * @return An array with the tracked ranges + */ + getLinesTrackedRanges(startLineNumber: number, endLineNumber: number): IModelTrackedRange[]; + } + + /** + * A model that can have decorations. + */ + export interface ITextModelWithDecorations { + /** + * Change the decorations. The callback will be called with a change accessor + * that becomes invalid as soon as the callback finishes executing. + * This allows for all events to be queued up until the change + * is completed. Returns whatever the callback returns. + * @param ownerId Identifies the editor id in which these decorations should appear. If no `ownerId` is provided, the decorations will appear in all editors that attach this model. + */ + changeDecorations(callback: (changeAccessor: IModelDecorationsChangeAccessor) => any, ownerId?: number): any; + /** + * Perform a minimum ammount of operations, in order to transform the decorations + * identified by `oldDecorations` to the decorations described by `newDecorations` + * and returns the new identifiers associated with the resulting decorations. + * + * @param oldDecorations Array containing previous decorations identifiers. + * @param newDecorations Array describing what decorations should result after the call. + * @param ownerId Identifies the editor id in which these decorations should appear. If no `ownerId` is provided, the decorations will appear in all editors that attach this model. + * @return An array containing the new decorations identifiers. + */ + deltaDecorations(oldDecorations: string[], newDecorations: IModelDeltaDecoration[], ownerId?: number): string[]; + /** + * Remove all decorations that have been added with this specific ownerId. + * @param ownerId The owner id to search for. + */ + removeAllDecorationsWithOwnerId(ownerId: number): void; + /** + * Get the options associated with a decoration. + * @param id The decoration id. + * @return The decoration options or null if the decoration was not found. + */ + getDecorationOptions(id: string): IModelDecorationOptions; + /** + * Get the range associated with a decoration. + * @param id The decoration id. + * @return The decoration range or null if the decoration was not found. + */ + getDecorationRange(id: string): IEditorRange; + /** + * Gets all the decorations for the line `lineNumber` as an array. + * @param lineNumber The line number + * @param ownerId If set, it will ignore decorations belonging to other owners. + * @param filterOutValidation If set, it will ignore decorations specific to validation (i.e. warnings, errors). + * @return An array with the decorations + */ + getLineDecorations(lineNumber: number, ownerId?: number, filterOutValidation?: boolean): IModelDecoration[]; + /** + * Gets all the decorations for the lines between `startLineNumber` and `endLineNumber` as an array. + * @param startLineNumber The start line number + * @param endLineNumber The end line number + * @param ownerId If set, it will ignore decorations belonging to other owners. + * @param filterOutValidation If set, it will ignore decorations specific to validation (i.e. warnings, errors). + * @return An array with the decorations + */ + getLinesDecorations(startLineNumber: number, endLineNumber: number, ownerId?: number, filterOutValidation?: boolean): IModelDecoration[]; + /** + * Gets all the deocorations in a range as an array. Only `startLineNumber` and `endLineNumber` from `range` are used for filtering. + * So for now it returns all the decorations on the same line as `range`. + * @param range The range to search in + * @param ownerId If set, it will ignore decorations belonging to other owners. + * @param filterOutValidation If set, it will ignore decorations specific to validation (i.e. warnings, errors). + * @return An array with the decorations + */ + getDecorationsInRange(range: IRange, ownerId?: number, filterOutValidation?: boolean): IModelDecoration[]; + /** + * Gets all the decorations as an array. + * @param ownerId If set, it will ignore decorations belonging to other owners. + * @param filterOutValidation If set, it will ignore decorations specific to validation (i.e. warnings, errors). + */ + getAllDecorations(ownerId?: number, filterOutValidation?: boolean): IModelDecoration[]; + } + + /** + * An editable text model. + */ + export interface IEditableTextModel extends ITextModelWithMarkers { + normalizeIndentation(str: string): string; + getOneIndent(): string; + updateOptions(newOpts: ITextModelUpdateOptions): void; + detectIndentation(defaultInsertSpaces: boolean, defaultTabSize: number): void; + /** + * Push a stack element onto the undo stack. This acts as an undo/redo point. + * The idea is to use `pushEditOperations` to edit the model and then to + * `pushStackElement` to create an undo/redo stop point. + */ + pushStackElement(): void; + /** + * Push edit operations, basically editing the model. This is the preferred way + * of editing the model. The edit operations will land on the undo stack. + * @param beforeCursorState The cursor state before the edit operaions. This cursor state will be returned when `undo` or `redo` are invoked. + * @param editOperations The edit operations. + * @param cursorStateComputer A callback that can compute the resulting cursors state after the edit operations have been executed. + * @return The cursor state returned by the `cursorStateComputer`. + */ + pushEditOperations(beforeCursorState: IEditorSelection[], editOperations: IIdentifiedSingleEditOperation[], cursorStateComputer: ICursorStateComputer): IEditorSelection[]; + /** + * Edit the model without adding the edits to the undo stack. + * This can have dire consequences on the undo stack! See @pushEditOperations for the preferred way. + * @param operations The edit operations. + * @return The inverse edit operations, that, when applied, will bring the model back to the previous state. + */ + applyEdits(operations: IIdentifiedSingleEditOperation[]): IIdentifiedSingleEditOperation[]; + /** + * Undo edit operations until the first previous stop point created by `pushStackElement`. + * The inverse edit operations will be pushed on the redo stack. + */ + undo(): IEditorSelection[]; + /** + * Redo edit operations until the next stop point created by `pushStackElement`. + * The inverse edit operations will be pushed on the undo stack. + */ + redo(): IEditorSelection[]; + /** + * Set an editable range on the model. + */ + setEditableRange(range: IRange): void; + /** + * Check if the model has an editable range. + */ + hasEditableRange(): boolean; + /** + * Get the editable range on the model. + */ + getEditableRange(): IEditorRange; + } + + /** + * A model. + */ + export interface IModel extends IReadOnlyModel, IEditableTextModel, ITextModelWithMarkers, ITokenizedModel, ITextModelWithTrackedRanges, ITextModelWithDecorations, IEventEmitter, IEditorModel { + /** + * A unique identifier associated with this model. + */ + id: string; + /** + * Destroy this model. This will unbind the model from the mode + * and make all necessary clean-up to release this object to the GC. + */ + destroy(): void; + /** + * Search the model. + * @param searchString The string used to search. If it is a regular expression, set `isRegex` to true. + * @param searchOnlyEditableRange Limit the searching to only search inside the editable range of the model. + * @param isRegex Used to indicate that `searchString` is a regular expression. + * @param matchCase Force the matching to match lower/upper case exactly. + * @param wholeWord Force the matching to match entire words only. + * @param limitResultCount Limit the number of results + * @return The ranges where the matches are. It is empty if not matches have been found. + */ + findMatches(searchString: string, searchOnlyEditableRange: boolean, isRegex: boolean, matchCase: boolean, wholeWord: boolean, limitResultCount?: number): IEditorRange[]; + /** + * Search the model. + * @param searchString The string used to search. If it is a regular expression, set `isRegex` to true. + * @param searchScope Limit the searching to only search inside this range. + * @param isRegex Used to indicate that `searchString` is a regular expression. + * @param matchCase Force the matching to match lower/upper case exactly. + * @param wholeWord Force the matching to match entire words only. + * @param limitResultCount Limit the number of results + * @return The ranges where the matches are. It is empty if no matches have been found. + */ + findMatches(searchString: string, searchScope: IRange, isRegex: boolean, matchCase: boolean, wholeWord: boolean, limitResultCount?: number): IEditorRange[]; + /** + * Search the model for the next match. Loops to the beginning of the model if needed. + * @param searchString The string used to search. If it is a regular expression, set `isRegex` to true. + * @param searchStart Start the searching at the specified position. + * @param isRegex Used to indicate that `searchString` is a regular expression. + * @param matchCase Force the matching to match lower/upper case exactly. + * @param wholeWord Force the matching to match entire words only. + * @return The range where the next match is. It is null if no next match has been found. + */ + findNextMatch(searchString: string, searchStart: IPosition, isRegex: boolean, matchCase: boolean, wholeWord: boolean): IEditorRange; + /** + * Search the model for the previous match. Loops to the end of the model if needed. + * @param searchString The string used to search. If it is a regular expression, set `isRegex` to true. + * @param searchStart Start the searching at the specified position. + * @param isRegex Used to indicate that `searchString` is a regular expression. + * @param matchCase Force the matching to match lower/upper case exactly. + * @param wholeWord Force the matching to match entire words only. + * @return The range where the previous match is. It is null if no previous match has been found. + */ + findPreviousMatch(searchString: string, searchStart: IPosition, isRegex: boolean, matchCase: boolean, wholeWord: boolean): IEditorRange; + /** + * Replace the entire text buffer value contained in this model. + * Optionally, the language mode of the model can be changed. + * This call clears all of the undo / redo stack, + * removes all decorations or tracked ranges, emits a + * ModelContentChanged(ModelContentChangedFlush) event and + * unbinds the mirror model from the previous mode to the new + * one if the mode has changed. + */ + setValue(newValue: string, newMode?: IMode): void; + setValue(newValue: string, newModePromise: TPromise): void; + setValueFromRawText(newValue: IRawText, newMode?: IMode): void; + setValueFromRawText(newValue: IRawText, newModePromise: TPromise): void; + onBeforeAttached(): void; + onBeforeDetached(): void; + /** + * Returns iff this model is attached to an editor or not. + */ + isAttachedToEditor(): boolean; + } + + export interface IRangeWithText { + text: string; + range: IRange; + } + + export interface IMirrorModel extends IEventEmitter, ITokenizedModel { + getEmbeddedAtPosition(position: IPosition): IMirrorModel; + getAllEmbedded(): IMirrorModel[]; + uri: Uri; + getOffsetFromPosition(position: IPosition): number; + getPositionFromOffset(offset: number): IPosition; + getOffsetAndLengthFromRange(range: IRange): { + offset: number; + length: number; + }; + getRangeFromOffsetAndLength(offset: number, length: number): IRange; + getLineStart(lineNumber: number): number; + getAllWordsWithRange(): IRangeWithText[]; + getAllUniqueWords(skipWordOnce?: string): string[]; + getModeId(): string; + } + + /** + * An event describing that the current mode associated with a model has changed. + */ + export interface IModelModeChangedEvent { + /** + * Previous mode + */ + oldMode: IMode; + /** + * New mode + */ + newMode: IMode; + } + + /** + * An event describing a change in the text of a model. + */ + export interface IModelContentChangedEvent2 { + /** + * The range that got replaced. + */ + range: IRange; + /** + * The length of the range that got replaced. + */ + rangeLength: number; + /** + * The new text for the range. + */ + text: string; + /** + * The (new) end-of-line character. + */ + eol: string; + /** + * The new version id the model has transitioned to. + */ + versionId: number; + /** + * Flag that indicates that this event was generated while undoing. + */ + isUndoing: boolean; + /** + * Flag that indicates that this event was generated while redoing. + */ + isRedoing: boolean; + } + + /** + * An event describing a change in the text of a model. + */ + export interface IModelContentChangedEvent { + /** + * The event type. It can be used to detect the actual event type: + * EditorCommon.EventType.ModelContentChangedFlush => IModelContentChangedFlushEvent + * EditorCommon.EventType.ModelContentChangedLinesDeleted => IModelContentChangedLineChangedEvent + * EditorCommon.EventType.ModelContentChangedLinesInserted => IModelContentChangedLinesDeletedEvent + * EditorCommon.EventType.ModelContentChangedLineChanged => IModelContentChangedLinesInsertedEvent + */ + changeType: string; + /** + * The new version id the model has transitioned to. + */ + versionId: number; + /** + * Flag that indicates that this event was generated while undoing. + */ + isUndoing: boolean; + /** + * Flag that indicates that this event was generated while redoing. + */ + isRedoing: boolean; + } + + export interface IRawText { + length: number; + lines: string[]; + BOM: string; + EOL: string; + options: ITextModelResolvedOptions; + } + + /** + * An event describing that a model has been reset to a new value. + */ + export interface IModelContentChangedFlushEvent extends IModelContentChangedEvent { + /** + * The new text content of the model. + */ + detail: IRawText; + } + + /** + * An event describing that a line has changed in a model. + */ + export interface IModelContentChangedLineChangedEvent extends IModelContentChangedEvent { + /** + * The line that has changed. + */ + lineNumber: number; + /** + * The new value of the line. + */ + detail: string; + } + + /** + * An event describing that line(s) have been deleted in a model. + */ + export interface IModelContentChangedLinesDeletedEvent extends IModelContentChangedEvent { + /** + * At what line the deletion began (inclusive). + */ + fromLineNumber: number; + /** + * At what line the deletion stopped (inclusive). + */ + toLineNumber: number; + } + + /** + * An event describing that line(s) have been inserted in a model. + */ + export interface IModelContentChangedLinesInsertedEvent extends IModelContentChangedEvent { + /** + * Before what line did the insertion begin + */ + fromLineNumber: number; + /** + * `toLineNumber` - `fromLineNumber` + 1 denotes the number of lines that were inserted + */ + toLineNumber: number; + /** + * The text that was inserted + */ + detail: string; + } + + /** + * Decoration data associated with a model decorations changed event. + */ + export interface IModelDecorationsChangedEventDecorationData { + id: string; + ownerId: number; + range: IRange; + isForValidation: boolean; + options: IModelDecorationOptions; + } + + /** + * An event describing that model decorations have changed. + */ + export interface IModelDecorationsChangedEvent { + /** + * A summary with ids of decorations that have changed. + */ + ids: string[]; + /** + * Lists of details + */ + addedOrChangedDecorations: IModelDecorationsChangedEventDecorationData[]; + removedDecorations: string[]; + oldOptions: { + [decorationId: string]: IModelDecorationOptions; + }; + oldRanges: { + [decorationId: string]: IRange; + }; + } + + /** + * An event describing that a range of lines has been tokenized + */ + export interface IModelTokensChangedEvent { + /** + * The start of the range (inclusive) + */ + fromLineNumber: number; + /** + * The end of the range (inclusive) + */ + toLineNumber: number; + } + + export enum CursorChangeReason { + NotSet = 0, + ContentFlush = 1, + RecoverFromMarkers = 2, + Explicit = 3, + Paste = 4, + Undo = 5, + Redo = 6, + } + + /** + * An event describing that the cursor position has changed. + */ + export interface ICursorPositionChangedEvent { + /** + * Primary cursor's position. + */ + position: IEditorPosition; + /** + * Primary cursor's view position + */ + viewPosition: IEditorPosition; + /** + * Secondary cursors' position. + */ + secondaryPositions: IEditorPosition[]; + /** + * Secondary cursors' view position. + */ + secondaryViewPositions: IEditorPosition[]; + /** + * Reason. + */ + reason: CursorChangeReason; + /** + * Source of the call that caused the event. + */ + source: string; + /** + * Is the primary cursor in the editable range? + */ + isInEditableRange: boolean; + } + + /** + * An event describing that the cursor selection has changed. + */ + export interface ICursorSelectionChangedEvent { + /** + * The primary selection. + */ + selection: IEditorSelection; + /** + * The primary selection in view coordinates. + */ + viewSelection: IEditorSelection; + /** + * The secondary selections. + */ + secondarySelections: IEditorSelection[]; + /** + * The secondary selections in view coordinates. + */ + secondaryViewSelections: IEditorSelection[]; + /** + * Source of the call that caused the event. + */ + source: string; + /** + * Reason. + */ + reason: CursorChangeReason; + } + + export enum VerticalRevealType { + Simple = 0, + Center = 1, + CenterIfOutsideViewport = 2, + } + + /** + * An event describing a request to reveal a specific range in the view of the editor. + */ + export interface ICursorRevealRangeEvent { + /** + * Range to be reavealed. + */ + range: IEditorRange; + /** + * View range to be reavealed. + */ + viewRange: IEditorRange; + verticalType: VerticalRevealType; + /** + * If true: there should be a horizontal & vertical revealing + * If false: there should be just a vertical revealing + */ + revealHorizontal: boolean; + } + + export interface ICursorScrollRequestEvent { + deltaLines: number; + } + + export interface IModelChangedEvent { + oldModelUrl: string; + newModelUrl: string; + } + + export interface IEditorWhitespace { + id: number; + afterLineNumber: number; + heightInLines: number; + } + + /** + * A description for the overview ruler position. + */ + export class OverviewRulerPosition { + _overviewRulerPositionBrand: void; + /** + * Width of the overview ruler + */ + width: number; + /** + * Height of the overview ruler + */ + height: number; + /** + * Top position for the overview ruler + */ + top: number; + /** + * Right position for the overview ruler + */ + right: number; + constructor(source: { + width: number; + height: number; + top: number; + right: number; + }); + equals(other: OverviewRulerPosition): boolean; + clone(): OverviewRulerPosition; + } + + /** + * The internal layout details of the editor. + */ + export class EditorLayoutInfo { + _editorLayoutInfoBrand: void; + /** + * Full editor width. + */ + width: number; + /** + * Full editor height. + */ + height: number; + /** + * Left position for the glyph margin. + */ + glyphMarginLeft: number; + /** + * The width of the glyph margin. + */ + glyphMarginWidth: number; + /** + * The height of the glyph margin. + */ + glyphMarginHeight: number; + /** + * Left position for the line numbers. + */ + lineNumbersLeft: number; + /** + * The width of the line numbers. + */ + lineNumbersWidth: number; + /** + * The height of the line numbers. + */ + lineNumbersHeight: number; + /** + * Left position for the line decorations. + */ + decorationsLeft: number; + /** + * The width of the line decorations. + */ + decorationsWidth: number; + /** + * The height of the line decorations. + */ + decorationsHeight: number; + /** + * Left position for the content (actual text) + */ + contentLeft: number; + /** + * The width of the content (actual text) + */ + contentWidth: number; + /** + * The height of the content (actual height) + */ + contentHeight: number; + /** + * The width of the vertical scrollbar. + */ + verticalScrollbarWidth: number; + /** + * The height of the horizontal scrollbar. + */ + horizontalScrollbarHeight: number; + /** + * The position of the overview ruler. + */ + overviewRuler: OverviewRulerPosition; + constructor(source: { + width: number; + height: number; + glyphMarginLeft: number; + glyphMarginWidth: number; + glyphMarginHeight: number; + lineNumbersLeft: number; + lineNumbersWidth: number; + lineNumbersHeight: number; + decorationsLeft: number; + decorationsWidth: number; + decorationsHeight: number; + contentLeft: number; + contentWidth: number; + contentHeight: number; + verticalScrollbarWidth: number; + horizontalScrollbarHeight: number; + overviewRuler: OverviewRulerPosition; + }); + equals(other: EditorLayoutInfo): boolean; + clone(): EditorLayoutInfo; + } + + /** + * Options for creating the editor. + */ + export interface ICodeEditorWidgetCreationOptions extends IEditorOptions { + model?: IModel; + } + + /** + * An editor model. + */ + export interface IEditorModel { + } + + /** + * An editor view state. + */ + export interface IEditorViewState { + } + + export interface IDimension { + width: number; + height: number; + } + + /** + * Conditions describing action enablement + */ + export interface IActionEnablement { + /** + * The action is enabled only if text in the editor is focused (e.g. blinking cursor). + * Warning: This condition will be disabled if the action is marked to be displayed in the context menu + * Defaults to false. + */ + textFocus?: boolean; + /** + * The action is enabled only if the editor or its widgets have focus (e.g. focus is in find widget). + * Defaults to false. + */ + widgetFocus?: boolean; + /** + * The action is enabled only if the editor is not in read only mode. + * Defaults to false. + */ + writeableEditor?: boolean; + /** + * The action is enabled only if the cursor position is over tokens of a certain kind. + * Defaults to no tokens required. + */ + tokensAtPosition?: string[]; + /** + * The action is enabled only if the cursor position is over a word (i.e. not whitespace). + * Defaults to false. + */ + wordAtPosition?: boolean; + } + + /** + * A (serializable) state of the cursors. + */ + export interface ICursorState { + inSelectionMode: boolean; + selectionStart: IPosition; + position: IPosition; + } + + /** + * A (serializable) state of the view. + */ + export interface IViewState { + scrollTop: number; + scrollTopWithoutViewZones: number; + scrollLeft: number; + } + + /** + * A (serializable) state of the code editor. + */ + export interface ICodeEditorViewState extends IEditorViewState { + cursorState: ICursorState[]; + viewState: IViewState; + contributionsState: { + [id: string]: any; + }; + } + + /** + * Type of hit element with the mouse in the editor. + */ + export enum MouseTargetType { + /** + * Mouse is on top of an unknown element. + */ + UNKNOWN = 0, + /** + * Mouse is on top of the textarea used for input. + */ + TEXTAREA = 1, + /** + * Mouse is on top of the glyph margin + */ + GUTTER_GLYPH_MARGIN = 2, + /** + * Mouse is on top of the line numbers + */ + GUTTER_LINE_NUMBERS = 3, + /** + * Mouse is on top of the line decorations + */ + GUTTER_LINE_DECORATIONS = 4, + /** + * Mouse is on top of the whitespace left in the gutter by a view zone. + */ + GUTTER_VIEW_ZONE = 5, + /** + * Mouse is on top of text in the content. + */ + CONTENT_TEXT = 6, + /** + * Mouse is on top of empty space in the content (e.g. after line text or below last line) + */ + CONTENT_EMPTY = 7, + /** + * Mouse is on top of a view zone in the content. + */ + CONTENT_VIEW_ZONE = 8, + /** + * Mouse is on top of a content widget. + */ + CONTENT_WIDGET = 9, + /** + * Mouse is on top of the decorations overview ruler. + */ + OVERVIEW_RULER = 10, + /** + * Mouse is on top of a scrollbar. + */ + SCROLLBAR = 11, + /** + * Mouse is on top of an overlay widget. + */ + OVERLAY_WIDGET = 12, + } + + /** + * A model for the diff editor. + */ + export interface IDiffEditorModel extends IEditorModel { + /** + * Original model. + */ + original: IModel; + /** + * Modified model. + */ + modified: IModel; + } + + /** + * (Serializable) View state for the diff editor. + */ + export interface IDiffEditorViewState extends IEditorViewState { + original: ICodeEditorViewState; + modified: ICodeEditorViewState; + } + + /** + * A change + */ + export interface IChange { + originalStartLineNumber: number; + originalEndLineNumber: number; + modifiedStartLineNumber: number; + modifiedEndLineNumber: number; + } + + /** + * A character level change. + */ + export interface ICharChange extends IChange { + originalStartColumn: number; + originalEndColumn: number; + modifiedStartColumn: number; + modifiedEndColumn: number; + } + + /** + * A line change + */ + export interface ILineChange extends IChange { + charChanges: ICharChange[]; + } + + /** + * Information about a line in the diff editor + */ + export interface IDiffLineInformation { + equivalentLineNumber: number; + } + + export const KEYBINDING_CONTEXT_EDITOR_TEXT_FOCUS: string; + + export const KEYBINDING_CONTEXT_EDITOR_FOCUS: string; + + export const KEYBINDING_CONTEXT_EDITOR_TAB_MOVES_FOCUS: string; + + export const KEYBINDING_CONTEXT_EDITOR_HAS_MULTIPLE_SELECTIONS: string; + + export const KEYBINDING_CONTEXT_EDITOR_HAS_NON_EMPTY_SELECTION: string; + + export const KEYBINDING_CONTEXT_EDITOR_LANGUAGE_ID: string; + + export const SHOW_ACCESSIBILITY_HELP_ACTION_ID: string; + + export class BareFontInfo { + _bareFontInfoBrand: void; + fontFamily: string; + fontSize: number; + lineHeight: number; + constructor(opts: { + fontFamily: string; + fontSize: number; + lineHeight: number; + }); + getId(): string; + } + + export class FontInfo extends BareFontInfo { + _editorStylingBrand: void; + typicalHalfwidthCharacterWidth: number; + typicalFullwidthCharacterWidth: number; + spaceWidth: number; + maxDigitWidth: number; + constructor(opts: { + fontFamily: string; + fontSize: number; + lineHeight: number; + typicalHalfwidthCharacterWidth: number; + typicalFullwidthCharacterWidth: number; + spaceWidth: number; + maxDigitWidth: number; + }); + equals(other: FontInfo): boolean; + clone(): FontInfo; + } + + export interface IConfiguration { + onDidChange: IEvent; + editor: InternalEditorOptions; + setLineCount(lineCount: number): void; + } + + export interface IViewEventNames { + ModelFlushedEvent: string; + LinesDeletedEvent: string; + LinesInsertedEvent: string; + LineChangedEvent: string; + TokensChangedEvent: string; + DecorationsChangedEvent: string; + CursorPositionChangedEvent: string; + CursorSelectionChangedEvent: string; + RevealRangeEvent: string; + LineMappingChangedEvent: string; + } + + export var ViewEventNames: { + ModelFlushedEvent: string; + LinesDeletedEvent: string; + LinesInsertedEvent: string; + LineChangedEvent: string; + TokensChangedEvent: string; + DecorationsChangedEvent: string; + CursorPositionChangedEvent: string; + CursorSelectionChangedEvent: string; + RevealRangeEvent: string; + LineMappingChangedEvent: string; + ScrollRequestEvent: string; + }; + + export interface IScrollEvent { + scrollTop: number; + scrollLeft: number; + scrollWidth: number; + scrollHeight: number; + scrollTopChanged: boolean; + scrollLeftChanged: boolean; + scrollWidthChanged: boolean; + scrollHeightChanged: boolean; + } + + export interface INewScrollPosition { + scrollLeft?: number; + scrollTop?: number; + } + + export interface IViewLinesDeletedEvent { + /** + * At what line the deletion began (inclusive). + */ + fromLineNumber: number; + /** + * At what line the deletion stopped (inclusive). + */ + toLineNumber: number; + } + + export interface IViewLinesInsertedEvent { + /** + * Before what line did the insertion begin + */ + fromLineNumber: number; + /** + * `toLineNumber` - `fromLineNumber` + 1 denotes the number of lines that were inserted + */ + toLineNumber: number; + } + + export interface IViewLineChangedEvent { + /** + * The line that has changed. + */ + lineNumber: number; + } + + export interface IViewTokensChangedEvent { + /** + * Start line number of range + */ + fromLineNumber: number; + /** + * End line number of range + */ + toLineNumber: number; + } + + export interface IViewDecorationsChangedEvent { + /** + * signals that at least one inline decoration has changed + */ + inlineDecorationsChanged: boolean; + } + + export interface IViewCursorPositionChangedEvent { + /** + * Primary cursor's position. + */ + position: IEditorPosition; + /** + * Secondary cursors' position. + */ + secondaryPositions: IEditorPosition[]; + /** + * Is the primary cursor in the editable range? + */ + isInEditableRange: boolean; + } + + export interface IViewCursorSelectionChangedEvent { + /** + * The primary selection. + */ + selection: IEditorSelection; + /** + * The secondary selections. + */ + secondarySelections: IEditorSelection[]; + } + + export interface IViewRevealRangeEvent { + /** + * Range to be reavealed. + */ + range: IEditorRange; + verticalType: VerticalRevealType; + /** + * If true: there should be a horizontal & vertical revealing + * If false: there should be just a vertical revealing + */ + revealHorizontal: boolean; + } + + export interface IViewScrollRequestEvent { + deltaLines: number; + } + + export interface IViewWhitespaceViewportData { + id: number; + afterLineNumber: number; + verticalOffset: number; + height: number; + } + + export class Viewport { + _viewportBrand: void; + top: number; + left: number; + width: number; + height: number; + constructor(top: number, left: number, width: number, height: number); + } + + /** + * Description of an action contribution + */ + export interface IActionDescriptor { + /** + * An unique identifier of the contributed action. + */ + id: string; + /** + * A label of the action that will be presented to the user. + */ + label: string; + /** + * An array of keybindings for the action. + */ + keybindings?: number[]; + keybindingContext?: string; + /** + * A set of enablement conditions. + */ + enablement?: IActionEnablement; + /** + * Control if the action should show up in the context menu and where. + * Built-in groups: + * 1_goto/* => e.g. 1_goto/1_peekDefinition + * 2_change/* => e.g. 2_change/2_format + * 3_edit/* => e.g. 3_edit/1_copy + * 4_tools/* => e.g. 4_tools/1_commands + * You can also create your own group. + * Defaults to null (don't show in context menu). + */ + contextMenuGroupId?: string; + /** + * Method that will be executed when the action is triggered. + * @param editor The editor instance is passed in as a convinience + */ + run: (editor: ICommonCodeEditor) => TPromise; + } + + /** + * Data associated with an editor action contribution + */ + export interface IEditorActionDescriptorData { + id: string; + label: string; + alias?: string; + } + + export type IEditorActionContributionCtor = IConstructorSignature2; + + export type ICommonEditorContributionCtor = IConstructorSignature1; + + /** + * An editor contribution descriptor that will be used to construct editor contributions + */ + export interface ICommonEditorContributionDescriptor { + /** + * Create an instance of the contribution + */ + createInstance(instantiationService: IInstantiationService, editor: ICommonCodeEditor): IEditorContribution; + } + + /** + * An editor. + */ + export interface IEditor extends IEventEmitter { + getId(): string; + /** + * Get the editor type. Current supported types: + * EditorCommon.EditorType.ICodeEditor => ICodeEditor; + * EditorCommon.EditorType.IDiffEditor => IDiffEditor; + * This is to avoid an instanceof check + */ + getEditorType(): string; + /** + * Destroy the editor. + */ + destroy(): void; + /** + * Update the editor's options after the editor has been created. + */ + updateOptions(newOptions: IEditorOptions): void; + /** + * Indicates that the editor becomes visible. + */ + onVisible(): void; + /** + * Indicates that the editor becomes hidden. + */ + onHide(): void; + /** + * Instructs the editor to remeasure its container. This method should + * be called when the container of the editor gets resized. + */ + layout(dimension?: IDimension): void; + /** + * Brings browser focus to the editor + */ + focus(): void; + /** + * Returns true if this editor has keyboard focus (e.g. cursor is blinking). + */ + isFocused(): boolean; + /** + * Add a new action to this editor. + */ + addAction(descriptor: IActionDescriptor): void; + /** + * Returns all actions associated with this editor. + */ + getActions(): IAction[]; + /** + * Saves current view state of the editor in a serializable object. + */ + saveViewState(): IEditorViewState; + /** + * Restores the view state of the editor from a serializable object generated by `saveViewState`. + */ + restoreViewState(state: IEditorViewState): void; + /** + * Given a position, returns a column number that takes tab-widths into account. + */ + getVisibleColumnFromPosition(position: IPosition): number; + /** + * Returns the primary position of the cursor. + */ + getPosition(): IEditorPosition; + /** + * Set the primary position of the cursor. This will remove any secondary cursors. + * @param position New primary cursor's position + */ + setPosition(position: IPosition): void; + /** + * Scroll vertically as necessary and reveal a line. + */ + revealLine(lineNumber: number): void; + /** + * Scroll vertically as necessary and reveal a line centered vertically. + */ + revealLineInCenter(lineNumber: number): void; + /** + * Scroll vertically as necessary and reveal a line centered vertically only if it lies outside the viewport. + */ + revealLineInCenterIfOutsideViewport(lineNumber: number): void; + /** + * Scroll vertically or horizontally as necessary and reveal a position. + */ + revealPosition(position: IPosition): void; + /** + * Scroll vertically or horizontally as necessary and reveal a position centered vertically. + */ + revealPositionInCenter(position: IPosition): void; + /** + * Scroll vertically or horizontally as necessary and reveal a position centered vertically only if it lies outside the viewport. + */ + revealPositionInCenterIfOutsideViewport(position: IPosition): void; + /** + * Returns the primary selection of the editor. + */ + getSelection(): IEditorSelection; + /** + * Returns all the selections of the editor. + */ + getSelections(): IEditorSelection[]; + /** + * Set the primary selection of the editor. This will remove any secondary cursors. + * @param selection The new selection + */ + setSelection(selection: IRange): void; + setSelection(selection: IEditorRange): void; + setSelection(selection: ISelection): void; + setSelection(selection: IEditorSelection): void; + /** + * Set the selections for all the cursors of the editor. + * Cursors will be removed or added, as necessary. + */ + setSelections(selections: ISelection[]): void; + /** + * Scroll vertically as necessary and reveal lines. + */ + revealLines(startLineNumber: number, endLineNumber: number): void; + /** + * Scroll vertically as necessary and reveal lines centered vertically. + */ + revealLinesInCenter(lineNumber: number, endLineNumber: number): void; + /** + * Scroll vertically as necessary and reveal lines centered vertically only if it lies outside the viewport. + */ + revealLinesInCenterIfOutsideViewport(lineNumber: number, endLineNumber: number): void; + /** + * Scroll vertically or horizontally as necessary and reveal a range. + */ + revealRange(range: IRange): void; + /** + * Scroll vertically or horizontally as necessary and reveal a range centered vertically. + */ + revealRangeInCenter(range: IRange): void; + /** + * Scroll vertically or horizontally as necessary and reveal a range centered vertically only if it lies outside the viewport. + */ + revealRangeInCenterIfOutsideViewport(range: IRange): void; + /** + * Directly trigger a handler or an editor action. + * @param source The source of the call. + * @param handlerId The id of the handler or the id of a contribution. + * @param payload Extra data to be sent to the handler. + */ + trigger(source: string, handlerId: string, payload: any): void; + /** + * Gets the current model attached to this editor. + */ + getModel(): IEditorModel; + /** + * Sets the current model attached to this editor. + * If the previous model was created by the editor via the value key in the options + * literal object, it will be destroyed. Otherwise, if the previous model was set + * via setModel, or the model key in the options literal object, the previous model + * will not be destroyed. + * It is safe to call setModel(null) to simply detach the current model from the editor. + */ + setModel(model: IEditorModel): void; + /** + * Change the decorations. All decorations added through this changeAccessor + * will get the ownerId of the editor (meaning they will not show up in other + * editors). + * @see IModel.changeDecorations + */ + changeDecorations(callback: (changeAccessor: IModelDecorationsChangeAccessor) => any): any; + } + + export interface ICodeEditorState { + validate(editor: ICommonCodeEditor): boolean; + } + + export enum CodeEditorStateFlag { + Value = 0, + Selection = 1, + Position = 2, + Scroll = 3, + } + + /** + * An editor contribution that gets created every time a new editor gets created and gets disposed when the editor gets disposed. + */ + export interface IEditorContribution { + /** + * Get a unique identifier for this contribution. + */ + getId(): string; + /** + * Dispose this contribution. + */ + dispose(): void; + /** + * Store view state. + */ + saveViewState?(): any; + /** + * Restore view state. + */ + restoreViewState?(state: any): void; + } + + export interface IThemeDecorationRenderOptions { + backgroundColor?: string; + outlineColor?: string; + outlineStyle?: string; + outlineWidth?: string; + borderColor?: string; + borderRadius?: string; + borderSpacing?: string; + borderStyle?: string; + borderWidth?: string; + textDecoration?: string; + cursor?: string; + color?: string; + letterSpacing?: string; + gutterIconPath?: string; + overviewRulerColor?: string; + } + + export interface IDecorationRenderOptions extends IThemeDecorationRenderOptions { + isWholeLine?: boolean; + overviewRulerLane?: OverviewRulerLane; + light?: IThemeDecorationRenderOptions; + dark?: IThemeDecorationRenderOptions; + } + + export interface IRangeWithMessage { + range: IRange; + hoverMessage?: IHTMLContentElement[]; + } + + export interface ICommonCodeEditor extends IEditor { + /** + * Returns true if this editor or one of its widgets has keyboard focus. + */ + hasWidgetFocus(): boolean; + /** + * Get a contribution of this editor. + * @id Unique identifier of the contribution. + * @return The contribution or null if contribution not found. + */ + getContribution(id: string): IEditorContribution; + captureState(...flags: CodeEditorStateFlag[]): ICodeEditorState; + /** + * Type the getModel() of IEditor. + */ + getModel(): IModel; + /** + * Returns the current editor's configuration + */ + getConfiguration(): InternalEditorOptions; + /** + * Returns the 'raw' editor's configuration, as it was applied over the defaults, but without any computed members. + */ + getRawConfiguration(): IEditorOptions; + /** + * Get value of the current model attached to this editor. + * @see IModel.getValue + */ + getValue(options?: { + preserveBOM: boolean; + lineEnding: string; + }): string; + /** + * Set the value of the current model attached to this editor. + * @see IModel.setValue + */ + setValue(newValue: string): void; + /** + * Get the scrollWidth of the editor's viewport. + */ + getScrollWidth(): number; + /** + * Get the scrollLeft of the editor's viewport. + */ + getScrollLeft(): number; + /** + * Get the scrollHeight of the editor's viewport. + */ + getScrollHeight(): number; + /** + * Get the scrollTop of the editor's viewport. + */ + getScrollTop(): number; + /** + * Change the scrollLeft of the editor's viewport. + */ + setScrollLeft(newScrollLeft: number): void; + /** + * Change the scrollTop of the editor's viewport. + */ + setScrollTop(newScrollTop: number): void; + /** + * Change the scroll position of the editor's viewport. + */ + setScrollPosition(position: INewScrollPosition): void; + /** + * Get an action that is a contribution to this editor. + * @id Unique identifier of the contribution. + * @return The action or null if action not found. + */ + getAction(id: string): IAction; + /** + * Execute a command on the editor. + * @param source The source of the call. + * @param command The command to execute + */ + executeCommand(source: string, command: ICommand): void; + /** + * Execute a command on the editor. + * @param source The source of the call. + * @param command The command to execute + */ + executeEdits(source: string, edits: IIdentifiedSingleEditOperation[]): boolean; + /** + * Execute multiple (concommitent) commands on the editor. + * @param source The source of the call. + * @param command The commands to execute + */ + executeCommands(source: string, commands: ICommand[]): void; + /** + * Get all the decorations on a line (filtering out decorations from other editors). + */ + getLineDecorations(lineNumber: number): IModelDecoration[]; + /** + * All decorations added through this call wii get the ownerId of this editor. + * @see IModel.deltaDecorations + */ + deltaDecorations(oldDecorations: string[], newDecorations: IModelDeltaDecoration[]): string[]; + setDecorations(decorationTypeKey: string, ranges: IRangeWithMessage[]): void; + removeDecorations(decorationTypeKey: string): void; + /** + * Get the layout info for the editor. + */ + getLayoutInfo(): EditorLayoutInfo; + /** + * Prevent the editor from sending a widgetFocusLost event, + * set it in a state where it believes that focus is in one of its widgets. + * Use this method with care and always add a matching `endForcedWidgetFocus` + */ + beginForcedWidgetFocus(): void; + /** + * End the preventing of sending a widgetFocusLost event. + */ + endForcedWidgetFocus(): void; + /** + * This listener is notified when a keypress produces a visible character. + * The callback should not do operations on the view, as the view might not be updated to reflect previous typed characters. + * @param character Character to listen to. + * @param callback Function to call when `character` is typed. + */ + addTypingListener(character: string, callback: () => void): ListenerUnbind; + } + + export interface ICommonDiffEditor extends IEditor { + /** + * Type the getModel() of IEditor. + */ + getModel(): IDiffEditorModel; + getOriginalEditor(): ICommonCodeEditor; + getModifiedEditor(): ICommonCodeEditor; + getLineChanges(): ILineChange[]; + /** + * Get information based on computed diff about a line number from the original model. + * If the diff computation is not finished or the model is missing, will return null. + */ + getDiffLineInformationForOriginal(lineNumber: number): IDiffLineInformation; + /** + * Get information based on computed diff about a line number from the modified model. + * If the diff computation is not finished or the model is missing, will return null. + */ + getDiffLineInformationForModified(lineNumber: number): IDiffLineInformation; + /** + * @see ICodeEditor.getValue + */ + getValue(options?: { + preserveBOM: boolean; + lineEnding: string; + }): string; + /** + * Returns whether the diff editor is ignoring trim whitespace or not. + */ + ignoreTrimWhitespace: boolean; + /** + * Returns whether the diff editor is rendering side by side or not. + */ + renderSideBySide: boolean; + } + + export var EditorType: { + ICodeEditor: string; + IDiffEditor: string; + }; + + export var ClassName: { + EditorWarningDecoration: string; + EditorErrorDecoration: string; + }; + + export var EventType: { + Disposed: string; + ConfigurationChanged: string; + ModelDispose: string; + ModelChanged: string; + ModelTokensChanged: string; + ModelModeChanged: string; + ModelModeSupportChanged: string; + ModelOptionsChanged: string; + ModelContentChanged: string; + ModelContentChanged2: string; + ModelContentChangedFlush: string; + ModelContentChangedLinesDeleted: string; + ModelContentChangedLinesInserted: string; + ModelContentChangedLineChanged: string; + EditorTextBlur: string; + EditorTextFocus: string; + EditorFocus: string; + EditorBlur: string; + ModelDecorationsChanged: string; + CursorPositionChanged: string; + CursorSelectionChanged: string; + CursorRevealRange: string; + CursorScrollRequest: string; + ViewFocusGained: string; + ViewFocusLost: string; + ViewFocusChanged: string; + ViewScrollChanged: string; + ViewZonesChanged: string; + ViewLayoutChanged: string; + ContextMenu: string; + MouseDown: string; + MouseUp: string; + MouseMove: string; + MouseLeave: string; + KeyDown: string; + KeyUp: string; + EditorLayout: string; + DiffUpdated: string; + }; + + export var Handler: { + ExecuteCommand: string; + ExecuteCommands: string; + CursorLeft: string; + CursorLeftSelect: string; + CursorWordLeft: string; + CursorWordStartLeft: string; + CursorWordEndLeft: string; + CursorWordLeftSelect: string; + CursorWordStartLeftSelect: string; + CursorWordEndLeftSelect: string; + CursorRight: string; + CursorRightSelect: string; + CursorWordRight: string; + CursorWordStartRight: string; + CursorWordEndRight: string; + CursorWordRightSelect: string; + CursorWordStartRightSelect: string; + CursorWordEndRightSelect: string; + CursorUp: string; + CursorUpSelect: string; + CursorDown: string; + CursorDownSelect: string; + CursorPageUp: string; + CursorPageUpSelect: string; + CursorPageDown: string; + CursorPageDownSelect: string; + CursorHome: string; + CursorHomeSelect: string; + CursorEnd: string; + CursorEndSelect: string; + ExpandLineSelection: string; + CursorTop: string; + CursorTopSelect: string; + CursorBottom: string; + CursorBottomSelect: string; + CursorColumnSelectLeft: string; + CursorColumnSelectRight: string; + CursorColumnSelectUp: string; + CursorColumnSelectPageUp: string; + CursorColumnSelectDown: string; + CursorColumnSelectPageDown: string; + AddCursorDown: string; + AddCursorUp: string; + CursorUndo: string; + MoveTo: string; + MoveToSelect: string; + ColumnSelect: string; + CreateCursor: string; + LastCursorMoveToSelect: string; + JumpToBracket: string; + Type: string; + ReplacePreviousChar: string; + Paste: string; + Tab: string; + Indent: string; + Outdent: string; + DeleteLeft: string; + DeleteRight: string; + DeleteWordLeft: string; + DeleteWordStartLeft: string; + DeleteWordEndLeft: string; + DeleteWordRight: string; + DeleteWordStartRight: string; + DeleteWordEndRight: string; + DeleteAllLeft: string; + DeleteAllRight: string; + RemoveSecondaryCursors: string; + CancelSelection: string; + Cut: string; + Undo: string; + Redo: string; + WordSelect: string; + WordSelectDrag: string; + LastCursorWordSelect: string; + LineSelect: string; + LineSelectDrag: string; + LastCursorLineSelect: string; + LastCursorLineSelectDrag: string; + LineInsertBefore: string; + LineInsertAfter: string; + LineBreakInsert: string; + SelectAll: string; + ScrollLineUp: string; + ScrollLineDown: string; + ScrollPageUp: string; + ScrollPageDown: string; + }; + + export enum TextEditorCursorStyle { + Line = 1, + Block = 2, + Underline = 3, + } + + export function cursorStyleToString(cursorStyle: TextEditorCursorStyle): string; + + export interface IContentWidgetData { + widget: IContentWidget; + position: IContentWidgetPosition; + } + + export interface IOverlayWidgetData { + widget: IOverlayWidget; + position: IOverlayWidgetPosition; + } + + export interface ICodeEditorHelper { + getScrollWidth(): number; + getScrollLeft(): number; + getScrollHeight(): number; + getScrollTop(): number; + setScrollPosition(position: INewScrollPosition): void; + getVerticalOffsetForPosition(lineNumber: number, column: number): number; + delegateVerticalScrollbarMouseDown(browserEvent: MouseEvent): void; + getOffsetForColumn(lineNumber: number, column: number): number; + } + + export interface IView extends IDisposable { + domNode: HTMLElement; + getInternalEventBus(): IEventEmitter; + createOverviewRuler(cssClassName: string, minimumHeight: number, maximumHeight: number): IOverviewRuler; + getCodeEditorHelper(): ICodeEditorHelper; + getCenteredRangeInViewport(): IEditorRange; + change(callback: (changeAccessor: IViewZoneChangeAccessor) => any): boolean; + getWhitespaces(): IEditorWhitespace[]; + renderOnce(callback: () => any): any; + render(now: boolean, everything: boolean): void; + setAriaActiveDescendant(id: string): void; + focus(): void; + isFocused(): boolean; + saveState(): IViewState; + restoreState(state: IViewState): void; + addContentWidget(widgetData: IContentWidgetData): void; + layoutContentWidget(widgetData: IContentWidgetData): void; + removeContentWidget(widgetData: IContentWidgetData): void; + addOverlayWidget(widgetData: IOverlayWidgetData): void; + layoutOverlayWidget(widgetData: IOverlayWidgetData): void; + removeOverlayWidget(widgetData: IOverlayWidgetData): void; + } + + export interface IViewZoneData { + viewZoneId: number; + positionBefore: IEditorPosition; + positionAfter: IEditorPosition; + position: IEditorPosition; + afterLineNumber: number; + } + + export interface IMouseDispatchData { + position: IEditorPosition; + /** + * Desired mouse column (e.g. when position.column gets clamped to text length -- clicking after text on a line). + */ + mouseColumn: number; + startedOnLineNumbers: boolean; + inSelectionMode: boolean; + mouseDownCount: number; + altKey: boolean; + ctrlKey: boolean; + metaKey: boolean; + shiftKey: boolean; + } + + export interface IViewController { + dispatchMouse(data: IMouseDispatchData): any; + moveTo(source: string, position: IEditorPosition): void; + paste(source: string, text: string, pasteOnNewLine: boolean): void; + type(source: string, text: string): void; + replacePreviousChar(source: string, text: string, replaceCharCnt: number): void; + cut(source: string): void; + emitKeyDown(e: IKeyboardEvent): void; + emitKeyUp(e: IKeyboardEvent): void; + emitContextMenu(e: IEditorMouseEvent): void; + emitMouseMove(e: IEditorMouseEvent): void; + emitMouseLeave(e: IEditorMouseEvent): void; + emitMouseUp(e: IEditorMouseEvent): void; + emitMouseDown(e: IEditorMouseEvent): void; + } + + export var ClassNames: { + TEXTAREA_COVER: string; + TEXTAREA: string; + LINES_CONTENT: string; + OVERFLOW_GUARD: string; + VIEW_LINES: string; + VIEW_LINE: string; + SCROLLABLE_ELEMENT: string; + CONTENT_WIDGETS: string; + OVERFLOWING_CONTENT_WIDGETS: string; + OVERLAY_WIDGETS: string; + MARGIN_VIEW_OVERLAYS: string; + LINE_NUMBERS: string; + GLYPH_MARGIN: string; + SCROLL_DECORATION: string; + VIEW_CURSORS_LAYER: string; + VIEW_ZONES: string; + }; + + export interface IViewportInfo { + visibleRange: IEditorRange; + width: number; + height: number; + deltaTop: number; + deltaLeft: number; + } + + /** + * A view zone is a full horizontal rectangle that 'pushes' text down. + * The editor reserves space for view zones when rendering. + */ + export interface IViewZone { + /** + * The line number after which this zone should appear. + * Use 0 to place a view zone before the first line number. + */ + afterLineNumber: number; + /** + * The column after which this zone should appear. + * If not set, the maxLineColumn of `afterLineNumber` will be used. + */ + afterColumn?: number; + /** + * Suppress mouse down events. + * If set, the editor will attach a mouse down listener to the view zone and .preventDefault on it. + * Defaults to false + */ + suppressMouseDown?: boolean; + /** + * The height in lines of the view zone. + * If specified, `heightInPx` will be used instead of this. + * If neither `heightInPx` nor `heightInLines` is specified, a default of `heightInLines` = 1 will be chosen. + */ + heightInLines?: number; + /** + * The height in px of the view zone. + * If this is set, the editor will give preference to it rather than `heightInLines` above. + * If neither `heightInPx` nor `heightInLines` is specified, a default of `heightInLines` = 1 will be chosen. + */ + heightInPx?: number; + /** + * The dom node of the view zone + */ + domNode: HTMLElement; + /** + * Callback which gives the relative top of the view zone as it appears (taking scrolling into account). + */ + onDomNodeTop?: (top: number) => void; + /** + * Callback which gives the height in pixels of the view zone. + */ + onComputedHeight?: (height: number) => void; + } + + /** + * An accessor that allows for zones to be added or removed. + */ + export interface IViewZoneChangeAccessor { + /** + * Create a new view zone. + * @param zone Zone to create + * @return A unique identifier to the view zone. + */ + addZone(zone: IViewZone): number; + /** + * Remove a zone + * @param id A unique identifier to the view zone, as returned by the `addZone` call. + */ + removeZone(id: number): void; + /** + * Change a zone's position. + * The editor will rescan the `afterLineNumber` and `afterColumn` properties of a view zone. + */ + layoutZone(id: number): void; + } + + /** + * A positioning preference for rendering content widgets. + */ + export enum ContentWidgetPositionPreference { + /** + * Place the content widget exactly at a position + */ + EXACT = 0, + /** + * Place the content widget above a position + */ + ABOVE = 1, + /** + * Place the content widget below a position + */ + BELOW = 2, + } + + /** + * A position for rendering content widgets. + */ + export interface IContentWidgetPosition { + /** + * Desired position for the content widget. + * `preference` will also affect the placement. + */ + position: IPosition; + /** + * Placement preference for position, in order of preference. + */ + preference: ContentWidgetPositionPreference[]; + } + + /** + * A content widget renders inline with the text and can be easily placed 'near' an editor position. + */ + export interface IContentWidget { + /** + * Render this content widget in a location where it could overflow the editor's view dom node. + */ + allowEditorOverflow?: boolean; + /** + * Get a unique identifier of the content widget. + */ + getId(): string; + /** + * Get the dom node of the content widget. + */ + getDomNode(): HTMLElement; + /** + * Get the placement of the content widget. + * If null is returned, the content widget will be placed off screen. + */ + getPosition(): IContentWidgetPosition; + } + + /** + * A positioning preference for rendering overlay widgets. + */ + export enum OverlayWidgetPositionPreference { + /** + * Position the overlay widget in the top right corner + */ + TOP_RIGHT_CORNER = 0, + /** + * Position the overlay widget in the bottom right corner + */ + BOTTOM_RIGHT_CORNER = 1, + /** + * Position the overlay widget in the top center + */ + TOP_CENTER = 2, + } + + /** + * A position for rendering overlay widgets. + */ + export interface IOverlayWidgetPosition { + /** + * The position preference for the overlay widget. + */ + preference: OverlayWidgetPositionPreference; + } + + /** + * An overlay widgets renders on top of the text. + */ + export interface IOverlayWidget { + /** + * Get a unique identifier of the overlay widget. + */ + getId(): string; + /** + * Get the dom node of the overlay widget. + */ + getDomNode(): HTMLElement; + /** + * Get the placement of the overlay widget. + * If null is returned, the overlay widget is responsible to place itself. + */ + getPosition(): IOverlayWidgetPosition; + } + + /** + * Target hit with the mouse in the editor. + */ + export interface IMouseTarget { + /** + * The target element + */ + element: Element; + /** + * The target type + */ + type: MouseTargetType; + /** + * The 'approximate' editor position + */ + position: IEditorPosition; + /** + * Desired mouse column (e.g. when position.column gets clamped to text length -- clicking after text on a line). + */ + mouseColumn: number; + /** + * The 'approximate' editor range + */ + range: IEditorRange; + /** + * Some extra detail. + */ + detail: any; + } + + /** + * A mouse event originating from the editor. + */ + export interface IEditorMouseEvent { + event: IMouseEvent; + target: IMouseTarget; + } + + export type ISimpleEditorContributionCtor = IConstructorSignature1; + + /** + * An editor contribution descriptor that will be used to construct editor contributions + */ + export interface IEditorContributionDescriptor { + /** + * Create an instance of the contribution + */ + createInstance(instantiationService: IInstantiationService, editor: ICodeEditor): IEditorContribution; + } + + export class ColorZone { + _colorZoneBrand: void; + from: number; + to: number; + colorId: number; + position: OverviewRulerLane; + constructor(from: number, to: number, colorId: number, position: OverviewRulerLane); + } + + /** + * A zone in the overview ruler + */ + export class OverviewRulerZone { + _overviewRulerZoneBrand: void; + startLineNumber: number; + endLineNumber: number; + position: OverviewRulerLane; + forceHeight: number; + private _color; + private _darkColor; + private _colorZones; + constructor(startLineNumber: number, endLineNumber: number, position: OverviewRulerLane, forceHeight: number, color: string, darkColor: string); + getColor(useDarkColor: boolean): string; + equals(other: OverviewRulerZone): boolean; + compareTo(other: OverviewRulerZone): number; + setColorZones(colorZones: ColorZone[]): void; + getColorZones(): ColorZone[]; + } + + /** + * An overview ruler + */ + export interface IOverviewRuler { + getDomNode(): HTMLElement; + dispose(): void; + setZones(zones: OverviewRulerZone[]): void; + setLayout(position: OverviewRulerPosition): void; + } + + /** + * A rich code editor. + */ + export interface ICodeEditor extends ICommonCodeEditor { + /** + * Returns the editor's dom node + */ + getDomNode(): HTMLElement; + /** + * Add a content widget. Widgets must have unique ids, otherwise they will be overwritten. + */ + addContentWidget(widget: IContentWidget): void; + /** + * Layout/Reposition a content widget. This is a ping to the editor to call widget.getPosition() + * and update appropiately. + */ + layoutContentWidget(widget: IContentWidget): void; + /** + * Remove a content widget. + */ + removeContentWidget(widget: IContentWidget): void; + /** + * Add an overlay widget. Widgets must have unique ids, otherwise they will be overwritten. + */ + addOverlayWidget(widget: IOverlayWidget): void; + /** + * Layout/Reposition an overlay widget. This is a ping to the editor to call widget.getPosition() + * and update appropiately. + */ + layoutOverlayWidget(widget: IOverlayWidget): void; + /** + * Remove an overlay widget. + */ + removeOverlayWidget(widget: IOverlayWidget): void; + /** + * Change the view zones. View zones are lost when a new model is attached to the editor. + */ + changeViewZones(callback: (accessor: IViewZoneChangeAccessor) => void): void; + /** + * Returns the range that is currently centered in the view port. + */ + getCenteredRangeInViewport(): IEditorRange; + /** + * Get the view zones. + */ + getWhitespaces(): IEditorWhitespace[]; + /** + * Get the horizontal position (left offset) for the column w.r.t to the beginning of the line. + * This method works only if the line `lineNumber` is currently rendered (in the editor's viewport). + * Use this method with caution. + */ + getOffsetForColumn(lineNumber: number, column: number): number; + /** + * Force an editor render now. + */ + render(): void; + /** + * Get the vertical position (top offset) for the line w.r.t. to the first line. + */ + getTopForLineNumber(lineNumber: number): number; + /** + * Get the vertical position (top offset) for the position w.r.t. to the first line. + */ + getTopForPosition(lineNumber: number, column: number): number; + /** + * Get the visible position for `position`. + * The result position takes scrolling into account and is relative to the top left corner of the editor. + * Explanation 1: the results of this method will change for the same `position` if the user scrolls the editor. + * Explanation 2: the results of this method will not change if the container of the editor gets repositioned. + * Warning: the results of this method are innacurate for positions that are outside the current editor viewport. + */ + getScrolledVisiblePosition(position: IPosition): { + top: number; + left: number; + height: number; + }; + /** + * Set the model ranges that will be hidden in the view. + */ + setHiddenAreas(ranges: IRange[]): void; + setAriaActiveDescendant(id: string): void; + /** + * Apply the same font settings as the editor to `target`. + */ + applyFontInfo(target: HTMLElement): void; + } + + /** + * A rich diff editor. + */ + export interface IDiffEditor extends ICommonDiffEditor { + /** + * @see ICodeEditor.getDomNode + */ + getDomNode(): HTMLElement; + } } \ No newline at end of file diff --git a/build/lib/monaco-editor.d.ts.recipe b/build/lib/monaco-editor.d.ts.recipe index 42a43b68610..533a5423985 100644 --- a/build/lib/monaco-editor.d.ts.recipe +++ b/build/lib/monaco-editor.d.ts.recipe @@ -1,57 +1,117 @@ +declare module monaco.editor { + + export function create(domElement: HTMLElement, options: IEditorConstructionOptions, services?: any): ICodeEditor; + export function createDiffEditor(domElement: HTMLElement, options: IDiffEditorConstructionOptions, services?: any): IDiffEditor; + export function createModel(value:string, mode:string|ILanguage|IMode, associatedResource?:any|string): IModel; + export function getOrCreateMode(modeId: string): TPromise; + export function createCustomMode(description:ILanguage): TPromise; + export function colorize(text: string, modeId: string, options: IColorizerOptions): TPromise; + export function colorizeElement(domNode: HTMLElement, options: IColorizerElementOptions): TPromise; + export function colorizeLine(line: string, tokens: ViewLineToken[], tabSize?: number): string; + export function colorizeModelLine(model: IModel, lineNumber: number, tabSize?: number): string; + export function registerWorkerParticipant(modeId:string, moduleName:string, ctorName:string): void; + export function configureMode(modeId: string, options: any): void; + + export interface IColorizerOptions { + tabSize?: number; + } + + export interface IColorizerElementOptions extends IColorizerOptions { + theme?: string; + mimeType?: string; + } + + export interface IEditorConstructionOptions extends ICodeEditorWidgetCreationOptions { + value?: string; + /** + * A mode name (such as text/javascript, etc.) or an IMonarchLanguage + */ + mode?: any; + enableTelemetry?: boolean; + } + + export interface IDiffEditorConstructionOptions extends IDiffEditorOptions { + } +} declare module monaco { - interface Thenable { - /** - * Attaches callbacks for the resolution and/or rejection of the Promise. - * @param onfulfilled The callback to execute when the Promise is resolved. - * @param onrejected The callback to execute when the Promise is rejected. - * @returns A Promise for the completion of which ever callback is executed. - */ - then(onfulfilled?: (value: R) => TResult | Thenable, onrejected?: (reason: any) => TResult | Thenable): Thenable; - then(onfulfilled?: (value: R) => TResult | Thenable, onrejected?: (reason: any) => void): Thenable; - } + interface Thenable { + /** + * Attaches callbacks for the resolution and/or rejection of the Promise. + * @param onfulfilled The callback to execute when the Promise is resolved. + * @param onrejected The callback to execute when the Promise is rejected. + * @returns A Promise for the completion of which ever callback is executed. + */ + then(onfulfilled?: (value: R) => TResult | Thenable, onrejected?: (reason: any) => TResult | Thenable): Thenable; + then(onfulfilled?: (value: R) => TResult | Thenable, onrejected?: (reason: any) => void): Thenable; + } - export interface Event { - (listener: (e: T) => any): IDisposable; - } + export interface IDisposable { + dispose(): void; + } - export class Emitter { - constructor(); - event: Event; - fire(event?: T): void; - dispose(): void; - } + export interface IEvent { + (listener: (e: T) => any, thisArg?: any): IDisposable; + } - export interface IDisposable { - dispose(): void; - } + export class Emitter { + constructor(); + event: IEvent; + fire(event?: T): void; + dispose(): void; + } - #include(vs/base/common/uri): URI + #include(vs/base/common/winjs.base.d.ts): TValueCallback, ProgressCallback, TPromise - #include(vs/base/common/winjs.base.d.ts): TValueCallback, ProgressCallback, TPromise + #include(vs/base/common/uri): URI + #include(vs/base/common/eventEmitter): IEmitterEvent, ListenerCallback, IBulkListenerCallback, ListenerUnbind, IEventEmitter + + #include(vs/base/common/keyCodes): KeyCode, KeyMod + + #include(vs/base/common/htmlContent): IHTMLContentElementCode, IHTMLContentElement + + #include(vs/base/common/actions): IAction + + #include(vs/base/browser/keyboardEvent): IKeyboardEvent + + #include(vs/base/browser/mouseEvent): IMouseEvent + + export interface IPlatformServices { + } + + export interface IInstantiationService { + } + + export interface IConstructorSignature1 { + new (context: IPlatformServices, first: A1): T; + } + + export interface IConstructorSignature2 { + new (context: IPlatformServices, first: A1, second: A2): T; + } } + declare module monaco.editor { - export function create(domElement: HTMLElement, options: IEditorConstructionOptions, services?: any): ICodeEditor; - export function createDiffEditor(domElement: HTMLElement, options: IDiffEditorConstructionOptions, services?: any): IDiffEditor; - export function createModel(value:string, mode:string|IMonarchLanguage|IMode, associatedResource?:any|string): IModel; - export function getOrCreateMode(modeId: string): TPromise; - export function createCustomMode(description:IMonarchLanguage): TPromise; - export function colorize(text: string, modeId: string, options: IColorizerOptions): TPromise; - export function colorizeElement(domNode: HTMLElement, options: IColorizerElementOptions): TPromise; - export function colorizeLine(line: string, tokens: Editor.ILineToken[], tabSize?: number): string; - export function colorizeModelLine(model: Editor.IModel, lineNumber: number, tabSize?: number): string; - export function registerWorkerParticipant(modeId:string, moduleName:string, ctorName:string): void; - export function configureMode(modeId: string, options: any): void; + #include(vs/editor/common/modes/monarch/monarchTypes): ILanguage, ILanguageBracket - #include(vs/base/browser/ui/scrollbar/scrollableElementOptions): ScrollbarVisibility - #include(vs/base/common/htmlContent): IHTMLContentElementCode, IHTMLContentElement - #include(vs/editor/common/modes): ILineContext, IMode, IModeTransition, IToken + #include(vs/editor/common/core/modeTransition): ModeTransition - #includeAll(vs/editor/common/editorCommon): - #includeAll(vs/editor/browser/editorBrowser): + #include(vs/editor/common/modes): IToken, IModeTransition, ILineContext + + export interface IMode { + + } + + #include(vs/base/browser/ui/scrollbar/scrollableElementOptions): ScrollbarVisibility + + #include(vs/editor/common/core/viewLineToken): ViewLineToken + + #includeAll(vs/editor/common/editorCommon): KeyCode, KeyMod + + #includeAll(vs/editor/browser/editorBrowser): } \ No newline at end of file diff --git a/build/lib/monaco.js b/build/lib/monaco.js index 61dce3bdb17..c967c62414c 100644 --- a/build/lib/monaco.js +++ b/build/lib/monaco.js @@ -27,6 +27,10 @@ function getSourceFile(moduleId) { } return SOURCE_FILE_MAP[moduleId]; } +function isDeclaration(a) { + var tmp = a; + return tmp.name && typeof tmp.name.text === 'string'; +} function visitTopLevelDeclarations(sourceFile, visitor) { var stop = false; var visit = function (node) { @@ -37,9 +41,18 @@ function visitTopLevelDeclarations(sourceFile, visitor) { case ts.SyntaxKind.InterfaceDeclaration: case ts.SyntaxKind.EnumDeclaration: case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.VariableStatement: + case ts.SyntaxKind.TypeAliasDeclaration: + case ts.SyntaxKind.FunctionDeclaration: stop = visitor(node); break; } + if (node.kind !== ts.SyntaxKind.SourceFile) { + if (getNodeText(sourceFile, node).indexOf('cursorStyleToString') >= 0) { + console.log('FOUND TEXT IN NODE: ' + ts.SyntaxKind[node.kind]); + console.log(getNodeText(sourceFile, node)); + } + } if (stop) { return; } @@ -58,11 +71,15 @@ function getAllTopLevelDeclarations(sourceFile) { function getTopLevelDeclaration(sourceFile, typeName) { var result = null; visitTopLevelDeclarations(sourceFile, function (node) { - if (node.name.text === typeName) { - result = node; - return true /*stop*/; + if (isDeclaration(node)) { + if (node.name.text === typeName) { + result = node; + return true /*stop*/; + } + return false /*continue*/; } - return false /*continue*/; + // node is ts.VariableStatement + return (getNodeText(sourceFile, node).indexOf(typeName) >= 0); }); return result; } @@ -75,6 +92,52 @@ function getMassagedTopLevelDeclarationText(sourceFile, declaration) { result = result.replace(/export declare/g, 'export'); return result; } +function format(text) { + var options = getDefaultOptions(); + // Parse the source text + var sourceFile = ts.createSourceFile('file.ts', text, ts.ScriptTarget.Latest, /*setParentPointers*/ true); + // Get the formatting edits on the input sources + var edits = ts.formatting.formatDocument(sourceFile, getRuleProvider(options), options); + // Apply the edits on the input code + return applyEdits(text, edits); + function getRuleProvider(options) { + // Share this between multiple formatters using the same options. + // This represents the bulk of the space the formatter uses. + var ruleProvider = new ts.formatting.RulesProvider(); + ruleProvider.ensureUpToDate(options); + return ruleProvider; + } + function applyEdits(text, edits) { + // Apply edits in reverse on the existing text + var result = text; + for (var i = edits.length - 1; i >= 0; i--) { + var change = edits[i]; + var head = result.slice(0, change.span.start); + var tail = result.slice(change.span.start + change.span.length); + result = head + change.newText + tail; + } + return result; + } + function getDefaultOptions() { + return { + IndentSize: 4, + TabSize: 4, + NewLineCharacter: '\r\n', + ConvertTabsToSpaces: true, + IndentStyle: ts.IndentStyle.Block, + InsertSpaceAfterCommaDelimiter: true, + InsertSpaceAfterSemicolonInForStatements: true, + InsertSpaceBeforeAndAfterBinaryOperators: true, + InsertSpaceAfterKeywordsInControlFlowStatements: true, + InsertSpaceAfterFunctionKeywordForAnonymousFunctions: false, + InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false, + InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: false, + InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: true, + PlaceOpenBraceOnNewLineForFunctions: false, + PlaceOpenBraceOnNewLineForControlBlocks: false, + }; + } +} var recipe = fs.readFileSync(path.join(__dirname, './monaco-editor.d.ts.recipe')).toString(); var lines = recipe.split(/\r\n|\n|\r/); var result = []; @@ -114,4 +177,10 @@ lines.forEach(function (line) { } result.push(line); }); -fs.writeFileSync(path.join(__dirname, './monaco-editor.d.ts'), result.join('\n')); +var resultTxt = result.join('\n'); +resultTxt = resultTxt.replace(/\beditorCommon\./g, ''); +resultTxt = resultTxt.replace(/\bEventa; + return tmp.name && typeof tmp.name.text === 'string'; +} -function visitTopLevelDeclarations(sourceFile:ts.SourceFile, visitor:(node:TypeScriptTypeDeclaration)=>boolean): void { +function visitTopLevelDeclarations(sourceFile:ts.SourceFile, visitor:(node:TSTopLevelDeclare)=>boolean): void { let stop = false; let visit = (node: ts.Node): void => { @@ -53,10 +58,20 @@ function visitTopLevelDeclarations(sourceFile:ts.SourceFile, visitor:(node:TypeS case ts.SyntaxKind.InterfaceDeclaration: case ts.SyntaxKind.EnumDeclaration: case ts.SyntaxKind.ClassDeclaration: - stop = visitor(node); + case ts.SyntaxKind.VariableStatement: + case ts.SyntaxKind.TypeAliasDeclaration: + case ts.SyntaxKind.FunctionDeclaration: + stop = visitor(node); break; } + if (node.kind !== ts.SyntaxKind.SourceFile) { + if (getNodeText(sourceFile, node).indexOf('cursorStyleToString') >= 0) { + console.log('FOUND TEXT IN NODE: ' + ts.SyntaxKind[node.kind]); + console.log(getNodeText(sourceFile, node)); + } + } + if (stop) { return; } @@ -67,8 +82,8 @@ function visitTopLevelDeclarations(sourceFile:ts.SourceFile, visitor:(node:TypeS } -function getAllTopLevelDeclarations(sourceFile:ts.SourceFile): TypeScriptTypeDeclaration[] { - let all:TypeScriptTypeDeclaration[] = []; +function getAllTopLevelDeclarations(sourceFile:ts.SourceFile): TSTopLevelDeclare[] { + let all:TSTopLevelDeclare[] = []; visitTopLevelDeclarations(sourceFile, (node) => { all.push(node); return false /*continue*/; @@ -77,14 +92,18 @@ function getAllTopLevelDeclarations(sourceFile:ts.SourceFile): TypeScriptTypeDec } -function getTopLevelDeclaration(sourceFile:ts.SourceFile, typeName:string): TypeScriptTypeDeclaration { - let result:TypeScriptTypeDeclaration = null; +function getTopLevelDeclaration(sourceFile:ts.SourceFile, typeName:string): TSTopLevelDeclare { + let result:TSTopLevelDeclare = null; visitTopLevelDeclarations(sourceFile, (node) => { - if (node.name.text === typeName) { - result = node; - return true /*stop*/; + if (isDeclaration(node)) { + if (node.name.text === typeName) { + result = node; + return true /*stop*/; + } + return false /*continue*/; } - return false /*continue*/; + // node is ts.VariableStatement + return (getNodeText(sourceFile, node).indexOf(typeName) >= 0); }); return result; } @@ -95,13 +114,66 @@ function getNodeText(sourceFile:ts.SourceFile, node:ts.Node): string { } -function getMassagedTopLevelDeclarationText(sourceFile:ts.SourceFile, declaration: TypeScriptTypeDeclaration): string { +function getMassagedTopLevelDeclarationText(sourceFile:ts.SourceFile, declaration: TSTopLevelDeclare): string { let result = getNodeText(sourceFile, declaration); result = result.replace(/export default/g, 'export'); result = result.replace(/export declare/g, 'export'); return result; } +function format(text:string): string { + let options = getDefaultOptions(); + + // Parse the source text + let sourceFile = ts.createSourceFile('file.ts', text, ts.ScriptTarget.Latest, /*setParentPointers*/ true); + + // Get the formatting edits on the input sources + let edits = (ts).formatting.formatDocument(sourceFile, getRuleProvider(options), options); + + // Apply the edits on the input code + return applyEdits(text, edits); + + function getRuleProvider(options: ts.FormatCodeOptions) { + // Share this between multiple formatters using the same options. + // This represents the bulk of the space the formatter uses. + let ruleProvider = new (ts).formatting.RulesProvider(); + ruleProvider.ensureUpToDate(options); + return ruleProvider; + } + + function applyEdits(text: string, edits: ts.TextChange[]): string { + // Apply edits in reverse on the existing text + let result = text; + for (let i = edits.length - 1; i >= 0; i--) { + let change = edits[i]; + let head = result.slice(0, change.span.start); + let tail = result.slice(change.span.start + change.span.length) + result = head + change.newText + tail; + } + return result; + } + + function getDefaultOptions(): ts.FormatCodeOptions { + return { + IndentSize: 4, + TabSize: 4, + NewLineCharacter: '\r\n', + ConvertTabsToSpaces: true, + IndentStyle: ts.IndentStyle.Block, + + InsertSpaceAfterCommaDelimiter: true, + InsertSpaceAfterSemicolonInForStatements: true, + InsertSpaceBeforeAndAfterBinaryOperators: true, + InsertSpaceAfterKeywordsInControlFlowStatements: true, + InsertSpaceAfterFunctionKeywordForAnonymousFunctions: false, + InsertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false, + InsertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: false, + InsertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: true, + PlaceOpenBraceOnNewLineForFunctions: false, + PlaceOpenBraceOnNewLineForControlBlocks: false, + }; + } +} var recipe = fs.readFileSync(path.join(__dirname, './monaco-editor.d.ts.recipe')).toString(); var lines = recipe.split(/\r\n|\n|\r/); @@ -150,4 +222,13 @@ lines.forEach(line => { result.push(line); }); -fs.writeFileSync(path.join(__dirname, './monaco-editor.d.ts'), result.join('\n')); +let resultTxt = result.join('\n'); +resultTxt = resultTxt.replace(/\beditorCommon\./g, ''); +resultTxt = resultTxt.replace(/\bEventaction).addBulkListener((events: IEmitterEvent[]) => { + let l = (action).addBulkListener2((events: EmitterEvent[]) => { if (!this.builder) { // we have not been rendered yet, so there @@ -56,7 +56,7 @@ export class BaseActionItem extends EventEmitter implements IActionItem { return; } - events.forEach((event: IEmitterEvent) => { + events.forEach((event: EmitterEvent) => { switch (event.getType()) { case Action.ENABLED: @@ -171,7 +171,7 @@ export class BaseActionItem extends EventEmitter implements IActionItem { // implement in subclass } - public _updateUnknown(event: IEmitterEvent): void { + public _updateUnknown(event: EmitterEvent): void { // can implement in subclass } @@ -188,7 +188,7 @@ export class BaseActionItem extends EventEmitter implements IActionItem { this.gesture = null; } - lifecycle.cAll(this._callOnDispose); + this._callOnDispose = lifecycle.dispose(this._callOnDispose); } } @@ -334,13 +334,13 @@ export class ProgressItem extends BaseActionItem { error.textContent = '!'; $(error).addClass('tag', 'error'); - this.callOnDispose.push(this.addListener(CommonEventType.BEFORE_RUN, () => { + this.callOnDispose.push(this.addListener2(CommonEventType.BEFORE_RUN, () => { $(progress).addClass('active'); $(done).removeClass('active'); $(error).removeClass('active'); })); - this.callOnDispose.push(this.addListener(CommonEventType.RUN, (result) => { + this.callOnDispose.push(this.addListener2(CommonEventType.RUN, (result) => { $(progress).removeClass('active'); if (result.error) { $(done).removeClass('active'); @@ -359,7 +359,6 @@ export class ProgressItem extends BaseActionItem { } public dispose(): void { - lifecycle.cAll(this.callOnDispose); super.dispose(); } } @@ -571,7 +570,7 @@ export class ActionBar extends EventEmitter implements IActionRunner { item.actionRunner = this._actionRunner; item.setActionContext(this.context); - this.addEmitter(item); + this.addEmitter2(item); item.render(actionItemElement); if (index === null || index < 0 || index >= this.actionsList.children.length) { diff --git a/src/vs/base/browser/ui/toolbar/toolbar.ts b/src/vs/base/browser/ui/toolbar/toolbar.ts index c1a33ba5c9f..808bd86438d 100644 --- a/src/vs/base/browser/ui/toolbar/toolbar.ts +++ b/src/vs/base/browser/ui/toolbar/toolbar.ts @@ -14,7 +14,6 @@ import types = require('vs/base/common/types'); import {Action, IActionRunner, IAction} from 'vs/base/common/actions'; import {ActionBar, ActionsOrientation, IActionItemProvider, BaseActionItem} from 'vs/base/browser/ui/actionbar/actionbar'; import {IContextMenuProvider, DropdownMenu, IActionProvider, ILabelRenderer, IDropdownMenuOptions} from 'vs/base/browser/ui/dropdown/dropdown'; -import {ListenerUnbind} from 'vs/base/common/eventEmitter'; import {Keybinding} from 'vs/base/common/keyCodes'; export const CONTEXT = 'context.toolbar'; @@ -170,7 +169,7 @@ class ToggleMenuAction extends Action { export class DropdownMenuActionItem extends BaseActionItem { private menuActionsOrProvider: any; private dropdownMenu: DropdownMenu; - private toUnbind: ListenerUnbind; + private toUnbind: IDisposable; private contextMenuProvider: IContextMenuProvider; private actionItemProvider: IActionItemProvider; private keybindings: (action: IAction) => Keybinding; @@ -226,7 +225,7 @@ export class DropdownMenuActionItem extends BaseActionItem { }; // Reemit events for running actions - this.toUnbind = this.addEmitter(this.dropdownMenu); + this.toUnbind = this.addEmitter2(this.dropdownMenu); } public show(): void { @@ -236,7 +235,7 @@ export class DropdownMenuActionItem extends BaseActionItem { } public dispose(): void { - this.toUnbind(); + this.toUnbind.dispose(); this.dropdownMenu.dispose(); super.dispose(); diff --git a/src/vs/base/common/actions.ts b/src/vs/base/common/actions.ts index 58f9b721b0f..840d99fec32 100644 --- a/src/vs/base/common/actions.ts +++ b/src/vs/base/common/actions.ts @@ -5,7 +5,7 @@ 'use strict'; import {TPromise} from 'vs/base/common/winjs.base'; -import { IEventEmitter, EventEmitter, ListenerCallback, IBulkListenerCallback, ListenerUnbind } from 'vs/base/common/eventEmitter'; +import { IEventEmitter, EventEmitter } from 'vs/base/common/eventEmitter'; import {IDisposable} from 'vs/base/common/lifecycle'; import * as Events from 'vs/base/common/events'; @@ -199,74 +199,6 @@ export class Action extends EventEmitter implements IAction { } } -class ProxyAction extends Action implements IEventEmitter { - - constructor(private delegate: Action, private runHandler: (e: any) => void) { - super(delegate.id, delegate.label, delegate.class, delegate.enabled, null); - } - - public get id(): string { - return this.delegate.id; - } - - public get label(): string { - return this.delegate.label; - } - - public set label(value: string) { - this.delegate.label = value; - } - - public get class(): string { - return this.delegate.class; - } - - public set class(value: string) { - this.delegate.class = value; - } - - public get enabled(): boolean { - return this.delegate.enabled; - } - - public set enabled(value: boolean) { - this.delegate.enabled = value; - } - - public get checked(): boolean { - return this.delegate.checked; - } - - public set checked(value: boolean) { - this.delegate.checked = value; - } - - public run(event?: any): TPromise { - this.runHandler(event); - return this.delegate.run(event); - } - - public addListener(eventType: string, listener: ListenerCallback): ListenerUnbind { - return this.delegate.addListener(eventType, listener); - } - - public addBulkListener(listener: IBulkListenerCallback): ListenerUnbind { - return this.delegate.addBulkListener(listener); - } - - public addEmitter(eventEmitter: IEventEmitter, emitterType?: string): ListenerUnbind { - return this.delegate.addEmitter(eventEmitter, emitterType); - } - - public addEmitterTypeListener(eventType: string, emitterType: string, listener: ListenerCallback): ListenerUnbind { - return this.delegate.addEmitterTypeListener(eventType, emitterType, listener); - } - - public emit(eventType: string, data?: any): void { - this.delegate.emit(eventType, data); - } -} - export interface IRunEvent { action: IAction; result?: any; diff --git a/src/vs/base/common/eventEmitter.ts b/src/vs/base/common/eventEmitter.ts index 6244c03be62..872dd0637c7 100644 --- a/src/vs/base/common/eventEmitter.ts +++ b/src/vs/base/common/eventEmitter.ts @@ -5,23 +5,16 @@ 'use strict'; import Errors = require('vs/base/common/errors'); -import Lifecycle = require('vs/base/common/lifecycle'); +import {IDisposable} from 'vs/base/common/lifecycle'; -export interface IEmitterEvent { - getType():string; - getData():any; -} - -export class EmitterEvent implements IEmitterEvent { +export class EmitterEvent { private _type:string; private _data:any; - private _emitterType:string; - constructor(eventType:string=null, data:any=null, emitterType:string=null) { + constructor(eventType:string=null, data:any=null) { this._type = eventType; this._data = data; - this._emitterType = emitterType; } public getType():string { @@ -31,37 +24,21 @@ export class EmitterEvent implements IEmitterEvent { public getData():any { return this._data; } - - public getEmitterType():string { - return this._emitterType; - } } export interface ListenerCallback { (value:any):void; } -export interface IBulkListenerCallback { - (value:IEmitterEvent[]):void; +export interface BulkListenerCallback { + (value:EmitterEvent[]):void; } -export interface ListenerUnbind { - ():void; -} - -export interface IEventEmitter extends Lifecycle.IDisposable { - addListener(eventType:string, listener:ListenerCallback):ListenerUnbind; - addListener2(eventType:string, listener:ListenerCallback):Lifecycle.IDisposable; - addOneTimeListener(eventType:string, listener:ListenerCallback):ListenerUnbind; - - addBulkListener(listener:IBulkListenerCallback):ListenerUnbind; - addBulkListener2(listener:IBulkListenerCallback):Lifecycle.IDisposable; - - addEmitter(eventEmitter:IEventEmitter, emitterType?:string):ListenerUnbind; - addEmitter2(eventEmitter:IEventEmitter, emitterType?:string):Lifecycle.IDisposable; - - addEmitterTypeListener(eventType:string, emitterType:string, listener:ListenerCallback):ListenerUnbind; - emit(eventType:string, data?:any):void; +export interface IEventEmitter extends IDisposable { + addListener2(eventType:string, listener:ListenerCallback):IDisposable; + addOneTimeDisposableListener(eventType:string, listener:ListenerCallback):IDisposable; + addBulkListener2(listener:BulkListenerCallback):IDisposable; + addEmitter2(eventEmitter:IEventEmitter):IDisposable; } export interface IListenersMap { @@ -99,7 +76,7 @@ export class EventEmitter implements IEventEmitter { this._allowedEventTypes = null; } - public addListener(eventType:string, listener:ListenerCallback):ListenerUnbind { + private addListener(eventType:string, listener:ListenerCallback):IDisposable { if (eventType === '*') { throw new Error('Use addBulkListener(listener) to register your listener!'); } @@ -115,73 +92,56 @@ export class EventEmitter implements IEventEmitter { } var bound = this; - return () => { - if (!bound) { - // Already called - return; - } - - bound._removeListener(eventType, listener); - - // Prevent leakers from holding on to the event emitter - bound = null; - listener = null; - }; - } - - public addListener2(eventType:string, listener:ListenerCallback):Lifecycle.IDisposable { - var dispose = this.addListener(eventType, listener); return { - dispose: dispose + dispose: () => { + if (!bound) { + // Already called + return; + } + + bound._removeListener(eventType, listener); + + // Prevent leakers from holding on to the event emitter + bound = null; + listener = null; + } }; } - public on(eventType:string, listener:ListenerCallback):ListenerUnbind { + public addListener2(eventType:string, listener:ListenerCallback):IDisposable { return this.addListener(eventType, listener); } - public addOneTimeListener(eventType:string, listener:ListenerCallback):ListenerUnbind { - var unbind:ListenerUnbind = this.addListener(eventType, function(value:any) { - unbind(); + private addOneTimeListener(eventType:string, listener:ListenerCallback):IDisposable { + var unbind = this.addListener(eventType, (value:any) => { + unbind.dispose(); listener(value); }); return unbind; } - public addOneTimeDisposableListener(eventType:string, listener:ListenerCallback):Lifecycle.IDisposable { - var dispose = this.addOneTimeListener(eventType, listener); - return { - dispose: dispose - }; + public addOneTimeDisposableListener(eventType:string, listener:ListenerCallback):IDisposable { + return this.addOneTimeListener(eventType, listener); } - public addBulkListener(listener:IBulkListenerCallback):ListenerUnbind { + private addBulkListener(listener:BulkListenerCallback):IDisposable { this._bulkListeners.push(listener); - return () => { - this._removeBulkListener(listener); - }; - } - - public addBulkListener2(listener:IBulkListenerCallback):Lifecycle.IDisposable { - var dispose = this.addBulkListener(listener); return { - dispose: dispose + dispose: () => { + this._removeBulkListener(listener); + } }; } - public addEmitter(eventEmitter:IEventEmitter, emitterType:string=null):ListenerUnbind { - return eventEmitter.addBulkListener((events:IEmitterEvent[]):void => { - var newEvents = events; + public addBulkListener2(listener:BulkListenerCallback):IDisposable { + return this.addBulkListener(listener); + } - if (emitterType) { - // If the emitter has an emitterType, recreate events - newEvents = []; - for (var i = 0, len = events.length; i < len; i++) { - newEvents.push(new EmitterEvent(events[i].getType(), events[i].getData(), emitterType)); - } - } + private addEmitter(eventEmitter:IEventEmitter):IDisposable { + return eventEmitter.addBulkListener2((events:EmitterEvent[]):void => { + var newEvents = events; if (this._deferredCnt === 0) { this._emitEvents(newEvents); @@ -192,23 +152,8 @@ export class EventEmitter implements IEventEmitter { }); } - public addEmitter2(eventEmitter:IEventEmitter, emitterType?:string):Lifecycle.IDisposable { - var dispose = this.addEmitter(eventEmitter, emitterType); - return { - dispose: dispose - }; - } - - public addEmitterTypeListener(eventType:string, emitterType:string, listener:ListenerCallback):ListenerUnbind { - if (emitterType) { - if (eventType === '*') { - throw new Error('Bulk listeners cannot specify an emitter type'); - } - - return this.addListener(eventType + '/' + emitterType, listener); - } else { - return this.addListener(eventType, listener); - } + public addEmitter2(eventEmitter:IEventEmitter):IDisposable { + return this.addEmitter(eventEmitter); } private _removeListener(eventType:string, listener:ListenerCallback): void { @@ -224,7 +169,7 @@ export class EventEmitter implements IEventEmitter { } } - private _removeBulkListener(listener:IBulkListenerCallback): void { + private _removeBulkListener(listener:BulkListenerCallback): void { for (var i = 0, len = this._bulkListeners.length; i < len; i++) { if (this._bulkListeners[i] === listener) { this._bulkListeners.splice(i, 1); @@ -257,9 +202,6 @@ export class EventEmitter implements IEventEmitter { var e = events[i]; this._emitToSpecificTypeListeners(e.getType(), e.getData()); - if (e.getEmitterType()) { - this._emitToSpecificTypeListeners(e.getType() + '/' + e.getEmitterType(), e.getData()); - } } } diff --git a/src/vs/base/common/lifecycle.ts b/src/vs/base/common/lifecycle.ts index 12268356fde..0ad5adb3487 100644 --- a/src/vs/base/common/lifecycle.ts +++ b/src/vs/base/common/lifecycle.ts @@ -37,32 +37,6 @@ export function toDisposable(...fns: (() => void)[]): IDisposable { return combinedDisposable(fns.map(fn => ({ dispose: fn }))); } -function callAll(arg: any): any { - if (!arg) { - return null; - } else if (typeof arg === 'function') { - arg(); - return null; - } else if (Array.isArray(arg)) { - while (arg.length > 0) { - arg.pop()(); - } - return arg; - } else { - return null; - } -} - -export interface CallAll { - (fn: Function): Function; - (fn: Function[]): Function[]; -} - -/** - * Calls all functions that are being passed to it. - */ -export const cAll: CallAll = callAll; - export abstract class Disposable implements IDisposable { private _toDispose: IDisposable[]; diff --git a/src/vs/base/parts/quickopen/browser/quickOpenWidget.ts b/src/vs/base/parts/quickopen/browser/quickOpenWidget.ts index 01d7c2fb65f..ce8b7f866ff 100644 --- a/src/vs/base/parts/quickopen/browser/quickOpenWidget.ts +++ b/src/vs/base/parts/quickopen/browser/quickOpenWidget.ts @@ -80,7 +80,7 @@ export class QuickOpenWidget implements IModelProvider { private visible: boolean; private isLoosingFocus: boolean; private callbacks: IQuickOpenCallbacks; - private toUnbind: { (): void; }[]; + private toUnbind: IDisposable[]; private currentInputToken: string; private quickNavigateConfiguration: IQuickNavigateConfiguration; private container: HTMLElement; @@ -198,11 +198,11 @@ export class QuickOpenWidget implements IModelProvider { this.treeElement = this.tree.getHTMLElement(); // Handle Focus and Selection event - this.toUnbind.push(this.tree.addListener(EventType.FOCUS, (event: IFocusEvent) => { + this.toUnbind.push(this.tree.addListener2(EventType.FOCUS, (event: IFocusEvent) => { this.elementFocused(event.focus, event); })); - this.toUnbind.push(this.tree.addListener(EventType.SELECTION, (event: ISelectionEvent) => { + this.toUnbind.push(this.tree.addListener2(EventType.SELECTION, (event: ISelectionEvent) => { if (event.selection && event.selection.length > 0) { this.elementSelected(event.selection[0], event); } @@ -839,9 +839,7 @@ export class QuickOpenWidget implements IModelProvider { } public dispose(): void { - while (this.toUnbind.length) { - this.toUnbind.pop()(); - } + this.toUnbind = dispose(this.toUnbind); this.progressBar.dispose(); this.inputBox.dispose(); diff --git a/src/vs/base/parts/tree/browser/tree.ts b/src/vs/base/parts/tree/browser/tree.ts index 2915e3c4f9a..c20a5bba7af 100644 --- a/src/vs/base/parts/tree/browser/tree.ts +++ b/src/vs/base/parts/tree/browser/tree.ts @@ -14,6 +14,8 @@ import { ScrollbarVisibility } from 'vs/base/browser/ui/scrollbar/scrollableElem export interface ITree extends Events.IEventEmitter { + emit(eventType:string, data?:any):void; + /** * Returns the tree's DOM element. */ diff --git a/src/vs/base/parts/tree/browser/treeImpl.ts b/src/vs/base/parts/tree/browser/treeImpl.ts index d75bd92cbfd..a614cd10ae9 100644 --- a/src/vs/base/parts/tree/browser/treeImpl.ts +++ b/src/vs/base/parts/tree/browser/treeImpl.ts @@ -76,8 +76,8 @@ export class Tree extends Events.EventEmitter implements _.ITree { this.view.setModel(this.model); - this.addEmitter(this.model); - this.addEmitter(this.view); + this.addEmitter2(this.model); + this.addEmitter2(this.view); } public getHTMLElement(): HTMLElement { diff --git a/src/vs/base/parts/tree/browser/treeModel.ts b/src/vs/base/parts/tree/browser/treeModel.ts index 5dbb33dc5a7..1b80259f5aa 100644 --- a/src/vs/base/parts/tree/browser/treeModel.ts +++ b/src/vs/base/parts/tree/browser/treeModel.ts @@ -81,13 +81,13 @@ export class Lock { var lock = this.getLock(item); if (lock) { - var unbindListener: Events.ListenerUnbind; + var unbindListener: IDisposable; return new WinJS.Promise((c, e) => { - unbindListener = lock.addOneTimeListener('unlock', () => { + unbindListener = lock.addOneTimeDisposableListener('unlock', () => { return this.run(item, fn).then(c, e); }); - }, () => unbindListener()); + }, () => { unbindListener.dispose(); }); } var result: WinJS.Promise; diff --git a/src/vs/base/parts/tree/browser/treeView.ts b/src/vs/base/parts/tree/browser/treeView.ts index 4dc7492aaae..612cc6d1b72 100644 --- a/src/vs/base/parts/tree/browser/treeView.ts +++ b/src/vs/base/parts/tree/browser/treeView.ts @@ -401,7 +401,7 @@ export class TreeView extends HeightMap { private static currentExternalDragAndDropData: _.IDragAndDropData = null; private context: IViewContext; - private modelListeners: { (): void; }[]; + private modelListeners: Lifecycle.IDisposable[]; private model: Model.TreeModel; private viewListeners: Lifecycle.IDisposable[]; @@ -663,7 +663,7 @@ export class TreeView extends HeightMap { this.releaseModel(); this.model = newModel; - this.modelListeners.push(this.model.addBulkListener((e) => this.onModelEvents(e))); + this.modelListeners.push(this.model.addBulkListener2((e) => this.onModelEvents(e))); } private onModelEvents(events:any[]): void { @@ -1588,9 +1588,7 @@ export class TreeView extends HeightMap { private releaseModel(): void { if (this.model) { - while (this.modelListeners.length) { - this.modelListeners.pop()(); - } + this.modelListeners = Lifecycle.dispose(this.modelListeners); this.model = null; } } diff --git a/src/vs/base/parts/tree/test/browser/treeModel.test.ts b/src/vs/base/parts/tree/test/browser/treeModel.test.ts index 8a797e1bab8..de245ea490a 100644 --- a/src/vs/base/parts/tree/test/browser/treeModel.test.ts +++ b/src/vs/base/parts/tree/test/browser/treeModel.test.ts @@ -1302,23 +1302,23 @@ suite('TreeModel - Dynamic data model', () => { model.collapse('father'); var times = 0; - var listener = dataModel.addListener('getChildren', (element) => { + var listener = dataModel.addListener2('getChildren', (element) => { times++; assert.equal(element, 'grandfather'); }); model.refresh('grandfather').done(() => { assert.equal(times, 1); - listener(); + listener.dispose(); - listener = dataModel.addListener('getChildren', (element) => { + listener = dataModel.addListener2('getChildren', (element) => { times++; assert.equal(element, 'father'); }); model.expand('father').done(() => { assert.equal(times, 2); - listener(); + listener.dispose(); done(); }); }); @@ -1351,8 +1351,8 @@ suite('TreeModel - Dynamic data model', () => { var getTimes = 0; var gotTimes = 0; - var getListener = dataModel.addListener('getChildren', (element) => { getTimes++; }); - var gotListener = dataModel.addListener('gotChildren', (element) => { gotTimes++; }); + var getListener = dataModel.addListener2('getChildren', (element) => { getTimes++; }); + var gotListener = dataModel.addListener2('gotChildren', (element) => { gotTimes++; }); var p1 = model.refresh('father'); assert.equal(getTimes, 1); @@ -1373,8 +1373,8 @@ suite('TreeModel - Dynamic data model', () => { assert.equal(nav.next().id, 'sister'); assert.equal(nav.next() && false, null); - getListener(); - gotListener(); + getListener.dispose(); + gotListener.dispose(); done(); }); }); @@ -1399,10 +1399,10 @@ suite('TreeModel - Dynamic data model', () => { counter.listen(model, 'item:refresh', (e) => { refreshTimes++; }); var getTimes = 0; - var getListener = dataModel.addListener('getChildren', (element) => { getTimes++; }); + var getListener = dataModel.addListener2('getChildren', (element) => { getTimes++; }); var gotTimes = 0; - var gotListener = dataModel.addListener('gotChildren', (element) => { gotTimes++; }); + var gotListener = dataModel.addListener2('gotChildren', (element) => { gotTimes++; }); var p1, p2; @@ -1455,8 +1455,8 @@ suite('TreeModel - Dynamic data model', () => { assert.equal(nav.next().id, 'son'); assert.equal(nav.next() && false, null); - getListener(); - gotListener(); + getListener.dispose(); + gotListener.dispose(); done(); }); }); @@ -1479,8 +1479,8 @@ suite('TreeModel - Dynamic data model', () => { var getTimes = 0; var gotTimes = 0; - var getListener = dataModel.addListener('getChildren', (element) => { getTimes++; }); - var gotListener = dataModel.addListener('gotChildren', (element) => { gotTimes++; }); + var getListener = dataModel.addListener2('getChildren', (element) => { getTimes++; }); + var gotListener = dataModel.addListener2('gotChildren', (element) => { gotTimes++; }); var p1, p2; @@ -1521,8 +1521,8 @@ suite('TreeModel - Dynamic data model', () => { assert.equal(nav.next().id, 'son'); assert.equal(nav.next() && false, null); - getListener(); - gotListener(); + getListener.dispose(); + gotListener.dispose(); done(); }); }); diff --git a/src/vs/base/test/common/eventEmitter.test.ts b/src/vs/base/test/common/eventEmitter.test.ts index 19dcc0e6c9e..ff206fbc94a 100644 --- a/src/vs/base/test/common/eventEmitter.test.ts +++ b/src/vs/base/test/common/eventEmitter.test.ts @@ -21,7 +21,7 @@ suite('EventEmitter', () => { test('add listener, emit other event type', function () { var didCall = false; - eventEmitter.addListener('eventType1', function (e) { + eventEmitter.addListener2('eventType1', function (e) { didCall = true; }); eventEmitter.emit('eventType2', {}); @@ -30,7 +30,7 @@ suite('EventEmitter', () => { test('add listener, emit event', function () { var didCall = false; - eventEmitter.addListener('eventType', function (e) { + eventEmitter.addListener2('eventType', function (e) { didCall = true; }); eventEmitter.emit('eventType', {}); @@ -39,11 +39,11 @@ suite('EventEmitter', () => { test('add 2 listeners, emit event', function () { var didCallFirst = false; - eventEmitter.addListener('eventType', function (e) { + eventEmitter.addListener2('eventType', function (e) { didCallFirst = true; }); var didCallSecond = false; - eventEmitter.addListener('eventType', function (e) { + eventEmitter.addListener2('eventType', function (e) { didCallSecond = true; }); eventEmitter.emit('eventType', {}); @@ -53,22 +53,22 @@ suite('EventEmitter', () => { test('add 1 listener, remove it, emit event', function () { var didCall = false; - var remove = eventEmitter.addListener('eventType', function (e) { + var remove = eventEmitter.addListener2('eventType', function (e) { didCall = true; }); - remove(); + remove.dispose(); eventEmitter.emit('eventType', {}); assert(!didCall); }); test('add 2 listeners, emit event, remove one while processing', function () { var firstCallCount = 0; - var remove1 = eventEmitter.addListener('eventType', function (e) { + var remove1 = eventEmitter.addListener2('eventType', function (e) { firstCallCount++; - remove1(); + remove1.dispose(); }); var secondCallCount = 0; - eventEmitter.addListener('eventType', function (e) { + eventEmitter.addListener2('eventType', function (e) { secondCallCount++; }); eventEmitter.emit('eventType', {}); @@ -79,7 +79,7 @@ suite('EventEmitter', () => { test('event object is assert', function () { var data: any; - eventEmitter.addListener('eventType', function (e) { + eventEmitter.addListener2('eventType', function (e) { data = e.data; }); eventEmitter.emit('eventType', { data: 5 }); @@ -88,7 +88,7 @@ suite('EventEmitter', () => { test('deferred emit', function () { var calledCount = 0; - eventEmitter.addListener('eventType', function (e) { + eventEmitter.addListener2('eventType', function (e) { calledCount++; }); eventEmitter.deferredEmit(function () { @@ -103,11 +103,11 @@ suite('EventEmitter', () => { test('deferred emit maintains events order', function () { var order = 0; - eventEmitter.addListener('eventType2', function (e) { + eventEmitter.addListener2('eventType2', function (e) { order++; assert.equal(order, 1); }); - eventEmitter.addListener('eventType1', function (e) { + eventEmitter.addListener2('eventType1', function (e) { order++; assert.equal(order, 2); }); @@ -120,7 +120,7 @@ suite('EventEmitter', () => { test('deferred emit maintains events order for bulk listeners', function () { var count = 0; - eventEmitter.addBulkListener(function (events) { + eventEmitter.addBulkListener2(function (events) { assert.equal(events[0].getType(), 'eventType2'); assert.equal(events[1].getType(), 'eventType1'); count++; @@ -134,7 +134,7 @@ suite('EventEmitter', () => { test('emit notifies bulk listeners', function () { var count = 0; - eventEmitter.addBulkListener(function (events) { + eventEmitter.addBulkListener2(function (events) { count++; }); eventEmitter.emit('eventType', {}); @@ -145,13 +145,13 @@ suite('EventEmitter', () => { var emitter = new EventEmitter(); var eventBus = new EventEmitter(); - eventBus.addEmitter(emitter, 'emitter1'); + eventBus.addEmitter2(emitter); var didCallFirst = false; - eventBus.addListener('eventType', function (e) { + eventBus.addListener2('eventType', function (e) { didCallFirst = true; }); var didCallSecond = false; - eventBus.addListener('eventType/emitter1', function (e) { + eventBus.addListener2('eventType', function (e) { didCallSecond = true; }); @@ -166,17 +166,13 @@ suite('EventEmitter', () => { var emitter2 = new EventEmitter(); var eventBus = new EventEmitter(); - eventBus.addEmitter(emitter1, 'emitter1'); - eventBus.addEmitter(emitter2, 'emitter2'); - eventBus.addListener('eventType1', function (e) { + eventBus.addEmitter2(emitter1); + eventBus.addEmitter2(emitter2); + eventBus.addListener2('eventType1', function (e) { assert(true); callCnt++; }); - eventBus.addListener('eventType1/emitter1', function (e) { - assert(true); - callCnt++; - }); - eventBus.addEmitterTypeListener('eventType1', 'emitter1', function (e) { + eventBus.addListener2('eventType1', function (e) { assert(true); callCnt++; }); @@ -196,12 +192,12 @@ suite('EventEmitter', () => { var emitter3 = new EventEmitter(); var emitter4 = new EventEmitter(); - emitter2.addEmitter(emitter1); - emitter3.addEmitter(emitter2); - emitter4.addEmitter(emitter3); + emitter2.addEmitter2(emitter1); + emitter3.addEmitter2(emitter2); + emitter4.addEmitter2(emitter3); var didCall = false; - emitter4.addListener('eventType', function (e) { + emitter4.addListener2('eventType', function (e) { didCall = true; }); @@ -213,16 +209,16 @@ suite('EventEmitter', () => { var emitter = new EventEmitter(); var actualCallOrder: string[] = []; - emitter.addListener('foo', function() { + emitter.addListener2('foo', function() { actualCallOrder.push('listener1-foo'); emitter.emit('bar'); }); - emitter.addListener('foo', function() { + emitter.addListener2('foo', function() { actualCallOrder.push('listener2-foo'); }); - emitter.addListener('bar', function() { + emitter.addListener2('bar', function() { actualCallOrder.push('listener2-bar'); }); @@ -239,7 +235,7 @@ suite('EventEmitter', () => { var emitter = new EventEmitter(); var actualCallOrder: string[] = []; - emitter.addListener('foo', function() { + emitter.addListener2('foo', function() { actualCallOrder.push('listener1-foo'); emitter.deferredEmit(() => { emitter.emit('bar'); @@ -247,10 +243,10 @@ suite('EventEmitter', () => { }); - emitter.addListener('foo', function() { + emitter.addListener2('foo', function() { actualCallOrder.push('listener2-foo'); }); - emitter.addListener('bar', function() { + emitter.addListener2('bar', function() { actualCallOrder.push('listener2-bar'); }); @@ -269,16 +265,16 @@ suite('EventEmitter', () => { var emitter = new OrderGuaranteeEventEmitter(); var actualCallOrder: string[] = []; - emitter.addListener('foo', function() { + emitter.addListener2('foo', function() { actualCallOrder.push('listener1-foo'); emitter.emit('bar'); }); - emitter.addListener('foo', function() { + emitter.addListener2('foo', function() { actualCallOrder.push('listener2-foo'); }); - emitter.addListener('bar', function() { + emitter.addListener2('bar', function() { actualCallOrder.push('listener2-bar'); }); @@ -295,7 +291,7 @@ suite('EventEmitter', () => { var emitter = new OrderGuaranteeEventEmitter(); var actualCallOrder: string[] = []; - emitter.addListener('foo', function() { + emitter.addListener2('foo', function() { actualCallOrder.push('listener1-foo'); emitter.deferredEmit(() => { emitter.emit('bar'); @@ -303,10 +299,10 @@ suite('EventEmitter', () => { }); - emitter.addListener('foo', function() { + emitter.addListener2('foo', function() { actualCallOrder.push('listener2-foo'); }); - emitter.addListener('bar', function() { + emitter.addListener2('bar', function() { actualCallOrder.push('listener2-bar'); }); diff --git a/src/vs/editor/browser/editorBrowser.ts b/src/vs/editor/browser/editorBrowser.ts index 03951ce0f96..969382def45 100644 --- a/src/vs/editor/browser/editorBrowser.ts +++ b/src/vs/editor/browser/editorBrowser.ts @@ -466,6 +466,16 @@ export interface IOverviewRuler { */ export interface ICodeEditor extends editorCommon.ICommonCodeEditor { + onMouseUp(listener: (e:IEditorMouseEvent)=>void): IDisposable; + onMouseDown(listener: (e:IEditorMouseEvent)=>void): IDisposable; + onContextMenu(listener: (e:IEditorMouseEvent)=>void): IDisposable; + onMouseMove(listener: (e:IEditorMouseEvent)=>void): IDisposable; + onMouseLeave(listener: (e:IEditorMouseEvent)=>void): IDisposable; + onKeyUp(listener: (e:IKeyboardEvent)=>void): IDisposable; + onKeyDown(listener: (e:IKeyboardEvent)=>void): IDisposable; + onDidLayoutChange(listener: (e:editorCommon.EditorLayoutInfo)=>void): IDisposable; + onDidScrollChange(listener: (e:editorCommon.IScrollEvent)=>void): IDisposable; + /** * Returns the editor's dom node */ diff --git a/src/vs/editor/browser/view/viewController.ts b/src/vs/editor/browser/view/viewController.ts index 766e5ec2da7..55fbe1efe52 100644 --- a/src/vs/editor/browser/view/viewController.ts +++ b/src/vs/editor/browser/view/viewController.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -import {IEventEmitter} from 'vs/base/common/eventEmitter'; +import {EventEmitter} from 'vs/base/common/eventEmitter'; import {IKeyboardEvent} from 'vs/base/browser/keyboardEvent'; import {Position} from 'vs/editor/common/core/position'; import * as editorCommon from 'vs/editor/common/editorCommon'; @@ -20,13 +20,13 @@ export class ViewController implements IViewController { private viewModel:IViewModel; private triggerCursorHandler:TriggerCursorHandler; - private outgoingEventBus:IEventEmitter; + private outgoingEventBus:EventEmitter; private keybindingService:IKeybindingService; constructor( viewModel:IViewModel, triggerCursorHandler:TriggerCursorHandler, - outgoingEventBus:IEventEmitter, + outgoingEventBus:EventEmitter, keybindingService:IKeybindingService ) { this.viewModel = viewModel; diff --git a/src/vs/editor/browser/view/viewEventDispatcher.ts b/src/vs/editor/browser/view/viewEventDispatcher.ts index 4218859b696..bf20e901f1d 100644 --- a/src/vs/editor/browser/view/viewEventDispatcher.ts +++ b/src/vs/editor/browser/view/viewEventDispatcher.ts @@ -4,14 +4,14 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -import {EmitterEvent, IEmitterEvent} from 'vs/base/common/eventEmitter'; +import {EmitterEvent} from 'vs/base/common/eventEmitter'; import {IViewEventBus, IViewEventHandler} from 'vs/editor/common/view/viewContext'; export class ViewEventDispatcher implements IViewEventBus { private _eventHandlerGateKeeper:(callback:()=>void)=>void; private _eventHandlers:IViewEventHandler[]; - private _eventQueue:IEmitterEvent[]; + private _eventQueue:EmitterEvent[]; private _isConsumingQueue:boolean; constructor(eventHandlerGateKeeper:(callback:()=>void)=>void) { @@ -53,7 +53,7 @@ export class ViewEventDispatcher implements IViewEventBus { } } - public emitMany(events:IEmitterEvent[]): void { + public emitMany(events:EmitterEvent[]): void { if (this._eventQueue) { this._eventQueue = this._eventQueue.concat(events); } else { diff --git a/src/vs/editor/browser/view/viewImpl.ts b/src/vs/editor/browser/view/viewImpl.ts index 574c007fee2..8a01ddc1bf5 100644 --- a/src/vs/editor/browser/view/viewImpl.ts +++ b/src/vs/editor/browser/view/viewImpl.ts @@ -5,7 +5,7 @@ 'use strict'; import {onUnexpectedError} from 'vs/base/common/errors'; -import {EventEmitter, IEmitterEvent, IEventEmitter, ListenerUnbind} from 'vs/base/common/eventEmitter'; +import {EventEmitter, EmitterEvent, IEventEmitter} from 'vs/base/common/eventEmitter'; import {IDisposable, dispose} from 'vs/base/common/lifecycle'; import * as timer from 'vs/base/common/timer'; import * as browser from 'vs/base/browser/browser'; @@ -49,7 +49,7 @@ export class View extends ViewEventHandler implements editorBrowser.IView, IDisp private eventDispatcher:ViewEventDispatcher; - private listenersToRemove:ListenerUnbind[]; + private listenersToRemove:IDisposable[]; private listenersToDispose:IDisposable[]; private layoutProvider: LayoutProvider; @@ -82,7 +82,7 @@ export class View extends ViewEventHandler implements editorBrowser.IView, IDisp private _isDisposed: boolean; private handleAccumulatedModelEventsTimeout:number; - private accumulatedModelEvents: IEmitterEvent[]; + private accumulatedModelEvents: EmitterEvent[]; private _renderAnimationFrame: IDisposable; private _keybindingService: IKeybindingService; @@ -148,7 +148,7 @@ export class View extends ViewEventHandler implements editorBrowser.IView, IDisp // This delayed processing of incoming model events acts as a guard against undesired/unexpected recursion. this.handleAccumulatedModelEventsTimeout = -1; this.accumulatedModelEvents = []; - this.listenersToRemove.push(model.addBulkListener((events:IEmitterEvent[]) => { + this.listenersToRemove.push(model.addBulkListener2((events:EmitterEvent[]) => { this.accumulatedModelEvents = this.accumulatedModelEvents.concat(events); if (this.handleAccumulatedModelEventsTimeout === -1) { this.handleAccumulatedModelEventsTimeout = setTimeout(() => { @@ -457,14 +457,7 @@ export class View extends ViewEventHandler implements editorBrowser.IView, IDisp return false; } public onScrollChanged(e:editorCommon.IScrollEvent): boolean { - this.outgoingEventBus.emit('scroll', { - scrollTop: this.layoutProvider.getScrollTop(), - scrollLeft: this.layoutProvider.getScrollLeft() - }); - this.outgoingEventBus.emit('scrollSize', { - scrollWidth: this.layoutProvider.getScrollWidth(), - scrollHeight: this.layoutProvider.getScrollHeight() - }); + this.outgoingEventBus.emit('scroll', e); return false; } public onViewFocusChanged(isFocused:boolean): boolean { @@ -494,11 +487,7 @@ export class View extends ViewEventHandler implements editorBrowser.IView, IDisp this.eventDispatcher.removeEventHandler(this); this.outgoingEventBus.dispose(); - this.listenersToRemove.forEach((element) => { - element(); - }); - this.listenersToRemove = []; - + this.listenersToRemove = dispose(this.listenersToRemove); this.listenersToDispose = dispose(this.listenersToDispose); this.keyboardHandler.dispose(); diff --git a/src/vs/editor/browser/widget/codeEditorWidget.ts b/src/vs/editor/browser/widget/codeEditorWidget.ts index 2df72cd3d74..19aecca1384 100644 --- a/src/vs/editor/browser/widget/codeEditorWidget.ts +++ b/src/vs/editor/browser/widget/codeEditorWidget.ts @@ -25,11 +25,40 @@ import * as editorBrowser from 'vs/editor/browser/editorBrowser'; import {EditorBrowserRegistry} from 'vs/editor/browser/editorBrowserExtensions'; import {Colorizer} from 'vs/editor/browser/standalone/colorizer'; import {View} from 'vs/editor/browser/view/viewImpl'; -import {Disposable} from 'vs/base/common/lifecycle'; +import {Disposable, IDisposable} from 'vs/base/common/lifecycle'; import Event, {Emitter} from 'vs/base/common/event'; +import {IKeyboardEvent} from 'vs/base/browser/keyboardEvent'; export class CodeEditorWidget extends CommonCodeEditor implements editorBrowser.ICodeEditor { + public onMouseUp(listener: (e:editorBrowser.IEditorMouseEvent)=>void): IDisposable { + return this.addListener2(editorCommon.EventType.MouseUp, listener); + } + public onMouseDown(listener: (e:editorBrowser.IEditorMouseEvent)=>void): IDisposable { + return this.addListener2(editorCommon.EventType.MouseDown, listener); + } + public onContextMenu(listener: (e:editorBrowser.IEditorMouseEvent)=>void): IDisposable { + return this.addListener2(editorCommon.EventType.ContextMenu, listener); + } + public onMouseMove(listener: (e:editorBrowser.IEditorMouseEvent)=>void): IDisposable { + return this.addListener2(editorCommon.EventType.MouseMove, listener); + } + public onMouseLeave(listener: (e:editorBrowser.IEditorMouseEvent)=>void): IDisposable { + return this.addListener2(editorCommon.EventType.MouseLeave, listener); + } + public onKeyUp(listener: (e:IKeyboardEvent)=>void): IDisposable { + return this.addListener2(editorCommon.EventType.KeyUp, listener); + } + public onKeyDown(listener: (e:IKeyboardEvent)=>void): IDisposable { + return this.addListener2(editorCommon.EventType.KeyDown, listener); + } + public onDidLayoutChange(listener: (e:editorCommon.EditorLayoutInfo)=>void): IDisposable { + return this.addListener2(editorCommon.EventType.EditorLayout, listener); + } + public onDidScrollChange(listener: (e:editorCommon.IScrollEvent)=>void): IDisposable { + return this.addListener2('scroll', listener); + } + protected domElement:HTMLElement; private _focusTracker: CodeEditorWidgetFocusTracker; diff --git a/src/vs/editor/browser/widget/diffEditorWidget.ts b/src/vs/editor/browser/widget/diffEditorWidget.ts index 781472c1905..aa574139b76 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget.ts @@ -8,7 +8,7 @@ import 'vs/css!./media/diffEditor'; import {IAction} from 'vs/base/common/actions'; import {RunOnceScheduler} from 'vs/base/common/async'; -import {EventEmitter, IEmitterEvent} from 'vs/base/common/eventEmitter'; +import {EventEmitter, EmitterEvent} from 'vs/base/common/eventEmitter'; import {IDisposable, dispose} from 'vs/base/common/lifecycle'; import * as objects from 'vs/base/common/objects'; import * as dom from 'vs/base/browser/dom'; @@ -26,11 +26,6 @@ import {CodeEditorWidget} from 'vs/editor/browser/widget/codeEditorWidget'; import {ViewLineToken, ViewLineTokens} from 'vs/editor/common/core/viewLineToken'; import {Configuration} from 'vs/editor/browser/config/configuration'; -interface IEditorScrollEvent { - scrollLeft: number; - scrollTop: number; -} - interface IEditorDiffDecorations { decorations:editorCommon.IModelDeltaDecoration[]; overviewZones:editorBrowser.OverviewRulerZone[]; @@ -129,6 +124,31 @@ var DIFF_EDITOR_ID = 0; export class DiffEditorWidget extends EventEmitter implements editorBrowser.IDiffEditor { + public onDidModelContentChange(listener: (e:editorCommon.IModelContentChangedEvent)=>void): IDisposable { + return this.addListener2(editorCommon.EventType.ModelContentChanged, listener); + } + public onDidModelModeChange(listener: (e:editorCommon.IModelModeChangedEvent)=>void): IDisposable { + return this.addListener2(editorCommon.EventType.ModelModeChanged, listener); + } + public onDidModelOptionsChange(listener: (e:editorCommon.IModelOptionsChangedEvent)=>void): IDisposable { + return this.addListener2(editorCommon.EventType.ModelOptionsChanged, listener); + } + public onDidConfigurationChange(listener: (e:editorCommon.IConfigurationChangedEvent)=>void): IDisposable { + return this.addListener2(editorCommon.EventType.ConfigurationChanged, listener); + } + public onDidCursorPositionChange(listener: (e:editorCommon.ICursorPositionChangedEvent)=>void): IDisposable { + return this.addListener2(editorCommon.EventType.CursorPositionChanged, listener); + } + public onDidCursorSelectionChange(listener: (e:editorCommon.ICursorSelectionChangedEvent)=>void): IDisposable { + return this.addListener2(editorCommon.EventType.CursorSelectionChanged, listener); + } + public onDidDispose(listener: ()=>void): IDisposable { + return this.addListener2(editorCommon.EventType.Disposed, listener); + } + public onDidUpdateDiff(listener: ()=>void): IDisposable { + return this.addListener2(editorCommon.EventType.DiffUpdated, listener); + } + private static ONE_OVERVIEW_WIDTH = 15; public static ENTIRE_DIFF_OVERVIEW_WIDTH = 30; private static UPDATE_DIFF_DECORATIONS_DELAY = 200; // ms @@ -327,13 +347,13 @@ export class DiffEditorWidget extends EventEmitter implements editorBrowser.IDif private _createLeftHandSideEditor(options:editorCommon.IDiffEditorOptions, instantiationService:IInstantiationService): void { this.originalEditor = instantiationService.createInstance(CodeEditorWidget, this._originalDomNode, this._adjustOptionsForLeftHandSide(options, this._originalIsEditable)); this._toDispose.push(this.originalEditor.addBulkListener2((events: any) => this._onOriginalEditorEvents(events))); - this._toDispose.push(this.addEmitter2(this.originalEditor, 'leftHandSide')); + this._toDispose.push(this.addEmitter2(this.originalEditor)); } private _createRightHandSideEditor(options:editorCommon.IDiffEditorOptions, instantiationService:IInstantiationService): void { this.modifiedEditor = instantiationService.createInstance(CodeEditorWidget, this._modifiedDomNode, this._adjustOptionsForRightHandSide(options)); this._toDispose.push(this.modifiedEditor.addBulkListener2((events: any) => this._onModifiedEditorEvents(events))); - this._toDispose.push(this.addEmitter2(this.modifiedEditor, 'rightHandSide')); + this._toDispose.push(this.addEmitter2(this.modifiedEditor)); } public destroy(): void { @@ -355,6 +375,8 @@ export class DiffEditorWidget extends EventEmitter implements editorBrowser.IDif this._strategy.dispose(); + this.emit(editorCommon.EventType.Disposed); + super.dispose(); } @@ -670,11 +692,11 @@ export class DiffEditorWidget extends EventEmitter implements editorBrowser.IDif //------------ end layouting methods - private _recomputeIfNecessary(events:IEmitterEvent[]): void { + private _recomputeIfNecessary(events:EmitterEvent[]): void { var changed = false; for (var i = 0; !changed && i < events.length; i++) { var type = events[i].getType(); - changed = changed || type === 'change' || type === editorCommon.EventType.ModelModeChanged; + changed = changed || type === editorCommon.EventType.ModelContentChanged || type === editorCommon.EventType.ModelModeChanged; } if (changed && this._isVisible) { // Clear previous timeout if necessary @@ -686,7 +708,7 @@ export class DiffEditorWidget extends EventEmitter implements editorBrowser.IDif } } - private _onOriginalEditorEvents(events:IEmitterEvent[]): void { + private _onOriginalEditorEvents(events:EmitterEvent[]): void { for (var i = 0; i < events.length; i++) { if (events[i].getType() === 'scroll') { this._onOriginalEditorScroll(events[i].getData()); @@ -698,15 +720,12 @@ export class DiffEditorWidget extends EventEmitter implements editorBrowser.IDif this._recomputeIfNecessary(events); } - private _onModifiedEditorEvents(events:IEmitterEvent[]): void { + private _onModifiedEditorEvents(events:EmitterEvent[]): void { for (var i = 0; i < events.length; i++) { if (events[i].getType() === 'scroll') { this._onModifiedEditorScroll(events[i].getData()); this._layoutOverviewViewport(); } - if (events[i].getType() === 'scrollSize') { - this._layoutOverviewViewport(); - } if (events[i].getType() === 'viewLayoutChanged') { this._layoutOverviewViewport(); } @@ -747,7 +766,7 @@ export class DiffEditorWidget extends EventEmitter implements editorBrowser.IDif { this._lineChanges = result; this._updateDecorationsRunner.schedule(); - this.emit(editorCommon.EventType.DiffUpdated, { editor: this, lineChanges: result }); + this.emit(editorCommon.EventType.DiffUpdated, { }); } }, (error) => { if (currentToken === this._diffComputationToken @@ -810,7 +829,10 @@ export class DiffEditorWidget extends EventEmitter implements editorBrowser.IDif return result; } - private _onOriginalEditorScroll(e:IEditorScrollEvent): void { + private _onOriginalEditorScroll(e:editorCommon.IScrollEvent): void { + if (!e.scrollTopChanged && !e.scrollLeftChanged) { + return; + } if (this._isHandlingScrollEvent) { return; } @@ -822,7 +844,10 @@ export class DiffEditorWidget extends EventEmitter implements editorBrowser.IDif this._isHandlingScrollEvent = false; } - private _onModifiedEditorScroll(e:IEditorScrollEvent): void { + private _onModifiedEditorScroll(e:editorCommon.IScrollEvent): void { + if (!e.scrollTopChanged && !e.scrollLeftChanged) { + return; + } if(this._isHandlingScrollEvent) { return; } @@ -1329,10 +1354,10 @@ class DiffEdtorWidgetSideBySide extends DiffEditorWidgetStyle implements IDiffEd this._sash.disable(); } - this._sash.on('start', () => this.onSashDragStart()); - this._sash.on('change', (e: ISashEvent) => this.onSashDrag(e)); - this._sash.on('end', () => this.onSashDragEnd()); - this._sash.on('reset', () => this.onSashReset()); + this._sash.addListener2('start', () => this.onSashDragStart()); + this._sash.addListener2('change', (e: ISashEvent) => this.onSashDrag(e)); + this._sash.addListener2('end', () => this.onSashDragEnd()); + this._sash.addListener2('reset', () => this.onSashReset()); } public dispose(): void { @@ -1594,7 +1619,7 @@ class DiffEdtorWidgetInline extends DiffEditorWidgetStyle implements IDiffEditor this.decorationsLeft = dataSource.getOriginalEditor().getLayoutInfo().decorationsLeft; this.toDispose = []; - this.toDispose.push(dataSource.getOriginalEditor().addListener2(editorCommon.EventType.EditorLayout, (layoutInfo:editorCommon.EditorLayoutInfo) => { + this.toDispose.push(dataSource.getOriginalEditor().onDidLayoutChange((layoutInfo:editorCommon.EditorLayoutInfo) => { if (this.decorationsLeft !== layoutInfo.decorationsLeft) { this.decorationsLeft = layoutInfo.decorationsLeft; dataSource.relayoutEditors(); diff --git a/src/vs/editor/browser/widget/embeddedCodeEditorWidget.ts b/src/vs/editor/browser/widget/embeddedCodeEditorWidget.ts index b1fe0a1564a..d1b53061f3a 100644 --- a/src/vs/editor/browser/widget/embeddedCodeEditorWidget.ts +++ b/src/vs/editor/browser/widget/embeddedCodeEditorWidget.ts @@ -8,7 +8,7 @@ import * as objects from 'vs/base/common/objects'; import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation'; import {IKeybindingService} from 'vs/platform/keybinding/common/keybindingService'; import {ITelemetryService} from 'vs/platform/telemetry/common/telemetry'; -import {EventType, ICodeEditorWidgetCreationOptions, IConfigurationChangedEvent, IEditorOptions} from 'vs/editor/common/editorCommon'; +import {ICodeEditorWidgetCreationOptions, IConfigurationChangedEvent, IEditorOptions} from 'vs/editor/common/editorCommon'; import {ICodeEditorService} from 'vs/editor/common/services/codeEditorService'; import {ICodeEditor} from 'vs/editor/browser/editorBrowser'; import {CodeEditorWidget} from 'vs/editor/browser/widget/codeEditorWidget'; @@ -35,7 +35,7 @@ export class EmbeddedCodeEditorWidget extends CodeEditorWidget { // Overwrite parent's options super.updateOptions(this._overwriteOptions); - this._lifetimeDispose.push(parentEditor.addListener2(EventType.ConfigurationChanged, (e:IConfigurationChangedEvent) => this._onParentConfigurationChanged(e))); + this._lifetimeDispose.push(parentEditor.onDidConfigurationChange((e:IConfigurationChangedEvent) => this._onParentConfigurationChanged(e))); } public getParentEditor(): ICodeEditor { diff --git a/src/vs/editor/common/commonCodeEditor.ts b/src/vs/editor/common/commonCodeEditor.ts index 76cd0cf08ff..8db13b98387 100644 --- a/src/vs/editor/common/commonCodeEditor.ts +++ b/src/vs/editor/common/commonCodeEditor.ts @@ -7,7 +7,7 @@ import * as nls from 'vs/nls'; import {IAction, IActionProvider, isAction} from 'vs/base/common/actions'; import {onUnexpectedError} from 'vs/base/common/errors'; -import {EventEmitter, IEventEmitter, ListenerUnbind} from 'vs/base/common/eventEmitter'; +import {EventEmitter, IEventEmitter} from 'vs/base/common/eventEmitter'; import {IDisposable, dispose} from 'vs/base/common/lifecycle'; import * as objects from 'vs/base/common/objects'; import * as timer from 'vs/base/common/timer'; @@ -36,6 +36,49 @@ var EDITOR_ID = 0; export abstract class CommonCodeEditor extends EventEmitter implements IActionProvider, editorCommon.ICommonCodeEditor { + public onDidModelContentChange(listener: (e:editorCommon.IModelContentChangedEvent)=>void): IDisposable { + return this.addListener2(editorCommon.EventType.ModelContentChanged, listener); + } + public onDidModelModeChange(listener: (e:editorCommon.IModelModeChangedEvent)=>void): IDisposable { + return this.addListener2(editorCommon.EventType.ModelModeChanged, listener); + } + public onDidModelOptionsChange(listener: (e:editorCommon.IModelOptionsChangedEvent)=>void): IDisposable { + return this.addListener2(editorCommon.EventType.ModelOptionsChanged, listener); + } + public onDidModelModeSupportChange(listener: (e:editorCommon.IModeSupportChangedEvent)=>void): IDisposable { + return this.addListener2(editorCommon.EventType.ModelModeSupportChanged, listener); + } + public onDidModelDecorationsChange(listener: (e:editorCommon.IModelDecorationsChangedEvent)=>void): IDisposable { + return this.addListener2(editorCommon.EventType.ModelDecorationsChanged, listener); + } + public onDidConfigurationChange(listener: (e:editorCommon.IConfigurationChangedEvent)=>void): IDisposable { + return this.addListener2(editorCommon.EventType.ConfigurationChanged, listener); + } + public onDidModelChange(listener: (e:editorCommon.IModelChangedEvent)=>void): IDisposable { + return this.addListener2(editorCommon.EventType.ModelChanged, listener); + } + public onDidCursorPositionChange(listener: (e:editorCommon.ICursorPositionChangedEvent)=>void): IDisposable { + return this.addListener2(editorCommon.EventType.CursorPositionChanged, listener); + } + public onDidCursorSelectionChange(listener: (e:editorCommon.ICursorSelectionChangedEvent)=>void): IDisposable { + return this.addListener2(editorCommon.EventType.CursorSelectionChanged, listener); + } + public onDidEditorTextFocus(listener: ()=>void): IDisposable { + return this.addListener2(editorCommon.EventType.EditorTextFocus, listener); + } + public onDidEditorTextBlur(listener: ()=>void): IDisposable { + return this.addListener2(editorCommon.EventType.EditorTextBlur, listener); + } + public onDidEditorFocus(listener: ()=>void): IDisposable { + return this.addListener2(editorCommon.EventType.EditorFocus, listener); + } + public onDidEditorBlur(listener: ()=>void): IDisposable { + return this.addListener2(editorCommon.EventType.EditorBlur, listener); + } + public onDidDispose(listener: ()=>void): IDisposable { + return this.addListener2(editorCommon.EventType.Disposed, listener); + } + protected domElement: IKeybindingScopeLocation; protected id:number; @@ -49,7 +92,7 @@ export abstract class CommonCodeEditor extends EventEmitter implements IActionPr // --- Members logically associated to a model protected model:editorCommon.IModel; - protected listenersToRemove:ListenerUnbind[]; + protected listenersToRemove:IDisposable[]; protected hasView: boolean; protected viewModel:ViewModel; @@ -153,7 +196,7 @@ export abstract class CommonCodeEditor extends EventEmitter implements IActionPr this._postDetachModelCleanup(this._detachModel()); this._configuration.dispose(); this._keybindingService.dispose(); - this.emit(editorCommon.EventType.Disposed, {}); + this.emit(editorCommon.EventType.Disposed); super.dispose(); } @@ -642,16 +685,20 @@ export abstract class CommonCodeEditor extends EventEmitter implements IActionPr } } - public addTypingListener(character:string, callback: () => void): ListenerUnbind { + public addTypingListener(character:string, callback: () => void): IDisposable { if (!this.cursor) { - return () => { - // no-op + return { + dispose: () => { + // no-op + } }; } this.cursor.addTypingListener(character, callback); - return () => { - if (this.cursor) { - this.cursor.removeTypingListener(character, callback); + return { + dispose: () => { + if (this.cursor) { + this.cursor.removeTypingListener(character, callback); + } } }; } @@ -730,7 +777,7 @@ export abstract class CommonCodeEditor extends EventEmitter implements IActionPr this._createView(); - this.listenersToRemove.push(this._getViewInternalEventBus().addBulkListener((events) => { + this.listenersToRemove.push(this._getViewInternalEventBus().addBulkListener2((events) => { for (var i = 0, len = events.length; i < len; i++) { var eventType = events[i].getType(); var e = events[i].getData(); @@ -746,10 +793,6 @@ export abstract class CommonCodeEditor extends EventEmitter implements IActionPr this.emit('scroll', e); break; - case 'scrollSize': - this.emit('scrollSize', e); - break; - case editorCommon.EventType.ViewFocusLost: this.emit(editorCommon.EventType.EditorTextBlur); break; @@ -792,7 +835,7 @@ export abstract class CommonCodeEditor extends EventEmitter implements IActionPr } })); - this.listenersToRemove.push(this.model.addBulkListener((events) => { + this.listenersToRemove.push(this.model.addBulkListener2((events) => { for (var i = 0, len = events.length; i < len; i++) { var eventType = events[i].getType(); var e = events[i].getData(); @@ -813,9 +856,7 @@ export abstract class CommonCodeEditor extends EventEmitter implements IActionPr break; case editorCommon.EventType.ModelContentChanged: - // TODO@Alex this.emit(editorCommon.EventType.ModelContentChanged, e); - this.emit('change', {}); break; case editorCommon.EventType.ModelOptionsChanged: @@ -838,7 +879,7 @@ export abstract class CommonCodeEditor extends EventEmitter implements IActionPr return allSelections.some(s => !s.isEmpty()); }; - this.listenersToRemove.push(this.cursor.addBulkListener((events) => { + this.listenersToRemove.push(this.cursor.addBulkListener2((events) => { var updateHasMultipleCursors = false, hasMultipleCursors = false, updateHasNonEmptySelection = false, @@ -910,10 +951,7 @@ export abstract class CommonCodeEditor extends EventEmitter implements IActionPr this.hasView = false; - this.listenersToRemove.forEach((element) => { - element(); - }); - this.listenersToRemove = []; + this.listenersToRemove = dispose(this.listenersToRemove); if (this.cursor) { this.cursor.dispose(); diff --git a/src/vs/editor/common/editorActionEnablement.ts b/src/vs/editor/common/editorActionEnablement.ts index 934b4214fcf..10add037488 100644 --- a/src/vs/editor/common/editorActionEnablement.ts +++ b/src/vs/editor/common/editorActionEnablement.ts @@ -5,7 +5,7 @@ 'use strict'; import {IDisposable, dispose} from 'vs/base/common/lifecycle'; -import {EventType, ICommonCodeEditor} from 'vs/editor/common/editorCommon'; +import {ICommonCodeEditor} from 'vs/editor/common/editorCommon'; export enum Behaviour { TextFocus = 1 << 0, @@ -115,15 +115,15 @@ class InternalEnablementState extends CachingEnablementState { this._callOnDispose = []; if (this._behaviour & Behaviour.TextFocus) { - this._callOnDispose.push(this.editor.addListener2(EventType.EditorTextFocus, () => this._updateTextFocus(true))); - this._callOnDispose.push(this.editor.addListener2(EventType.EditorTextBlur, () => this._updateTextFocus(false))); + this._callOnDispose.push(this.editor.onDidEditorTextFocus(() => this._updateTextFocus(true))); + this._callOnDispose.push(this.editor.onDidEditorTextBlur(() => this._updateTextFocus(false))); } if (this._behaviour & Behaviour.WidgetFocus) { - this._callOnDispose.push(this.editor.addListener2(EventType.EditorFocus, () => this._updateWidgetFocus(true))); - this._callOnDispose.push(this.editor.addListener2(EventType.EditorBlur, () => this._updateWidgetFocus(false))); + this._callOnDispose.push(this.editor.onDidEditorFocus(() => this._updateWidgetFocus(true))); + this._callOnDispose.push(this.editor.onDidEditorBlur(() => this._updateWidgetFocus(false))); } if (this._behaviour & Behaviour.Writeable) { - this._callOnDispose.push(this.editor.addListener2(EventType.ConfigurationChanged, (e) => this._update())); + this._callOnDispose.push(this.editor.onDidConfigurationChange((e) => this._update())); } } @@ -168,18 +168,18 @@ class InternalEnablementState extends CachingEnablementState { */ class DescentEnablementState extends CachingEnablementState { - private _callOnDispose:Function[] = []; + private _callOnDispose:IDisposable[] = []; constructor(behaviour:Behaviour, private editor:ICommonCodeEditor, private _action:IEditorAction) { super(); if (behaviour & Behaviour.UpdateOnModelChange) { - this._callOnDispose.push(this.editor.addListener(EventType.ModelChanged, () => this.reset())); - this._callOnDispose.push(this.editor.addListener(EventType.ModelModeChanged, () => this.reset())); - this._callOnDispose.push(this.editor.addListener(EventType.ModelModeSupportChanged, () => this.reset())); + this._callOnDispose.push(this.editor.onDidModelChange(() => this.reset())); + this._callOnDispose.push(this.editor.onDidModelModeChange(() => this.reset())); + this._callOnDispose.push(this.editor.onDidModelModeSupportChange(() => this.reset())); } if (behaviour & Behaviour.UpdateOnCursorPositionChange) { - this._callOnDispose.push(this.editor.addListener(EventType.CursorPositionChanged, () => this.reset())); + this._callOnDispose.push(this.editor.onDidCursorPositionChange(() => this.reset())); } } diff --git a/src/vs/editor/common/editorCommon.ts b/src/vs/editor/common/editorCommon.ts index 6139d3d244c..cb9854ca003 100644 --- a/src/vs/editor/common/editorCommon.ts +++ b/src/vs/editor/common/editorCommon.ts @@ -5,19 +5,19 @@ 'use strict'; import {IAction} from 'vs/base/common/actions'; -import Event from 'vs/base/common/event'; -import {IEventEmitter, ListenerUnbind} from 'vs/base/common/eventEmitter'; +import {IEventEmitter} from 'vs/base/common/eventEmitter'; import {IHTMLContentElement} from 'vs/base/common/htmlContent'; -import {KeyCode, KeyMod} from 'vs/base/common/keyCodes'; import URI from 'vs/base/common/uri'; import {TPromise} from 'vs/base/common/winjs.base'; import {IInstantiationService, IConstructorSignature1, IConstructorSignature2} from 'vs/platform/instantiation/common/instantiation'; import {ILineContext, IMode, IModeTransition, IToken} from 'vs/editor/common/modes'; import {ViewLineToken} from 'vs/editor/common/core/viewLineToken'; import {ScrollbarVisibility} from 'vs/base/browser/ui/scrollbar/scrollableElementOptions'; +import {IDisposable} from 'vs/base/common/lifecycle'; -export type KeyCode = KeyCode; -export type KeyMod = KeyMod; +export interface Event { + (listener: (e: T) => any, thisArg?: any): IDisposable; +} // --- position & range @@ -3049,7 +3049,17 @@ export interface ICommonEditorContributionDescriptor { /** * An editor. */ -export interface IEditor extends IEventEmitter { +export interface IEditor { + + onDidModelContentChange(listener: (e:IModelContentChangedEvent)=>void): IDisposable; + onDidModelModeChange(listener: (e:IModelModeChangedEvent)=>void): IDisposable; + onDidModelOptionsChange(listener: (e:IModelOptionsChangedEvent)=>void): IDisposable; + onDidConfigurationChange(listener: (e:IConfigurationChangedEvent)=>void): IDisposable; + onDidCursorPositionChange(listener: (e:ICursorPositionChangedEvent)=>void): IDisposable; + onDidCursorSelectionChange(listener: (e:ICursorSelectionChangedEvent)=>void): IDisposable; + onDidDispose(listener: ()=>void): IDisposable; + + dispose(): void; getId(): string; @@ -3322,6 +3332,16 @@ export interface IRangeWithMessage { export interface ICommonCodeEditor extends IEditor { + onDidModelChange(listener: (e:IModelChangedEvent)=>void): IDisposable; + onDidModelModeSupportChange(listener: (e:IModeSupportChangedEvent)=>void): IDisposable; + onDidModelDecorationsChange(listener: (e:IModelDecorationsChangedEvent)=>void): IDisposable; + + onDidEditorTextFocus(listener: ()=>void): IDisposable; + onDidEditorTextBlur(listener: ()=>void): IDisposable; + + onDidEditorFocus(listener: ()=>void): IDisposable; + onDidEditorBlur(listener: ()=>void): IDisposable; + /** * Returns true if this editor or one of its widgets has keyboard focus. */ @@ -3460,11 +3480,13 @@ export interface ICommonCodeEditor extends IEditor { * @param character Character to listen to. * @param callback Function to call when `character` is typed. */ - addTypingListener(character: string, callback: () => void): ListenerUnbind; + addTypingListener(character: string, callback: () => void): IDisposable; } export interface ICommonDiffEditor extends IEditor { + onDidUpdateDiff(listener: ()=>void): IDisposable; + /** * Type the getModel() of IEditor. */ diff --git a/src/vs/editor/common/services/bulkEdit.ts b/src/vs/editor/common/services/bulkEdit.ts index d468b19f7a2..8f093d66197 100644 --- a/src/vs/editor/common/services/bulkEdit.ts +++ b/src/vs/editor/common/services/bulkEdit.ts @@ -42,7 +42,7 @@ class ChangeRecorder { var changes: IStringDictionary = Object.create(null); - var stop = this._eventService.addListener(FileEventType.FILE_CHANGES,(event: FileChangesEvent) => { + var stop = this._eventService.addListener2(FileEventType.FILE_CHANGES,(event: FileChangesEvent) => { event.changes.forEach(change => { var key = String(change.resource), @@ -57,7 +57,7 @@ class ChangeRecorder { }); return { - stop, + stop: () => { stop.dispose(); }, hasChanged: (resource: URI) => !!changes[resource.toString()], allChanges: () => merge(values(changes)) }; diff --git a/src/vs/editor/common/services/modelServiceImpl.ts b/src/vs/editor/common/services/modelServiceImpl.ts index df2c358862e..6ed8495aa6e 100644 --- a/src/vs/editor/common/services/modelServiceImpl.ts +++ b/src/vs/editor/common/services/modelServiceImpl.ts @@ -7,7 +7,7 @@ import * as nls from 'vs/nls'; import {onUnexpectedError} from 'vs/base/common/errors'; import Event, {Emitter} from 'vs/base/common/event'; -import {IEmitterEvent} from 'vs/base/common/eventEmitter'; +import {EmitterEvent} from 'vs/base/common/eventEmitter'; import {IHTMLContentElement} from 'vs/base/common/htmlContent'; import {IDisposable} from 'vs/base/common/lifecycle'; import Severity from 'vs/base/common/severity'; @@ -47,7 +47,7 @@ class ModelData implements IDisposable { private _markerDecorations: string[]; private _modelEventsListener: IDisposable; - constructor(model: editorCommon.IModel, eventsHandler: (modelData: ModelData, events: IEmitterEvent[]) => void) { + constructor(model: editorCommon.IModel, eventsHandler: (modelData: ModelData, events: EmitterEvent[]) => void) { this.model = model; this.isSyncedToWorkers = false; @@ -493,7 +493,7 @@ export class ModelServiceImpl implements IModelService { }; } - private _onModelEvents(modelData: ModelData, events: IEmitterEvent[]): void { + private _onModelEvents(modelData: ModelData, events: EmitterEvent[]): void { // First look for dispose for (let i = 0, len = events.length; i < len; i++) { diff --git a/src/vs/editor/common/services/resourceService.ts b/src/vs/editor/common/services/resourceService.ts index 932f5b7082d..9511dd6b1ec 100644 --- a/src/vs/editor/common/services/resourceService.ts +++ b/src/vs/editor/common/services/resourceService.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -import {IEmitterEvent, ListenerCallback, ListenerUnbind} from 'vs/base/common/eventEmitter'; +import {EmitterEvent, ListenerCallback} from 'vs/base/common/eventEmitter'; import {IDisposable} from 'vs/base/common/lifecycle'; import URI from 'vs/base/common/uri'; import {ServiceIdentifier, createDecorator} from 'vs/platform/instantiation/common/instantiation'; @@ -30,7 +30,7 @@ export interface IResourceRemovedEvent { export interface IResourceChangedEvent { url: URI; - originalEvents: IEmitterEvent[]; + originalEvents: EmitterEvent[]; } export var IResourceService = createDecorator('resourceService'); @@ -42,10 +42,6 @@ export interface IResourceService { all(): IMirrorModel[]; contains(url: URI): boolean; remove(url: URI): void; - addListener_(eventType: 'resource.added', listener: (event: IResourceAddedEvent) => void): ListenerUnbind; - addListener_(eventType: 'resource.removed', listener: (event: IResourceRemovedEvent) => void): ListenerUnbind; - addListener_(eventType: 'resource.changed', listener: (event: IResourceChangedEvent) => void): ListenerUnbind; - addListener_(eventType: string, listener: ListenerCallback): ListenerUnbind; addListener2_(eventType: 'resource.added', listener: (event: IResourceAddedEvent) => void): IDisposable; addListener2_(eventType: 'resource.removed', listener: (event: IResourceRemovedEvent) => void): IDisposable; addListener2_(eventType: 'resource.changed', listener: (event: IResourceChangedEvent) => void): IDisposable; diff --git a/src/vs/editor/common/services/resourceServiceImpl.ts b/src/vs/editor/common/services/resourceServiceImpl.ts index 9b8543cc553..8cc3a8856bd 100644 --- a/src/vs/editor/common/services/resourceServiceImpl.ts +++ b/src/vs/editor/common/services/resourceServiceImpl.ts @@ -4,8 +4,8 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -import {EventEmitter, IEmitterEvent, ListenerCallback, ListenerUnbind} from 'vs/base/common/eventEmitter'; -import {IDisposable} from 'vs/base/common/lifecycle'; +import {EventEmitter, EmitterEvent, ListenerCallback} from 'vs/base/common/eventEmitter'; +import {IDisposable, dispose} from 'vs/base/common/lifecycle'; import URI from 'vs/base/common/uri'; import {IMirrorModel} from 'vs/editor/common/editorCommon'; import {IResourceAddedEvent, IResourceChangedEvent, IResourceRemovedEvent, IResourceService, ResourceEvents} from 'vs/editor/common/services/resourceService'; @@ -13,7 +13,7 @@ import {IResourceAddedEvent, IResourceChangedEvent, IResourceRemovedEvent, IReso export class ResourceService extends EventEmitter implements IResourceService { public serviceId = IResourceService; private data:{[url:string]:IMirrorModel;}; - private unbinds:{[url:string]:ListenerUnbind[];}; + private unbinds:{[url:string]:IDisposable[];}; constructor() { super(); @@ -21,10 +21,6 @@ export class ResourceService extends EventEmitter implements IResourceService { this.unbinds = {}; } - public addListener_(eventType: string, listener: ListenerCallback): ListenerUnbind { - return super.addListener(eventType, listener); - } - public addListener2_(eventType: string, listener: ListenerCallback): IDisposable { return super.addListener2(eventType, listener); } @@ -61,7 +57,7 @@ export class ResourceService extends EventEmitter implements IResourceService { var key = url.toString(); this.data[key] = element; this.unbinds[key] = []; - this.unbinds[key].push(element.addBulkListener((value:IEmitterEvent[]) => { + this.unbinds[key].push(element.addBulkListener2((value:EmitterEvent[]) => { this.emit(ResourceEvents.CHANGED, { url: url, originalEvents: value }); })); @@ -96,7 +92,7 @@ export class ResourceService extends EventEmitter implements IResourceService { element = this.data[key]; // stop listen - while(this.unbinds[key].length > 0) { this.unbinds[key].pop()(); } + this.unbinds[key] = dispose(this.unbinds[key]); // removal delete this.unbinds[key]; diff --git a/src/vs/editor/common/view/viewContext.ts b/src/vs/editor/common/view/viewContext.ts index 7eb0a32e79f..a6b322238ec 100644 --- a/src/vs/editor/common/view/viewContext.ts +++ b/src/vs/editor/common/view/viewContext.ts @@ -5,7 +5,7 @@ 'use strict'; import {IConfiguration} from 'vs/editor/common/editorCommon'; -import {IEmitterEvent} from 'vs/base/common/eventEmitter'; +import {EmitterEvent} from 'vs/base/common/eventEmitter'; import {IViewModel} from 'vs/editor/common/viewModel/viewModel'; export interface IViewEventBus { @@ -13,7 +13,7 @@ export interface IViewEventBus { } export interface IViewEventHandler { - handleEvents(events:IEmitterEvent[]): void; + handleEvents(events:EmitterEvent[]): void; } export class ViewContext { diff --git a/src/vs/editor/common/viewModel/viewEventHandler.ts b/src/vs/editor/common/viewModel/viewEventHandler.ts index c5889d87f16..06883bbca7d 100644 --- a/src/vs/editor/common/viewModel/viewEventHandler.ts +++ b/src/vs/editor/common/viewModel/viewEventHandler.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -import {IEmitterEvent} from 'vs/base/common/eventEmitter'; +import {EmitterEvent} from 'vs/base/common/eventEmitter'; import * as editorCommon from 'vs/editor/common/editorCommon'; export class ViewEventHandler { @@ -80,7 +80,7 @@ export class ViewEventHandler { // --- end event handlers - public handleEvents(events:IEmitterEvent[]): void { + public handleEvents(events:EmitterEvent[]): void { let shouldRender = false; diff --git a/src/vs/editor/common/viewModel/viewModelImpl.ts b/src/vs/editor/common/viewModel/viewModelImpl.ts index e9bae0dc8b6..30d6b1baf48 100644 --- a/src/vs/editor/common/viewModel/viewModelImpl.ts +++ b/src/vs/editor/common/viewModel/viewModelImpl.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -import {EmitterEvent, EventEmitter, IEmitterEvent, IEventEmitter, ListenerUnbind} from 'vs/base/common/eventEmitter'; +import {EmitterEvent, EventEmitter, IEventEmitter} from 'vs/base/common/eventEmitter'; import {IDisposable, dispose} from 'vs/base/common/lifecycle'; import * as strings from 'vs/base/common/strings'; import {Position} from 'vs/editor/common/core/position'; @@ -43,7 +43,7 @@ export class ViewModel extends EventEmitter implements IViewModel { private configuration:editorCommon.IConfiguration; private model:editorCommon.IModel; - private listenersToRemove:ListenerUnbind[]; + private listenersToRemove:IDisposable[]; private _toDispose: IDisposable[]; private lines:ILinesCollection; private decorations:ViewModelDecorations; @@ -75,7 +75,7 @@ export class ViewModel extends EventEmitter implements IViewModel { this.listenersToRemove = []; this._toDispose = []; - this.listenersToRemove.push(this.model.addBulkListener((events:IEmitterEvent[]) => this.onEvents(events))); + this.listenersToRemove.push(this.model.addBulkListener2((events:EmitterEvent[]) => this.onEvents(events))); this._toDispose.push(this.configuration.onDidChange((e) => { this.onEvents([new EmitterEvent(editorCommon.EventType.ConfigurationChanged, e)]); })); @@ -93,11 +93,8 @@ export class ViewModel extends EventEmitter implements IViewModel { } public dispose(): void { - this.listenersToRemove.forEach((element) => { - element(); - }); + this.listenersToRemove = dispose(this.listenersToRemove); this._toDispose = dispose(this._toDispose); - this.listenersToRemove = []; this.decorations.dispose(); this.decorations = null; this.lines.dispose(); @@ -150,10 +147,10 @@ export class ViewModel extends EventEmitter implements IViewModel { } public addEventSource(eventSource:IEventEmitter): void { - this.listenersToRemove.push(eventSource.addBulkListener((events:IEmitterEvent[]) => this.onEvents(events))); + this.listenersToRemove.push(eventSource.addBulkListener2((events:EmitterEvent[]) => this.onEvents(events))); } - private onEvents(events:IEmitterEvent[]): void { + private onEvents(events:EmitterEvent[]): void { this.deferredEmit(() => { let hasContentChange = events.some((e) => e.getType() === editorCommon.EventType.ModelContentChanged), @@ -165,7 +162,7 @@ export class ViewModel extends EventEmitter implements IViewModel { let i:number, len:number, - e: IEmitterEvent, + e: EmitterEvent, data:any, modelContentChangedEvent:editorCommon.IModelContentChangedEvent, hadOtherModelChange = false, diff --git a/src/vs/editor/common/worker/validationHelper.ts b/src/vs/editor/common/worker/validationHelper.ts index 750a5deb144..695b6f2bbfb 100644 --- a/src/vs/editor/common/worker/validationHelper.ts +++ b/src/vs/editor/common/worker/validationHelper.ts @@ -5,7 +5,7 @@ 'use strict'; import {RunOnceScheduler} from 'vs/base/common/async'; -import {IEmitterEvent} from 'vs/base/common/eventEmitter'; +import {EmitterEvent} from 'vs/base/common/eventEmitter'; import {IDisposable, dispose} from 'vs/base/common/lifecycle'; import URI from 'vs/base/common/uri'; import {IMirrorModel} from 'vs/editor/common/editorCommon'; @@ -31,9 +31,7 @@ class ValidationModel implements IDisposable { this._changeCallback = changeCallback; this._model = model; this._isDirty = false; - this._toDispose.push({ - dispose: model.addBulkListener((events) => this._onModelChanged(events)) - }); + this._toDispose.push(model.addBulkListener2((events) => this._onModelChanged(events))); } public dispose(): void { @@ -57,7 +55,7 @@ class ValidationModel implements IDisposable { return this._model; } - private _onModelChanged(events:IEmitterEvent[]): void { + private _onModelChanged(events:EmitterEvent[]): void { var containsChanged = false; for (var i = 0; !containsChanged && i < events.length; i++) { if (events[i].getType() === 'changed') { diff --git a/src/vs/editor/contrib/accessibility/browser/accessibility.ts b/src/vs/editor/contrib/accessibility/browser/accessibility.ts index fcaa87a2d09..08a5c86ba13 100644 --- a/src/vs/editor/contrib/accessibility/browser/accessibility.ts +++ b/src/vs/editor/contrib/accessibility/browser/accessibility.ts @@ -21,7 +21,7 @@ import {KeybindingsRegistry} from 'vs/platform/keybinding/common/keybindingsRegi import {GlobalScreenReaderNVDA} from 'vs/editor/common/config/commonEditorConfig'; import {EditorAction} from 'vs/editor/common/editorAction'; import {Behaviour} from 'vs/editor/common/editorActionEnablement'; -import {EventType, ICommonCodeEditor, IEditorActionDescriptorData, IEditorContribution, SHOW_ACCESSIBILITY_HELP_ACTION_ID} from 'vs/editor/common/editorCommon'; +import {ICommonCodeEditor, IEditorActionDescriptorData, IEditorContribution, SHOW_ACCESSIBILITY_HELP_ACTION_ID} from 'vs/editor/common/editorCommon'; import {CommonEditorRegistry, ContextKey, EditorActionDescriptor} from 'vs/editor/common/editorCommonExtensions'; import {ICodeEditor, IOverlayWidget, IOverlayWidgetPosition} from 'vs/editor/browser/editorBrowser'; import {EditorBrowserRegistry} from 'vs/editor/browser/editorBrowserExtensions'; @@ -91,7 +91,7 @@ class AccessibilityHelpWidget extends Widget implements IOverlayWidget { this._domNode.setAttribute('aria-hidden', 'true'); this._isVisible = false; - this._register(this._editor.addListener2(EventType.EditorLayout, () => { + this._register(this._editor.onDidLayoutChange(() => { if (this._isVisible) { this._layout(); } diff --git a/src/vs/editor/contrib/clipboard/browser/clipboard.ts b/src/vs/editor/contrib/clipboard/browser/clipboard.ts index fe2234238d0..40abb8f771a 100644 --- a/src/vs/editor/contrib/clipboard/browser/clipboard.ts +++ b/src/vs/editor/contrib/clipboard/browser/clipboard.ts @@ -8,7 +8,7 @@ import 'vs/css!./clipboard'; import * as nls from 'vs/nls'; import {KeyCode, KeyMod} from 'vs/base/common/keyCodes'; -import {cAll} from 'vs/base/common/lifecycle'; +import {dispose, IDisposable} from 'vs/base/common/lifecycle'; import {TPromise} from 'vs/base/common/winjs.base'; import * as browser from 'vs/base/browser/browser'; import {ServicesAccessor} from 'vs/platform/instantiation/common/instantiation'; @@ -21,18 +21,18 @@ import {CommonEditorRegistry, ContextKey, EditorActionDescriptor} from 'vs/edito class ClipboardWritingAction extends EditorAction { - private toUnhook:Function[]; + private toUnhook:IDisposable[]; constructor(descriptor:editorCommon.IEditorActionDescriptorData, editor:editorCommon.ICommonCodeEditor, condition:Behaviour) { super(descriptor, editor, condition); this.toUnhook = []; - this.toUnhook.push(this.editor.addListener(editorCommon.EventType.CursorSelectionChanged, (e:editorCommon.ICursorSelectionChangedEvent) => { + this.toUnhook.push(this.editor.onDidCursorSelectionChange((e:editorCommon.ICursorSelectionChangedEvent) => { this.resetEnablementState(); })); } public dispose(): void { - this.toUnhook = cAll(this.toUnhook); + this.toUnhook = dispose(this.toUnhook); super.dispose(); } diff --git a/src/vs/editor/contrib/codelens/browser/codelens.ts b/src/vs/editor/contrib/codelens/browser/codelens.ts index a21e4613e3c..7c3c74e8117 100644 --- a/src/vs/editor/contrib/codelens/browser/codelens.ts +++ b/src/vs/editor/contrib/codelens/browser/codelens.ts @@ -362,9 +362,9 @@ export class CodeLensContribution implements editorCommon.IEditorContribution { this._currentFindCodeLensSymbolsPromise = null; this._modelChangeCounter = 0; - this._globalToDispose.push(this._editor.addListener2(editorCommon.EventType.ModelChanged, () => this.onModelChange())); - this._globalToDispose.push(this._editor.addListener2(editorCommon.EventType.ModelModeChanged, () => this.onModelChange())); - this._globalToDispose.push(this._editor.addListener2(editorCommon.EventType.ConfigurationChanged, (e: editorCommon.IConfigurationChangedEvent) => { + this._globalToDispose.push(this._editor.onDidModelChange(() => this.onModelChange())); + this._globalToDispose.push(this._editor.onDidModelModeChange(() => this.onModelChange())); + this._globalToDispose.push(this._editor.onDidConfigurationChange((e: editorCommon.IConfigurationChangedEvent) => { let prevIsEnabled = this._isEnabled; this._isEnabled = this._editor.getConfiguration().contribInfo.referenceInfos; if (prevIsEnabled !== this._isEnabled) { @@ -472,8 +472,10 @@ export class CodeLensContribution implements editorCommon.IEditorContribution { scheduler.schedule(); } })); - this._localToDispose.push(this._editor.addListener2('scroll', (e) => { - detectVisible.schedule(); + this._localToDispose.push(this._editor.onDidScrollChange((e) => { + if (e.scrollTopChanged) { + detectVisible.schedule(); + } })); this._localToDispose.push({ dispose: () => { diff --git a/src/vs/editor/contrib/color/browser/color.ts b/src/vs/editor/contrib/color/browser/color.ts index db75b3dd8ae..715511f3cff 100644 --- a/src/vs/editor/contrib/color/browser/color.ts +++ b/src/vs/editor/contrib/color/browser/color.ts @@ -8,7 +8,7 @@ import 'vs/css!./color'; import {RunOnceScheduler} from 'vs/base/common/async'; import {onUnexpectedError} from 'vs/base/common/errors'; -import {IDisposable, cAll, dispose} from 'vs/base/common/lifecycle'; +import {IDisposable, dispose} from 'vs/base/common/lifecycle'; import * as strings from 'vs/base/common/strings'; import {TPromise} from 'vs/base/common/winjs.base'; import * as dom from 'vs/base/browser/dom'; @@ -73,7 +73,7 @@ export class ColorContribution implements editorCommon.IEditorContribution { private _decorationsChangedScheduler:RunOnceScheduler; private _callOnDispose:IDisposable[]; - private _callOnModelChange:IFunction[]; + private _callOnModelChange:IDisposable[]; private _currentFindColorDeclarationsPromise:TPromise<{range:editorCommon.IRange; value:string; }[]>; private _currentDecorations:ColorDecoration[]; @@ -94,9 +94,9 @@ export class ColorContribution implements editorCommon.IEditorContribution { this._callOnDispose.push(this._contentChangedScheduler); this._callOnDispose.push(this._decorationsChangedScheduler); - this._callOnDispose.push(this._editor.addListener2(editorCommon.EventType.ModelChanged, () => this.onModelChange())); - this._callOnDispose.push(this._editor.addListener2(editorCommon.EventType.ModelModeChanged,() => this.onModelChange())); - this._callOnDispose.push(this._editor.addListener2(editorCommon.EventType.ModelModeSupportChanged,(e: editorCommon.IModeSupportChangedEvent) => { + this._callOnDispose.push(this._editor.onDidModelChange(() => this.onModelChange())); + this._callOnDispose.push(this._editor.onDidModelModeChange(() => this.onModelChange())); + this._callOnDispose.push(this._editor.onDidModelModeSupportChange((e: editorCommon.IModeSupportChangedEvent) => { this.onModelChange(); })); @@ -126,7 +126,7 @@ export class ColorContribution implements editorCommon.IEditorContribution { } private onModelChange(): void { - cAll(this._callOnModelChange); + this._callOnModelChange = dispose(this._callOnModelChange); var model = this._editor.getModel(); if(!model) { @@ -158,18 +158,22 @@ export class ColorContribution implements editorCommon.IEditorContribution { this._contentChangedScheduler.schedule(); - this._callOnModelChange.push(() => { - this._contentChangedScheduler.cancel(); - this._decorationsChangedScheduler.cancel(); - }); - this._callOnModelChange.push(() => { - if (this._currentFindColorDeclarationsPromise) { - this._currentFindColorDeclarationsPromise.cancel(); + this._callOnModelChange.push({ + dispose: () => { + this._contentChangedScheduler.cancel(); + this._decorationsChangedScheduler.cancel(); } - this._currentFindColorDeclarationsPromise = null; }); - this._callOnModelChange.push(this._editor.addListener(editorCommon.EventType.ModelContentChanged, (event) => this._contentChangedScheduler.schedule())); - this._callOnModelChange.push(model.addListener(editorCommon.EventType.ModelDecorationsChanged, (event) => this._decorationsChangedScheduler.schedule())); + this._callOnModelChange.push({ + dispose: () => { + if (this._currentFindColorDeclarationsPromise) { + this._currentFindColorDeclarationsPromise.cancel(); + } + this._currentFindColorDeclarationsPromise = null; + } + }); + this._callOnModelChange.push(this._editor.onDidModelContentChange((event) => this._contentChangedScheduler.schedule())); + this._callOnModelChange.push(model.addListener2(editorCommon.EventType.ModelDecorationsChanged, (event) => this._decorationsChangedScheduler.schedule())); } private renderAndTrackColors(colors:{range:editorCommon.IRange; value:string; }[]): void { diff --git a/src/vs/editor/contrib/contextmenu/browser/contextmenu.ts b/src/vs/editor/contrib/contextmenu/browser/contextmenu.ts index 01b8bc3392e..d43874e4507 100644 --- a/src/vs/editor/contrib/contextmenu/browser/contextmenu.ts +++ b/src/vs/editor/contrib/contextmenu/browser/contextmenu.ts @@ -17,7 +17,7 @@ import {IContextMenuService, IContextViewService} from 'vs/platform/contextview/ import {IKeybindingService} from 'vs/platform/keybinding/common/keybindingService'; import {EditorAction} from 'vs/editor/common/editorAction'; import {Behaviour} from 'vs/editor/common/editorActionEnablement'; -import {EventType, ICommonCodeEditor, IEditorActionDescriptorData, IEditorContribution, MouseTargetType} from 'vs/editor/common/editorCommon'; +import {ICommonCodeEditor, IEditorActionDescriptorData, IEditorContribution, MouseTargetType} from 'vs/editor/common/editorCommon'; import {CommonEditorRegistry, ContextKey, EditorActionDescriptor} from 'vs/editor/common/editorCommonExtensions'; import {ICodeEditor, IEditorMouseEvent} from 'vs/editor/browser/editorBrowser'; import {EditorBrowserRegistry} from 'vs/editor/browser/editorBrowserExtensions'; @@ -49,8 +49,8 @@ class ContextMenuController implements IEditorContribution { this._contextMenuIsBeingShownCount = 0; - this._toDispose.push(this._editor.addListener2(EventType.ContextMenu, (e:IEditorMouseEvent)=>this._onContextMenu(e))); - this._toDispose.push(this._editor.addListener2(EventType.KeyDown, (e:IKeyboardEvent)=> { + this._toDispose.push(this._editor.onContextMenu((e:IEditorMouseEvent)=>this._onContextMenu(e))); + this._toDispose.push(this._editor.onKeyDown((e:IKeyboardEvent)=> { if (e.keyCode === KeyCode.ContextMenu) { // Chrome is funny like that e.preventDefault(); diff --git a/src/vs/editor/contrib/defineKeybinding/browser/defineKeybinding.ts b/src/vs/editor/contrib/defineKeybinding/browser/defineKeybinding.ts index c42f1242e8d..0de34c046d4 100644 --- a/src/vs/editor/contrib/defineKeybinding/browser/defineKeybinding.ts +++ b/src/vs/editor/contrib/defineKeybinding/browser/defineKeybinding.ts @@ -61,14 +61,14 @@ export class DefineKeybindingController implements editorCommon.IEditorContribut this._launchWidget = new DefineKeybindingLauncherWidget(this._editor, keybindingService, () => this.launch()); this._defineWidget = new DefineKeybindingWidget(this._editor, keybindingService, (keybinding) => this._onAccepted(keybinding)); - this._toDispose.push(this._editor.addListener2(editorCommon.EventType.ConfigurationChanged, (e) => { + this._toDispose.push(this._editor.onDidConfigurationChange((e) => { if (isInterestingEditorModel(this._editor)) { this._launchWidget.show(); } else { this._launchWidget.hide(); } })); - this._toDispose.push(this._editor.addListener2(editorCommon.EventType.ModelChanged, (e) => { + this._toDispose.push(this._editor.onDidModelChange((e) => { if (isInterestingEditorModel(this._editor)) { this._launchWidget.show(); } else { @@ -374,7 +374,7 @@ class DefineKeybindingWidget implements IOverlayWidget { let htmlkb = this._keybindingService.getHTMLLabelFor(this._lastKeybinding); htmlkb.forEach((item) => this._outputNode.appendChild(renderHtml(item))); })); - this._toDispose.push(this._editor.addListener2(editorCommon.EventType.ConfigurationChanged, (e) => { + this._toDispose.push(this._editor.onDidConfigurationChange((e) => { if (this._isVisible) { this._layout(); } diff --git a/src/vs/editor/contrib/diffNavigator/common/diffNavigator.ts b/src/vs/editor/contrib/diffNavigator/common/diffNavigator.ts index 6c8731de2a7..08cff37b48b 100644 --- a/src/vs/editor/contrib/diffNavigator/common/diffNavigator.ts +++ b/src/vs/editor/contrib/diffNavigator/common/diffNavigator.ts @@ -5,10 +5,11 @@ 'use strict'; import * as assert from 'vs/base/common/assert'; -import {EventEmitter, ListenerUnbind} from 'vs/base/common/eventEmitter'; +import {EventEmitter} from 'vs/base/common/eventEmitter'; import * as objects from 'vs/base/common/objects'; import {Range} from 'vs/editor/common/core/range'; -import {EventType, ICommonDiffEditor, ICursorPositionChangedEvent, IEditorRange, ILineChange} from 'vs/editor/common/editorCommon'; +import {ICommonDiffEditor, ICursorPositionChangedEvent, IEditorRange, ILineChange} from 'vs/editor/common/editorCommon'; +import {IDisposable, dispose} from 'vs/base/common/lifecycle'; interface IDiffRange { rhs:boolean; @@ -39,7 +40,7 @@ export class DiffNavigator extends EventEmitter { private editor:ICommonDiffEditor; private options:Options; private disposed:boolean; - private toUnbind:ListenerUnbind[]; + private toUnbind:IDisposable[]; private nextIdx:number; private ranges:IDiffRange[]; @@ -62,11 +63,11 @@ export class DiffNavigator extends EventEmitter { this.revealFirst = this.options.alwaysRevealFirst; // hook up to diff editor for diff, disposal, and caret move - this.toUnbind.push(this.editor.addListener(EventType.Disposed, () => this.dispose() )); - this.toUnbind.push(this.editor.addListener(EventType.DiffUpdated, () => this.onDiffUpdated() )); + this.toUnbind.push(this.editor.onDidDispose(() => this.dispose() )); + this.toUnbind.push(this.editor.onDidUpdateDiff(() => this.onDiffUpdated() )); if(this.options.followsCaret) { - this.toUnbind.push(this.editor.getModifiedEditor().addListener(EventType.CursorPositionChanged, (e:ICursorPositionChangedEvent) => { + this.toUnbind.push(this.editor.getModifiedEditor().onDidCursorPositionChange((e:ICursorPositionChangedEvent) => { if(this.ignoreSelectionChange) { return; } @@ -74,7 +75,7 @@ export class DiffNavigator extends EventEmitter { })); } if(this.options.alwaysRevealFirst) { - this.toUnbind.push(this.editor.getModifiedEditor().addListener(EventType.ModelChanged, (e) => { + this.toUnbind.push(this.editor.getModifiedEditor().onDidModelChange((e) => { this.revealFirst = true; })); } @@ -214,9 +215,7 @@ export class DiffNavigator extends EventEmitter { } public dispose():void { - while(this.toUnbind.length > 0) { - this.toUnbind.pop()(); - } + this.toUnbind = dispose(this.toUnbind); this.ranges = null; this.disposed = true; diff --git a/src/vs/editor/contrib/find/browser/findWidget.ts b/src/vs/editor/contrib/find/browser/findWidget.ts index fcad63a1314..01049fc647c 100644 --- a/src/vs/editor/contrib/find/browser/findWidget.ts +++ b/src/vs/editor/contrib/find/browser/findWidget.ts @@ -17,7 +17,7 @@ import {FindInput} from 'vs/base/browser/ui/findinput/findInput'; import {IMessage as InputBoxMessage, InputBox} from 'vs/base/browser/ui/inputbox/inputBox'; import {Widget} from 'vs/base/browser/ui/widget'; import {IKeybindingService} from 'vs/platform/keybinding/common/keybindingService'; -import {EventType, IConfigurationChangedEvent} from 'vs/editor/common/editorCommon'; +import {IConfigurationChangedEvent} from 'vs/editor/common/editorCommon'; import {ICodeEditor, IOverlayWidget, IOverlayWidgetPosition, OverlayWidgetPositionPreference} from 'vs/editor/browser/editorBrowser'; import {FIND_IDS, MATCHES_LIMIT} from 'vs/editor/contrib/find/common/findModel'; import {FindReplaceState, FindReplaceStateChangedEvent} from 'vs/editor/contrib/find/common/findState'; @@ -98,7 +98,7 @@ export class FindWidget extends Widget implements IOverlayWidget { this.focusTracker = this._register(dom.trackFocus(this._findInput.inputBox.inputElement)); this.focusTracker.addFocusListener(() => this._reseedFindScope()); - this._register(this._codeEditor.addListener2(EventType.ConfigurationChanged, (e:IConfigurationChangedEvent) => { + this._register(this._codeEditor.onDidConfigurationChange((e:IConfigurationChangedEvent) => { if (e.readOnly) { if (this._codeEditor.getConfiguration().readOnly) { // Hide replace part if editor becomes read only @@ -107,7 +107,7 @@ export class FindWidget extends Widget implements IOverlayWidget { this._updateButtons(); } })); - this._register(this._codeEditor.addListener2(EventType.CursorSelectionChanged, () => { + this._register(this._codeEditor.onDidCursorSelectionChange(() => { if (this._isVisible) { this._updateToggleSelectionFindButton(); } diff --git a/src/vs/editor/contrib/find/common/findController.ts b/src/vs/editor/contrib/find/common/findController.ts index 88005ea502a..130c69f9af5 100644 --- a/src/vs/editor/contrib/find/common/findController.ts +++ b/src/vs/editor/contrib/find/common/findController.ts @@ -60,7 +60,7 @@ export class CommonFindController extends Disposable implements editorCommon.IEd this._model = null; - this._register(this._editor.addListener2(editorCommon.EventType.ModelChanged, () => { + this._register(this._editor.onDidModelChange(() => { let shouldRestartFind = (this._editor.getModel() && this._state.isRevealed); this.disposeModel(); @@ -523,7 +523,7 @@ export class SelectionHighlighter extends Disposable implements editorCommon.IEd this.updateSoon = this._register(new RunOnceScheduler(() => this._update(), 300)); this.lastWordUnderCursor = null; - this._register(editor.addListener2(editorCommon.EventType.CursorSelectionChanged, (e: editorCommon.ICursorSelectionChangedEvent) => { + this._register(editor.onDidCursorSelectionChange((e: editorCommon.ICursorSelectionChangedEvent) => { if (e.selection.isEmpty()) { if (e.reason === editorCommon.CursorChangeReason.Explicit) { if (!this.lastWordUnderCursor || !this.lastWordUnderCursor.containsPosition(e.selection.getStartPosition())) { @@ -539,7 +539,7 @@ export class SelectionHighlighter extends Disposable implements editorCommon.IEd this._update(); } })); - this._register(editor.addListener2(editorCommon.EventType.ModelChanged, (e) => { + this._register(editor.onDidModelChange((e) => { this.removeDecorations(); })); this._register(CommonFindController.getFindController(editor).getState().addChangeListener((e) => { diff --git a/src/vs/editor/contrib/find/common/findModel.ts b/src/vs/editor/contrib/find/common/findModel.ts index 520a4a2d6fa..316981d22ea 100644 --- a/src/vs/editor/contrib/find/common/findModel.ts +++ b/src/vs/editor/contrib/find/common/findModel.ts @@ -57,7 +57,7 @@ export class FindModelBoundToEditorModel { this._updateDecorationsScheduler = new RunOnceScheduler(() => this.research(false), 100); this._toDispose.push(this._updateDecorationsScheduler); - this._toDispose.push(this._editor.addListener2(editorCommon.EventType.CursorPositionChanged, (e:editorCommon.ICursorPositionChangedEvent) => { + this._toDispose.push(this._editor.onDidCursorPositionChange((e:editorCommon.ICursorPositionChangedEvent) => { if ( e.reason === editorCommon.CursorChangeReason.Explicit || e.reason === editorCommon.CursorChangeReason.Undo @@ -68,7 +68,7 @@ export class FindModelBoundToEditorModel { })); this._ignoreModelContentChanged = false; - this._toDispose.push(this._editor.addListener2(editorCommon.EventType.ModelContentChanged, (e:editorCommon.IModelContentChangedEvent) => { + this._toDispose.push(this._editor.onDidModelContentChange((e:editorCommon.IModelContentChangedEvent) => { if (this._ignoreModelContentChanged) { return; } diff --git a/src/vs/editor/contrib/folding/browser/folding.ts b/src/vs/editor/contrib/folding/browser/folding.ts index 6e84142c162..5b0947000cd 100644 --- a/src/vs/editor/contrib/folding/browser/folding.ts +++ b/src/vs/editor/contrib/folding/browser/folding.ts @@ -159,8 +159,8 @@ export class FoldingController implements editorCommon.IEditorContribution { this.decorations = []; this.computeToken = 0; - this.globalToDispose.push(this.editor.addListener2(editorCommon.EventType.ModelChanged, () => this.onModelChanged())); - this.globalToDispose.push(this.editor.addListener2(editorCommon.EventType.ConfigurationChanged, (e: editorCommon.IConfigurationChangedEvent) => { + this.globalToDispose.push(this.editor.onDidModelChange(() => this.onModelChanged())); + this.globalToDispose.push(this.editor.onDidConfigurationChange((e: editorCommon.IConfigurationChangedEvent) => { let oldIsEnabled = this._isEnabled; this._isEnabled = this.editor.getConfiguration().contribInfo.folding; if (oldIsEnabled !== this._isEnabled) { @@ -311,7 +311,7 @@ export class FoldingController implements editorCommon.IEditorContribution { this.localToDispose.push(this.contentChangedScheduler); this.localToDispose.push(this.cursorChangedScheduler); - this.localToDispose.push(this.editor.addListener2('change', () => { + this.localToDispose.push(this.editor.onDidModelContentChange(() => { this.contentChangedScheduler.schedule(); })); this.localToDispose.push({ dispose: () => { @@ -323,9 +323,9 @@ export class FoldingController implements editorCommon.IEditorContribution { this.decorations = []; this.editor.setHiddenAreas([]); }}); - this.localToDispose.push(this.editor.addListener2(editorCommon.EventType.MouseDown, e => this.onEditorMouseDown(e))); - this.localToDispose.push(this.editor.addListener2(editorCommon.EventType.MouseUp, e => this.onEditorMouseUp(e))); - this.localToDispose.push(this.editor.addListener2(editorCommon.EventType.CursorPositionChanged, e => { + this.localToDispose.push(this.editor.onMouseDown(e => this.onEditorMouseDown(e))); + this.localToDispose.push(this.editor.onMouseUp(e => this.onEditorMouseUp(e))); + this.localToDispose.push(this.editor.onDidCursorPositionChange(e => { this.cursorChangedScheduler.schedule(); })); diff --git a/src/vs/editor/contrib/format/common/formatActions.ts b/src/vs/editor/contrib/format/common/formatActions.ts index 1e5aeb7e8cb..8c145205910 100644 --- a/src/vs/editor/contrib/format/common/formatActions.ts +++ b/src/vs/editor/contrib/format/common/formatActions.ts @@ -7,7 +7,7 @@ import * as nls from 'vs/nls'; import * as arrays from 'vs/base/common/arrays'; import {KeyCode, KeyMod} from 'vs/base/common/keyCodes'; -import {IDisposable, cAll, dispose} from 'vs/base/common/lifecycle'; +import {IDisposable, dispose} from 'vs/base/common/lifecycle'; import {TPromise} from 'vs/base/common/winjs.base'; import {EditorAction} from 'vs/editor/common/editorAction'; import {Behaviour} from 'vs/editor/common/editorActionEnablement'; @@ -29,23 +29,23 @@ class FormatOnType implements editorCommon.IEditorContribution { private editor: editorCommon.ICommonCodeEditor; private callOnDispose: IDisposable[]; - private callOnModel: Function[]; + private callOnModel: IDisposable[]; constructor(editor: editorCommon.ICommonCodeEditor) { this.editor = editor; this.callOnDispose = []; this.callOnModel = []; - this.callOnDispose.push(editor.addListener2(editorCommon.EventType.ConfigurationChanged, () => this.update())); - this.callOnDispose.push(editor.addListener2(editorCommon.EventType.ModelChanged, () => this.update())); - this.callOnDispose.push(editor.addListener2(editorCommon.EventType.ModelModeChanged, () => this.update())); + this.callOnDispose.push(editor.onDidConfigurationChange(() => this.update())); + this.callOnDispose.push(editor.onDidModelChange(() => this.update())); + this.callOnDispose.push(editor.onDidModelModeChange(() => this.update())); this.callOnDispose.push(OnTypeFormattingEditProviderRegistry.onDidChange(this.update, this)); } private update(): void { // clean up - this.callOnModel = cAll(this.callOnModel); + this.callOnModel = dispose(this.callOnModel); // we are disabled if (!this.editor.getConfiguration().contribInfo.formatOnType) { @@ -84,7 +84,7 @@ class FormatOnType implements editorCommon.IEditorContribution { // install a listener that checks if edits happens before the // position on which we format right now. Iff so, we won't // apply the format edits - var unbind = this.editor.addListener(editorCommon.EventType.ModelContentChanged,(e: editorCommon.IModelContentChangedEvent) => { + var unbind = this.editor.onDidModelContentChange((e: editorCommon.IModelContentChangedEvent) => { if (e.changeType === editorCommon.EventType.ModelContentChangedFlush) { // a model.setValue() was called canceled = true; @@ -103,7 +103,7 @@ class FormatOnType implements editorCommon.IEditorContribution { if (canceled) { // cancel only once - unbind(); + unbind.dispose(); } }); @@ -114,7 +114,7 @@ class FormatOnType implements editorCommon.IEditorContribution { insertSpaces: modelOpts.insertSpaces }).then(edits => { - unbind(); + unbind.dispose(); if (canceled || arrays.isFalsyOrEmpty(edits)) { return; @@ -123,7 +123,7 @@ class FormatOnType implements editorCommon.IEditorContribution { this.editor.executeCommand(this.getId(), new EditOperationsCommand(edits, this.editor.getSelection())); },(err) => { - unbind(); + unbind.dispose(); throw err; }); } @@ -134,9 +134,7 @@ class FormatOnType implements editorCommon.IEditorContribution { public dispose(): void { this.callOnDispose = dispose(this.callOnDispose); - while (this.callOnModel.length > 0) { - this.callOnModel.pop()(); - } + this.callOnModel = dispose(this.callOnModel); } } diff --git a/src/vs/editor/contrib/goToDeclaration/browser/goToDeclaration.ts b/src/vs/editor/contrib/goToDeclaration/browser/goToDeclaration.ts index 7dee1b38888..cf2473dafb8 100644 --- a/src/vs/editor/contrib/goToDeclaration/browser/goToDeclaration.ts +++ b/src/vs/editor/contrib/goToDeclaration/browser/goToDeclaration.ts @@ -9,7 +9,6 @@ import 'vs/css!./goToDeclaration'; import * as nls from 'vs/nls'; import {Throttler} from 'vs/base/common/async'; import {onUnexpectedError} from 'vs/base/common/errors'; -import {ListenerUnbind} from 'vs/base/common/eventEmitter'; import {IHTMLContentElement} from 'vs/base/common/htmlContent'; import {KeyCode, KeyMod} from 'vs/base/common/keyCodes'; import * as platform from 'vs/base/common/platform'; @@ -32,6 +31,7 @@ import {EditorBrowserRegistry} from 'vs/editor/browser/editorBrowserExtensions'; import {getDeclarationsAtPosition} from 'vs/editor/contrib/goToDeclaration/common/goToDeclaration'; import {ReferencesController} from 'vs/editor/contrib/referenceSearch/browser/referencesController'; import {ReferencesModel} from 'vs/editor/contrib/referenceSearch/browser/referencesModel'; +import {IDisposable, dispose} from 'vs/base/common/lifecycle'; export class DefinitionActionConfig { @@ -206,7 +206,7 @@ class GotoDefinitionWithMouseEditorContribution implements editorCommon.IEditorC static MAX_SOURCE_PREVIEW_LINES = 7; private editor: ICodeEditor; - private toUnhook: ListenerUnbind[]; + private toUnhook: IDisposable[]; private decorations: string[]; private currentWordUnderMouse: editorCommon.IWordAtPosition; private throttler: Throttler; @@ -222,15 +222,19 @@ class GotoDefinitionWithMouseEditorContribution implements editorCommon.IEditorC this.editor = editor; this.throttler = new Throttler(); - this.toUnhook.push(this.editor.addListener(editorCommon.EventType.MouseDown, (e: IEditorMouseEvent) => this.onEditorMouseDown(e))); - this.toUnhook.push(this.editor.addListener(editorCommon.EventType.MouseUp, (e: IEditorMouseEvent) => this.onEditorMouseUp(e))); - this.toUnhook.push(this.editor.addListener(editorCommon.EventType.MouseMove, (e: IEditorMouseEvent) => this.onEditorMouseMove(e))); - this.toUnhook.push(this.editor.addListener(editorCommon.EventType.KeyDown, (e: IKeyboardEvent) => this.onEditorKeyDown(e))); - this.toUnhook.push(this.editor.addListener(editorCommon.EventType.KeyUp, (e: IKeyboardEvent) => this.onEditorKeyUp(e))); + this.toUnhook.push(this.editor.onMouseDown((e: IEditorMouseEvent) => this.onEditorMouseDown(e))); + this.toUnhook.push(this.editor.onMouseUp((e: IEditorMouseEvent) => this.onEditorMouseUp(e))); + this.toUnhook.push(this.editor.onMouseMove((e: IEditorMouseEvent) => this.onEditorMouseMove(e))); + this.toUnhook.push(this.editor.onKeyDown((e: IKeyboardEvent) => this.onEditorKeyDown(e))); + this.toUnhook.push(this.editor.onKeyUp((e: IKeyboardEvent) => this.onEditorKeyUp(e))); - this.toUnhook.push(this.editor.addListener(editorCommon.EventType.ModelChanged, (e: editorCommon.IModelContentChangedEvent) => this.resetHandler())); - this.toUnhook.push(this.editor.addListener('change', (e: editorCommon.IModelContentChangedEvent) => this.resetHandler())); - this.toUnhook.push(this.editor.addListener('scroll', () => this.resetHandler())); + this.toUnhook.push(this.editor.onDidModelChange((e) => this.resetHandler())); + this.toUnhook.push(this.editor.onDidModelContentChange((e: editorCommon.IModelContentChangedEvent) => this.resetHandler())); + this.toUnhook.push(this.editor.onDidScrollChange((e) => { + if (e.scrollTopChanged || e.scrollLeftChanged) { + this.resetHandler(); + } + })); } private onEditorMouseMove(mouseEvent: IEditorMouseEvent, withKey?: IKeyboardEvent): void { @@ -457,9 +461,7 @@ class GotoDefinitionWithMouseEditorContribution implements editorCommon.IEditorC } public dispose(): void { - while (this.toUnhook.length > 0) { - this.toUnhook.pop()(); - } + this.toUnhook = dispose(this.toUnhook); } } diff --git a/src/vs/editor/contrib/gotoError/browser/gotoError.ts b/src/vs/editor/contrib/gotoError/browser/gotoError.ts index 468f7735892..f6ab1a248d7 100644 --- a/src/vs/editor/contrib/gotoError/browser/gotoError.ts +++ b/src/vs/editor/contrib/gotoError/browser/gotoError.ts @@ -10,7 +10,7 @@ import * as nls from 'vs/nls'; import {onUnexpectedError} from 'vs/base/common/errors'; import {Emitter} from 'vs/base/common/event'; import {CommonKeybindings, KeyCode, KeyMod} from 'vs/base/common/keyCodes'; -import {IDisposable, cAll, dispose} from 'vs/base/common/lifecycle'; +import {IDisposable, dispose} from 'vs/base/common/lifecycle'; import Severity from 'vs/base/common/severity'; import * as strings from 'vs/base/common/strings'; import URI from 'vs/base/common/uri'; @@ -36,7 +36,7 @@ class MarkerModel { private _editor: ICodeEditor; private _markers: IMarker[]; private _nextIdx: number; - private _toUnbind: Function[]; + private _toUnbind: IDisposable[]; private _ignoreSelectionChange: boolean; private _onCurrentMarkerChanged: Emitter; private _onMarkerSetChanged: Emitter; @@ -52,8 +52,8 @@ class MarkerModel { this.setMarkers(markers); // listen on editor - this._toUnbind.push(this._editor.addListener(editorCommon.EventType.Disposed, () => this.dispose())); - this._toUnbind.push(this._editor.addListener(editorCommon.EventType.CursorPositionChanged, () => { + this._toUnbind.push(this._editor.onDidDispose(() => this.dispose())); + this._toUnbind.push(this._editor.onDidCursorPositionChange(() => { if (!this._ignoreSelectionChange) { this._nextIdx = -1; } @@ -177,7 +177,7 @@ class MarkerModel { } public dispose(): void { - this._toUnbind = cAll(this._toUnbind); + this._toUnbind = dispose(this._toUnbind); } } @@ -437,7 +437,7 @@ class MarkerController implements editorCommon.IEditorContribution { this._callOnClose.push(this._model); this._callOnClose.push(this._zone); - this._callOnClose.push(this._editor.addListener2(editorCommon.EventType.ModelChanged, () => { + this._callOnClose.push(this._editor.onDidModelChange(() => { this._cleanUp(); })); diff --git a/src/vs/editor/contrib/hover/browser/hover.ts b/src/vs/editor/contrib/hover/browser/hover.ts index bb55f292fab..ddebdeea3ae 100644 --- a/src/vs/editor/contrib/hover/browser/hover.ts +++ b/src/vs/editor/contrib/hover/browser/hover.ts @@ -7,7 +7,6 @@ import 'vs/css!./hover'; import * as nls from 'vs/nls'; -import {ListenerUnbind} from 'vs/base/common/eventEmitter'; import {KeyCode, KeyMod} from 'vs/base/common/keyCodes'; import * as platform from 'vs/base/common/platform'; import {TPromise} from 'vs/base/common/winjs.base'; @@ -23,13 +22,14 @@ import {ICodeEditor, IEditorMouseEvent} from 'vs/editor/browser/editorBrowser'; import {EditorBrowserRegistry} from 'vs/editor/browser/editorBrowserExtensions'; import {ModesContentHoverWidget} from './modesContentHover'; import {ModesGlyphHoverWidget} from './modesGlyphHover'; +import {IDisposable, dispose} from 'vs/base/common/lifecycle'; class ModesHoverController implements editorCommon.IEditorContribution { static ID = 'editor.contrib.hover'; private _editor: ICodeEditor; - private _toUnhook:ListenerUnbind[]; + private _toUnhook:IDisposable[]; private _contentWidget: ModesContentHoverWidget; private _glyphWidget: ModesGlyphHoverWidget; @@ -46,13 +46,17 @@ class ModesHoverController implements editorCommon.IEditorContribution { this._toUnhook = []; if (editor.getConfiguration().contribInfo.hover) { - this._toUnhook.push(this._editor.addListener(editorCommon.EventType.MouseDown, (e: IEditorMouseEvent) => this._onEditorMouseDown(e))); - this._toUnhook.push(this._editor.addListener(editorCommon.EventType.MouseMove, (e: IEditorMouseEvent) => this._onEditorMouseMove(e))); - this._toUnhook.push(this._editor.addListener(editorCommon.EventType.MouseLeave, (e: IEditorMouseEvent) => this._hideWidgets())); - this._toUnhook.push(this._editor.addListener(editorCommon.EventType.KeyDown, (e:IKeyboardEvent) => this._onKeyDown(e))); - this._toUnhook.push(this._editor.addListener(editorCommon.EventType.ModelChanged, () => this._hideWidgets())); - this._toUnhook.push(this._editor.addListener(editorCommon.EventType.ModelDecorationsChanged, () => this._onModelDecorationsChanged())); - this._toUnhook.push(this._editor.addListener('scroll', () => this._hideWidgets())); + this._toUnhook.push(this._editor.onMouseDown((e: IEditorMouseEvent) => this._onEditorMouseDown(e))); + this._toUnhook.push(this._editor.onMouseMove((e: IEditorMouseEvent) => this._onEditorMouseMove(e))); + this._toUnhook.push(this._editor.onMouseLeave((e: IEditorMouseEvent) => this._hideWidgets())); + this._toUnhook.push(this._editor.onKeyDown((e:IKeyboardEvent) => this._onKeyDown(e))); + this._toUnhook.push(this._editor.onDidModelChange(() => this._hideWidgets())); + this._toUnhook.push(this._editor.onDidModelDecorationsChange(() => this._onModelDecorationsChanged())); + this._toUnhook.push(this._editor.onDidScrollChange((e) => { + if (e.scrollTopChanged || e.scrollLeftChanged) { + this._hideWidgets(); + } + })); this._contentWidget = new ModesContentHoverWidget(editor, openerService); this._glyphWidget = new ModesGlyphHoverWidget(editor); @@ -127,9 +131,7 @@ class ModesHoverController implements editorCommon.IEditorContribution { } public dispose(): void { - while(this._toUnhook.length > 0) { - this._toUnhook.pop()(); - } + this._toUnhook = dispose(this._toUnhook); if (this._glyphWidget) { this._glyphWidget.dispose(); this._glyphWidget = null; diff --git a/src/vs/editor/contrib/hover/browser/hoverWidgets.ts b/src/vs/editor/contrib/hover/browser/hoverWidgets.ts index c225b831314..92d2d94124b 100644 --- a/src/vs/editor/contrib/hover/browser/hoverWidgets.ts +++ b/src/vs/editor/contrib/hover/browser/hoverWidgets.ts @@ -8,7 +8,7 @@ import {CommonKeybindings} from 'vs/base/common/keyCodes'; import {IKeyboardEvent} from 'vs/base/browser/keyboardEvent'; import {StyleMutator} from 'vs/base/browser/styleMutator'; import {Position} from 'vs/editor/common/core/position'; -import {IEditorPosition, IPosition, EventType, IConfigurationChangedEvent} from 'vs/editor/common/editorCommon'; +import {IEditorPosition, IPosition, IConfigurationChangedEvent} from 'vs/editor/common/editorCommon'; import * as editorBrowser from 'vs/editor/browser/editorBrowser'; import {Widget} from 'vs/base/browser/ui/widget'; @@ -45,7 +45,7 @@ export class ContentHoverWidget extends Widget implements editorBrowser.IContent }); this._editor.applyFontInfo(this._domNode); - this._register(this._editor.addListener2(EventType.ConfigurationChanged, (e:IConfigurationChangedEvent) => { + this._register(this._editor.onDidConfigurationChange((e:IConfigurationChangedEvent) => { if (e.fontInfo) { this._editor.applyFontInfo(this._domNode); } @@ -144,7 +144,7 @@ export class GlyphHoverWidget extends Widget implements editorBrowser.IOverlayWi this._showAtLineNumber = -1; this._editor.applyFontInfo(this._domNode); - this._register(this._editor.addListener2(EventType.ConfigurationChanged, (e:IConfigurationChangedEvent) => { + this._register(this._editor.onDidConfigurationChange((e:IConfigurationChangedEvent) => { if (e.fontInfo) { this._editor.applyFontInfo(this._domNode); } diff --git a/src/vs/editor/contrib/iPadShowKeyboard/browser/iPadShowKeyboard.ts b/src/vs/editor/contrib/iPadShowKeyboard/browser/iPadShowKeyboard.ts index ab7c931c9a3..5aa3530eb3a 100644 --- a/src/vs/editor/contrib/iPadShowKeyboard/browser/iPadShowKeyboard.ts +++ b/src/vs/editor/contrib/iPadShowKeyboard/browser/iPadShowKeyboard.ts @@ -9,7 +9,7 @@ import 'vs/css!./iPadShowKeyboard'; import {IDisposable, dispose} from 'vs/base/common/lifecycle'; import * as browser from 'vs/base/browser/browser'; import * as dom from 'vs/base/browser/dom'; -import {EventType, IEditorContribution} from 'vs/editor/common/editorCommon'; +import {IEditorContribution} from 'vs/editor/common/editorCommon'; import {ICodeEditor, IOverlayWidget, IOverlayWidgetPosition, OverlayWidgetPositionPreference} from 'vs/editor/browser/editorBrowser'; import {EditorBrowserRegistry} from 'vs/editor/browser/editorBrowserExtensions'; @@ -25,7 +25,7 @@ export class IPadShowKeyboard implements IEditorContribution { this.editor = editor; this.toDispose = []; if (browser.isIPad) { - this.toDispose.push(editor.addListener2(EventType.ConfigurationChanged, () => this.update())); + this.toDispose.push(editor.onDidConfigurationChange(() => this.update())); this.update(); } } diff --git a/src/vs/editor/contrib/links/browser/links.ts b/src/vs/editor/contrib/links/browser/links.ts index 7312b99d64e..05f06892349 100644 --- a/src/vs/editor/contrib/links/browser/links.ts +++ b/src/vs/editor/contrib/links/browser/links.ts @@ -8,7 +8,6 @@ import 'vs/css!./links'; import * as nls from 'vs/nls'; import {onUnexpectedError} from 'vs/base/common/errors'; -import {ListenerUnbind} from 'vs/base/common/eventEmitter'; import {KeyCode} from 'vs/base/common/keyCodes'; import * as platform from 'vs/base/common/platform'; import Severity from 'vs/base/common/severity'; @@ -24,8 +23,10 @@ import * as editorCommon from 'vs/editor/common/editorCommon'; import {CommonEditorRegistry, EditorActionDescriptor} from 'vs/editor/common/editorCommonExtensions'; import {ILink, LinkProviderRegistry} from 'vs/editor/common/modes'; import {IEditorWorkerService} from 'vs/editor/common/services/editorWorkerService'; -import {IEditorMouseEvent} from 'vs/editor/browser/editorBrowser'; +import {IEditorMouseEvent, ICodeEditor} from 'vs/editor/browser/editorBrowser'; import {getLinks} from 'vs/editor/contrib/links/common/links'; +import {IDisposable, dispose} from 'vs/base/common/lifecycle'; +import {EditorBrowserRegistry} from 'vs/editor/browser/editorBrowserExtensions'; class LinkOccurence { @@ -84,7 +85,13 @@ class Link { } } -class LinkDetector { +class LinkDetector implements editorCommon.IEditorContribution { + + public static ID: string = 'editor.linkDetector'; + public static get(editor:editorCommon.ICommonCodeEditor): LinkDetector { + return editor.getContribution(LinkDetector.ID); + } + static RECOMPUTE_TIME = 1000; // ms static TRIGGER_KEY_VALUE = platform.isMacintosh ? KeyCode.Meta : KeyCode.Ctrl; static TRIGGER_MODIFIER = platform.isMacintosh ? 'metaKey' : 'ctrlKey'; @@ -92,8 +99,8 @@ class LinkDetector { static CLASS_NAME = 'detected-link'; static CLASS_NAME_ACTIVE = 'detected-link-active'; - private editor:editorCommon.ICommonCodeEditor; - private listenersToRemove:ListenerUnbind[]; + private editor:ICodeEditor; + private listenersToRemove:IDisposable[]; private timeoutPromise:TPromise; private computePromise:TPromise; private activeLinkDecorationId:string; @@ -104,23 +111,23 @@ class LinkDetector { private currentOccurences:{ [decorationId:string]:LinkOccurence; }; constructor( - editor:editorCommon.ICommonCodeEditor, - editorService:IEditorService, - messageService:IMessageService, - editorWorkerService: IEditorWorkerService + editor:ICodeEditor, + @IEditorService editorService:IEditorService, + @IMessageService messageService:IMessageService, + @IEditorWorkerService editorWorkerService: IEditorWorkerService ) { this.editor = editor; this.editorService = editorService; this.messageService = messageService; this.editorWorkerService = editorWorkerService; this.listenersToRemove = []; - this.listenersToRemove.push(editor.addListener('change', (e:editorCommon.IModelContentChangedEvent) => this.onChange())); - this.listenersToRemove.push(editor.addListener(editorCommon.EventType.ModelChanged, (e:editorCommon.IModelContentChangedEvent) => this.onModelChanged())); - this.listenersToRemove.push(editor.addListener(editorCommon.EventType.ModelModeChanged, (e:editorCommon.IModelModeChangedEvent) => this.onModelModeChanged())); - this.listenersToRemove.push(this.editor.addListener(editorCommon.EventType.MouseUp, (e:IEditorMouseEvent) => this.onEditorMouseUp(e))); - this.listenersToRemove.push(this.editor.addListener(editorCommon.EventType.MouseMove, (e:IEditorMouseEvent) => this.onEditorMouseMove(e))); - this.listenersToRemove.push(this.editor.addListener(editorCommon.EventType.KeyDown, (e:IKeyboardEvent) => this.onEditorKeyDown(e))); - this.listenersToRemove.push(this.editor.addListener(editorCommon.EventType.KeyUp, (e:IKeyboardEvent) => this.onEditorKeyUp(e))); + this.listenersToRemove.push(editor.onDidModelContentChange((e:editorCommon.IModelContentChangedEvent) => this.onChange())); + this.listenersToRemove.push(editor.onDidModelChange((e) => this.onModelChanged())); + this.listenersToRemove.push(editor.onDidModelModeChange((e) => this.onModelModeChanged())); + this.listenersToRemove.push(this.editor.onMouseUp((e:IEditorMouseEvent) => this.onEditorMouseUp(e))); + this.listenersToRemove.push(this.editor.onMouseMove((e:IEditorMouseEvent) => this.onEditorMouseMove(e))); + this.listenersToRemove.push(this.editor.onKeyDown((e:IKeyboardEvent) => this.onEditorKeyDown(e))); + this.listenersToRemove.push(this.editor.onKeyUp((e:IKeyboardEvent) => this.onEditorKeyUp(e))); this.timeoutPromise = null; this.computePromise = null; this.currentOccurences = {}; @@ -128,6 +135,10 @@ class LinkDetector { this.beginCompute(); } + public getId(): string { + return LinkDetector.ID; + } + public isComputing(): boolean { return TPromise.is(this.computePromise); } @@ -397,10 +408,7 @@ class LinkDetector { } public dispose():void { - this.listenersToRemove.forEach((element) => { - element(); - }); - this.listenersToRemove = []; + this.listenersToRemove = dispose(this.listenersToRemove); this.stop(); } } @@ -409,40 +417,33 @@ class OpenLinkAction extends EditorAction { static ID = 'editor.action.openLink'; - private _linkDetector: LinkDetector; - constructor( descriptor:editorCommon.IEditorActionDescriptorData, - editor:editorCommon.ICommonCodeEditor, - @IEditorService editorService:IEditorService, - @IMessageService messageService:IMessageService, - @IEditorWorkerService editorWorkerService: IEditorWorkerService + editor:editorCommon.ICommonCodeEditor ) { super(descriptor, editor, Behaviour.WidgetFocus | Behaviour.UpdateOnCursorPositionChange); - - this._linkDetector = new LinkDetector(editor, editorService, messageService, editorWorkerService); } public dispose(): void { - this._linkDetector.dispose(); super.dispose(); } public getEnablementState(): boolean { - if(this._linkDetector.isComputing()) { + if (LinkDetector.get(this.editor).isComputing()) { // optimistic enablement while state is being computed return true; } - return !!this._linkDetector.getLinkOccurence(this.editor.getPosition()); + return !!LinkDetector.get(this.editor).getLinkOccurence(this.editor.getPosition()); } public run():TPromise { - var link = this._linkDetector.getLinkOccurence(this.editor.getPosition()); + var link = LinkDetector.get(this.editor).getLinkOccurence(this.editor.getPosition()); if(link) { - this._linkDetector.openLinkOccurence(link, false); + LinkDetector.get(this.editor).openLinkOccurence(link, false); } return TPromise.as(null); } } CommonEditorRegistry.registerEditorAction(new EditorActionDescriptor(OpenLinkAction, OpenLinkAction.ID, nls.localize('label', "Open Link"), void 0, 'Open Link')); +EditorBrowserRegistry.registerEditorContribution(LinkDetector); diff --git a/src/vs/editor/contrib/outlineMarker/browser/outlineMarker.ts b/src/vs/editor/contrib/outlineMarker/browser/outlineMarker.ts index 2bea5b95ef3..c7150b5596a 100644 --- a/src/vs/editor/contrib/outlineMarker/browser/outlineMarker.ts +++ b/src/vs/editor/contrib/outlineMarker/browser/outlineMarker.ts @@ -129,9 +129,9 @@ export class OutlineMarkerContribution implements editorCommon.IEditorContributi this._markers = []; this._currentOutlinePromise = null; - this._globalToDispose.push(this._editor.addListener2(editorCommon.EventType.ModelChanged, () => this.onChange(true))); - this._globalToDispose.push(this._editor.addListener2(editorCommon.EventType.ModelModeChanged, () => this.onChange(false))); - this._globalToDispose.push(this._editor.addListener2(editorCommon.EventType.ConfigurationChanged,(e: editorCommon.IConfigurationChangedEvent) => { + this._globalToDispose.push(this._editor.onDidModelChange(() => this.onChange(true))); + this._globalToDispose.push(this._editor.onDidModelModeChange(() => this.onChange(false))); + this._globalToDispose.push(this._editor.onDidConfigurationChange((e: editorCommon.IConfigurationChangedEvent) => { let oldIsEnabled = this._isEnabled; this._isEnabled = this._editor.getConfiguration().contribInfo.outlineMarkers; if (oldIsEnabled !== this._isEnabled) { @@ -193,7 +193,7 @@ export class OutlineMarkerContribution implements editorCommon.IEditorContributi }); }, 250); this._localToDispose.push(scheduler); - this._localToDispose.push(this._editor.addListener2('change',() => { + this._localToDispose.push(this._editor.onDidModelContentChange(() => { // Synchronously move markers this._editor.changeViewZones((viewAccessor) => { diff --git a/src/vs/editor/contrib/parameterHints/browser/parameterHintsModel.ts b/src/vs/editor/contrib/parameterHints/browser/parameterHintsModel.ts index ed21df81fc0..8c16f9b3307 100644 --- a/src/vs/editor/contrib/parameterHints/browser/parameterHintsModel.ts +++ b/src/vs/editor/contrib/parameterHints/browser/parameterHintsModel.ts @@ -8,7 +8,7 @@ import {RunOnceScheduler} from 'vs/base/common/async'; import {onUnexpectedError} from 'vs/base/common/errors'; import Event, {Emitter} from 'vs/base/common/event'; import {IDisposable, dispose, Disposable} from 'vs/base/common/lifecycle'; -import {EventType, ICommonCodeEditor, ICursorSelectionChangedEvent} from 'vs/editor/common/editorCommon'; +import {ICommonCodeEditor, ICursorSelectionChangedEvent} from 'vs/editor/common/editorCommon'; import {SignatureHelpProviderRegistry, SignatureHelp} from 'vs/editor/common/modes'; import {provideSignatureHelp} from '../common/parameterHints'; @@ -42,9 +42,9 @@ export class ParameterHintsModel extends Disposable { this.active = false; - this._register(this.editor.addListener2(EventType.ModelChanged, e => this.onModelChanged())); - this._register(this.editor.addListener2(EventType.ModelModeChanged, _ => this.onModelChanged())); - this._register(this.editor.addListener2(EventType.CursorSelectionChanged, e => this.onCursorChange(e))); + this._register(this.editor.onDidModelChange(e => this.onModelChanged())); + this._register(this.editor.onDidModelModeChange(_ => this.onModelChanged())); + this._register(this.editor.onDidCursorSelectionChange(e => this.onCursorChange(e))); this._register(SignatureHelpProviderRegistry.onDidChange(this.onModelChanged, this)); this.onModelChanged(); } @@ -107,11 +107,9 @@ export class ParameterHintsModel extends Disposable { } this.triggerCharactersListeners = support.signatureHelpTriggerCharacters.map((ch) => { - let listener = this.editor.addTypingListener(ch, () => { + return this.editor.addTypingListener(ch, () => { this.trigger(); }); - - return { dispose: listener }; }); } diff --git a/src/vs/editor/contrib/parameterHints/browser/parameterHintsWidget.ts b/src/vs/editor/contrib/parameterHints/browser/parameterHintsWidget.ts index c10aa19f8eb..b9c45f4501c 100644 --- a/src/vs/editor/contrib/parameterHints/browser/parameterHintsWidget.ts +++ b/src/vs/editor/contrib/parameterHints/browser/parameterHintsWidget.ts @@ -11,7 +11,7 @@ import {IDisposable, dispose} from 'vs/base/common/lifecycle'; import {TPromise} from 'vs/base/common/winjs.base'; import {Builder, $} from 'vs/base/browser/builder'; import aria = require('vs/base/browser/ui/aria/aria'); -import {EventType, ICursorSelectionChangedEvent, IConfigurationChangedEvent} from 'vs/editor/common/editorCommon'; +import {ICursorSelectionChangedEvent, IConfigurationChangedEvent} from 'vs/editor/common/editorCommon'; import {SignatureHelp, SignatureInformation} from 'vs/editor/common/modes'; import {ContentWidgetPositionPreference, ICodeEditor, IContentWidget, IContentWidgetPosition} from 'vs/editor/browser/editorBrowser'; import {IHintEvent, ParameterHintsModel} from './parameterHintsModel'; @@ -100,14 +100,14 @@ export class ParameterHintsWidget implements IContentWidget { this.editor.addContentWidget(this); this.hide(); - this.toDispose.push(this.editor.addListener2(EventType.CursorSelectionChanged,(e: ICursorSelectionChangedEvent) => { + this.toDispose.push(this.editor.onDidCursorSelectionChange((e: ICursorSelectionChangedEvent) => { if (this.isVisible) { this.editor.layoutContentWidget(this); } })); this.editor.applyFontInfo(this.getDomNode()); - this.toDispose.push(this.editor.addListener2(EventType.ConfigurationChanged,(e: IConfigurationChangedEvent) => { + this.toDispose.push(this.editor.onDidConfigurationChange((e: IConfigurationChangedEvent) => { if (e.fontInfo) { this.editor.applyFontInfo(this.getDomNode()); } diff --git a/src/vs/editor/contrib/quickFix/browser/quickFixModel.ts b/src/vs/editor/contrib/quickFix/browser/quickFixModel.ts index 2d60999776d..3567b2895b7 100644 --- a/src/vs/editor/contrib/quickFix/browser/quickFixModel.ts +++ b/src/vs/editor/contrib/quickFix/browser/quickFixModel.ts @@ -14,7 +14,7 @@ import URI from 'vs/base/common/uri'; import {TPromise} from 'vs/base/common/winjs.base'; import {IMarker, IMarkerService} from 'vs/platform/markers/common/markers'; import {Range} from 'vs/editor/common/core/range'; -import {EventType, ICursorPositionChangedEvent, IPosition, IRange} from 'vs/editor/common/editorCommon'; +import {ICursorPositionChangedEvent, IPosition, IRange} from 'vs/editor/common/editorCommon'; import {ICodeEditor} from 'vs/editor/browser/editorBrowser'; import {CodeActionProviderRegistry} from 'vs/editor/common/modes'; import {IQuickFix2, getCodeActions} from '../common/quickFix'; @@ -78,8 +78,8 @@ export class QuickFixModel extends EventEmitter { this.autoSuggestDelay = 300; } - this.toDispose.push(this.editor.addListener2(EventType.ModelChanged, () => this.onModelChanged())); - this.toDispose.push(this.editor.addListener2(EventType.ModelModeChanged, () => this.onModelChanged())); + this.toDispose.push(this.editor.onDidModelChange(() => this.onModelChanged())); + this.toDispose.push(this.editor.onDidModelModeChange(() => this.onModelChanged())); this.toDispose.push(CodeActionProviderRegistry.onDidChange(this.onModelChanged, this)); } @@ -98,7 +98,7 @@ export class QuickFixModel extends EventEmitter { this.markerService.onMarkerChanged(this.onMarkerChanged, this, this.toLocalDispose); - this.toLocalDispose.push(this.editor.addListener2(EventType.CursorPositionChanged, (e: ICursorPositionChangedEvent) => { + this.toLocalDispose.push(this.editor.onDidCursorPositionChange((e: ICursorPositionChangedEvent) => { this.onCursorPositionChanged(); })); } diff --git a/src/vs/editor/contrib/quickFix/browser/quickFixSelectionWidget.ts b/src/vs/editor/contrib/quickFix/browser/quickFixSelectionWidget.ts index 1b09c084ae4..eed53aa1587 100644 --- a/src/vs/editor/contrib/quickFix/browser/quickFixSelectionWidget.ts +++ b/src/vs/editor/contrib/quickFix/browser/quickFixSelectionWidget.ts @@ -8,7 +8,6 @@ import 'vs/css!./quickFix'; import * as nls from 'vs/nls'; import {illegalArgument, onUnexpectedError} from 'vs/base/common/errors'; -import {ListenerUnbind} from 'vs/base/common/eventEmitter'; import * as timer from 'vs/base/common/timer'; import {TPromise} from 'vs/base/common/winjs.base'; import * as dom from 'vs/base/browser/dom'; @@ -17,12 +16,13 @@ import {IDataSource, IFocusEvent, IRenderer, ISelectionEvent, ITree, IAccessibil import {DefaultController} from 'vs/base/parts/tree/browser/treeDefaults'; import {Tree} from 'vs/base/parts/tree/browser/treeImpl'; import {ITelemetryService} from 'vs/platform/telemetry/common/telemetry'; -import {EventType, ICursorSelectionChangedEvent, IRange} from 'vs/editor/common/editorCommon'; +import {ICursorSelectionChangedEvent, IRange} from 'vs/editor/common/editorCommon'; import {ContentWidgetPositionPreference, ICodeEditor, IContentWidget, IContentWidgetPosition} from 'vs/editor/browser/editorBrowser'; import {IQuickFix2} from '../common/quickFix'; import {QuickFixModel} from './quickFixModel'; import {alert} from 'vs/base/browser/ui/aria/aria'; import {ScrollbarVisibility} from 'vs/base/browser/ui/scrollbar/scrollableElementOptions'; +import {IDisposable, dispose} from 'vs/base/common/lifecycle'; var $ = dom.emmet; @@ -207,8 +207,8 @@ export class QuickFixSelectionWidget implements IContentWidget { private isActive: boolean; private isLoading: boolean; private isAuto: boolean; - private listenersToRemove: ListenerUnbind[]; - private modelListenersToRemove: ListenerUnbind[]; + private listenersToRemove: IDisposable[]; + private modelListenersToRemove: IDisposable[]; private model: QuickFixModel; private telemetryData: ITelemetryData; @@ -259,7 +259,7 @@ export class QuickFixSelectionWidget implements IContentWidget { ariaLabel: nls.localize('treeAriaLabel', "Quick Fix") }); - this.listenersToRemove.push(this.tree.addListener('selection', (e:ISelectionEvent) => { + this.listenersToRemove.push(this.tree.addListener2('selection', (e:ISelectionEvent) => { if (e.selection && e.selection.length > 0) { var element = e.selection[0]; if (isQuickFix(element) && !(element instanceof MessageRoot) && !(element instanceof Message)) { @@ -278,7 +278,7 @@ export class QuickFixSelectionWidget implements IContentWidget { var oldFocus: any = null; - this.listenersToRemove.push(this.tree.addListener('focus', (e:IFocusEvent) => { + this.listenersToRemove.push(this.tree.addListener2('focus', (e:IFocusEvent) => { var focus = e.focus; var payload = e.payload; @@ -313,7 +313,7 @@ export class QuickFixSelectionWidget implements IContentWidget { this.editor.addContentWidget(this); - this.listenersToRemove.push(this.editor.addListener(EventType.CursorSelectionChanged, (e: ICursorSelectionChangedEvent) => { + this.listenersToRemove.push(this.editor.onDidCursorSelectionChange((e: ICursorSelectionChangedEvent) => { if (this.isActive) { this.editor.layoutContentWidget(this); } @@ -340,7 +340,7 @@ export class QuickFixSelectionWidget implements IContentWidget { var timer : timer.ITimerEvent = null, loadingHandle:number; - this.modelListenersToRemove.push(this.model.addListener('loading', (e: any) => { + this.modelListenersToRemove.push(this.model.addListener2('loading', (e: any) => { if (!this.isActive) { timer = this.telemetryService.timedPublicLog('QuickFixSelectionWidgetLoadingTime'); this.isLoading = true; @@ -363,7 +363,7 @@ export class QuickFixSelectionWidget implements IContentWidget { } })); - this.modelListenersToRemove.push(this.model.addListener('suggest',(e: { fixes: IQuickFix2[]; range: IRange; auto:boolean; }) => { + this.modelListenersToRemove.push(this.model.addListener2('suggest',(e: { fixes: IQuickFix2[]; range: IRange; auto:boolean; }) => { this.isLoading = false; if(typeof loadingHandle !== 'undefined') { @@ -405,7 +405,7 @@ export class QuickFixSelectionWidget implements IContentWidget { } })); - this.modelListenersToRemove.push(this.model.addListener('empty', (e: { auto:boolean; }) => { + this.modelListenersToRemove.push(this.model.addListener2('empty', (e: { auto:boolean; }) => { var wasLoading = this.isLoading; this.isLoading = false; @@ -436,7 +436,7 @@ export class QuickFixSelectionWidget implements IContentWidget { } })); - this.modelListenersToRemove.push(this.model.addListener('cancel', (e:any) => { + this.modelListenersToRemove.push(this.model.addListener2('cancel', (e:any) => { this.isLoading = false; if(typeof loadingHandle !== 'undefined') { @@ -532,10 +532,7 @@ export class QuickFixSelectionWidget implements IContentWidget { } private releaseModel() : void { - var listener:()=>void; - while (listener = this.modelListenersToRemove.pop()) { - listener(); - } + this.modelListenersToRemove = dispose(this.modelListenersToRemove); this.model = null; } @@ -603,9 +600,6 @@ export class QuickFixSelectionWidget implements IContentWidget { this.tree.dispose(); this.tree = null; - this.listenersToRemove.forEach((element) => { - element(); - }); - this.listenersToRemove = null; + this.listenersToRemove = dispose(this.listenersToRemove); } } \ No newline at end of file diff --git a/src/vs/editor/contrib/referenceSearch/browser/referencesController.ts b/src/vs/editor/contrib/referenceSearch/browser/referencesController.ts index 3a903c685e6..0e4ae500885 100644 --- a/src/vs/editor/contrib/referenceSearch/browser/referencesController.ts +++ b/src/vs/editor/contrib/referenceSearch/browser/referencesController.ts @@ -89,8 +89,8 @@ export class ReferencesController implements editorCommon.IEditorContribution { this._referenceSearchVisible.set(true); // close the widget on model/mode changes - this._disposables.push(this._editor.addListener2(editorCommon.EventType.ModelModeChanged, () => { this.closeWidget(); })); - this._disposables.push(this._editor.addListener2(editorCommon.EventType.ModelChanged, () => { + this._disposables.push(this._editor.onDidModelModeChange(() => { this.closeWidget(); })); + this._disposables.push(this._editor.onDidModelChange(() => { if(!this._ignoreModelChangeEvent) { this.closeWidget(); } diff --git a/src/vs/editor/contrib/referenceSearch/browser/referencesWidget.ts b/src/vs/editor/contrib/referenceSearch/browser/referencesWidget.ts index 7010f7e1cc7..6ccfe122793 100644 --- a/src/vs/editor/contrib/referenceSearch/browser/referencesWidget.ts +++ b/src/vs/editor/contrib/referenceSearch/browser/referencesWidget.ts @@ -10,7 +10,7 @@ import * as collections from 'vs/base/common/collections'; import {onUnexpectedError} from 'vs/base/common/errors'; import {getPathLabel} from 'vs/base/common/labels'; import Event, {Emitter} from 'vs/base/common/event'; -import {IDisposable, cAll, dispose, Disposables} from 'vs/base/common/lifecycle'; +import {IDisposable, dispose, Disposables} from 'vs/base/common/lifecycle'; import {Schemas} from 'vs/base/common/network'; import * as strings from 'vs/base/common/strings'; import {TPromise} from 'vs/base/common/winjs.base'; @@ -34,7 +34,7 @@ import {DefaultConfig} from 'vs/editor/common/config/defaultConfig'; import {Range} from 'vs/editor/common/core/range'; import * as editorCommon from 'vs/editor/common/editorCommon'; import {Model} from 'vs/editor/common/model/model'; -import {ICodeEditor, IMouseTarget} from 'vs/editor/browser/editorBrowser'; +import {ICodeEditor} from 'vs/editor/browser/editorBrowser'; import {EmbeddedCodeEditorWidget} from 'vs/editor/browser/widget/embeddedCodeEditorWidget'; import {PeekViewWidget, IPeekViewService} from 'vs/editor/contrib/zoneWidget/browser/peekViewWidget'; import {FileReferences, OneReference, ReferencesModel} from './referencesModel'; @@ -48,24 +48,24 @@ class DecorationsManager implements IDisposable { private _decorationSet = collections.createStringDictionary(); private _decorationIgnoreSet = collections.createStringDictionary(); - private _callOnDispose:Function[] = []; - private _callOnModelChange:Function[] = []; + private _callOnDispose:IDisposable[] = []; + private _callOnModelChange:IDisposable[] = []; constructor(private editor:ICodeEditor, private model:ReferencesModel) { - this._callOnDispose.push(this.editor.addListener(editorCommon.EventType.ModelChanged, () => this._onModelChanged())); + this._callOnDispose.push(this.editor.onDidModelChange(() => this._onModelChanged())); this._onModelChanged(); } public dispose(): void { - this._callOnModelChange = cAll(this._callOnModelChange); - this._callOnDispose = cAll(this._callOnDispose); + this._callOnModelChange = dispose(this._callOnModelChange); + this._callOnDispose = dispose(this._callOnDispose); this.removeDecorations(); } private _onModelChanged():void { this.removeDecorations(); - this._callOnModelChange = cAll(this._callOnModelChange); + this._callOnModelChange = dispose(this._callOnModelChange); var model = this.editor.getModel(); if(!model) { @@ -81,7 +81,7 @@ class DecorationsManager implements IDisposable { } private _addDecorations(reference:FileReferences):void { - this._callOnModelChange.push(this.editor.getModel().addListener(editorCommon.EventType.ModelDecorationsChanged, (event) => this._onDecorationChanged(event))); + this._callOnModelChange.push(this.editor.getModel().addListener2(editorCommon.EventType.ModelDecorationsChanged, (event) => this._onDecorationChanged(event))); this.editor.getModel().changeDecorations((accessor) => { var newDecorations: editorCommon.IModelDeltaDecoration[] = []; @@ -649,7 +649,7 @@ export class ReferenceWidget extends PeekViewWidget { })); // listen on editor - this._disposeOnNewModel.push(this._preview.addListener2(editorCommon.EventType.MouseDown, (e: { event: MouseEvent; target: IMouseTarget; }) => { + this._disposeOnNewModel.push(this._preview.onMouseDown((e) => { if (e.event.detail === 2) { this._onDidSelectReference.fire({ element: this._getFocusedReference(), diff --git a/src/vs/editor/contrib/rename/browser/renameInputField.ts b/src/vs/editor/contrib/rename/browser/renameInputField.ts index 79dbc76b870..45c82361333 100644 --- a/src/vs/editor/contrib/rename/browser/renameInputField.ts +++ b/src/vs/editor/contrib/rename/browser/renameInputField.ts @@ -11,7 +11,7 @@ import {canceled} from 'vs/base/common/errors'; import {IDisposable, dispose} from 'vs/base/common/lifecycle'; import {TPromise} from 'vs/base/common/winjs.base'; import {Range} from 'vs/editor/common/core/range'; -import {EventType, IPosition, IRange} from 'vs/editor/common/editorCommon'; +import {IPosition, IRange} from 'vs/editor/common/editorCommon'; import {ContentWidgetPositionPreference, ICodeEditor, IContentWidget, IContentWidgetPosition} from 'vs/editor/browser/editorBrowser'; export default class RenameInputField implements IContentWidget, IDisposable { @@ -116,8 +116,8 @@ export default class RenameInputField implements IContentWidget, IDisposable { } }; - disposeOnDone.push(this._editor.addListener2(EventType.CursorSelectionChanged, onCursorChanged)); - disposeOnDone.push(this._editor.addListener2(EventType.EditorBlur, this._currentCancelInput)); + disposeOnDone.push(this._editor.onDidCursorSelectionChange(onCursorChanged)); + disposeOnDone.push(this._editor.onDidEditorBlur(this._currentCancelInput)); this._show(); diff --git a/src/vs/editor/contrib/selectionClipboard/electron-browser/selectionClipboard.ts b/src/vs/editor/contrib/selectionClipboard/electron-browser/selectionClipboard.ts index 72fe4eaa3e9..94673ab4820 100644 --- a/src/vs/editor/contrib/selectionClipboard/electron-browser/selectionClipboard.ts +++ b/src/vs/editor/contrib/selectionClipboard/electron-browser/selectionClipboard.ts @@ -9,7 +9,7 @@ import {clipboard} from 'electron'; import * as platform from 'vs/base/common/platform'; import {ICodeEditor, IEditorMouseEvent} from 'vs/editor/browser/editorBrowser'; import {Disposable} from 'vs/base/common/lifecycle'; -import {EndOfLinePreference, EventType, IEditorContribution, ICursorSelectionChangedEvent, IConfigurationChangedEvent} from 'vs/editor/common/editorCommon'; +import {EndOfLinePreference, IEditorContribution, ICursorSelectionChangedEvent, IConfigurationChangedEvent} from 'vs/editor/common/editorCommon'; import {EditorBrowserRegistry} from 'vs/editor/browser/editorBrowserExtensions'; import {IKeybindingService} from 'vs/platform/keybinding/common/keybindingService'; import {RunOnceScheduler} from 'vs/base/common/async'; @@ -25,13 +25,13 @@ class SelectionClipboard extends Disposable implements IEditorContribution { if (platform.isLinux) { var isEnabled = editor.getConfiguration().contribInfo.selectionClipboard; - this._register(editor.addListener2(EventType.ConfigurationChanged, (e:IConfigurationChangedEvent) => { + this._register(editor.onDidConfigurationChange((e:IConfigurationChangedEvent) => { if (e.contribInfo) { isEnabled = editor.getConfiguration().contribInfo.selectionClipboard; } })); - this._register(editor.addListener2(EventType.MouseDown, (e:IEditorMouseEvent) => { + this._register(editor.onMouseDown((e:IEditorMouseEvent) => { if (!isEnabled) { return; } @@ -81,7 +81,7 @@ class SelectionClipboard extends Disposable implements IEditorContribution { clipboard.writeText(textToCopy, 'selection'); }, 100)); - this._register(editor.addListener2(EventType.CursorSelectionChanged, (e:ICursorSelectionChangedEvent) => { + this._register(editor.onDidCursorSelectionChange((e:ICursorSelectionChangedEvent) => { if (!isEnabled) { return; } diff --git a/src/vs/editor/contrib/smartSelect/common/smartSelect.ts b/src/vs/editor/contrib/smartSelect/common/smartSelect.ts index b7db51d062f..61a60b36112 100644 --- a/src/vs/editor/contrib/smartSelect/common/smartSelect.ts +++ b/src/vs/editor/contrib/smartSelect/common/smartSelect.ts @@ -12,7 +12,7 @@ import {IInstantiationService} from 'vs/platform/instantiation/common/instantiat import {Range} from 'vs/editor/common/core/range'; import {EditorAction} from 'vs/editor/common/editorAction'; import {Behaviour} from 'vs/editor/common/editorActionEnablement'; -import {EventType, ICommonCodeEditor, ICursorPositionChangedEvent, IEditorActionDescriptorData, IEditorRange} from 'vs/editor/common/editorCommon'; +import {ICommonCodeEditor, ICursorPositionChangedEvent, IEditorActionDescriptorData, IEditorRange} from 'vs/editor/common/editorCommon'; import {CommonEditorRegistry, ContextKey, EditorActionDescriptor} from 'vs/editor/common/editorCommonExtensions'; import {TokenSelectionSupport, ILogicalSelectionEntry} from './tokenSelectionSupport'; @@ -98,12 +98,12 @@ class SmartSelect extends EditorAction { state = editorState; // listen to caret move and forget about state - var unhook: () => void = this.editor.addListener(EventType.CursorPositionChanged,(e: ICursorPositionChangedEvent) => { + var unhook = this.editor.onDidCursorPositionChange((e: ICursorPositionChangedEvent) => { if (ignoreSelection) { return; } state = null; - unhook(); + unhook.dispose(); }); }); } diff --git a/src/vs/editor/contrib/snippet/common/snippet.ts b/src/vs/editor/contrib/snippet/common/snippet.ts index 1471788d328..73f8912a7d9 100644 --- a/src/vs/editor/contrib/snippet/common/snippet.ts +++ b/src/vs/editor/contrib/snippet/common/snippet.ts @@ -6,7 +6,6 @@ 'use strict'; import * as collections from 'vs/base/common/collections'; -import {ListenerUnbind} from 'vs/base/common/eventEmitter'; import {KeyCode, KeyMod} from 'vs/base/common/keyCodes'; import * as strings from 'vs/base/common/strings'; import {IKeybindingContextKey, IKeybindingService} from 'vs/platform/keybinding/common/keybindingService'; @@ -15,6 +14,7 @@ import {Range} from 'vs/editor/common/core/range'; import {Selection} from 'vs/editor/common/core/selection'; import * as editorCommon from 'vs/editor/common/editorCommon'; import {CommonEditorRegistry} from 'vs/editor/common/editorCommonExtensions'; +import {IDisposable, dispose} from 'vs/base/common/lifecycle'; interface IParsedLinePlaceHolderInfo { id: string; @@ -384,7 +384,7 @@ class InsertSnippetController { private model: editorCommon.IModel; private finishPlaceHolderIndex:number; - private listenersToRemove:ListenerUnbind[]; + private listenersToRemove:IDisposable[]; private trackedPlaceHolders:ITrackedPlaceHolder[]; private placeHolderDecorations: string[]; private currentPlaceHolderIndex:number; @@ -460,7 +460,7 @@ class InsertSnippetController { }); this.listenersToRemove = []; - this.listenersToRemove.push(this.editor.addListener(editorCommon.EventType.ModelContentChanged, (e:editorCommon.IModelContentChangedEvent) => { + this.listenersToRemove.push(this.editor.onDidModelContentChange((e:editorCommon.IModelContentChangedEvent) => { if (this.isFinished) { return; } @@ -502,7 +502,7 @@ class InsertSnippetController { } })); - this.listenersToRemove.push(this.editor.addListener(editorCommon.EventType.CursorPositionChanged, (e:editorCommon.ICursorPositionChangedEvent) => { + this.listenersToRemove.push(this.editor.onDidCursorPositionChange((e:editorCommon.ICursorPositionChangedEvent) => { if (this.isFinished) { return; } @@ -513,19 +513,19 @@ class InsertSnippetController { } })); - this.listenersToRemove.push(this.editor.addListener(editorCommon.EventType.ModelChanged, () => { + this.listenersToRemove.push(this.editor.onDidModelChange(() => { this.stopAll(); })); var blurTimeout = -1; - this.listenersToRemove.push(this.editor.addListener(editorCommon.EventType.EditorBlur, () => { + this.listenersToRemove.push(this.editor.onDidEditorBlur(() => { // Blur if within 100ms we do not focus back blurTimeout = setTimeout(() => { this.stopAll(); }, 100); })); - this.listenersToRemove.push(this.editor.addListener(editorCommon.EventType.EditorFocus, () => { + this.listenersToRemove.push(this.editor.onDidEditorFocus(() => { // Cancel the blur timeout (if any) if (blurTimeout !== -1) { clearTimeout(blurTimeout); @@ -533,7 +533,7 @@ class InsertSnippetController { } })); - this.listenersToRemove.push(this.model.addListener(editorCommon.EventType.ModelDecorationsChanged, (e: editorCommon.IModelDecorationsChangedEvent) => { + this.listenersToRemove.push(this.model.addListener2(editorCommon.EventType.ModelDecorationsChanged, (e: editorCommon.IModelDecorationsChangedEvent) => { if (this.isFinished) { return; } @@ -676,10 +676,7 @@ class InsertSnippetController { this.isFinished = true; - this.listenersToRemove.forEach((element) => { - element(); - }); - this.listenersToRemove = []; + this.listenersToRemove = dispose(this.listenersToRemove); for (var i = 0; i < this.trackedPlaceHolders.length; i++) { var ranges = this.trackedPlaceHolders[i].ranges; diff --git a/src/vs/editor/contrib/suggest/browser/suggest.ts b/src/vs/editor/contrib/suggest/browser/suggest.ts index 23127b8e44a..caea6a07f9f 100644 --- a/src/vs/editor/contrib/suggest/browser/suggest.ts +++ b/src/vs/editor/contrib/suggest/browser/suggest.ts @@ -7,12 +7,12 @@ import * as nls from 'vs/nls'; import {onUnexpectedError} from 'vs/base/common/errors'; import {KeyCode, KeyMod} from 'vs/base/common/keyCodes'; -import {IDisposable, cAll, dispose} from 'vs/base/common/lifecycle'; +import {IDisposable, dispose} from 'vs/base/common/lifecycle'; import {TPromise} from 'vs/base/common/winjs.base'; import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation'; import {IKeybindingContextKey, IKeybindingService, KbExpr} from 'vs/platform/keybinding/common/keybindingService'; import {EditorAction} from 'vs/editor/common/editorAction'; -import {EventType, ICommonCodeEditor, IEditorActionDescriptorData, IEditorContribution} from 'vs/editor/common/editorCommon'; +import {ICommonCodeEditor, IEditorActionDescriptorData, IEditorContribution} from 'vs/editor/common/editorCommon'; import {CommonEditorRegistry, ContextKey, EditorActionDescriptor} from 'vs/editor/common/editorCommonExtensions'; import {ISuggestSupport, SuggestRegistry} from 'vs/editor/common/modes'; import {ICodeEditor} from 'vs/editor/browser/editorBrowser'; @@ -33,7 +33,7 @@ export class SuggestController implements IEditorContribution { private model: SuggestModel; private widget: SuggestWidget; - private triggerCharacterListeners: Function[]; + private triggerCharacterListeners: IDisposable[]; private suggestWidgetVisible: IKeybindingContextKey; private toDispose: IDisposable[]; @@ -50,9 +50,9 @@ export class SuggestController implements IEditorContribution { this.toDispose = []; this.toDispose.push(this.widget.onDidVisibilityChange(visible => visible ? this.suggestWidgetVisible.set(true) : this.suggestWidgetVisible.reset())); - this.toDispose.push(editor.addListener2(EventType.ConfigurationChanged, () => this.update())); - this.toDispose.push(editor.addListener2(EventType.ModelChanged, () => this.update())); - this.toDispose.push(editor.addListener2(EventType.ModelModeChanged, () => this.update())); + this.toDispose.push(editor.onDidConfigurationChange(() => this.update())); + this.toDispose.push(editor.onDidModelChange(() => this.update())); + this.toDispose.push(editor.onDidModelModeChange(() => this.update())); this.toDispose.push(SuggestRegistry.onDidChange(this.update, this)); this.toDispose.push(this.model.onDidAccept(e => getSnippetController(this.editor).run(e.snippet, e.overwriteBefore, e.overwriteAfter))); @@ -66,7 +66,7 @@ export class SuggestController implements IEditorContribution { public dispose(): void { this.toDispose = dispose(this.toDispose); - this.triggerCharacterListeners = cAll(this.triggerCharacterListeners); + this.triggerCharacterListeners = dispose(this.triggerCharacterListeners); if (this.widget) { this.widget.dispose(); @@ -80,7 +80,7 @@ export class SuggestController implements IEditorContribution { private update(): void { - this.triggerCharacterListeners = cAll(this.triggerCharacterListeners); + this.triggerCharacterListeners = dispose(this.triggerCharacterListeners); if (this.editor.getConfiguration().readOnly || !this.editor.getModel() diff --git a/src/vs/editor/contrib/suggest/browser/suggestModel.ts b/src/vs/editor/contrib/suggest/browser/suggestModel.ts index 7408e97415e..d2d6db4b696 100644 --- a/src/vs/editor/contrib/suggest/browser/suggestModel.ts +++ b/src/vs/editor/contrib/suggest/browser/suggestModel.ts @@ -9,7 +9,7 @@ import Event, { Emitter } from 'vs/base/common/event'; import {IDisposable, dispose} from 'vs/base/common/lifecycle'; import {startsWith} from 'vs/base/common/strings'; import {TPromise} from 'vs/base/common/winjs.base'; -import {EventType, ICommonCodeEditor, ICursorSelectionChangedEvent, IEditorPosition, CursorChangeReason} from 'vs/editor/common/editorCommon'; +import {ICommonCodeEditor, ICursorSelectionChangedEvent, IEditorPosition, CursorChangeReason} from 'vs/editor/common/editorCommon'; import {ISuggestSupport, ISuggestion, SuggestRegistry} from 'vs/editor/common/modes'; import {CodeSnippet} from 'vs/editor/contrib/snippet/common/snippet'; import {ISuggestResult2, provideCompletionItems} from '../common/suggest'; @@ -196,9 +196,9 @@ export class SuggestModel implements IDisposable { this.context = null; this.toDispose = []; - this.toDispose.push(this.editor.addListener2(EventType.ConfigurationChanged, () => this.onEditorConfigurationChange())); - this.toDispose.push(this.editor.addListener2(EventType.CursorSelectionChanged, e => this.onCursorChange(e))); - this.toDispose.push(this.editor.addListener2(EventType.ModelChanged, () => this.cancel())); + this.toDispose.push(this.editor.onDidConfigurationChange(() => this.onEditorConfigurationChange())); + this.toDispose.push(this.editor.onDidCursorSelectionChange(e => this.onCursorChange(e))); + this.toDispose.push(this.editor.onDidModelChange(() => this.cancel())); this.toDispose.push(SuggestRegistry.onDidChange(this.onSuggestRegistryChange, this)); this.onEditorConfigurationChange(); } diff --git a/src/vs/editor/contrib/suggest/browser/suggestWidget.ts b/src/vs/editor/contrib/suggest/browser/suggestWidget.ts index 446102826d0..63f057a96ee 100644 --- a/src/vs/editor/contrib/suggest/browser/suggestWidget.ts +++ b/src/vs/editor/contrib/suggest/browser/suggestWidget.ts @@ -21,7 +21,7 @@ import {DomScrollableElement} from 'vs/base/browser/ui/scrollbar/scrollableEleme import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation'; import {IKeybindingContextKey, IKeybindingService} from 'vs/platform/keybinding/common/keybindingService'; import {ITelemetryService} from 'vs/platform/telemetry/common/telemetry'; -import {EventType, IConfigurationChangedEvent} from 'vs/editor/common/editorCommon'; +import {IConfigurationChangedEvent} from 'vs/editor/common/editorCommon'; import {ContentWidgetPositionPreference, ICodeEditor, IContentWidget, IContentWidgetPosition} from 'vs/editor/browser/editorBrowser'; import {CONTEXT_SUGGESTION_SUPPORTS_ACCEPT_ON_KEY} from '../common/suggest'; import {CompletionItem, CompletionModel} from './completionModel'; @@ -81,7 +81,7 @@ class Renderer implements IRenderer { configureFont(); - data.disposables.push(this.editor.addListener2(EventType.ConfigurationChanged, (e: IConfigurationChangedEvent) => { + data.disposables.push(this.editor.onDidConfigurationChange((e: IConfigurationChangedEvent) => { if (e.fontInfo) { configureFont(); } @@ -231,7 +231,7 @@ class SuggestionDetails { this.configureFont(); - this.disposables.push(this.editor.addListener2(EventType.ConfigurationChanged, (e: IConfigurationChangedEvent) => { + this.disposables.push(this.editor.onDidConfigurationChange((e: IConfigurationChangedEvent) => { if (e.fontInfo) { this.configureFont(); } @@ -369,10 +369,10 @@ export class SuggestWidget implements IContentWidget, IDisposable { this.list = new List(this.listElement, this.delegate, [renderer]); this.toDispose = [ - editor.addListener2(EventType.EditorTextBlur, () => this.onEditorBlur()), + editor.onDidEditorTextBlur(() => this.onEditorBlur()), this.list.onSelectionChange(e => this.onListSelection(e)), this.list.onFocusChange(e => this.onListFocus(e)), - this.editor.addListener2(EventType.CursorSelectionChanged, () => this.onCursorSelectionChanged()), + this.editor.onDidCursorSelectionChange(() => this.onCursorSelectionChanged()), this.model.onDidTrigger(e => this.onDidTrigger(e)), this.model.onDidSuggest(e => this.onDidSuggest(e)), this.model.onDidCancel(e => this.onDidCancel(e)) diff --git a/src/vs/editor/contrib/wordHighlighter/common/wordHighlighter.ts b/src/vs/editor/contrib/wordHighlighter/common/wordHighlighter.ts index 1edf78e99df..e8fcca14489 100644 --- a/src/vs/editor/contrib/wordHighlighter/common/wordHighlighter.ts +++ b/src/vs/editor/contrib/wordHighlighter/common/wordHighlighter.ts @@ -11,6 +11,7 @@ import {Range} from 'vs/editor/common/core/range'; import * as editorCommon from 'vs/editor/common/editorCommon'; import {CommonEditorRegistry} from 'vs/editor/common/editorCommonExtensions'; import {DocumentHighlight, DocumentHighlightKind, DocumentHighlightProviderRegistry} from 'vs/editor/common/modes'; +import {IDisposable, dispose} from 'vs/base/common/lifecycle'; export function getOccurrencesAtPosition(model: editorCommon.IReadOnlyModel, position: editorCommon.IEditorPosition):TPromise { @@ -48,7 +49,7 @@ class WordHighlighter { private model: editorCommon.IModel; private _lastWordRange: editorCommon.IEditorRange; private _decorationIds: string[]; - private toUnhook: Function[]; + private toUnhook: IDisposable[]; private workerRequestTokenId:number = 0; private workerRequest:TPromise = null; @@ -62,14 +63,14 @@ class WordHighlighter { this.editor = editor; this.model = this.editor.getModel(); this.toUnhook = []; - this.toUnhook.push(editor.addListener(editorCommon.EventType.CursorPositionChanged, (e:editorCommon.ICursorPositionChangedEvent) => { + this.toUnhook.push(editor.onDidCursorPositionChange((e:editorCommon.ICursorPositionChangedEvent) => { this._onPositionChanged(e); })); - this.toUnhook.push(editor.addListener(editorCommon.EventType.ModelChanged, (e) => { + this.toUnhook.push(editor.onDidModelChange((e) => { this._stopAll(); this.model = this.editor.getModel(); })); - this.toUnhook.push(editor.addListener('change', (e) => { + this.toUnhook.push(editor.onDidModelContentChange((e) => { this._stopAll(); })); @@ -265,9 +266,7 @@ class WordHighlighter { public destroy(): void { this._stopAll(); - while(this.toUnhook.length > 0) { - this.toUnhook.pop()(); - } + this.toUnhook = dispose(this.toUnhook); } } diff --git a/src/vs/editor/contrib/zoneWidget/browser/zoneWidget.ts b/src/vs/editor/contrib/zoneWidget/browser/zoneWidget.ts index 458016f2417..6e0d87a59a4 100644 --- a/src/vs/editor/contrib/zoneWidget/browser/zoneWidget.ts +++ b/src/vs/editor/contrib/zoneWidget/browser/zoneWidget.ts @@ -10,7 +10,7 @@ import {Disposables} from 'vs/base/common/lifecycle'; import * as objects from 'vs/base/common/objects'; import * as dom from 'vs/base/browser/dom'; import {Sash, Orientation, IHorizontalSashLayoutProvider, ISashEvent} from 'vs/base/browser/ui/sash/sash'; -import {EventType, EditorLayoutInfo, IPosition, IRange} from 'vs/editor/common/editorCommon'; +import {EditorLayoutInfo, IPosition, IRange} from 'vs/editor/common/editorCommon'; import {Range} from 'vs/editor/common/core/range'; import {Position} from 'vs/editor/common/core/position'; import {ICodeEditor, IOverlayWidget, IOverlayWidgetPosition, IViewZone, IViewZoneChangeAccessor} from 'vs/editor/browser/editorBrowser'; @@ -111,7 +111,7 @@ export abstract class ZoneWidget implements IHorizontalSashLayoutProvider { this.domNode.setAttribute('role', 'presentation'); } - this._disposables.add(this.editor.addListener2(EventType.EditorLayout, (info: EditorLayoutInfo) => { + this._disposables.add(this.editor.onDidLayoutChange((info: EditorLayoutInfo) => { var width = this._getWidth(info); this.domNode.style.width = width + 'px'; this._onWidth(width); diff --git a/src/vs/editor/test/common/controller/cursor.test.ts b/src/vs/editor/test/common/controller/cursor.test.ts index 0221c68b9ea..fe9d121ba2f 100644 --- a/src/vs/editor/test/common/controller/cursor.test.ts +++ b/src/vs/editor/test/common/controller/cursor.test.ts @@ -722,10 +722,10 @@ suite('Editor Controller - Cursor', () => { // --------- eventing test('no move doesn\'t trigger event', () => { - thisCursor.addListener(EventType.CursorPositionChanged, (e) => { + thisCursor.addListener2(EventType.CursorPositionChanged, (e) => { assert.ok(false, 'was not expecting event'); }); - thisCursor.addListener(EventType.CursorSelectionChanged, (e) => { + thisCursor.addListener2(EventType.CursorSelectionChanged, (e) => { assert.ok(false, 'was not expecting event'); }); moveTo(thisCursor, 1, 1); @@ -733,11 +733,11 @@ suite('Editor Controller - Cursor', () => { test('move eventing', () => { let events = 0; - thisCursor.addListener(EventType.CursorPositionChanged, (e) => { + thisCursor.addListener2(EventType.CursorPositionChanged, (e) => { events++; positionEqual(e.position, 1, 2); }); - thisCursor.addListener(EventType.CursorSelectionChanged, (e) => { + thisCursor.addListener2(EventType.CursorSelectionChanged, (e) => { events++; selectionEqual(e.selection, 1, 2, 1, 2); }); @@ -747,11 +747,11 @@ suite('Editor Controller - Cursor', () => { test('move in selection mode eventing', () => { let events = 0; - thisCursor.addListener(EventType.CursorPositionChanged, (e) => { + thisCursor.addListener2(EventType.CursorPositionChanged, (e) => { events++; positionEqual(e.position, 1, 2); }); - thisCursor.addListener(EventType.CursorSelectionChanged, (e) => { + thisCursor.addListener2(EventType.CursorSelectionChanged, (e) => { events++; selectionEqual(e.selection, 1, 2, 1, 1); }); diff --git a/src/vs/editor/test/common/model/editableTextModel.test.ts b/src/vs/editor/test/common/model/editableTextModel.test.ts index 6cbdafa02b7..7d8004f3326 100644 --- a/src/vs/editor/test/common/model/editableTextModel.test.ts +++ b/src/vs/editor/test/common/model/editableTextModel.test.ts @@ -1340,7 +1340,7 @@ suite('EditorModel - EditableTextModel.applyEdits', () => { }, (model) => { var isFirstTime = true; - model.addBulkListener((events) => { + model.addBulkListener2((events) => { if (!isFirstTime) { return; } @@ -1370,7 +1370,7 @@ suite('EditorModel - EditableTextModel.applyEdits', () => { }, (model) => { var isFirstTime = true; - model.addListener(EventType.ModelContentChanged2, (e:IModelContentChangedEvent2) => { + model.addListener2(EventType.ModelContentChanged2, (e:IModelContentChangedEvent2) => { if (!isFirstTime) { return; } @@ -1393,7 +1393,7 @@ suite('EditorModel - EditableTextModel.applyEdits', () => { let mirrorModel2 = new MirrorModel2(null, model.toRawText().lines, model.toRawText().EOL, model.getVersionId()); let mirrorModel2PrevVersionId = model.getVersionId(); - model.addListener(EventType.ModelContentChanged2, (e:IModelContentChangedEvent2) => { + model.addListener2(EventType.ModelContentChanged2, (e:IModelContentChangedEvent2) => { let versionId = e.versionId; if (versionId < mirrorModel2PrevVersionId) { console.warn('Model version id did not advance between edits (2)'); diff --git a/src/vs/editor/test/common/model/editableTextModelTestUtils.ts b/src/vs/editor/test/common/model/editableTextModelTestUtils.ts index 90c86bab9ce..0a8a5bd0460 100644 --- a/src/vs/editor/test/common/model/editableTextModelTestUtils.ts +++ b/src/vs/editor/test/common/model/editableTextModelTestUtils.ts @@ -51,7 +51,7 @@ export function assertSyncedModels(text:string, callback:(model:EditableTextMod var mirrorModel2 = new MirrorModel2(null, model.toRawText().lines, model.toRawText().EOL, model.getVersionId()); var mirrorModel2PrevVersionId = model.getVersionId(); - model.addListener(editorCommon.EventType.ModelContentChanged, (e:editorCommon.IModelContentChangedEvent) => { + model.addListener2(editorCommon.EventType.ModelContentChanged, (e:editorCommon.IModelContentChangedEvent) => { let versionId = e.versionId; if (versionId < mirrorModel1PrevVersionId) { console.warn('Model version id did not advance between edits (1)'); @@ -63,7 +63,7 @@ export function assertSyncedModels(text:string, callback:(model:EditableTextMod mirrorModel1.onEvents(mirrorModelEvents); }); - model.addListener(editorCommon.EventType.ModelContentChanged2, (e:editorCommon.IModelContentChangedEvent2) => { + model.addListener2(editorCommon.EventType.ModelContentChanged2, (e:editorCommon.IModelContentChangedEvent2) => { let versionId = e.versionId; if (versionId < mirrorModel2PrevVersionId) { console.warn('Model version id did not advance between edits (2)'); diff --git a/src/vs/editor/test/common/model/model.test.ts b/src/vs/editor/test/common/model/model.test.ts index 501b4d97e69..d4b1b00d65c 100644 --- a/src/vs/editor/test/common/model/model.test.ts +++ b/src/vs/editor/test/common/model/model.test.ts @@ -109,7 +109,7 @@ suite('Editor Model - Model', () => { // --------- insert text eventing test('model insert empty text does not trigger eventing', () => { - thisModel.addListener(EventType.ModelContentChanged, (e) => { + thisModel.addListener2(EventType.ModelContentChanged, (e) => { assert.ok(false, 'was not expecting event'); }); thisModel.applyEdits([EditOperation.insert(new Position(1, 1), '')]); @@ -117,7 +117,7 @@ suite('Editor Model - Model', () => { test('model insert text without newline eventing', () => { var listenerCalls = 0; - thisModel.addListener(EventType.ModelContentChanged, (e) => { + thisModel.addListener2(EventType.ModelContentChanged, (e) => { listenerCalls++; assert.equal(e.changeType, EventType.ModelContentChangedLineChanged); assert.equal(e.lineNumber, 1); @@ -130,7 +130,7 @@ suite('Editor Model - Model', () => { var listenerCalls = 0; var order = 0; - thisModel.addListener(EventType.ModelContentChanged, (e) => { + thisModel.addListener2(EventType.ModelContentChanged, (e) => { listenerCalls++; if (e.changeType === EventType.ModelContentChangedLineChanged) { @@ -206,7 +206,7 @@ suite('Editor Model - Model', () => { // --------- delete text eventing test('model delete empty text does not trigger eventing', () => { - thisModel.addListener(EventType.ModelContentChanged, (e) => { + thisModel.addListener2(EventType.ModelContentChanged, (e) => { assert.ok(false, 'was not expecting event'); }); thisModel.applyEdits([EditOperation.delete(new Range(1, 1, 1, 1))]); @@ -214,7 +214,7 @@ suite('Editor Model - Model', () => { test('model delete text from one line eventing', () => { var listenerCalls = 0; - thisModel.addListener(EventType.ModelContentChanged, (e) => { + thisModel.addListener2(EventType.ModelContentChanged, (e) => { listenerCalls++; assert.equal(e.changeType, EventType.ModelContentChangedLineChanged); assert.equal(e.lineNumber, 1); @@ -225,7 +225,7 @@ suite('Editor Model - Model', () => { test('model delete all text from a line eventing', () => { var listenerCalls = 0; - thisModel.addListener(EventType.ModelContentChanged, (e) => { + thisModel.addListener2(EventType.ModelContentChanged, (e) => { listenerCalls++; assert.equal(e.changeType, EventType.ModelContentChangedLineChanged); assert.equal(e.lineNumber, 1); @@ -237,7 +237,7 @@ suite('Editor Model - Model', () => { test('model delete text from two lines eventing', () => { var listenerCalls = 0; var order = 0; - thisModel.addListener(EventType.ModelContentChanged, (e) => { + thisModel.addListener2(EventType.ModelContentChanged, (e) => { listenerCalls++; if (e.changeType === EventType.ModelContentChangedLineChanged) { @@ -265,7 +265,7 @@ suite('Editor Model - Model', () => { var listenerCalls = 0; var order = 0; - thisModel.addListener(EventType.ModelContentChanged, (e) => { + thisModel.addListener2(EventType.ModelContentChanged, (e) => { listenerCalls++; if (e.changeType === EventType.ModelContentChangedLineChanged) { @@ -324,7 +324,7 @@ suite('Editor Model - Model', () => { // --------- setValue test('setValue eventing', () => { var listenerCalls = 0; - thisModel.addOneTimeListener(EventType.ModelContentChanged, (e:IModelContentChangedEvent) => { + thisModel.addOneTimeDisposableListener(EventType.ModelContentChanged, (e:IModelContentChangedEvent) => { listenerCalls++; assert.equal(e.changeType, EventType.ModelContentChangedFlush); diff --git a/src/vs/editor/test/common/model/modelDecorations.test.ts b/src/vs/editor/test/common/model/modelDecorations.test.ts index f3a96344a13..b6dde6fbf63 100644 --- a/src/vs/editor/test/common/model/modelDecorations.test.ts +++ b/src/vs/editor/test/common/model/modelDecorations.test.ts @@ -200,7 +200,7 @@ suite('Editor Model - Model Decorations', () => { test('decorations emit event on add', () => { var listenerCalled = 0; - thisModel.addListener(EventType.ModelDecorationsChanged, (e) => { + thisModel.addListener2(EventType.ModelDecorationsChanged, (e) => { listenerCalled++; assert.equal(e.ids.length, 1); assert.equal(e.addedOrChangedDecorations.length, 1); @@ -219,7 +219,7 @@ suite('Editor Model - Model Decorations', () => { test('decorations emit event on change', () => { var listenerCalled = 0; var decId = addDecoration(thisModel, 1, 2, 3, 2, 'myType'); - thisModel.addListener(EventType.ModelDecorationsChanged, (e) => { + thisModel.addListener2(EventType.ModelDecorationsChanged, (e) => { listenerCalled++; assert.equal(e.ids.length, 1); assert.equal(e.addedOrChangedDecorations.length, 1); @@ -246,7 +246,7 @@ suite('Editor Model - Model Decorations', () => { test('decorations emit event on remove', () => { var listenerCalled = 0; var decId = addDecoration(thisModel, 1, 2, 3, 2, 'myType'); - thisModel.addListener(EventType.ModelDecorationsChanged, (e) => { + thisModel.addListener2(EventType.ModelDecorationsChanged, (e) => { listenerCalled++; assert.equal(e.ids.length, 1); assert.equal(e.addedOrChangedDecorations.length, 0); @@ -269,7 +269,7 @@ suite('Editor Model - Model Decorations', () => { var listenerCalled = 0; var decId = addDecoration(thisModel, 1, 2, 3, 2, 'myType'); - thisModel.addListener(EventType.ModelDecorationsChanged, (e) => { + thisModel.addListener2(EventType.ModelDecorationsChanged, (e) => { listenerCalled++; assert.equal(e.ids.length, 1); assert.equal(e.addedOrChangedDecorations.length, 1); diff --git a/src/vs/editor/test/common/services/resourceService.test.ts b/src/vs/editor/test/common/services/resourceService.test.ts index ea053ffa0a4..6a8ed426609 100644 --- a/src/vs/editor/test/common/services/resourceService.test.ts +++ b/src/vs/editor/test/common/services/resourceService.test.ts @@ -39,11 +39,11 @@ suite('Editor Services - ResourceService', () => { var url = URI.parse('far'); var element = createTestMirrorModelFromString('hi'); var service = new ResourceService(); - service.addListener(ResourceEvents.ADDED, () => { + service.addListener2(ResourceEvents.ADDED, () => { eventCnt++; assert.ok(true); }); - service.addListener(ResourceEvents.REMOVED, () => { + service.addListener2(ResourceEvents.REMOVED, () => { eventCnt++; assert.ok(true); }); @@ -64,7 +64,7 @@ suite('Editor Services - ResourceService', () => { var service = new ResourceService(); service.insert(url, element); - service.addBulkListener((events) => { + service.addBulkListener2((events) => { eventCnt++; assert.equal(events.length, 1); assert.equal(events[0].getData().originalEvents.length, 1); diff --git a/src/vs/languages/css/common/services/cssLanguageService.ts b/src/vs/languages/css/common/services/cssLanguageService.ts index 0d920140ba0..99669545561 100644 --- a/src/vs/languages/css/common/services/cssLanguageService.ts +++ b/src/vs/languages/css/common/services/cssLanguageService.ts @@ -10,6 +10,7 @@ import nodes = require('vs/languages/css/common/parser/cssNodes'); import parser = require('vs/languages/css/common/parser/cssParser'); import EditorCommon = require('vs/editor/common/editorCommon'); import resourceService = require('vs/editor/common/services/resourceService'); +import {IDisposable, dispose} from 'vs/base/common/lifecycle'; interface Entry { node:nodes.Stylesheet; @@ -50,7 +51,7 @@ export class CSSLanguageService implements ILanguageService { private entries:{[url:string]:Entry;}; private activeDelay:PromiseWithTrigger; private onChangeHandle:number; - private callOnDispose:Function[]; + private callOnDispose:IDisposable[]; private createParser: () => parser.Parser; constructor(service:resourceService.IResourceService, createParser: () => parser.Parser, private _cssModeId:string) { @@ -60,15 +61,13 @@ export class CSSLanguageService implements ILanguageService { this.createParser = createParser; this.updateResources(); - this.callOnDispose.push(this.resourceService.addListener_(resourceService.ResourceEvents.ADDED, (e: resourceService.IResourceAddedEvent) => this.onResourceAdded(e))); - this.callOnDispose.push(this.resourceService.addListener_(resourceService.ResourceEvents.REMOVED, (e: resourceService.IResourceRemovedEvent) => this.onResourceRemoved(e))); - this.callOnDispose.push(this.resourceService.addListener_(resourceService.ResourceEvents.CHANGED, (e: resourceService.IResourceChangedEvent) => this.onResourceChange(e))); + this.callOnDispose.push(this.resourceService.addListener2_(resourceService.ResourceEvents.ADDED, (e: resourceService.IResourceAddedEvent) => this.onResourceAdded(e))); + this.callOnDispose.push(this.resourceService.addListener2_(resourceService.ResourceEvents.REMOVED, (e: resourceService.IResourceRemovedEvent) => this.onResourceRemoved(e))); + this.callOnDispose.push(this.resourceService.addListener2_(resourceService.ResourceEvents.CHANGED, (e: resourceService.IResourceChangedEvent) => this.onResourceChange(e))); } public dispose():void { - while(this.callOnDispose.length > 0) { - this.callOnDispose.pop()(); - } + this.callOnDispose = dispose(this.callOnDispose); clearTimeout(this.onChangeHandle); this.onChangeHandle = null; this.entries = null; diff --git a/src/vs/languages/json/common/jsonSchemaService.ts b/src/vs/languages/json/common/jsonSchemaService.ts index 8d2a52329ab..4ea938fc81f 100644 --- a/src/vs/languages/json/common/jsonSchemaService.ts +++ b/src/vs/languages/json/common/jsonSchemaService.ts @@ -19,6 +19,7 @@ import {IResourceService, ResourceEvents, IResourceChangedEvent} from 'vs/editor import {IRequestService} from 'vs/platform/request/common/request'; import {IWorkspaceContextService} from 'vs/platform/workspace/common/workspace'; import {ISchemaContributions} from 'vs/platform/jsonschemas/common/jsonContributionRegistry'; +import {IDisposable, dispose} from 'vs/base/common/lifecycle'; export interface IJSONSchemaService { @@ -213,7 +214,7 @@ export class JSONSchemaService implements IJSONSchemaService { private requestService: IRequestService; private contextService : IWorkspaceContextService; - private callOnDispose:Function[]; + private callOnDispose:IDisposable[]; constructor(@IRequestService requestService: IRequestService, @IWorkspaceContextService contextService?: IWorkspaceContextService, @@ -223,7 +224,7 @@ export class JSONSchemaService implements IJSONSchemaService { this.callOnDispose = []; if (resourceService) { - this.callOnDispose.push(resourceService.addListener_(ResourceEvents.CHANGED, (e: IResourceChangedEvent) => this.onResourceChange(e))); + this.callOnDispose.push(resourceService.addListener2_(ResourceEvents.CHANGED, (e: IResourceChangedEvent) => this.onResourceChange(e))); } this.contributionSchemas = {}; @@ -234,9 +235,7 @@ export class JSONSchemaService implements IJSONSchemaService { } public dispose(): void { - while(this.callOnDispose.length > 0) { - this.callOnDispose.pop()(); - } + this.callOnDispose = dispose(this.callOnDispose); } private onResourceChange(e: IResourceChangedEvent): void { diff --git a/src/vs/platform/actions/common/actions.ts b/src/vs/platform/actions/common/actions.ts index 2fbfb1e656a..cd1d1bb4f51 100644 --- a/src/vs/platform/actions/common/actions.ts +++ b/src/vs/platform/actions/common/actions.ts @@ -7,12 +7,12 @@ import Actions = require('vs/base/common/actions'); import WinJS = require('vs/base/common/winjs.base'); import Assert = require('vs/base/common/assert'); -import EventEmitter = require('vs/base/common/eventEmitter'); import Descriptors = require('vs/platform/instantiation/common/descriptors'); import Instantiation = require('vs/platform/instantiation/common/instantiation'); import {KbExpr, IKeybindings} from 'vs/platform/keybinding/common/keybindingService'; import {createDecorator, ServiceIdentifier} from 'vs/platform/instantiation/common/instantiation'; +import {IDisposable} from 'vs/base/common/lifecycle'; export let IActionsService = createDecorator('actionsService'); @@ -73,7 +73,7 @@ export class SyncActionDescriptor { */ export class DeferredAction extends Actions.Action { private _cachedAction: Actions.IAction; - private _emitterUnbind: EventEmitter.ListenerUnbind; + private _emitterUnbind: IDisposable; constructor(private _instantiationService: Instantiation.IInstantiationService, private _descriptor: Descriptors.AsyncDescriptor0, id: string, label = '', cssClass = '', enabled = true) { @@ -178,7 +178,7 @@ export class DeferredAction extends Actions.Action { this._cachedAction = action; // Pipe events from the instantated action through this deferred action - this._emitterUnbind = this.addEmitter(this._cachedAction); + this._emitterUnbind = this.addEmitter2(this._cachedAction); return action; }); @@ -186,7 +186,7 @@ export class DeferredAction extends Actions.Action { public dispose(): void { if (this._emitterUnbind) { - this._emitterUnbind(); + this._emitterUnbind.dispose(); } if (this._cachedAction) { this._cachedAction.dispose(); diff --git a/src/vs/platform/configuration/common/configurationService.ts b/src/vs/platform/configuration/common/configurationService.ts index 5370b6a8fef..ebdae7743dd 100644 --- a/src/vs/platform/configuration/common/configurationService.ts +++ b/src/vs/platform/configuration/common/configurationService.ts @@ -11,7 +11,7 @@ import errors = require('vs/base/common/errors'); import uri from 'vs/base/common/uri'; import model = require('./model'); import {RunOnceScheduler} from 'vs/base/common/async'; -import {IDisposable, cAll} from 'vs/base/common/lifecycle'; +import {IDisposable} from 'vs/base/common/lifecycle'; import collections = require('vs/base/common/collections'); import {IConfigurationService, IConfigurationServiceEvent} from './configuration'; import {IEventService} from 'vs/platform/event/common/event'; @@ -56,7 +56,7 @@ export abstract class ConfigurationService implements IConfigurationService, IDi private bulkFetchFromWorkspacePromise: TPromise; private workspaceFilePathToConfiguration: { [relativeWorkspacePath: string]: TPromise }; - private callOnDispose: Function; + private callOnDispose: IDisposable; private reloadConfigurationScheduler: RunOnceScheduler; constructor(contextService: IWorkspaceContextService, eventService: IEventService, workspaceSettingsRootFolder: string = '.vscode') { @@ -78,11 +78,13 @@ export abstract class ConfigurationService implements IConfigurationService, IDi } protected registerListeners(): void { - let unbind = this.eventService.addListener(EventType.FILE_CHANGES, (events) => this.handleFileEvents(events)); + let unbind = this.eventService.addListener2(EventType.FILE_CHANGES, (events) => this.handleFileEvents(events)); let subscription = Registry.as(Extensions.Configuration).onDidRegisterConfiguration(() => this.onDidRegisterConfiguration()); - this.callOnDispose = () => { - unbind(); - subscription.dispose(); + this.callOnDispose = { + dispose: () => { + unbind.dispose(); + subscription.dispose(); + } }; } @@ -261,7 +263,7 @@ export abstract class ConfigurationService implements IConfigurationService, IDi if (this.reloadConfigurationScheduler) { this.reloadConfigurationScheduler.dispose(); } - this.callOnDispose = cAll(this.callOnDispose); + this.callOnDispose.dispose(); this._onDidUpdateConfiguration.dispose(); } } diff --git a/src/vs/platform/editor/common/editor.ts b/src/vs/platform/editor/common/editor.ts index 2896ba21636..4d0477e73e3 100644 --- a/src/vs/platform/editor/common/editor.ts +++ b/src/vs/platform/editor/common/editor.ts @@ -50,6 +50,10 @@ export interface IResourceInput { options?: ITextEditorOptions; } +export interface IEditorControl { + +} + export interface IEditor { /** @@ -75,7 +79,7 @@ export interface IEditor { /** * Returns the underlying control of this editor. */ - getControl(): IEventEmitter; + getControl(): IEditorControl; /** * Asks the underlying control to focus. diff --git a/src/vs/platform/event/common/event.ts b/src/vs/platform/event/common/event.ts index 42930f0aa9b..75a865648d2 100644 --- a/src/vs/platform/event/common/event.ts +++ b/src/vs/platform/event/common/event.ts @@ -13,26 +13,16 @@ export const IEventService = createDecorator('eventService'); export interface IEventService { serviceId: ServiceIdentifier; - /** - * Allows to add a listener to the platform event bus for all emitters that are known to the platform. - */ - addListener(eventType: string, listener: (event: any) => void): () => void; - /** * Allows to add a listener to the platform event bus for all emitters that are known to the platform. */ addListener2(eventType: string, listener: (event: any) => void): IDisposable; - /** - * Allows to add a listener to an emitter on the platform event bus with the given type identifier. - */ - addEmitterTypeListener(eventType: string, emitterType: string, listener: (event: any) => void): () => void; - /** * Allows to add an event emitter to the platform bus such as Events from the emitter * can be received from all listeners on the bus. */ - addEmitter(eventEmitter: IEventEmitter, emitterType?: string): () => void; + addEmitter2(eventEmitter: IEventEmitter, emitterType?: string): IDisposable; /** * Emits an event of the given type into the platform event bus. diff --git a/src/vs/platform/jsonschemas/common/jsonContributionRegistry.ts b/src/vs/platform/jsonschemas/common/jsonContributionRegistry.ts index 9ceda9bdd9a..352ee7ed984 100644 --- a/src/vs/platform/jsonschemas/common/jsonContributionRegistry.ts +++ b/src/vs/platform/jsonschemas/common/jsonContributionRegistry.ts @@ -7,7 +7,7 @@ import nls = require('vs/nls'); import {IJSONSchema} from 'vs/base/common/jsonSchema'; import platform = require('vs/platform/platform'); -import {IEventEmitter, EventEmitter} from 'vs/base/common/eventEmitter'; +import {EventEmitter} from 'vs/base/common/eventEmitter'; import {IDisposable} from 'vs/base/common/lifecycle'; export const Extensions = { @@ -52,7 +52,7 @@ function normalizeId(id: string) { class JSONContributionRegistry implements IJSONContributionRegistry { private schemasById: { [id: string]: IJSONSchema }; - private eventEmitter: IEventEmitter; + private eventEmitter: EventEmitter; constructor() { this.schemasById = {}; diff --git a/src/vs/workbench/api/node/extHostDocuments.ts b/src/vs/workbench/api/node/extHostDocuments.ts index ba0dc9fd0ce..56c0275f8d4 100644 --- a/src/vs/workbench/api/node/extHostDocuments.ts +++ b/src/vs/workbench/api/node/extHostDocuments.ts @@ -5,7 +5,7 @@ 'use strict'; import {toErrorMessage, onUnexpectedError} from 'vs/base/common/errors'; -import {IEmitterEvent} from 'vs/base/common/eventEmitter'; +import {EmitterEvent} from 'vs/base/common/eventEmitter'; import {IModelService} from 'vs/editor/common/services/modelService'; import * as EditorCommon from 'vs/editor/common/editorCommon'; import {MirrorModel2} from 'vs/editor/common/model/mirrorModel2'; @@ -551,7 +551,7 @@ export class MainThreadDocuments { this._proxy._acceptModelRemoved(modelUrl.toString()); } - private _onModelEvents(modelUrl: URI, events: IEmitterEvent[]): void { + private _onModelEvents(modelUrl: URI, events: EmitterEvent[]): void { let changedEvents: EditorCommon.IModelContentChangedEvent2[] = []; for (let i = 0, len = events.length; i < len; i++) { let e = events[i]; diff --git a/src/vs/workbench/api/node/extHostFileSystemEventService.ts b/src/vs/workbench/api/node/extHostFileSystemEventService.ts index aba21f14e52..c78706a6d6e 100644 --- a/src/vs/workbench/api/node/extHostFileSystemEventService.ts +++ b/src/vs/workbench/api/node/extHostFileSystemEventService.ts @@ -132,7 +132,7 @@ export class MainThreadFileSystemEventService { events.deleted.length = 0; }, 100); - eventService.addListener('files:fileChanges', (event: FileChangesEvent) => { + eventService.addListener2('files:fileChanges', (event: FileChangesEvent) => { for (let change of event.changes) { switch (change.type) { case FileChangeType.ADDED: diff --git a/src/vs/workbench/api/node/mainThreadEditors.ts b/src/vs/workbench/api/node/mainThreadEditors.ts index d7d64f96d03..3c18f5f2b91 100644 --- a/src/vs/workbench/api/node/mainThreadEditors.ts +++ b/src/vs/workbench/api/node/mainThreadEditors.ts @@ -127,7 +127,7 @@ export class MainThreadTextEditor { if (this._codeEditor) { // Catch early the case that this code editor gets a different model set and disassociate from this model - this._codeEditorListeners.push(this._codeEditor.addListener2(EditorCommon.EventType.ModelChanged, () => { + this._codeEditorListeners.push(this._codeEditor.onDidModelChange(() => { this.setCodeEditor(null); })); @@ -135,17 +135,17 @@ export class MainThreadTextEditor { this._lastSelection = this._codeEditor.getSelections(); this._onSelectionChanged.fire(this._lastSelection); }; - this._codeEditorListeners.push(this._codeEditor.addListener2(EditorCommon.EventType.CursorSelectionChanged, forwardSelection)); + this._codeEditorListeners.push(this._codeEditor.onDidCursorSelectionChange(forwardSelection)); if (!Selection.selectionsArrEqual(this._lastSelection, this._codeEditor.getSelections())) { forwardSelection(); } - this._codeEditorListeners.push(this._codeEditor.addListener2(EditorCommon.EventType.EditorFocus, () => { + this._codeEditorListeners.push(this._codeEditor.onDidEditorFocus(() => { this._focusTracker.onGainedFocus(); })); - this._codeEditorListeners.push(this._codeEditor.addListener2(EditorCommon.EventType.EditorBlur, () => { + this._codeEditorListeners.push(this._codeEditor.onDidEditorBlur(() => { this._focusTracker.onLostFocus(); })); - this._codeEditorListeners.push(this._codeEditor.addListener2(EditorCommon.EventType.ConfigurationChanged, () => { + this._codeEditorListeners.push(this._codeEditor.onDidConfigurationChange(() => { this._setConfiguration(this._readConfiguration(this._model, this._codeEditor)); })); this._setConfiguration(this._readConfiguration(this._model, this._codeEditor)); @@ -407,7 +407,7 @@ export class MainThreadEditorsTracker { } private _onCodeEditorAdd(codeEditor: EditorCommon.ICommonCodeEditor): void { - this._editorModelChangeListeners[codeEditor.getId()] = codeEditor.addListener2(EditorCommon.EventType.ModelChanged, _ => this._updateMapping.schedule()); + this._editorModelChangeListeners[codeEditor.getId()] = codeEditor.onDidModelChange(_ => this._updateMapping.schedule()); this._updateMapping.schedule(); } diff --git a/src/vs/workbench/browser/composite.ts b/src/vs/workbench/browser/composite.ts index 85806932cdb..3ebbabdcb04 100644 --- a/src/vs/workbench/browser/composite.ts +++ b/src/vs/workbench/browser/composite.ts @@ -4,7 +4,6 @@ *--------------------------------------------------------------------------------------------*/ import {TPromise} from 'vs/base/common/winjs.base'; -import {IEventEmitter} from 'vs/base/common/eventEmitter'; import {Dimension, Builder} from 'vs/base/browser/builder'; import {IAction, IActionRunner, ActionRunner} from 'vs/base/common/actions'; import {IActionItem} from 'vs/base/browser/ui/actionbar/actionbar'; @@ -13,6 +12,7 @@ import {CompositeEvent} from 'vs/workbench/common/events'; import {ITelemetryService} from 'vs/platform/telemetry/common/telemetry'; import {AsyncDescriptor} from 'vs/platform/instantiation/common/descriptors'; import {IComposite} from 'vs/workbench/common/composite'; +import {IEditorControl} from 'vs/platform/editor/common/editor'; /** * Internal composite events to communicate with composite container. @@ -187,7 +187,7 @@ export abstract class Composite extends WorkbenchComponent implements IComposite /** * Returns the underlying composite control or null if it is not accessible. */ - public getControl(): IEventEmitter { + public getControl(): IEditorControl { return null; } } diff --git a/src/vs/workbench/browser/layout.ts b/src/vs/workbench/browser/layout.ts index 12eaa95e436..877689dba5b 100644 --- a/src/vs/workbench/browser/layout.ts +++ b/src/vs/workbench/browser/layout.ts @@ -131,17 +131,17 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal let startX: number = 0; let startY: number = 0; - this.sashX.addListener('start', (e: ISashEvent) => { + this.sashX.addListener2('start', (e: ISashEvent) => { this.startSidebarWidth = this.sidebarWidth; startX = e.startX; }); - this.sashY.addListener('start', (e: ISashEvent) => { + this.sashY.addListener2('start', (e: ISashEvent) => { this.startPanelHeight = this.panelHeight; startY = e.startY; }); - this.sashX.addListener('change', (e: ISashEvent) => { + this.sashX.addListener2('change', (e: ISashEvent) => { let doLayout = false; let sidebarPosition = this.partService.getSideBarPosition(); let isSidebarHidden = this.partService.isSideBarHidden(); @@ -180,7 +180,7 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal } }); - this.sashY.addListener('change', (e: ISashEvent) => { + this.sashY.addListener2('change', (e: ISashEvent) => { let doLayout = false; let isPanelHidden = this.partService.isPanelHidden(); let newSashHeight = this.startPanelHeight - (e.currentY - startY); @@ -216,22 +216,22 @@ export class WorkbenchLayout implements IVerticalSashLayoutProvider, IHorizontal } }); - this.sashX.addListener('end', () => { + this.sashX.addListener2('end', () => { this.storageService.store(WorkbenchLayout.sashXWidthSettingsKey, this.sidebarWidth, StorageScope.GLOBAL); }); - this.sashY.addListener('end', () => { + this.sashY.addListener2('end', () => { this.storageService.store(WorkbenchLayout.sashYHeightSettingsKey, this.panelHeight, StorageScope.GLOBAL); }); - this.sashY.addListener('reset', () => { + this.sashY.addListener2('reset', () => { this.panelHeight = DEFAULT_MIN_PANEL_PART_HEIGHT; this.storageService.store(WorkbenchLayout.sashYHeightSettingsKey, this.panelHeight, StorageScope.GLOBAL); this.partService.setPanelHidden(false); this.layout(); }); - this.sashX.addListener('reset', () => { + this.sashX.addListener2('reset', () => { let activeViewlet = this.viewletService.getActiveViewlet(); let optimalWidth = activeViewlet && activeViewlet.getOptimalWidth(); this.sidebarWidth = Math.max(DEFAULT_MIN_PART_WIDTH, optimalWidth || 0); diff --git a/src/vs/workbench/browser/parts/activitybar/activityAction.ts b/src/vs/workbench/browser/parts/activitybar/activityAction.ts index 6c5556c0a74..24195b0a4ba 100644 --- a/src/vs/workbench/browser/parts/activitybar/activityAction.ts +++ b/src/vs/workbench/browser/parts/activitybar/activityAction.ts @@ -11,7 +11,7 @@ import {Builder, $} from 'vs/base/browser/builder'; import {DelayedDragHandler} from 'vs/base/browser/dnd'; import {Action} from 'vs/base/common/actions'; import {BaseActionItem} from 'vs/base/browser/ui/actionbar/actionbar'; -import {IEmitterEvent} from 'vs/base/common/eventEmitter'; +import {EmitterEvent} from 'vs/base/common/eventEmitter'; import {ProgressBadge, TextBadge, NumberBadge, IconBadge, IBadge} from 'vs/workbench/services/activity/common/activityService'; export class ActivityAction extends Action { @@ -175,7 +175,7 @@ export class ActivityActionItem extends BaseActionItem { } } - public _updateUnknown(event: IEmitterEvent): void { + public _updateUnknown(event: EmitterEvent): void { if (event.getType() === ActivityAction.BADGE) { let action = this.getAction(); if (action instanceof ActivityAction) { diff --git a/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts b/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts index 07f3e6f8b48..8900a724e12 100644 --- a/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts +++ b/src/vs/workbench/browser/parts/activitybar/activitybarPart.ts @@ -56,10 +56,10 @@ export class ActivitybarPart extends Part implements IActivityService { private registerListeners(): void { // Activate viewlet action on opening of a viewlet - this.toUnbind.push(this.eventService.addListener(EventType.COMPOSITE_OPENING, (e: CompositeEvent) => this.onCompositeOpening(e))); + this.toUnbind.push(this.eventService.addListener2(EventType.COMPOSITE_OPENING, (e: CompositeEvent) => this.onCompositeOpening(e))); // Deactivate viewlet action on close - this.toUnbind.push(this.eventService.addListener(EventType.COMPOSITE_CLOSED, (e: CompositeEvent) => this.onCompositeClosed(e))); + this.toUnbind.push(this.eventService.addListener2(EventType.COMPOSITE_CLOSED, (e: CompositeEvent) => this.onCompositeClosed(e))); } private onCompositeOpening(e: CompositeEvent): void { diff --git a/src/vs/workbench/browser/parts/compositePart.ts b/src/vs/workbench/browser/parts/compositePart.ts index 2251ad4006b..a32be14c7e7 100644 --- a/src/vs/workbench/browser/parts/compositePart.ts +++ b/src/vs/workbench/browser/parts/compositePart.ts @@ -9,7 +9,7 @@ import timer = require('vs/base/common/timer'); import uuid = require('vs/base/common/uuid'); import {TPromise} from 'vs/base/common/winjs.base'; import {Registry} from 'vs/platform/platform'; -import {IDisposable} from 'vs/base/common/lifecycle'; +import {IDisposable, dispose} from 'vs/base/common/lifecycle'; import {Dimension, Builder, $} from 'vs/base/browser/builder'; import events = require('vs/base/common/events'); import strings = require('vs/base/common/strings'); @@ -38,8 +38,8 @@ import {ITelemetryService} from 'vs/platform/telemetry/common/telemetry'; import {IKeybindingService} from 'vs/platform/keybinding/common/keybindingService'; export abstract class CompositePart extends Part { - private activeCompositeListeners: { (): void; }[]; - private instantiatedCompositeListeners: { (): void; }[]; + private activeCompositeListeners: IDisposable[]; + private instantiatedCompositeListeners: IDisposable[]; private mapCompositeToCompositeContainer: { [compositeId: string]: Builder; }; private mapActionsBindingToComposite: { [compositeId: string]: () => void; }; private mapProgressServiceToComposite: { [compositeId: string]: IProgressService; }; @@ -181,7 +181,7 @@ export abstract class CompositePart extends Part { this.instantiatedComposits.push(composite); // Register to title area update events from the composite - this.instantiatedCompositeListeners.push(composite.addListener(CompositeEventType.INTERNAL_COMPOSITE_TITLE_AREA_UPDATE, (e) => { this.onTitleAreaUpdate(e); })); + this.instantiatedCompositeListeners.push(composite.addListener2(CompositeEventType.INTERNAL_COMPOSITE_TITLE_AREA_UPDATE, (e) => { this.onTitleAreaUpdate(e); })); // Remove from Promises Cache since Loaded delete this.compositeLoaderPromises[id]; @@ -214,7 +214,7 @@ export abstract class CompositePart extends Part { this.lastActiveCompositeId = this.activeComposite.getId(); // Register as Emitter to Workbench Bus - this.activeCompositeListeners.push(this.eventService.addEmitter(this.activeComposite, this.activeComposite.getId())); + this.activeCompositeListeners.push(this.eventService.addEmitter2(this.activeComposite, this.activeComposite.getId())); let createCompositePromise: TPromise; @@ -405,9 +405,7 @@ export abstract class CompositePart extends Part { this.toolBar.setActions([])(); // Clear Listeners - while (this.activeCompositeListeners.length) { - this.activeCompositeListeners.pop()(); - } + this.activeCompositeListeners = dispose(this.activeCompositeListeners); // Emit Composite Closed Event this.emit(WorkbenchEventType.COMPOSITE_CLOSED, new CompositeEvent(composite.getId())); @@ -520,13 +518,9 @@ export abstract class CompositePart extends Part { this.instantiatedComposits = []; - while (this.activeCompositeListeners.length) { - this.activeCompositeListeners.pop()(); - } + this.activeCompositeListeners = dispose(this.activeCompositeListeners); - while (this.instantiatedCompositeListeners.length) { - this.instantiatedCompositeListeners.pop()(); - } + this.instantiatedCompositeListeners = dispose(this.instantiatedCompositeListeners); this.progressBar.dispose(); this.toolBar.dispose(); diff --git a/src/vs/workbench/browser/parts/editor/binaryDiffEditor.ts b/src/vs/workbench/browser/parts/editor/binaryDiffEditor.ts index c2f2a4eee80..408d290aa9c 100644 --- a/src/vs/workbench/browser/parts/editor/binaryDiffEditor.ts +++ b/src/vs/workbench/browser/parts/editor/binaryDiffEditor.ts @@ -65,10 +65,10 @@ export class BinaryResourceDiffEditor extends BaseEditor implements IVerticalSas // Sash this.sash = new Sash(parent.getHTMLElement(), this); - this.sash.addListener('start', () => this.onSashDragStart()); - this.sash.addListener('change', (e: ISashEvent) => this.onSashDrag(e)); - this.sash.addListener('end', () => this.onSashDragEnd()); - this.sash.addListener('reset', () => this.onSashReset()); + this.sash.addListener2('start', () => this.onSashDragStart()); + this.sash.addListener2('change', (e: ISashEvent) => this.onSashDrag(e)); + this.sash.addListener2('end', () => this.onSashDragEnd()); + this.sash.addListener2('reset', () => this.onSashReset()); // Right Container for Binary let rightBinaryContainerElement = document.createElement('div'); diff --git a/src/vs/workbench/browser/parts/editor/editorPart.ts b/src/vs/workbench/browser/parts/editor/editorPart.ts index c4f06c813d2..928213422d7 100644 --- a/src/vs/workbench/browser/parts/editor/editorPart.ts +++ b/src/vs/workbench/browser/parts/editor/editorPart.ts @@ -39,6 +39,7 @@ import {IMessageService, IMessageWithAction, Severity} from 'vs/platform/message import {ITelemetryService} from 'vs/platform/telemetry/common/telemetry'; import {IProgressService} from 'vs/platform/progress/common/progress'; import {EditorStacksModel, EditorGroup, IEditorIdentifier} from 'vs/workbench/common/editor/editorStacksModel'; +import {IDisposable, dispose} from 'vs/base/common/lifecycle'; class ProgressMonitor { @@ -77,7 +78,7 @@ export class EditorPart extends Part implements IEditorPart { // The following data structures are partitioned into array of Position as provided by Services.POSITION array private visibleInputs: EditorInput[]; private visibleEditors: BaseEditor[]; - private visibleEditorListeners: Function[][]; + private visibleEditorListeners: IDisposable[][]; private instantiatedEditors: BaseEditor[][]; private mapEditorToEditorContainers: { [editorId: string]: Builder; }[]; private mapEditorInstantiationPromiseToEditor: { [editorId: string]: TPromise; }[]; @@ -116,10 +117,8 @@ export class EditorPart extends Part implements IEditorPart { } private registerListeners(): void { - this.toUnbind.push(this.eventService.addListener(WorkbenchEventType.EDITOR_INPUT_DIRTY_STATE_CHANGED, (event: EditorInputEvent) => this.onEditorInputDirtyStateChanged(event))); - - const unbind = this.stacks.onEditorDisposed(identifier => this.onEditorDisposed(identifier)); - this.toUnbind.push(() => unbind.dispose()); + this.toUnbind.push(this.eventService.addListener2(WorkbenchEventType.EDITOR_INPUT_DIRTY_STATE_CHANGED, (event: EditorInputEvent) => this.onEditorInputDirtyStateChanged(event))); + this.toUnbind.push(this.stacks.onEditorDisposed(identifier => this.onEditorDisposed(identifier))); } private onEditorInputDirtyStateChanged(event: EditorInputEvent): void { @@ -290,7 +289,7 @@ export class EditorPart extends Part implements IEditorPart { this.visibleEditors[position] = editor; // Register as Emitter to Workbench Bus - this.visibleEditorListeners[position].push(this.eventService.addEmitter(this.visibleEditors[position], this.visibleEditors[position].getId())); + this.visibleEditorListeners[position].push(this.eventService.addEmitter2(this.visibleEditors[position], this.visibleEditors[position].getId())); // Create editor as needed if (newlyCreatedEditorContainerBuilder) { @@ -556,9 +555,7 @@ export class EditorPart extends Part implements IEditorPart { this.sideBySideControl.updateProgress(position, ProgressState.STOP); // Clear Listeners - while (this.visibleEditorListeners[position].length) { - this.visibleEditorListeners[position].pop()(); - } + this.visibleEditorListeners[position] = dispose(this.visibleEditorListeners[position]); // Indicate to Editor editor.clearInput(); @@ -798,11 +795,8 @@ export class EditorPart extends Part implements IEditorPart { // Side by Side Control this.sideBySideControl = this.instantiationService.createInstance(SideBySideEditorControl, contentArea); - const focusListener = this.sideBySideControl.onGroupFocusChanged(() => this.onGroupFocusChanged()); - this.toUnbind.push(() => focusListener.dispose()); - - const titleClickListener = this.sideBySideControl.onEditorTitleDoubleclick((position) => this.onEditorTitleDoubleclick(position)); - this.toUnbind.push(() => titleClickListener.dispose()); + this.toUnbind.push(this.sideBySideControl.onGroupFocusChanged(() => this.onGroupFocusChanged())); + this.toUnbind.push(this.sideBySideControl.onEditorTitleDoubleclick((position) => this.onEditorTitleDoubleclick(position))); // get settings this.memento = this.getMemento(this.storageService, MementoScope.WORKSPACE); @@ -1063,9 +1057,7 @@ export class EditorPart extends Part implements IEditorPart { // Editor listeners for (let i = 0; i < this.visibleEditorListeners.length; i++) { - while (this.visibleEditorListeners[i].length) { - this.visibleEditorListeners[i].pop()(); - } + this.visibleEditorListeners[i] = dispose(this.visibleEditorListeners[i]); } // Pass to active editors diff --git a/src/vs/workbench/browser/parts/editor/sideBySideEditorControl.ts b/src/vs/workbench/browser/parts/editor/sideBySideEditorControl.ts index 471c91f458a..f091783d7ba 100644 --- a/src/vs/workbench/browser/parts/editor/sideBySideEditorControl.ts +++ b/src/vs/workbench/browser/parts/editor/sideBySideEditorControl.ts @@ -34,6 +34,7 @@ import {ITelemetryService} from 'vs/platform/telemetry/common/telemetry'; import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation'; import {IKeybindingService} from 'vs/platform/keybinding/common/keybindingService'; import {ShowEditorsInGroupAction, CloseEditorsInGroupAction, CloseEditorsInOtherGroupsAction, CloseAllEditorsAction, MoveGroupLeftAction, MoveGroupRightAction, SplitEditorAction, CloseEditorAction} from 'vs/workbench/browser/parts/editor/editorActions'; +import {IDisposable, dispose} from 'vs/base/common/lifecycle'; export enum Rochade { NONE, @@ -147,6 +148,8 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti private _onGroupFocusChanged: Emitter; private _onEditorTitleDoubleclick: Emitter; + private toDispose: IDisposable[]; + constructor( parent: Builder, @IWorkbenchEditorService private editorService: IWorkbenchEditorService, @@ -179,6 +182,8 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti this._onGroupFocusChanged = new Emitter(); this._onEditorTitleDoubleclick = new Emitter(); + this.toDispose = []; + this.initActions(); this.initStyles(); this.create(this.parent); @@ -770,10 +775,10 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti // Left Sash this.leftSash = new Sash(parent.getHTMLElement(), this, { baseSize: 5 }); - this.leftSash.addListener('start', () => this.onLeftSashDragStart()); - this.leftSash.addListener('change', (e: ISashEvent) => this.onLeftSashDrag(e)); - this.leftSash.addListener('end', () => this.onLeftSashDragEnd()); - this.leftSash.addListener('reset', () => this.onLeftSashReset()); + this.toDispose.push(this.leftSash.addListener2('start', () => this.onLeftSashDragStart())); + this.toDispose.push(this.leftSash.addListener2('change', (e: ISashEvent) => this.onLeftSashDrag(e))); + this.toDispose.push(this.leftSash.addListener2('end', () => this.onLeftSashDragEnd())); + this.toDispose.push(this.leftSash.addListener2('reset', () => this.onLeftSashReset())); this.leftSash.hide(); // Center Container @@ -781,10 +786,10 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti // Right Sash this.rightSash = new Sash(parent.getHTMLElement(), this, { baseSize: 5 }); - this.rightSash.addListener('start', () => this.onRightSashDragStart()); - this.rightSash.addListener('change', (e: ISashEvent) => this.onRightSashDrag(e)); - this.rightSash.addListener('end', () => this.onRightSashDragEnd()); - this.rightSash.addListener('reset', () => this.onRightSashReset()); + this.toDispose.push(this.rightSash.addListener2('start', () => this.onRightSashDragStart())); + this.toDispose.push(this.rightSash.addListener2('change', (e: ISashEvent) => this.onRightSashDrag(e))); + this.toDispose.push(this.rightSash.addListener2('end', () => this.onRightSashDragEnd())); + this.toDispose.push(this.rightSash.addListener2('reset', () => this.onRightSashReset())); this.rightSash.hide(); // Right Container @@ -1071,7 +1076,7 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti }); // Action Run Handling - toolbar.actionRunner.addListener(BaseEventType.RUN, (e: any) => { + this.toDispose.push(toolbar.actionRunner.addListener2(BaseEventType.RUN, (e: any) => { // Check for Error if (e.error && !errors.isPromiseCanceledError(e.error)) { @@ -1082,7 +1087,7 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti if (this.telemetryService) { this.telemetryService.publicLog('workbenchActionExecuted', { id: e.action.id, from: 'editorPart' }); } - }); + })); return toolbar; } @@ -1704,6 +1709,7 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti } public dispose(): void { + dispose(this.toDispose); // Positions POSITIONS.forEach((position) => { diff --git a/src/vs/workbench/browser/parts/editor/stringEditor.ts b/src/vs/workbench/browser/parts/editor/stringEditor.ts index b30d47755ab..1812f99ac25 100644 --- a/src/vs/workbench/browser/parts/editor/stringEditor.ts +++ b/src/vs/workbench/browser/parts/editor/stringEditor.ts @@ -51,7 +51,7 @@ export class StringEditor extends BaseTextEditor { this.mapResourceToEditorViewState = Object.create(null); - this.toUnbind.push(this.eventService.addListener(EventType.UNTITLED_FILE_DELETED, (e: UntitledEditorEvent) => this.onUntitledDeletedEvent(e))); + this.toUnbind.push(this.eventService.addListener2(EventType.UNTITLED_FILE_DELETED, (e: UntitledEditorEvent) => this.onUntitledDeletedEvent(e))); } private onUntitledDeletedEvent(e: UntitledEditorEvent): void { diff --git a/src/vs/workbench/browser/parts/editor/textDiffEditor.ts b/src/vs/workbench/browser/parts/editor/textDiffEditor.ts index 59828ee0e84..75de5404efc 100644 --- a/src/vs/workbench/browser/parts/editor/textDiffEditor.ts +++ b/src/vs/workbench/browser/parts/editor/textDiffEditor.ts @@ -169,7 +169,7 @@ export class TextDiffEditor extends BaseTextEditor { this.diffNavigator = new DiffNavigator(diffEditor, { alwaysRevealFirst: autoRevealFirstChange }); - this.diffNavigator.addListener(DiffNavigator.Events.UPDATED, () => { + this.diffNavigator.addListener2(DiffNavigator.Events.UPDATED, () => { this.nextDiffAction.updateEnablement(); this.previousDiffAction.updateEnablement(); }); diff --git a/src/vs/workbench/browser/parts/editor/textEditor.ts b/src/vs/workbench/browser/parts/editor/textEditor.ts index 68e80efe31c..32e56db3233 100644 --- a/src/vs/workbench/browser/parts/editor/textEditor.ts +++ b/src/vs/workbench/browser/parts/editor/textEditor.ts @@ -54,10 +54,10 @@ export abstract class BaseTextEditor extends BaseEditor { ) { super(id, telemetryService); - this.toUnbind.push(this._eventService.addListener(WorkbenchEventType.WORKBENCH_OPTIONS_CHANGED, (e) => this.onOptionsChanged(e))); - this.toUnbind.push(this.configurationService.onDidUpdateConfiguration(e => this.applyConfiguration(e.config)).dispose); + this.toUnbind.push(this._eventService.addListener2(WorkbenchEventType.WORKBENCH_OPTIONS_CHANGED, (e) => this.onOptionsChanged(e))); + this.toUnbind.push(this.configurationService.onDidUpdateConfiguration(e => this.applyConfiguration(e.config))); - this.toUnbind.push(_themeService.onDidThemeChange(_ => this.onThemeChanged()).dispose); + this.toUnbind.push(_themeService.onDidThemeChange(_ => this.onThemeChanged())); } public get instantiationService(): IInstantiationService { @@ -133,28 +133,28 @@ export abstract class BaseTextEditor extends BaseEditor { this.editorControl = this.createEditorControl(parent); // Hook Listener for Selection changes - this.toUnbind.push(this.editorControl.addListener(EventType.CursorPositionChanged, (event: ICursorPositionChangedEvent) => { + this.toUnbind.push(this.editorControl.onDidCursorPositionChange((event: ICursorPositionChangedEvent) => { let selection = this.editorControl.getSelection(); this.eventService.emit(WorkbenchEventType.TEXT_EDITOR_SELECTION_CHANGED, new TextEditorSelectionEvent(selection, this, this.getId(), this.input, null, this.position, event)); })); // Hook Listener for mode changes - this.toUnbind.push(this.editorControl.addListener(EventType.ModelModeChanged, (event: IModelModeChangedEvent) => { + this.toUnbind.push(this.editorControl.onDidModelModeChange((event: IModelModeChangedEvent) => { this.eventService.emit(WorkbenchEventType.TEXT_EDITOR_MODE_CHANGED, new EditorEvent(this, this.getId(), this.input, null, this.position, event)); })); // Hook Listener for content changes - this.toUnbind.push(this.editorControl.addListener(EventType.ModelContentChanged, (event: IModelContentChangedEvent) => { + this.toUnbind.push(this.editorControl.onDidModelContentChange((event: IModelContentChangedEvent) => { this.eventService.emit(WorkbenchEventType.TEXT_EDITOR_CONTENT_CHANGED, new EditorEvent(this, this.getId(), this.input, null, this.position, event)); })); // Hook Listener for content options changes - this.toUnbind.push(this.editorControl.addListener(EventType.ModelOptionsChanged, (event: IModelOptionsChangedEvent) => { + this.toUnbind.push(this.editorControl.onDidModelOptionsChange((event: IModelOptionsChangedEvent) => { this.eventService.emit(WorkbenchEventType.TEXT_EDITOR_CONTENT_OPTIONS_CHANGED, new EditorEvent(this, this.getId(), this.input, null, this.position, event)); })); // Hook Listener for options changes - this.toUnbind.push(this.editorControl.addListener(EventType.ConfigurationChanged, (event: IConfigurationChangedEvent) => { + this.toUnbind.push(this.editorControl.onDidConfigurationChange((event: IConfigurationChangedEvent) => { this.eventService.emit(WorkbenchEventType.TEXT_EDITOR_CONFIGURATION_CHANGED, new EditorEvent(this, this.getId(), this.input, null, this.position, event)); })); diff --git a/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts b/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts index 10a6602b436..6dba0cb7067 100644 --- a/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts +++ b/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts @@ -124,8 +124,8 @@ export class QuickOpenController extends WorkbenchComponent implements IQuickOpe public create(): void { // Listen on Editor Input Changes to show in MRU List - this.toUnbind.push(this.eventService.addListener(EventType.EDITOR_INPUT_CHANGING, (e: EditorEvent) => this.onEditorInputChanging(e))); - this.toUnbind.push(this.eventService.addListener(EventType.EDITOR_SET_INPUT_ERROR, (e: EditorEvent) => this.onEditorInputSetError(e))); + this.toUnbind.push(this.eventService.addListener2(EventType.EDITOR_INPUT_CHANGING, (e: EditorEvent) => this.onEditorInputChanging(e))); + this.toUnbind.push(this.eventService.addListener2(EventType.EDITOR_SET_INPUT_ERROR, (e: EditorEvent) => this.onEditorInputSetError(e))); // Editor History Model this.editorHistoryModel = new EditorHistoryModel(this.editorService, this.instantiationService, this.contextService); diff --git a/src/vs/workbench/browser/viewlet.ts b/src/vs/workbench/browser/viewlet.ts index c78e9f8c85c..995dd8c34e1 100644 --- a/src/vs/workbench/browser/viewlet.ts +++ b/src/vs/workbench/browser/viewlet.ts @@ -52,8 +52,8 @@ export abstract class ViewerViewlet extends Viewlet { this.viewer = this.createViewer(this.viewerContainer); // Eventing - this.toUnbind.push(this.viewer.addListener('selection', (e: ISelectionEvent) => this.onSelection(e))); - this.toUnbind.push(this.viewer.addListener('focus', (e: IFocusEvent) => this.onFocus(e))); + this.toUnbind.push(this.viewer.addListener2('selection', (e: ISelectionEvent) => this.onSelection(e))); + this.toUnbind.push(this.viewer.addListener2('focus', (e: IFocusEvent) => this.onFocus(e))); return TPromise.as(null); } diff --git a/src/vs/workbench/browser/workbench.ts b/src/vs/workbench/browser/workbench.ts index 7b986ad9607..183461ab4f1 100644 --- a/src/vs/workbench/browser/workbench.ts +++ b/src/vs/workbench/browser/workbench.ts @@ -636,14 +636,14 @@ export class Workbench implements IPartService { } private hookPartListeners(part: Part): void { - this.toDispose.push(this.toDisposable(this.eventService.addEmitter(part, part.getId()))); + this.toDispose.push(this.eventService.addEmitter2(part, part.getId())); } private registerListeners(): void { // Listen to editor changes - this.toDispose.push(this.toDisposable(this.eventService.addListener(EventType.EDITOR_CLOSED, () => this.onEditorOpenedOrClosed()))); - this.toDispose.push(this.toDisposable(this.eventService.addListener(EventType.EDITOR_OPENED, () => this.onEditorOpenedOrClosed()))); + this.toDispose.push(this.eventService.addListener2(EventType.EDITOR_CLOSED, () => this.onEditorOpenedOrClosed())); + this.toDispose.push(this.eventService.addListener2(EventType.EDITOR_OPENED, () => this.onEditorOpenedOrClosed())); // Handle message service and quick open events if (this.messageService instanceof WorkbenchMessageService) { @@ -670,14 +670,6 @@ export class Workbench implements IPartService { } } - private toDisposable(fn: () => void): IDisposable { - return { - dispose: function () { - fn(); - } - }; - } - private createWorkbenchLayout(): void { let options = new LayoutOptions(); options.setMargin(new Box(0, 0, 0, 0)); diff --git a/src/vs/workbench/common/component.ts b/src/vs/workbench/common/component.ts index e9f660903f6..691a5302656 100644 --- a/src/vs/workbench/common/component.ts +++ b/src/vs/workbench/common/component.ts @@ -5,7 +5,7 @@ 'use strict'; import {EventEmitter, IEventEmitter} from 'vs/base/common/eventEmitter'; -import {IDisposable} from 'vs/base/common/lifecycle'; +import {IDisposable, dispose} from 'vs/base/common/lifecycle'; import {Scope, Memento} from 'vs/workbench/common/memento'; import {IStorageService} from 'vs/platform/storage/common/storage'; @@ -56,7 +56,7 @@ export interface IWorkbenchComponent extends IDisposable, IEventEmitter { } export class WorkbenchComponent extends EventEmitter implements IWorkbenchComponent { - private _toUnbind: { (): void; }[]; + private _toUnbind: IDisposable[]; private id: string; private componentMemento: Memento; @@ -91,9 +91,7 @@ export class WorkbenchComponent extends EventEmitter implements IWorkbenchCompon } public dispose(): void { - while (this._toUnbind.length) { - this._toUnbind.pop()(); - } + this._toUnbind = dispose(this._toUnbind); super.dispose(); } diff --git a/src/vs/workbench/common/composite.ts b/src/vs/workbench/common/composite.ts index ae682d9688d..e6deb53689c 100644 --- a/src/vs/workbench/common/composite.ts +++ b/src/vs/workbench/common/composite.ts @@ -3,8 +3,8 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import {IEventEmitter} from 'vs/base/common/eventEmitter'; import {IAction, IActionItem} from 'vs/base/common/actions'; +import {IEditorControl} from 'vs/platform/editor/common/editor'; export interface IComposite { @@ -36,7 +36,7 @@ export interface IComposite { /** * Returns the underlying control of this composite. */ - getControl(): IEventEmitter; + getControl(): IEditorControl; /** * Asks the underlying control to focus. diff --git a/src/vs/workbench/common/editor/diffEditorInput.ts b/src/vs/workbench/common/editor/diffEditorInput.ts index eab578c5ace..a9b831affd7 100644 --- a/src/vs/workbench/common/editor/diffEditorInput.ts +++ b/src/vs/workbench/common/editor/diffEditorInput.ts @@ -15,6 +15,7 @@ import {EditorModel, IFileEditorInput, EditorInput, BaseDiffEditorInput} from 'v import {BaseTextEditorModel} from 'vs/workbench/common/editor/textEditorModel'; import {DiffEditorModel} from 'vs/workbench/common/editor/diffEditorModel'; import {TextDiffEditorModel} from 'vs/workbench/common/editor/textDiffEditorModel'; +import {IDisposable, dispose} from 'vs/base/common/lifecycle'; /** * The base editor input for the diff editor. It is made up of two editor inputs, the original version @@ -24,7 +25,7 @@ export class DiffEditorInput extends BaseDiffEditorInput { public static ID = 'workbench.editors.diffEditorInput'; - private _toUnbind: { (): void; }[]; + private _toUnbind: IDisposable[]; private name: string; private description: string; private cachedModel: DiffEditorModel; @@ -45,13 +46,13 @@ export class DiffEditorInput extends BaseDiffEditorInput { private registerListeners(): void { // When the original or modified input gets disposed, dispose this diff editor input - this._toUnbind.push(this.originalInput.addListener(EventType.DISPOSE, () => { + this._toUnbind.push(this.originalInput.addListener2(EventType.DISPOSE, () => { if (!this.isDisposed()) { this.dispose(); } })); - this._toUnbind.push(this.modifiedInput.addListener(EventType.DISPOSE, () => { + this._toUnbind.push(this.modifiedInput.addListener2(EventType.DISPOSE, () => { if (!this.isDisposed()) { this.dispose(); } @@ -167,9 +168,7 @@ export class DiffEditorInput extends BaseDiffEditorInput { } public dispose(): void { - while (this._toUnbind.length) { - this._toUnbind.pop()(); - } + this._toUnbind = dispose(this._toUnbind); // Dispose Model if (this.cachedModel) { diff --git a/src/vs/workbench/common/editor/resourceEditorInput.ts b/src/vs/workbench/common/editor/resourceEditorInput.ts index 9c687ef8587..01314f3e445 100644 --- a/src/vs/workbench/common/editor/resourceEditorInput.ts +++ b/src/vs/workbench/common/editor/resourceEditorInput.ts @@ -155,9 +155,9 @@ export class ResourceEditorInput extends EditorInput { // Otherwise Create Model and handle dispose event return ResourceEditorInput.getOrCreateModel(this.modelService, this.resource).then(() => { let model = this.instantiationService.createInstance(ResourceEditorModel, this.resource); - const unbind = model.addListener(EventType.DISPOSE, () => { + const unbind = model.addListener2(EventType.DISPOSE, () => { this.cachedModel = null; // make sure we do not dispose model again - unbind(); + unbind.dispose(); this.dispose(); }); diff --git a/src/vs/workbench/common/editor/textEditorModel.ts b/src/vs/workbench/common/editor/textEditorModel.ts index cd4a43613be..00b2d8827e8 100644 --- a/src/vs/workbench/common/editor/textEditorModel.ts +++ b/src/vs/workbench/common/editor/textEditorModel.ts @@ -40,9 +40,9 @@ export abstract class BaseTextEditorModel extends EditorModel implements ITextEd // Since we did not create the model, we need to listen to it disposing // and properly trigger our dispose function so that events get emitted - const unbind = model.addListener(EventType.ModelDispose, () => { + const unbind = model.addListener2(EventType.ModelDispose, () => { this.textEditorModelHandle = null; // make sure we do not dispose code editor model again - unbind(); + unbind.dispose(); this.dispose(); }); } diff --git a/src/vs/workbench/common/editor/untitledEditorModel.ts b/src/vs/workbench/common/editor/untitledEditorModel.ts index a5a59833004..ad427541811 100644 --- a/src/vs/workbench/common/editor/untitledEditorModel.ts +++ b/src/vs/workbench/common/editor/untitledEditorModel.ts @@ -18,7 +18,7 @@ import {IModeService} from 'vs/editor/common/services/modeService'; import {IModelService} from 'vs/editor/common/services/modelService'; export class UntitledEditorModel extends StringEditorModel implements IEncodingSupport { - private textModelChangeListener: () => void; + private textModelChangeListener: IDisposable; private configurationChangeListener: IDisposable; private dirty: boolean; @@ -94,7 +94,7 @@ export class UntitledEditorModel extends StringEditorModel implements IEncodingS this.configuredEncoding = configuration && configuration.files && configuration.files.encoding; // Listen to content changes - this.textModelChangeListener = this.textEditorModel.addListener(EventType.ModelContentChanged, (e: IModelContentChangedEvent) => this.onModelContentChanged(e)); + this.textModelChangeListener = this.textEditorModel.addListener2(EventType.ModelContentChanged, (e: IModelContentChangedEvent) => this.onModelContentChanged(e)); // Emit initial dirty event if we are if (this.dirty) { @@ -118,7 +118,7 @@ export class UntitledEditorModel extends StringEditorModel implements IEncodingS super.dispose(); if (this.textModelChangeListener) { - this.textModelChangeListener(); + this.textModelChangeListener.dispose(); this.textModelChangeListener = null; } diff --git a/src/vs/workbench/electron-browser/window.ts b/src/vs/workbench/electron-browser/window.ts index d37937887d0..9dfe97c57c9 100644 --- a/src/vs/workbench/electron-browser/window.ts +++ b/src/vs/workbench/electron-browser/window.ts @@ -52,7 +52,7 @@ export class ElectronWindow { // React to editor input changes (Mac only) if (platform.platform === platform.Platform.Mac) { - this.eventService.addListener(EventType.EDITOR_INPUT_CHANGED, (e: EditorEvent) => { + this.eventService.addListener2(EventType.EDITOR_INPUT_CHANGED, (e: EditorEvent) => { let fileInput = workbenchEditorCommon.asFileEditorInput(e.editorInput, true); let representedFilename = ''; if (fileInput) { diff --git a/src/vs/workbench/parts/debug/browser/breakpointWidget.ts b/src/vs/workbench/parts/debug/browser/breakpointWidget.ts index 2903dd0c834..c6fa9c8caf7 100644 --- a/src/vs/workbench/parts/debug/browser/breakpointWidget.ts +++ b/src/vs/workbench/parts/debug/browser/breakpointWidget.ts @@ -13,7 +13,6 @@ import lifecycle = require('vs/base/common/lifecycle'); import dom = require('vs/base/browser/dom'); import { InputBox } from 'vs/base/browser/ui/inputbox/inputBox'; import { CommonEditorRegistry } from 'vs/editor/common/editorCommonExtensions'; -import editorcommon = require('vs/editor/common/editorCommon'); import editorbrowser = require('vs/editor/browser/editorBrowser'); import { ZoneWidget } from 'vs/editor/contrib/zoneWidget/browser/zoneWidget'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; @@ -46,7 +45,7 @@ export class BreakpointWidget extends ZoneWidget { this.breakpointWidgetVisible = keybindingService.createKey(CONTEXT_BREAKPOINT_WIDGET_VISIBLE, false); this.breakpointWidgetVisible.set(true); BreakpointWidget.INSTANCE = this; - this.toDispose.push(editor.addListener2(editorcommon.EventType.ModelChanged, () => this.dispose())); + this.toDispose.push(editor.onDidModelChange(() => this.dispose())); } public static createInstance(editor: editorbrowser.ICodeEditor, lineNumber: number, instantiationService: IInstantiationService): void { diff --git a/src/vs/workbench/parts/debug/browser/debugEditorContribution.ts b/src/vs/workbench/parts/debug/browser/debugEditorContribution.ts index 6af7381f7fe..b8ad5c417e2 100644 --- a/src/vs/workbench/parts/debug/browser/debugEditorContribution.ts +++ b/src/vs/workbench/parts/debug/browser/debugEditorContribution.ts @@ -73,7 +73,7 @@ export class DebugEditorContribution implements debug.IDebugEditorContribution { } private registerListeners(): void { - this.toDispose.push(this.editor.addListener2(editorcommon.EventType.MouseDown, (e: editorbrowser.IEditorMouseEvent) => { + this.toDispose.push(this.editor.onMouseDown((e: editorbrowser.IEditorMouseEvent) => { if (e.target.type !== editorcommon.MouseTargetType.GUTTER_GLYPH_MARGIN || /* after last line */ e.target.detail) { return; } @@ -105,7 +105,7 @@ export class DebugEditorContribution implements debug.IDebugEditorContribution { } })); - this.toDispose.push(this.editor.addListener2(editorcommon.EventType.MouseMove, (e: editorbrowser.IEditorMouseEvent) => { + this.toDispose.push(this.editor.onMouseMove((e: editorbrowser.IEditorMouseEvent) => { var showBreakpointHintAtLineNumber = -1; if (e.target.type === editorcommon.MouseTargetType.GUTTER_GLYPH_MARGIN && this.debugService.getConfigurationManager().canSetBreakpointsIn(this.editor.getModel())) { if (!e.target.detail) { @@ -115,18 +115,18 @@ export class DebugEditorContribution implements debug.IDebugEditorContribution { } this.ensureBreakpointHintDecoration(showBreakpointHintAtLineNumber); })); - this.toDispose.push(this.editor.addListener2(editorcommon.EventType.MouseLeave, (e: editorbrowser.IEditorMouseEvent) => { + this.toDispose.push(this.editor.onMouseLeave((e: editorbrowser.IEditorMouseEvent) => { this.ensureBreakpointHintDecoration(-1); })); this.toDispose.push(this.debugService.onDidChangeState(state => this.onDebugStateUpdate(state))); // hover listeners & hover widget - this.toDispose.push(this.editor.addListener2(editorcommon.EventType.MouseDown, (e: editorbrowser.IEditorMouseEvent) => this.onEditorMouseDown(e))); - this.toDispose.push(this.editor.addListener2(editorcommon.EventType.MouseMove, (e: editorbrowser.IEditorMouseEvent) => this.onEditorMouseMove(e))); - this.toDispose.push(this.editor.addListener2(editorcommon.EventType.MouseLeave, (e: editorbrowser.IEditorMouseEvent) => this.hoverWidget.hide())); - this.toDispose.push(this.editor.addListener2(editorcommon.EventType.KeyDown, (e: keyboard.IKeyboardEvent) => this.onKeyDown(e))); - this.toDispose.push(this.editor.addListener2(editorcommon.EventType.ModelChanged, () => this.hideHoverWidget())); - this.toDispose.push(this.editor.addListener2('scroll', () => this.hideHoverWidget)); + this.toDispose.push(this.editor.onMouseDown((e: editorbrowser.IEditorMouseEvent) => this.onEditorMouseDown(e))); + this.toDispose.push(this.editor.onMouseMove((e: editorbrowser.IEditorMouseEvent) => this.onEditorMouseMove(e))); + this.toDispose.push(this.editor.onMouseLeave((e: editorbrowser.IEditorMouseEvent) => this.hoverWidget.hide())); + this.toDispose.push(this.editor.onKeyDown((e: keyboard.IKeyboardEvent) => this.onKeyDown(e))); + this.toDispose.push(this.editor.onDidModelChange(() => this.hideHoverWidget())); + this.toDispose.push(this.editor.onDidScrollChange(() => this.hideHoverWidget)); } public getId(): string { diff --git a/src/vs/workbench/parts/debug/browser/debugHover.ts b/src/vs/workbench/parts/debug/browser/debugHover.ts index a99b9ffd079..dde080b5679 100644 --- a/src/vs/workbench/parts/debug/browser/debugHover.ts +++ b/src/vs/workbench/parts/debug/browser/debugHover.ts @@ -12,7 +12,7 @@ import * as nls from 'vs/nls'; import { ITree } from 'vs/base/parts/tree/browser/tree'; import { Tree } from 'vs/base/parts/tree/browser/treeImpl'; import { DefaultController, ICancelableEvent } from 'vs/base/parts/tree/browser/treeDefaults'; -import { EventType, IConfigurationChangedEvent, IEditorPosition, IEditorRange } from 'vs/editor/common/editorCommon'; +import { IConfigurationChangedEvent, IEditorPosition, IEditorRange } from 'vs/editor/common/editorCommon'; import editorbrowser = require('vs/editor/browser/editorBrowser'); import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import debug = require('vs/workbench/parts/debug/common/debug'); @@ -83,7 +83,7 @@ export class DebugHoverWidget implements editorbrowser.IContentWidget { this.hide(); } })); - this.toDispose.push(this.editor.addListener2(EventType.ConfigurationChanged, (e: IConfigurationChangedEvent) => { + this.toDispose.push(this.editor.onDidConfigurationChange((e: IConfigurationChangedEvent) => { if (e.fontInfo) { this.editor.applyFontInfo(this.domNode); } diff --git a/src/vs/workbench/parts/debug/browser/debugViews.ts b/src/vs/workbench/parts/debug/browser/debugViews.ts index b71d912aa99..96fa612b0d0 100644 --- a/src/vs/workbench/parts/debug/browser/debugViews.ts +++ b/src/vs/workbench/parts/debug/browser/debugViews.ts @@ -171,7 +171,7 @@ export class WatchExpressionsView extends viewlet.CollapsibleViewletView { this.tree.refresh(expression, false).then(() => { this.tree.setHighlight(expression); - this.tree.addOneTimeListener(events.EventType.HIGHLIGHT, (e: tree.IHighlightEvent) => { + this.tree.addOneTimeDisposableListener(events.EventType.HIGHLIGHT, (e: tree.IHighlightEvent) => { if (!e.highlight) { this.debugService.getViewModel().setSelectedExpression(null); } @@ -359,7 +359,7 @@ export class BreakpointsView extends viewlet.AdaptiveCollapsibleViewletView { this.tree.refresh(fbp, false).then(() => { this.tree.setHighlight(fbp); - this.tree.addOneTimeListener(events.EventType.HIGHLIGHT, (e: tree.IHighlightEvent) => { + this.tree.addOneTimeDisposableListener(events.EventType.HIGHLIGHT, (e: tree.IHighlightEvent) => { if (!e.highlight) { this.debugService.getViewModel().setSelectedFunctionBreakpoint(null); } diff --git a/src/vs/workbench/parts/debug/electron-browser/debugService.ts b/src/vs/workbench/parts/debug/electron-browser/debugService.ts index 53e80fef1a6..2ed1b476f19 100644 --- a/src/vs/workbench/parts/debug/electron-browser/debugService.ts +++ b/src/vs/workbench/parts/debug/electron-browser/debugService.ts @@ -661,7 +661,7 @@ export class DebugService implements debug.IDebugService { }); if (filteredTasks[0].isWatching) { - return new TPromise((c, e) => this.taskService.addOneTimeListener(TaskServiceEvents.Inactive, () => c(null))); + return new TPromise((c, e) => this.taskService.addOneTimeDisposableListener(TaskServiceEvents.Inactive, () => c(null))); } return taskPromise; diff --git a/src/vs/workbench/parts/files/browser/editors/textFileEditor.ts b/src/vs/workbench/parts/files/browser/editors/textFileEditor.ts index 7546d441f17..92dc23f2eeb 100644 --- a/src/vs/workbench/parts/files/browser/editors/textFileEditor.ts +++ b/src/vs/workbench/parts/files/browser/editors/textFileEditor.ts @@ -63,7 +63,7 @@ export class TextFileEditor extends BaseTextEditor { TextFileEditorModel.setSaveErrorHandler(instantiationService.createInstance(SaveErrorHandler)); // Clear view state for deleted files - this.toUnbind.push(this.eventService.addListener(EventType.FILE_CHANGES, (e: FileChangesEvent) => this.onFilesChanged(e))); + this.toUnbind.push(this.eventService.addListener2(EventType.FILE_CHANGES, (e: FileChangesEvent) => this.onFilesChanged(e))); } private onFilesChanged(e: FileChangesEvent): void { diff --git a/src/vs/workbench/parts/files/browser/fileActions.ts b/src/vs/workbench/parts/files/browser/fileActions.ts index ba950692efb..f431b590bc9 100644 --- a/src/vs/workbench/parts/files/browser/fileActions.ts +++ b/src/vs/workbench/parts/files/browser/fileActions.ts @@ -62,7 +62,7 @@ export interface IFileViewletState { export class BaseFileAction extends Action { private _element: FileStat; - private listenerToUnbind: () => void; + private listenerToUnbind: IDisposable; constructor( id: string, @@ -79,7 +79,7 @@ export class BaseFileAction extends Action { this.enabled = false; // update enablement when options change - this.listenerToUnbind = this._eventService.addListener(WorkbenchEventType.WORKBENCH_OPTIONS_CHANGED, () => this._updateEnablement()); + this.listenerToUnbind = this._eventService.addListener2(WorkbenchEventType.WORKBENCH_OPTIONS_CHANGED, () => this._updateEnablement()); } public get contextService() { @@ -166,7 +166,7 @@ export class BaseFileAction extends Action { } public dispose(): void { - this.listenerToUnbind(); + this.listenerToUnbind.dispose(); super.dispose(); } @@ -237,11 +237,11 @@ export class TriggerRenameFileAction extends BaseFileAction { this.tree.refresh(stat, false).then(() => { this.tree.setHighlight(stat); - let unbind = this.tree.addListener(CommonEventType.HIGHLIGHT, (e: IHighlightEvent) => { + let unbind = this.tree.addListener2(CommonEventType.HIGHLIGHT, (e: IHighlightEvent) => { if (!e.highlight) { viewletState.clearEditable(stat); this.tree.refresh(stat).done(null, errors.onUnexpectedError); - unbind(); + unbind.dispose(); } }); }).done(null, errors.onUnexpectedError); @@ -449,11 +449,11 @@ export class BaseNewAction extends BaseFileAction { return this.tree.reveal(stat, 0.5).then(() => { this.tree.setHighlight(stat); - let unbind: () => void = this.tree.addListener(CommonEventType.HIGHLIGHT, (e: IHighlightEvent) => { + let unbind = this.tree.addListener2(CommonEventType.HIGHLIGHT, (e: IHighlightEvent) => { if (!e.highlight) { stat.destroy(); this.tree.refresh(folder).done(null, errors.onUnexpectedError); - unbind(); + unbind.dispose(); } }); }); @@ -1226,8 +1226,8 @@ export class GlobalCompareResourcesAction extends Action { globalResourceToCompare = fileInput.getResource(); // Listen for next editor to open - let unbind = this.eventService.addListener(WorkbenchEventType.EDITOR_INPUT_OPENING, (e: EditorEvent) => { - unbind(); // listen once + let unbind = this.eventService.addListener2(WorkbenchEventType.EDITOR_INPUT_OPENING, (e: EditorEvent) => { + unbind.dispose(); // listen once let otherFileInput = asFileEditorInput(e.editorInput); if (otherFileInput) { @@ -1244,7 +1244,7 @@ export class GlobalCompareResourcesAction extends Action { // Bring up quick open this.quickOpenService.show().then(() => { - unbind(); // make sure to unbind if quick open is closing + unbind.dispose(); // make sure to unbind if quick open is closing }); } else { diff --git a/src/vs/workbench/parts/files/browser/fileTracker.ts b/src/vs/workbench/parts/files/browser/fileTracker.ts index 387cff9c15a..356c04db8c9 100644 --- a/src/vs/workbench/parts/files/browser/fileTracker.ts +++ b/src/vs/workbench/parts/files/browser/fileTracker.ts @@ -28,6 +28,7 @@ import {IQuickOpenService} from 'vs/workbench/services/quickopen/common/quickOpe import {IActivityService, NumberBadge} from 'vs/workbench/services/activity/common/activityService'; import {IEventService} from 'vs/platform/event/common/event'; import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation'; +import {IDisposable, dispose} from 'vs/base/common/lifecycle'; // This extension tracks files for changes to update editors and inputs accordingly. export class FileTracker implements IWorkbenchContribution { @@ -38,7 +39,7 @@ export class FileTracker implements IWorkbenchContribution { private lastDirtyCount: number; - private toUnbind: { (): void; }[]; + private toUnbind: IDisposable[]; constructor( @IEventService private eventService: IEventService, @@ -61,16 +62,16 @@ export class FileTracker implements IWorkbenchContribution { private registerListeners(): void { // Update editors and inputs from local changes and saves - this.toUnbind.push(this.eventService.addListener(WorkbenchEventType.UNTITLED_FILE_DELETED, (e: UntitledEditorEvent) => this.onUntitledEditorDeleted(e))); - this.toUnbind.push(this.eventService.addListener(WorkbenchEventType.UNTITLED_FILE_DIRTY, (e: UntitledEditorEvent) => this.onUntitledEditorDirty(e))); - this.toUnbind.push(this.eventService.addListener(FileEventType.FILE_DIRTY, (e: TextFileChangeEvent) => this.onTextFileDirty(e))); - this.toUnbind.push(this.eventService.addListener(FileEventType.FILE_SAVE_ERROR, (e: TextFileChangeEvent) => this.onTextFileSaveError(e))); - this.toUnbind.push(this.eventService.addListener(FileEventType.FILE_SAVED, (e: TextFileChangeEvent) => this.onTextFileSaved(e))); - this.toUnbind.push(this.eventService.addListener(FileEventType.FILE_REVERTED, (e: TextFileChangeEvent) => this.onTextFileReverted(e))); - this.toUnbind.push(this.eventService.addListener('files.internal:fileChanged', (e: LocalFileChangeEvent) => this.onLocalFileChange(e))); + this.toUnbind.push(this.eventService.addListener2(WorkbenchEventType.UNTITLED_FILE_DELETED, (e: UntitledEditorEvent) => this.onUntitledEditorDeleted(e))); + this.toUnbind.push(this.eventService.addListener2(WorkbenchEventType.UNTITLED_FILE_DIRTY, (e: UntitledEditorEvent) => this.onUntitledEditorDirty(e))); + this.toUnbind.push(this.eventService.addListener2(FileEventType.FILE_DIRTY, (e: TextFileChangeEvent) => this.onTextFileDirty(e))); + this.toUnbind.push(this.eventService.addListener2(FileEventType.FILE_SAVE_ERROR, (e: TextFileChangeEvent) => this.onTextFileSaveError(e))); + this.toUnbind.push(this.eventService.addListener2(FileEventType.FILE_SAVED, (e: TextFileChangeEvent) => this.onTextFileSaved(e))); + this.toUnbind.push(this.eventService.addListener2(FileEventType.FILE_REVERTED, (e: TextFileChangeEvent) => this.onTextFileReverted(e))); + this.toUnbind.push(this.eventService.addListener2('files.internal:fileChanged', (e: LocalFileChangeEvent) => this.onLocalFileChange(e))); // Update editors and inputs from disk changes - this.toUnbind.push(this.eventService.addListener(CommonFileEventType.FILE_CHANGES, (e: FileChangesEvent) => this.onFileChanges(e))); + this.toUnbind.push(this.eventService.addListener2(CommonFileEventType.FILE_CHANGES, (e: FileChangesEvent) => this.onFileChanges(e))); } private onTextFileDirty(e: TextFileChangeEvent): void { @@ -479,8 +480,6 @@ export class FileTracker implements IWorkbenchContribution { } public dispose(): void { - while (this.toUnbind.length) { - this.toUnbind.pop()(); - } + dispose(this.toUnbind); } } \ No newline at end of file diff --git a/src/vs/workbench/parts/files/browser/saveErrorHandler.ts b/src/vs/workbench/parts/files/browser/saveErrorHandler.ts index d711d10fcee..066015be350 100644 --- a/src/vs/workbench/parts/files/browser/saveErrorHandler.ts +++ b/src/vs/workbench/parts/files/browser/saveErrorHandler.ts @@ -44,8 +44,8 @@ export class SaveErrorHandler implements ISaveErrorHandler { } private registerListeners(): void { - this.eventService.addListener(FileEventType.FILE_SAVED, (e: TextFileChangeEvent) => this.onFileSavedOrReverted(e.resource)); - this.eventService.addListener(FileEventType.FILE_REVERTED, (e: TextFileChangeEvent) => this.onFileSavedOrReverted(e.resource)); + this.eventService.addListener2(FileEventType.FILE_SAVED, (e: TextFileChangeEvent) => this.onFileSavedOrReverted(e.resource)); + this.eventService.addListener2(FileEventType.FILE_REVERTED, (e: TextFileChangeEvent) => this.onFileSavedOrReverted(e.resource)); } private onFileSavedOrReverted(resource: URI): void { diff --git a/src/vs/workbench/parts/files/browser/textFileServices.ts b/src/vs/workbench/parts/files/browser/textFileServices.ts index 7175b9e999e..b8d064fad42 100644 --- a/src/vs/workbench/parts/files/browser/textFileServices.ts +++ b/src/vs/workbench/parts/files/browser/textFileServices.ts @@ -7,7 +7,6 @@ import {TPromise} from 'vs/base/common/winjs.base'; import URI from 'vs/base/common/uri'; import errors = require('vs/base/common/errors'); -import {ListenerUnbind} from 'vs/base/common/eventEmitter'; import Event, {Emitter} from 'vs/base/common/event'; import {FileEditorInput} from 'vs/workbench/parts/files/browser/editors/fileEditorInput'; import {CACHE, TextFileEditorModel} from 'vs/workbench/parts/files/common/editors/textFileEditorModel'; @@ -20,6 +19,7 @@ import {IInstantiationService} from 'vs/platform/instantiation/common/instantiat import {IEventService} from 'vs/platform/event/common/event'; import {IConfigurationService} from 'vs/platform/configuration/common/configuration'; import {ITelemetryService} from 'vs/platform/telemetry/common/telemetry'; +import {IDisposable, dispose} from 'vs/base/common/lifecycle'; /** * The workbench file service implementation implements the raw file service spec and adds additional methods on top. @@ -30,7 +30,7 @@ export abstract class TextFileService implements ITextFileService { public serviceId = ITextFileService; - private listenerToUnbind: ListenerUnbind[]; + private listenerToUnbind: IDisposable[]; private _onAutoSaveConfigurationChange: Emitter; @@ -65,11 +65,11 @@ export abstract class TextFileService implements ITextFileService { protected registerListeners(): void { // Configuration changes - this.listenerToUnbind.push(this.configurationService.onDidUpdateConfiguration(e => this.onConfigurationChange(e.config)).dispose); + this.listenerToUnbind.push(this.configurationService.onDidUpdateConfiguration(e => this.onConfigurationChange(e.config))); // Editor focus change window.addEventListener('blur', () => this.onEditorFocusChange(), true); - this.listenerToUnbind.push(this.eventService.addListener(EventType.EDITOR_INPUT_CHANGED, () => this.onEditorFocusChange())); + this.listenerToUnbind.push(this.eventService.addListener2(EventType.EDITOR_INPUT_CHANGED, () => this.onEditorFocusChange())); } private onEditorFocusChange(): void { @@ -234,9 +234,7 @@ export abstract class TextFileService implements ITextFileService { } public dispose(): void { - while (this.listenerToUnbind.length) { - this.listenerToUnbind.pop()(); - } + this.listenerToUnbind = dispose(this.listenerToUnbind); // Clear all caches CACHE.clear(); diff --git a/src/vs/workbench/parts/files/browser/views/emptyView.ts b/src/vs/workbench/parts/files/browser/views/emptyView.ts index 8816af3b3fa..b98bd4a3f1b 100644 --- a/src/vs/workbench/parts/files/browser/views/emptyView.ts +++ b/src/vs/workbench/parts/files/browser/views/emptyView.ts @@ -41,7 +41,7 @@ export class EmptyView extends CollapsibleView { let button = new Button(section); button.label = nls.localize('openFolder', "Open Folder"); - button.on('click', () => { + button.addListener2('click', () => { this.runWorkbenchAction(env.isMacintosh ? 'workbench.action.files.openFileFolder' : 'workbench.action.files.openFolder'); }); } diff --git a/src/vs/workbench/parts/files/common/editors/textFileEditorModel.ts b/src/vs/workbench/parts/files/common/editors/textFileEditorModel.ts index aa680dc2eed..739eb5de10b 100644 --- a/src/vs/workbench/parts/files/common/editors/textFileEditorModel.ts +++ b/src/vs/workbench/parts/files/common/editors/textFileEditorModel.ts @@ -66,7 +66,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements IEncodin private resource: URI; private contentEncoding: string; // encoding as reported from disk private preferredEncoding: string; // encoding as chosen by the user - private textModelChangeListener: () => void; + private textModelChangeListener: IDisposable; private textFileServiceListener: IDisposable; private dirty: boolean; private versionId: number; @@ -272,7 +272,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements IEncodin this.createTextEditorModelPromise = null; this.setDirty(false); // Ensure we are not tracking a stale state - this.textModelChangeListener = this.textEditorModel.addListener(EditorEventType.ModelContentChanged, (e: IModelContentChangedEvent) => this.onModelContentChanged(e)); + this.textModelChangeListener = this.textEditorModel.addListener2(EditorEventType.ModelContentChanged, (e: IModelContentChangedEvent) => this.onModelContentChanged(e)); return this; }, (error) => { @@ -715,7 +715,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements IEncodin this.createTextEditorModelPromise = null; if (this.textModelChangeListener) { - this.textModelChangeListener(); + this.textModelChangeListener.dispose(); this.textModelChangeListener = null; } diff --git a/src/vs/workbench/parts/files/electron-browser/electronFileTracker.ts b/src/vs/workbench/parts/files/electron-browser/electronFileTracker.ts index dc85929555d..bd418a59513 100644 --- a/src/vs/workbench/parts/files/electron-browser/electronFileTracker.ts +++ b/src/vs/workbench/parts/files/electron-browser/electronFileTracker.ts @@ -26,7 +26,7 @@ import {IEventService} from 'vs/platform/event/common/event'; import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation'; import {ILifecycleService} from 'vs/platform/lifecycle/common/lifecycle'; import {IViewletService} from 'vs/workbench/services/viewlet/common/viewletService'; - +import {IDisposable, dispose} from 'vs/base/common/lifecycle'; import {ipcRenderer as ipc} from 'electron'; export interface IPath { @@ -45,7 +45,7 @@ export interface IOpenFileRequest { export class FileTracker implements IWorkbenchContribution { private activeOutOfWorkspaceWatchers: { [resource: string]: boolean; }; private isDocumentedEdited: boolean; - private toUnbind: { (): void; }[]; + private toUnbind: IDisposable[];; constructor( @IWorkspaceContextService private contextService: IWorkspaceContextService, @@ -75,18 +75,18 @@ export class FileTracker implements IWorkbenchContribution { private registerListeners(): void { // Local text file changes - this.toUnbind.push(this.eventService.addListener(WorkbenchEventType.UNTITLED_FILE_DELETED, () => this.onUntitledDeletedEvent())); - this.toUnbind.push(this.eventService.addListener(WorkbenchEventType.UNTITLED_FILE_DIRTY, () => this.onUntitledDirtyEvent())); - this.toUnbind.push(this.eventService.addListener(FileEventType.FILE_DIRTY, (e: TextFileChangeEvent) => this.onTextFileDirty(e))); - this.toUnbind.push(this.eventService.addListener(FileEventType.FILE_SAVED, (e: TextFileChangeEvent) => this.onTextFileSaved(e))); - this.toUnbind.push(this.eventService.addListener(FileEventType.FILE_SAVE_ERROR, (e: TextFileChangeEvent) => this.onTextFileSaveError(e))); - this.toUnbind.push(this.eventService.addListener(FileEventType.FILE_REVERTED, (e: TextFileChangeEvent) => this.onTextFileReverted(e))); + this.toUnbind.push(this.eventService.addListener2(WorkbenchEventType.UNTITLED_FILE_DELETED, () => this.onUntitledDeletedEvent())); + this.toUnbind.push(this.eventService.addListener2(WorkbenchEventType.UNTITLED_FILE_DIRTY, () => this.onUntitledDirtyEvent())); + this.toUnbind.push(this.eventService.addListener2(FileEventType.FILE_DIRTY, (e: TextFileChangeEvent) => this.onTextFileDirty(e))); + this.toUnbind.push(this.eventService.addListener2(FileEventType.FILE_SAVED, (e: TextFileChangeEvent) => this.onTextFileSaved(e))); + this.toUnbind.push(this.eventService.addListener2(FileEventType.FILE_SAVE_ERROR, (e: TextFileChangeEvent) => this.onTextFileSaveError(e))); + this.toUnbind.push(this.eventService.addListener2(FileEventType.FILE_REVERTED, (e: TextFileChangeEvent) => this.onTextFileReverted(e))); // Support openFiles event for existing and new files ipc.on('vscode:openFiles', (event, request: IOpenFileRequest) => this.onOpenFiles(request)); // Editor input changes - this.toUnbind.push(this.eventService.addListener(WorkbenchEventType.EDITOR_INPUT_CHANGED, () => this.onEditorInputChanged())); + this.toUnbind.push(this.eventService.addListener2(WorkbenchEventType.EDITOR_INPUT_CHANGED, () => this.onEditorInputChanged())); // Lifecycle this.lifecycleService.onShutdown(this.dispose, this); @@ -241,9 +241,7 @@ export class FileTracker implements IWorkbenchContribution { } public dispose(): void { - while (this.toUnbind.length) { - this.toUnbind.pop()(); - } + this.toUnbind = dispose(this.toUnbind); // Dispose watchers if any for (let key in this.activeOutOfWorkspaceWatchers) { diff --git a/src/vs/workbench/parts/files/test/browser/fileEditorModel.test.ts b/src/vs/workbench/parts/files/test/browser/fileEditorModel.test.ts index 056adcec4c9..e40eae2dc9a 100644 --- a/src/vs/workbench/parts/files/test/browser/fileEditorModel.test.ts +++ b/src/vs/workbench/parts/files/test/browser/fileEditorModel.test.ts @@ -104,15 +104,15 @@ suite('Files - TextFileEditorModel', () => { test('Load does not trigger save', function (done) { let m1 = baseInstantiationService.createInstance(TextFileEditorModel, toResource('/path/index.txt'), 'utf8'); - eventService.addListener('files:internalFileChanged', () => { + eventService.addListener2('files:internalFileChanged', () => { assert.ok(false); }); - eventService.addListener(EventType.FILE_DIRTY, () => { + eventService.addListener2(EventType.FILE_DIRTY, () => { assert.ok(false); }); - eventService.addListener(EventType.FILE_SAVED, () => { + eventService.addListener2(EventType.FILE_SAVED, () => { assert.ok(false); }); @@ -145,7 +145,7 @@ suite('Files - TextFileEditorModel', () => { test('Revert', function (done) { let eventCounter = 0; - eventService.addListener('files:fileReverted', () => { + eventService.addListener2('files:fileReverted', () => { eventCounter++; }); @@ -200,11 +200,11 @@ suite('Files - TextFileEditorModel', () => { (m1).autoSaveAfterMillies = 10; (m1).autoSaveAfterMilliesEnabled = true; - eventService.addListener(EventType.FILE_DIRTY, () => { + eventService.addListener2(EventType.FILE_DIRTY, () => { eventCounter++; }); - eventService.addListener(EventType.FILE_SAVED, () => { + eventService.addListener2(EventType.FILE_SAVED, () => { eventCounter++; }); @@ -285,13 +285,13 @@ suite('Files - TextFileEditorModel', () => { let eventCounter = 0; let m1 = baseInstantiationService.createInstance(TextFileEditorModel, toResource('/path/index_async.txt'), 'utf8'); - eventService.addListener(EventType.FILE_SAVED, (e) => { + eventService.addListener2(EventType.FILE_SAVED, (e) => { assert.equal(m1.getValue(), 'bar'); assert.ok(!m1.isDirty()); eventCounter++; }); - eventService.addListener(EventType.FILE_SAVING, (e) => { + eventService.addListener2(EventType.FILE_SAVING, (e) => { assert.ok(m1.isDirty()); m1.textEditorModel.setValue('bar'); assert.ok(m1.isDirty()); diff --git a/src/vs/workbench/parts/git/browser/gitActions.contribution.ts b/src/vs/workbench/parts/git/browser/gitActions.contribution.ts index 825c2a6d384..914aff6ec27 100644 --- a/src/vs/workbench/parts/git/browser/gitActions.contribution.ts +++ b/src/vs/workbench/parts/git/browser/gitActions.contribution.ts @@ -255,8 +255,8 @@ export class StageRangesAction extends baseeditor.EditorInputAction { this.editorService = editorService; this.gitService = gitService; this.editor = editor.getControl(); - this.editor.addListener(editorcommon.EventType.CursorSelectionChanged, this.updateEnablement.bind(this)); - this.editor.addListener(editorcommon.EventType.DiffUpdated, this.updateEnablement.bind(this)); + this.editor.onDidCursorSelectionChange(() => this.updateEnablement()); + this.editor.onDidUpdateDiff(() => this.updateEnablement()); this.class = 'git-action stage-ranges'; } diff --git a/src/vs/workbench/parts/git/browser/gitEditorContributions.ts b/src/vs/workbench/parts/git/browser/gitEditorContributions.ts index dd260638370..176c50669fd 100644 --- a/src/vs/workbench/parts/git/browser/gitEditorContributions.ts +++ b/src/vs/workbench/parts/git/browser/gitEditorContributions.ts @@ -4,12 +4,11 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -import ee = require('vs/base/common/eventEmitter'); import editorbrowser = require('vs/editor/browser/editorBrowser'); import common = require('vs/editor/common/editorCommon'); import git = require('vs/workbench/parts/git/common/git'); import {IWorkspaceContextService} from 'vs/platform/workspace/common/workspace'; -import {Disposable} from 'vs/base/common/lifecycle'; +import {Disposable, IDisposable, dispose} from 'vs/base/common/lifecycle'; import {RunOnceScheduler} from 'vs/base/common/async'; import IGitService = git.IGitService; @@ -91,7 +90,7 @@ export class MergeDecorator implements common.IEditorContribution { private editor: editorbrowser.ICodeEditor; private gitService: git.IGitService; private contextService: IWorkspaceContextService; - private toUnbind: ee.ListenerUnbind[]; + private toUnbind: IDisposable[]; private mergeDecorator: MergeDecoratorBoundToModel; @@ -99,7 +98,7 @@ export class MergeDecorator implements common.IEditorContribution { this.gitService = gitService; this.contextService = contextService; this.editor = editor; - this.toUnbind = [ this.editor.addListener(common.EventType.ModelChanged, this.onModelChanged.bind(this)) ]; + this.toUnbind = [ this.editor.onDidModelChange(() => this.onModelChanged()) ]; this.mergeDecorator = null; } @@ -140,8 +139,6 @@ export class MergeDecorator implements common.IEditorContribution { this.mergeDecorator.dispose(); this.mergeDecorator = null; } - while(this.toUnbind.length) { - this.toUnbind.pop()(); - } + this.toUnbind = dispose(this.toUnbind); } } diff --git a/src/vs/workbench/parts/git/browser/gitServices.ts b/src/vs/workbench/parts/git/browser/gitServices.ts index 644ff78809a..1904e9a8fd5 100644 --- a/src/vs/workbench/parts/git/browser/gitServices.ts +++ b/src/vs/workbench/parts/git/browser/gitServices.ts @@ -377,7 +377,7 @@ export class GitService extends ee.EventEmitter git.IGitService { public serviceId = git.IGitService; - + private eventService: IEventService; private contextService: IWorkspaceContextService; private messageService: IMessageService; @@ -391,7 +391,6 @@ export class GitService extends ee.EventEmitter private operations: git.IGitOperation[]; private model: git.IModel; private inputCache: EditorInputCache; - private remoteListenerUnbind:ee.ListenerUnbind; private toDispose: lifecycle.IDisposable[]; private needsRefresh: boolean; private refreshDelayer: async.ThrottledDelayer; @@ -814,11 +813,6 @@ export class GitService extends ee.EventEmitter this.model = null; } - if (this.remoteListenerUnbind) { - this.remoteListenerUnbind(); - this.remoteListenerUnbind = null; - } - super.dispose(); } } \ No newline at end of file diff --git a/src/vs/workbench/parts/git/browser/gitViewlet.ts b/src/vs/workbench/parts/git/browser/gitViewlet.ts index ad6dc9ed7f4..9c56bcd9bb0 100644 --- a/src/vs/workbench/parts/git/browser/gitViewlet.ts +++ b/src/vs/workbench/parts/git/browser/gitViewlet.ts @@ -69,7 +69,7 @@ export class GitViewlet this.toDispose.push(v); }); - this.toUnbind.push(this.gitService.addBulkListener(() => this.onGitServiceChanges())); + this.toUnbind.push(this.gitService.addBulkListener2(() => this.onGitServiceChanges())); } // GitView.IController diff --git a/src/vs/workbench/parts/git/browser/gitWorkbenchContributions.ts b/src/vs/workbench/parts/git/browser/gitWorkbenchContributions.ts index 6c706277ee6..fe5d6d01814 100644 --- a/src/vs/workbench/parts/git/browser/gitWorkbenchContributions.ts +++ b/src/vs/workbench/parts/git/browser/gitWorkbenchContributions.ts @@ -368,7 +368,7 @@ export class DirtyDiffDecorator implements ext.IWorkbenchContribution { // If there is no repository root, just wait until that changes if (typeof repositoryRoot !== 'string') { - this.gitService.addOneTimeListener(git.ServiceEvents.STATE_CHANGED, () => this.onEditorInputChange()); + this.gitService.addOneTimeDisposableListener(git.ServiceEvents.STATE_CHANGED, () => this.onEditorInputChange()); this.models.forEach(m => this.onModelInvisible(m)); this.models = []; diff --git a/src/vs/workbench/parts/git/browser/views/empty/emptyView.ts b/src/vs/workbench/parts/git/browser/views/empty/emptyView.ts index 7387addf666..c7926460bb4 100644 --- a/src/vs/workbench/parts/git/browser/views/empty/emptyView.ts +++ b/src/vs/workbench/parts/git/browser/views/empty/emptyView.ts @@ -98,7 +98,7 @@ export class EmptyView extends EventEmitter.EventEmitter implements GitView.IVie var initSection = $('.section').appendTo(this.$el); this.initButton = new Button(initSection); this.initButton.label = nls.localize('gitinit', 'Initialize git repository'); - this.initButton.on('click', (e) => { + this.initButton.addListener2('click', (e) => { DOM.EventHelper.stop(e); this.disableUI(); diff --git a/src/vs/workbench/parts/markdown/browser/markdownExtension.ts b/src/vs/workbench/parts/markdown/browser/markdownExtension.ts index 7aa23d58944..8da42410e3e 100644 --- a/src/vs/workbench/parts/markdown/browser/markdownExtension.ts +++ b/src/vs/workbench/parts/markdown/browser/markdownExtension.ts @@ -23,7 +23,7 @@ import {IEventService} from 'vs/platform/event/common/event'; import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation'; import {IModeService} from 'vs/editor/common/services/modeService'; import {IThemeService} from 'vs/workbench/services/themes/common/themeService'; -import {IDisposable} from 'vs/base/common/lifecycle'; +import {IDisposable, dispose} from 'vs/base/common/lifecycle'; interface ILanguageConfiguration { markdown: { @@ -36,10 +36,10 @@ export class MarkdownFileTracker implements IWorkbenchContribution { private static RELOAD_MARKDOWN_DELAY = 300; // delay before reloading markdown preview after user typing - private fileChangeListener: () => void; + private fileChangeListener: IDisposable; private configFileChangeListener: IDisposable; private themeChangeListener: IDisposable; - private editorInputChangeListener: () => void; + private editorInputChangeListener: IDisposable; private markdownConfigurationThumbprint: string; private markdownConfigurationPaths: string[]; private reloadTimeout: number; @@ -64,11 +64,11 @@ export class MarkdownFileTracker implements IWorkbenchContribution { } private registerListeners(): void { - this.fileChangeListener = this.eventService.addListener(FileEventType.FILE_CHANGES, (e: FileChangesEvent) => this.onFileChanges(e)); + this.fileChangeListener = this.eventService.addListener2(FileEventType.FILE_CHANGES, (e: FileChangesEvent) => this.onFileChanges(e)); this.configFileChangeListener = this.configurationService.onDidUpdateConfiguration(e => this.onConfigFileChange(e)); // reload markdown editors when their resources change - this.editorInputChangeListener = this.eventService.addListener(WorkbenchEventType.EDITOR_INPUT_CHANGED, (e: EditorEvent) => this.onEditorInputChanged(e)); + this.editorInputChangeListener = this.eventService.addListener2(WorkbenchEventType.EDITOR_INPUT_CHANGED, (e: EditorEvent) => this.onEditorInputChanged(e)); // initially read the config for CSS styles in preview this.readMarkdownConfiguration(this.configurationService.getConfiguration()); @@ -86,17 +86,15 @@ export class MarkdownFileTracker implements IWorkbenchContribution { let markdownResource = input.getResource(); let editorModel = this.modelService.getModel(markdownResource); if (editorModel && !this.hasModelListenerOnResourcePath[markdownResource.toString()]) { - let toUnbind: Function[] = []; + let toUnbind: IDisposable[] = []; let unbind = () => { - while (toUnbind.length) { - toUnbind.pop()(); - } + toUnbind = dispose(toUnbind); this.hasModelListenerOnResourcePath[markdownResource.toString()] = false; }; // Listen on changes to the underlying resource of the markdown preview - toUnbind.push(editorModel.addListener(EditorEventType.ModelContentChanged, (modelEvent: IModelContentChangedEvent) => { + toUnbind.push(editorModel.addListener2(EditorEventType.ModelContentChanged, (modelEvent: IModelContentChangedEvent) => { if (this.reloadTimeout) { window.clearTimeout(this.reloadTimeout); } @@ -112,8 +110,8 @@ export class MarkdownFileTracker implements IWorkbenchContribution { this.hasModelListenerOnResourcePath[markdownResource.toString()] = true; // Unbind when input or model gets disposed - toUnbind.push(input.addListener(EventType.DISPOSE, unbind)); - toUnbind.push(editorModel.addListener(EditorEventType.ModelDispose, unbind)); + toUnbind.push(input.addListener2(EventType.DISPOSE, unbind)); + toUnbind.push(editorModel.addListener2(EditorEventType.ModelDispose, unbind)); } } } @@ -190,7 +188,7 @@ export class MarkdownFileTracker implements IWorkbenchContribution { public dispose(): void { if (this.fileChangeListener) { - this.fileChangeListener(); + this.fileChangeListener.dispose(); this.fileChangeListener = null; } @@ -200,7 +198,7 @@ export class MarkdownFileTracker implements IWorkbenchContribution { } if (this.editorInputChangeListener) { - this.editorInputChangeListener(); + this.editorInputChangeListener.dispose(); this.editorInputChangeListener = null; } } diff --git a/src/vs/workbench/parts/search/browser/searchViewlet.ts b/src/vs/workbench/parts/search/browser/searchViewlet.ts index cb99a64facb..e6785c989db 100644 --- a/src/vs/workbench/parts/search/browser/searchViewlet.ts +++ b/src/vs/workbench/parts/search/browser/searchViewlet.ts @@ -645,7 +645,7 @@ export class SearchViewlet extends Viewlet { private loading: boolean; private queryBuilder: QueryBuilder; private viewModel: SearchResult; - private callOnModelChange: Function[]; + private callOnModelChange: lifecycle.IDisposable[]; private viewletVisible: IKeybindingContextKey; private actionRegistry: { [key: string]: Action; }; @@ -686,9 +686,9 @@ export class SearchViewlet extends Viewlet { this.queryBuilder = this.instantiationService.createInstance(QueryBuilder); this.viewletSettings = this.getMemento(storageService, Scope.WORKSPACE); - this.toUnbind.push(this.eventService.addListener(FileEventType.FILE_CHANGES, (e) => this.onFilesChanged(e))); - this.toUnbind.push(this.eventService.addListener(WorkbenchEventType.UNTITLED_FILE_DELETED, (e) => this.onUntitledFileDeleted(e))); - this.toUnbind.push(this.configurationService.onDidUpdateConfiguration(e => this.onConfigurationUpdated(e.config)).dispose); + this.toUnbind.push(this.eventService.addListener2(FileEventType.FILE_CHANGES, (e) => this.onFilesChanged(e))); + this.toUnbind.push(this.eventService.addListener2(WorkbenchEventType.UNTITLED_FILE_DELETED, (e) => this.onUntitledFileDeleted(e))); + this.toUnbind.push(this.configurationService.onDidUpdateConfiguration(e => this.onConfigurationUpdated(e.config))); } private onConfigurationUpdated(configuration: any): void { @@ -882,9 +882,9 @@ export class SearchViewlet extends Viewlet { ariaLabel: nls.localize('treeAriaLabel', "Search Results") }); - this.toUnbind.push(() => renderer.dispose()); + this.toUnbind.push(renderer); - this.toUnbind.push(this.tree.addListener('selection', (event: any) => { + this.toUnbind.push(this.tree.addListener2('selection', (event: any) => { let element: any, keyboard = event.payload && event.payload.origin === 'keyboard'; if (keyboard) { element = this.tree.getFocus(); @@ -1365,7 +1365,7 @@ export class SearchViewlet extends Viewlet { this.viewModel = this.instantiationService.createInstance(SearchResult, query.contentPattern); this.tree.setInput(this.viewModel).then(() => { autoExpand(false); - this.callOnModelChange.push(this.viewModel.addListener('changed', (e: any) => this.tree.refresh(e, true))); + this.callOnModelChange.push(this.viewModel.addListener2('changed', (e: any) => this.tree.refresh(e, true))); }).done(null, errors.onUnexpectedError); } @@ -1501,6 +1501,6 @@ export class SearchViewlet extends Viewlet { this.viewModel.dispose(); this.viewModel = null; } - lifecycle.cAll(this.callOnModelChange); + this.callOnModelChange = lifecycle.dispose(this.callOnModelChange); } } diff --git a/src/vs/workbench/parts/search/common/searchModel.ts b/src/vs/workbench/parts/search/common/searchModel.ts index 4eba048d32c..ac153b98877 100644 --- a/src/vs/workbench/parts/search/common/searchModel.ts +++ b/src/vs/workbench/parts/search/common/searchModel.ts @@ -139,7 +139,7 @@ export class LiveFileMatch extends FileMatch implements lifecycle.IDisposable { private _query: Search.IPatternInfo; private _updateScheduler: RunOnceScheduler; private _modelDecorations: string[] = []; - private _unbind: Function[] = []; + private _unbind: lifecycle.IDisposable[] = []; _diskFileMatch: FileMatch; constructor(parent: SearchResult, resource: URI, query: Search.IPatternInfo, model: IModel, fileMatch: FileMatch) { @@ -149,12 +149,12 @@ export class LiveFileMatch extends FileMatch implements lifecycle.IDisposable { this._model = model; this._diskFileMatch = fileMatch; this._updateScheduler = new RunOnceScheduler(this._updateMatches.bind(this), 250); - this._unbind.push(this._model.addListener(EventType.ModelContentChanged, _ => this._updateScheduler.schedule())); + this._unbind.push(this._model.addListener2(EventType.ModelContentChanged, _ => this._updateScheduler.schedule())); this._updateMatches(); } public dispose(): void { - this._unbind = lifecycle.cAll(this._unbind); + this._unbind = lifecycle.dispose(this._unbind); if (!this._isTextModelDisposed()) { this._model.deltaDecorations(this._modelDecorations, []); } diff --git a/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts b/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts index c4177de6bf8..7d1982212df 100644 --- a/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts +++ b/src/vs/workbench/parts/tasks/electron-browser/task.contribution.ts @@ -17,7 +17,7 @@ import { IStringDictionary } from 'vs/base/common/collections'; import { Action } from 'vs/base/common/actions'; import * as Dom from 'vs/base/browser/dom'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; -import { EventEmitter, ListenerUnbind } from 'vs/base/common/eventEmitter'; +import { EventEmitter } from 'vs/base/common/eventEmitter'; import * as Builder from 'vs/base/browser/builder'; import * as Types from 'vs/base/common/types'; import { KeyMod, KeyCode } from 'vs/base/common/keyCodes'; @@ -560,11 +560,11 @@ class TaskService extends EventEmitter implements ITaskService { private _taskSystemPromise: TPromise; private _taskSystem: ITaskSystem; - private taskSystemListeners: ListenerUnbind[]; + private taskSystemListeners: IDisposable[]; private clearTaskSystemPromise: boolean; private outputChannel: IOutputChannel; - private fileChangesListener: ListenerUnbind; + private fileChangesListener: IDisposable; constructor(@IModeService modeService: IModeService, @IConfigurationService configurationService: IConfigurationService, @IMarkerService markerService: IMarkerService, @IOutputService outputService: IOutputService, @@ -609,13 +609,12 @@ class TaskService extends EventEmitter implements ITaskService { } private disposeTaskSystemListeners(): void { - this.taskSystemListeners.forEach(unbind => unbind()); - this.taskSystemListeners = []; + this.taskSystemListeners = dispose(this.taskSystemListeners); } private disposeFileChangesListener(): void { if (this.fileChangesListener) { - this.fileChangesListener(); + this.fileChangesListener.dispose(); this.fileChangesListener = null; } } @@ -694,8 +693,8 @@ class TaskService extends EventEmitter implements ITaskService { this._taskSystemPromise = null; throw new TaskError(Severity.Info, nls.localize('TaskSystem.noBuildType', "No valid task runner configured. Supported task runners are 'service' and 'program'."), TaskErrors.NoValidTaskRunner); } - this.taskSystemListeners.push(result.addListener(TaskSystemEvents.Active, (event) => this.emit(TaskServiceEvents.Active, event))); - this.taskSystemListeners.push(result.addListener(TaskSystemEvents.Inactive, (event) => this.emit(TaskServiceEvents.Inactive, event))); + this.taskSystemListeners.push(result.addListener2(TaskSystemEvents.Active, (event) => this.emit(TaskServiceEvents.Active, event))); + this.taskSystemListeners.push(result.addListener2(TaskSystemEvents.Inactive, (event) => this.emit(TaskServiceEvents.Inactive, event))); this._taskSystem = result; return result; }, (err: any) => { @@ -773,7 +772,7 @@ class TaskService extends EventEmitter implements ITaskService { then((runResult: ITaskRunResult) => { if (runResult.restartOnFileChanges) { let pattern = runResult.restartOnFileChanges; - this.fileChangesListener = this.eventService.addListener(FileEventType.FILE_CHANGES, (event: FileChangesEvent) => { + this.fileChangesListener = this.eventService.addListener2(FileEventType.FILE_CHANGES, (event: FileChangesEvent) => { let needsRestart = event.changes.some((change) => { return (change.type === FileChangeType.ADDED || change.type === FileChangeType.DELETED) && !!match(pattern, change.resource.fsPath); }); diff --git a/src/vs/workbench/parts/tasks/node/processRunnerSystem.ts b/src/vs/workbench/parts/tasks/node/processRunnerSystem.ts index c3a49d241da..296ff776e1e 100644 --- a/src/vs/workbench/parts/tasks/node/processRunnerSystem.ts +++ b/src/vs/workbench/parts/tasks/node/processRunnerSystem.ts @@ -12,7 +12,7 @@ import { TPromise, Promise } from 'vs/base/common/winjs.base'; import * as Async from 'vs/base/common/async'; import Severity from 'vs/base/common/severity'; import * as Strings from 'vs/base/common/strings'; -import { EventEmitter, ListenerUnbind } from 'vs/base/common/eventEmitter'; +import { EventEmitter } from 'vs/base/common/eventEmitter'; import { TerminateResponse, SuccessData, ErrorData } from 'vs/base/common/processes'; import { LineProcess, LineData } from 'vs/base/node/processes'; @@ -30,6 +30,8 @@ import { StartStopProblemCollector, WatchingProblemCollector, ProblemCollectorEv import { ITaskSystem, ITaskSummary, ITaskRunResult, TaskError, TaskErrors, TaskRunnerConfiguration, TaskDescription, CommandOptions, ShowOutput, TelemetryEvent, Triggers, TaskSystemEvents, TaskEvent, TaskType } from 'vs/workbench/parts/tasks/common/taskSystem'; import * as FileConfig from './processRunnerConfiguration'; +import {IDisposable, dispose} from 'vs/base/common/lifecycle'; + export class ProcessRunnerSystem extends EventEmitter implements ITaskSystem { public static TelemetryEventName: string = 'taskService'; @@ -224,14 +226,14 @@ export class ProcessRunnerSystem extends EventEmitter implements ITaskSystem { } if (task.isWatching) { let watchingProblemMatcher = new WatchingProblemCollector(this.resolveMatchers(task.problemMatchers), this.markerService, this.modelService); - let toUnbind: ListenerUnbind[] = []; + let toUnbind: IDisposable[] = []; let event: TaskEvent = { taskId: task.id, taskName: task.name, type: TaskType.Watching }; let eventCounter: number = 0; - toUnbind.push(watchingProblemMatcher.on(ProblemCollectorEvents.WatchingBeginDetected, () => { + toUnbind.push(watchingProblemMatcher.addListener2(ProblemCollectorEvents.WatchingBeginDetected, () => { eventCounter++; this.emit(TaskSystemEvents.Active, event); })); - toUnbind.push(watchingProblemMatcher.on(ProblemCollectorEvents.WatchingEndDetected, () => { + toUnbind.push(watchingProblemMatcher.addListener2(ProblemCollectorEvents.WatchingEndDetected, () => { eventCounter--; this.emit(TaskSystemEvents.Inactive, event); })); @@ -241,7 +243,7 @@ export class ProcessRunnerSystem extends EventEmitter implements ITaskSystem { let promise = this.childProcess.start().then((success): ITaskSummary => { this.childProcessEnded(); watchingProblemMatcher.dispose(); - toUnbind.forEach(unbind => unbind()); + toUnbind = dispose(toUnbind); toUnbind = null; for (let i = 0; i < eventCounter; i++) { this.emit(TaskSystemEvents.Inactive, event); @@ -258,7 +260,7 @@ export class ProcessRunnerSystem extends EventEmitter implements ITaskSystem { }, (error: ErrorData) => { this.childProcessEnded(); watchingProblemMatcher.dispose(); - toUnbind.forEach(unbind => unbind()); + toUnbind = dispose(toUnbind); toUnbind = null; for (let i = 0; i < eventCounter; i++) { this.emit(TaskSystemEvents.Inactive, event); diff --git a/src/vs/workbench/parts/terminal/electron-browser/terminalPanel.ts b/src/vs/workbench/parts/terminal/electron-browser/terminalPanel.ts index f059f639b62..3bc231a7bbf 100644 --- a/src/vs/workbench/parts/terminal/electron-browser/terminalPanel.ts +++ b/src/vs/workbench/parts/terminal/electron-browser/terminalPanel.ts @@ -6,6 +6,7 @@ import cp = require('child_process'); import termJs = require('term.js'); import lifecycle = require('vs/base/common/lifecycle'); +import os = require('os'); import path = require('path'); import URI from 'vs/base/common/uri'; import DOM = require('vs/base/browser/dom'); @@ -69,7 +70,7 @@ export class TerminalPanel extends Panel { private createTerminalProcess(): cp.ChildProcess { let env = this.cloneEnv(); env['PTYSHELL'] = this.getShell(); - env['PTYCWD'] = this.contextService.getWorkspace() ? this.contextService.getWorkspace().resource.fsPath : process.env.HOME; + env['PTYCWD'] = this.contextService.getWorkspace() ? this.contextService.getWorkspace().resource.fsPath : os.homedir(); return cp.fork('./terminalProcess', [], { env: env, cwd: URI.parse(path.dirname(require.toUrl('./terminalProcess'))).fsPath diff --git a/src/vs/workbench/services/configuration/node/configurationService.ts b/src/vs/workbench/services/configuration/node/configurationService.ts index 30d2229072e..d49469db3ed 100644 --- a/src/vs/workbench/services/configuration/node/configurationService.ts +++ b/src/vs/workbench/services/configuration/node/configurationService.ts @@ -18,6 +18,7 @@ import {IWorkspaceContextService} from 'vs/workbench/services/workspace/common/c import {OptionsChangeEvent, EventType} from 'vs/workbench/common/events'; import {IEventService} from 'vs/platform/event/common/event'; import {IConfigurationService} from 'vs/platform/configuration/common/configuration'; +import {IDisposable} from 'vs/base/common/lifecycle'; import fs = require('fs'); @@ -26,7 +27,7 @@ export class ConfigurationService extends CommonConfigurationService { public serviceId = IConfigurationService; protected contextService: IWorkspaceContextService; - private toDispose: Function; + private toDispose: IDisposable; constructor(contextService: IWorkspaceContextService, eventService: IEventService) { super(contextService, eventService); @@ -37,7 +38,7 @@ export class ConfigurationService extends CommonConfigurationService { protected registerListeners(): void { super.registerListeners(); - this.toDispose = this.eventService.addListener(EventType.WORKBENCH_OPTIONS_CHANGED, (e) => this.onOptionsChanged(e)); + this.toDispose = this.eventService.addListener2(EventType.WORKBENCH_OPTIONS_CHANGED, (e) => this.onOptionsChanged(e)); } private onOptionsChanged(e: OptionsChangeEvent): void { @@ -129,6 +130,6 @@ export class ConfigurationService extends CommonConfigurationService { public dispose(): void { super.dispose(); - this.toDispose(); + this.toDispose.dispose(); } } \ No newline at end of file diff --git a/src/vs/workbench/services/files/test/node/fileService.test.ts b/src/vs/workbench/services/files/test/node/fileService.test.ts index ae982935bc9..61e0f8af2ed 100644 --- a/src/vs/workbench/services/files/test/node/fileService.test.ts +++ b/src/vs/workbench/services/files/test/node/fileService.test.ts @@ -443,7 +443,7 @@ suite('FileService', () => { service.watchFileChanges(toWatch); - events.on(EventType.FILE_CHANGES, (e: FileChangesEvent) => { + events.addListener2(EventType.FILE_CHANGES, (e: FileChangesEvent) => { assert.ok(e); service.unwatchFileChanges(toWatch); diff --git a/src/vs/workbench/services/files/test/node/watcher.test.ts b/src/vs/workbench/services/files/test/node/watcher.test.ts index 06ad72f89c6..72c86e82c05 100644 --- a/src/vs/workbench/services/files/test/node/watcher.test.ts +++ b/src/vs/workbench/services/files/test/node/watcher.test.ts @@ -59,7 +59,7 @@ suite('Watcher', () => { { path: deleted.fsPath, type: FileChangeType.DELETED }, ]; - events.on(EventType.FILE_CHANGES, (e: FileChangesEvent) => { + events.addListener2(EventType.FILE_CHANGES, (e: FileChangesEvent) => { assert.ok(e); assert.equal(e.changes.length, 3); assert.ok(e.contains(added, FileChangeType.ADDED)); @@ -99,7 +99,7 @@ suite('Watcher', () => { { path: updatedFile.fsPath, type: FileChangeType.UPDATED } ]; - events.on(EventType.FILE_CHANGES, (e: FileChangesEvent) => { + events.addListener2(EventType.FILE_CHANGES, (e: FileChangesEvent) => { assert.ok(e); assert.equal(e.changes.length, 5); @@ -130,7 +130,7 @@ suite('Watcher', () => { { path: unrelated.fsPath, type: FileChangeType.UPDATED }, ]; - events.on(EventType.FILE_CHANGES, (e: FileChangesEvent) => { + events.addListener2(EventType.FILE_CHANGES, (e: FileChangesEvent) => { assert.ok(e); assert.equal(e.changes.length, 1); @@ -156,7 +156,7 @@ suite('Watcher', () => { { path: unrelated.fsPath, type: FileChangeType.UPDATED }, ]; - events.on(EventType.FILE_CHANGES, (e: FileChangesEvent) => { + events.addListener2(EventType.FILE_CHANGES, (e: FileChangesEvent) => { assert.ok(e); assert.equal(e.changes.length, 2); @@ -183,7 +183,7 @@ suite('Watcher', () => { { path: unrelated.fsPath, type: FileChangeType.UPDATED }, ]; - events.on(EventType.FILE_CHANGES, (e: FileChangesEvent) => { + events.addListener2(EventType.FILE_CHANGES, (e: FileChangesEvent) => { assert.ok(e); assert.equal(e.changes.length, 2); @@ -213,7 +213,7 @@ suite('Watcher', () => { { path: updated.fsPath, type: FileChangeType.DELETED } ]; - events.on(EventType.FILE_CHANGES, (e: FileChangesEvent) => { + events.addListener2(EventType.FILE_CHANGES, (e: FileChangesEvent) => { assert.ok(e); assert.equal(e.changes.length, 2); diff --git a/src/vs/workbench/services/history/browser/history.ts b/src/vs/workbench/services/history/browser/history.ts index e895e764d8a..be9d3eeceee 100644 --- a/src/vs/workbench/services/history/browser/history.ts +++ b/src/vs/workbench/services/history/browser/history.ts @@ -19,6 +19,7 @@ import {Selection} from 'vs/editor/common/core/selection'; import {Position, IEditorInput} from 'vs/platform/editor/common/editor'; import {IEventService} from 'vs/platform/event/common/event'; import {IWorkspaceContextService} from 'vs/platform/workspace/common/workspace'; +import {IDisposable, dispose} from 'vs/base/common/lifecycle'; /** * Stores the selection & view state of an editor and allows to compare it to other selection states. @@ -67,7 +68,7 @@ interface IInputWithPath { } export abstract class BaseHistoryService { - protected toUnbind: { (): void; }[]; + protected toUnbind: IDisposable[]; constructor( private eventService: IEventService, @@ -80,13 +81,13 @@ export abstract class BaseHistoryService { window.document.title = this.getWindowTitle(null); // Editor Input Changes - this.toUnbind.push(this.eventService.addListener(WorkbenchEventType.EDITOR_INPUT_CHANGED, (e: EditorEvent) => this.onEditorInputChanged(e))); + this.toUnbind.push(this.eventService.addListener2(WorkbenchEventType.EDITOR_INPUT_CHANGED, (e: EditorEvent) => this.onEditorInputChanged(e))); // Editor Input State Changes - this.toUnbind.push(this.eventService.addListener(WorkbenchEventType.EDITOR_INPUT_DIRTY_STATE_CHANGED, (e: EditorInputEvent) => this.onEditorInputDirtyStateChanged(e.editorInput))); + this.toUnbind.push(this.eventService.addListener2(WorkbenchEventType.EDITOR_INPUT_DIRTY_STATE_CHANGED, (e: EditorInputEvent) => this.onEditorInputDirtyStateChanged(e.editorInput))); // Text Editor Selection Changes - this.toUnbind.push(this.eventService.addListener(WorkbenchEventType.TEXT_EDITOR_SELECTION_CHANGED, (event: TextEditorSelectionEvent) => this.onTextEditorSelectionChanged(event))); + this.toUnbind.push(this.eventService.addListener2(WorkbenchEventType.TEXT_EDITOR_SELECTION_CHANGED, (event: TextEditorSelectionEvent) => this.onTextEditorSelectionChanged(event))); } private onEditorInputDirtyStateChanged(input: IEditorInput): void { @@ -218,9 +219,7 @@ export abstract class BaseHistoryService { } public dispose(): void { - while (this.toUnbind.length) { - this.toUnbind.pop()(); - } + this.toUnbind = dispose(this.toUnbind); } } @@ -369,7 +368,7 @@ export class HistoryService extends BaseHistoryService implements IHistoryServic } // Take out on dispose - input.addOneTimeListener(EventType.DISPOSE, () => { + input.addOneTimeDisposableListener(EventType.DISPOSE, () => { this.stack.forEach((e, i) => { if (e.input.matches(input)) { this.stack.splice(i, 1); diff --git a/src/vs/workbench/services/keybinding/electron-browser/keybindingService.ts b/src/vs/workbench/services/keybinding/electron-browser/keybindingService.ts index de8a32c51a3..88bda1e3cee 100644 --- a/src/vs/workbench/services/keybinding/electron-browser/keybindingService.ts +++ b/src/vs/workbench/services/keybinding/electron-browser/keybindingService.ts @@ -26,6 +26,7 @@ import {IWorkspaceContextService} from 'vs/platform/workspace/common/workspace'; import {EventType, OptionsChangeEvent} from 'vs/workbench/common/events'; import {getNativeLabelProvider, getNativeAriaLabelProvider} from 'vs/workbench/services/keybinding/electron-browser/nativeKeymap'; import {IMessageService} from 'vs/platform/message/common/message'; +import {IDisposable} from 'vs/base/common/lifecycle'; interface ContributedKeyBinding { command: string; @@ -119,7 +120,7 @@ export class WorkbenchKeybindingService extends KeybindingService { private contextService: IWorkspaceContextService; private eventService: IEventService; private telemetryService: ITelemetryService; - private toDispose: Function; + private toDispose: IDisposable; private _extensionService: IExtensionService; private _eventService: IEventService; @@ -129,7 +130,7 @@ export class WorkbenchKeybindingService extends KeybindingService { this.eventService = eventService; this.telemetryService = telemetryService; this._extensionService = extensionService; - this.toDispose = this.eventService.addListener(EventType.WORKBENCH_OPTIONS_CHANGED, (e) => this.onOptionsChanged(e)); + this.toDispose = this.eventService.addListener2(EventType.WORKBENCH_OPTIONS_CHANGED, (e) => this.onOptionsChanged(e)); this._eventService = eventService; keybindingsExtPoint.setHandler((extensions) => { let commandAdded = false; @@ -181,7 +182,7 @@ export class WorkbenchKeybindingService extends KeybindingService { } public dispose(): void { - this.toDispose(); + this.toDispose.dispose(); } public getLabelFor(keybinding: Keybinding): string { diff --git a/src/vs/workbench/services/progress/browser/progressService.ts b/src/vs/workbench/services/progress/browser/progressService.ts index 99624b0c092..4feaca0399e 100644 --- a/src/vs/workbench/services/progress/browser/progressService.ts +++ b/src/vs/workbench/services/progress/browser/progressService.ts @@ -35,25 +35,25 @@ export abstract class ScopedService { } public registerListeners(): void { - this.eventService.addListener(EventType.EDITOR_CLOSED, (e: EditorEvent) => { + this.eventService.addListener2(EventType.EDITOR_CLOSED, (e: EditorEvent) => { if (e.editorId === this.scopeId) { this.onScopeDeactivated(); } }); - this.eventService.addListener(EventType.EDITOR_OPENED, (e: EditorEvent) => { + this.eventService.addListener2(EventType.EDITOR_OPENED, (e: EditorEvent) => { if (e.editorId === this.scopeId) { this.onScopeActivated(); } }); - this.eventService.addListener(EventType.COMPOSITE_CLOSED, (e: CompositeEvent) => { + this.eventService.addListener2(EventType.COMPOSITE_CLOSED, (e: CompositeEvent) => { if (e.compositeId === this.scopeId) { this.onScopeDeactivated(); } }); - this.eventService.addListener(EventType.COMPOSITE_OPENED, (e: CompositeEvent) => { + this.eventService.addListener2(EventType.COMPOSITE_OPENED, (e: CompositeEvent) => { if (e.compositeId === this.scopeId) { this.onScopeActivated(); } diff --git a/src/vs/workbench/services/untitled/common/untitledEditorService.ts b/src/vs/workbench/services/untitled/common/untitledEditorService.ts index 4bef4be7af3..2107f71c889 100644 --- a/src/vs/workbench/services/untitled/common/untitledEditorService.ts +++ b/src/vs/workbench/services/untitled/common/untitledEditorService.ts @@ -119,7 +119,7 @@ export class UntitledEditorService implements IUntitledEditorService { let input = this.instantiationService.createInstance(UntitledEditorInput, resource, hasAssociatedFilePath, modeId); // Remove from cache on dispose - input.addOneTimeListener(EventType.DISPOSE, () => { + input.addOneTimeDisposableListener(EventType.DISPOSE, () => { delete UntitledEditorService.CACHE[input.getResource().toString()]; delete UntitledEditorService.KNOWN_ASSOCIATED_FILE_PATHS[input.getResource().toString()]; }); diff --git a/src/vs/workbench/test/browser/parts/editor/baseEditor.test.ts b/src/vs/workbench/test/browser/parts/editor/baseEditor.test.ts index c8aef5a870b..9f33eeda439 100644 --- a/src/vs/workbench/test/browser/parts/editor/baseEditor.test.ts +++ b/src/vs/workbench/test/browser/parts/editor/baseEditor.test.ts @@ -140,7 +140,7 @@ suite('Workbench BaseEditor', () => { e.setVisible(true) assert(e.isVisible()); - input.addListener('dispose', function () { + input.addListener2('dispose', function () { assert(false); }); e.dispose(); diff --git a/src/vs/workbench/test/common/editor/editorInput.test.ts b/src/vs/workbench/test/common/editor/editorInput.test.ts index 6a044afc58d..155d7c81d75 100644 --- a/src/vs/workbench/test/common/editor/editorInput.test.ts +++ b/src/vs/workbench/test/common/editor/editorInput.test.ts @@ -35,7 +35,7 @@ suite('Workbench - EditorInput', () => { assert(!input.matches(null)); assert(!input.getName()); - input.addListener('dispose', function () { + input.addListener2('dispose', function () { assert(true); counter++; }); @@ -47,13 +47,13 @@ suite('Workbench - EditorInput', () => { test('DiffEditorInput', function () { let counter = 0; let input = new MyEditorInput(); - input.addListener('dispose', function () { + input.addListener2('dispose', function () { assert(true); counter++; }); let otherInput = new MyEditorInput(); - otherInput.addListener('dispose', function () { + otherInput.addListener2('dispose', function () { assert(true); counter++; }); @@ -76,7 +76,7 @@ suite('Workbench - EditorInput', () => { let otherInput = new MyEditorInput(); let diffInput = new DiffEditorInput('name', 'description', input, otherInput); - diffInput.addListener('dispose', function () { + diffInput.addListener2('dispose', function () { counter++; assert(true); }); @@ -87,7 +87,7 @@ suite('Workbench - EditorInput', () => { otherInput = new MyEditorInput(); let diffInput2 = new DiffEditorInput('name', 'description', input, otherInput); - diffInput2.addListener('dispose', function () { + diffInput2.addListener2('dispose', function () { counter++; assert(true); });