-
Notifications
You must be signed in to change notification settings - Fork 29.5k
/
codeActionWidget.ts
79 lines (66 loc) · 2.75 KB
/
codeActionWidget.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { getDomNodePagePosition } from 'vs/base/browser/dom';
import { Action } from 'vs/base/common/actions';
import { always } from 'vs/base/common/async';
import { canceled } from 'vs/base/common/errors';
import { Emitter, Event } from 'vs/base/common/event';
import { TPromise } from 'vs/base/common/winjs.base';
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
import { Position } from 'vs/editor/common/core/position';
import { ScrollType } from 'vs/editor/common/editorCommon';
import { CodeAction } from 'vs/editor/common/modes';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
export class CodeActionContextMenu {
private _visible: boolean;
private _onDidExecuteCodeAction = new Emitter<void>();
readonly onDidExecuteCodeAction: Event<void> = this._onDidExecuteCodeAction.event;
constructor(
private readonly _editor: ICodeEditor,
private readonly _contextMenuService: IContextMenuService,
private readonly _onApplyCodeAction: (action: CodeAction) => TPromise<any>
) { }
show(fixes: TPromise<CodeAction[]>, at: { x: number; y: number } | Position) {
const actions = fixes.then(value => {
return value.map(action => {
return new Action(action.command ? action.command.id : action.title, action.title, undefined, true, () => {
return always(
this._onApplyCodeAction(action),
() => this._onDidExecuteCodeAction.fire(undefined));
});
});
}).then(actions => {
if (!this._editor.getDomNode()) {
// cancel when editor went off-dom
return TPromise.wrapError<any>(canceled());
}
return actions;
});
this._contextMenuService.showContextMenu({
getAnchor: () => {
if (Position.isIPosition(at)) {
at = this._toCoords(at);
}
return at;
},
getActions: () => actions,
onHide: () => { this._visible = false; },
autoSelectFirstItem: true
});
}
get isVisible(): boolean {
return this._visible;
}
private _toCoords(position: Position): { x: number, y: number } {
this._editor.revealPosition(position, ScrollType.Immediate);
this._editor.render();
// Translate to absolute editor position
const cursorCoords = this._editor.getScrolledVisiblePosition(this._editor.getPosition());
const editorCoords = getDomNodePagePosition(this._editor.getDomNode());
const x = editorCoords.left + cursorCoords.left;
const y = editorCoords.top + cursorCoords.top + cursorCoords.height;
return { x, y };
}
}