mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-03-21 12:20:29 -04:00
Merge from vscode 81d7885dc2e9dc617e1522697a2966bc4025a45d (#5949)
* Merge from vscode 81d7885dc2e9dc617e1522697a2966bc4025a45d * Fix vs unit tests and hygiene issue * Fix strict null check issue
This commit is contained in:
@@ -4,8 +4,8 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { CancelablePromise, createCancelablePromise, TimeoutTimer } from 'vs/base/common/async';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
import { dispose, Disposable } from 'vs/base/common/lifecycle';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
@@ -14,36 +14,34 @@ import { Selection } from 'vs/editor/common/core/selection';
|
||||
import { CodeActionProviderRegistry } from 'vs/editor/common/modes';
|
||||
import { IContextKey, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { IMarkerService } from 'vs/platform/markers/common/markers';
|
||||
import { IProgressService } from 'vs/platform/progress/common/progress';
|
||||
import { ILocalProgressService } from 'vs/platform/progress/common/progress';
|
||||
import { getCodeActions, CodeActionSet } from './codeAction';
|
||||
import { CodeActionTrigger } from './codeActionTrigger';
|
||||
|
||||
export const SUPPORTED_CODE_ACTIONS = new RawContextKey<string>('supportedCodeAction', '');
|
||||
|
||||
export class CodeActionOracle {
|
||||
export type TriggeredCodeAction = undefined | {
|
||||
readonly selection: Selection;
|
||||
readonly trigger: CodeActionTrigger;
|
||||
readonly position: Position;
|
||||
};
|
||||
|
||||
private _disposables: IDisposable[] = [];
|
||||
private readonly _autoTriggerTimer = new TimeoutTimer();
|
||||
class CodeActionOracle extends Disposable {
|
||||
|
||||
private readonly _autoTriggerTimer = this._register(new TimeoutTimer());
|
||||
|
||||
constructor(
|
||||
private readonly _editor: ICodeEditor,
|
||||
private readonly _markerService: IMarkerService,
|
||||
private readonly _signalChange: (newState: CodeActionsState.State) => void,
|
||||
private readonly _signalChange: (triggered: TriggeredCodeAction) => void,
|
||||
private readonly _delay: number = 250,
|
||||
private readonly _progressService?: IProgressService,
|
||||
) {
|
||||
this._disposables.push(
|
||||
this._markerService.onMarkerChanged(e => this._onMarkerChanges(e)),
|
||||
this._editor.onDidChangeCursorPosition(() => this._onCursorChange()),
|
||||
);
|
||||
super();
|
||||
this._register(this._markerService.onMarkerChanged(e => this._onMarkerChanges(e)));
|
||||
this._register(this._editor.onDidChangeCursorPosition(() => this._onCursorChange()));
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this._disposables = dispose(this._disposables);
|
||||
this._autoTriggerTimer.cancel();
|
||||
}
|
||||
|
||||
trigger(trigger: CodeActionTrigger) {
|
||||
public trigger(trigger: CodeActionTrigger): TriggeredCodeAction {
|
||||
const selection = this._getRangeOfSelectionUnlessWhitespaceEnclosed(trigger);
|
||||
return this._createEventAndSignalChange(trigger, selection);
|
||||
}
|
||||
@@ -112,35 +110,24 @@ export class CodeActionOracle {
|
||||
return selection ? selection : undefined;
|
||||
}
|
||||
|
||||
private _createEventAndSignalChange(trigger: CodeActionTrigger, selection: Selection | undefined): Promise<CodeActionSet | undefined> {
|
||||
if (!selection) {
|
||||
private _createEventAndSignalChange(trigger: CodeActionTrigger, selection: Selection | undefined): TriggeredCodeAction {
|
||||
const model = this._editor.getModel();
|
||||
if (!selection || !model) {
|
||||
// cancel
|
||||
this._signalChange(CodeActionsState.Empty);
|
||||
return Promise.resolve(undefined);
|
||||
} else {
|
||||
const model = this._editor.getModel();
|
||||
if (!model) {
|
||||
// cancel
|
||||
this._signalChange(CodeActionsState.Empty);
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
const markerRange = this._getRangeOfMarker(selection);
|
||||
const position = markerRange ? markerRange.getStartPosition() : selection.getStartPosition();
|
||||
const actions = createCancelablePromise(token => getCodeActions(model, selection, trigger, token));
|
||||
|
||||
if (this._progressService && trigger.type === 'manual') {
|
||||
this._progressService.showWhile(actions, 250);
|
||||
}
|
||||
|
||||
this._signalChange(new CodeActionsState.Triggered(
|
||||
trigger,
|
||||
selection,
|
||||
position,
|
||||
actions
|
||||
));
|
||||
return actions;
|
||||
this._signalChange(undefined);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const markerRange = this._getRangeOfMarker(selection);
|
||||
const position = markerRange ? markerRange.getStartPosition() : selection.getStartPosition();
|
||||
|
||||
const e: TriggeredCodeAction = {
|
||||
trigger,
|
||||
selection,
|
||||
position
|
||||
};
|
||||
this._signalChange(e);
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,36 +154,35 @@ export namespace CodeActionsState {
|
||||
export type State = typeof Empty | Triggered;
|
||||
}
|
||||
|
||||
export class CodeActionModel {
|
||||
export class CodeActionModel extends Disposable {
|
||||
|
||||
private _codeActionOracle?: CodeActionOracle;
|
||||
private _state: CodeActionsState.State = CodeActionsState.Empty;
|
||||
private _onDidChangeState = new Emitter<CodeActionsState.State>();
|
||||
private _disposables: IDisposable[] = [];
|
||||
private readonly _supportedCodeActions: IContextKey<string>;
|
||||
|
||||
private readonly _onDidChangeState = this._register(new Emitter<CodeActionsState.State>());
|
||||
public readonly onDidChangeState = this._onDidChangeState.event;
|
||||
|
||||
constructor(
|
||||
private readonly _editor: ICodeEditor,
|
||||
private readonly _markerService: IMarkerService,
|
||||
contextKeyService: IContextKeyService,
|
||||
private readonly _progressService: IProgressService
|
||||
private readonly _progressService?: ILocalProgressService
|
||||
) {
|
||||
super();
|
||||
this._supportedCodeActions = SUPPORTED_CODE_ACTIONS.bindTo(contextKeyService);
|
||||
|
||||
this._disposables.push(this._editor.onDidChangeModel(() => this._update()));
|
||||
this._disposables.push(this._editor.onDidChangeModelLanguage(() => this._update()));
|
||||
this._disposables.push(CodeActionProviderRegistry.onDidChange(() => this._update()));
|
||||
this._register(this._editor.onDidChangeModel(() => this._update()));
|
||||
this._register(this._editor.onDidChangeModelLanguage(() => this._update()));
|
||||
this._register(CodeActionProviderRegistry.onDidChange(() => this._update()));
|
||||
|
||||
this._update();
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this._disposables = dispose(this._disposables);
|
||||
super.dispose();
|
||||
dispose(this._codeActionOracle);
|
||||
}
|
||||
|
||||
get onDidChangeState(): Event<CodeActionsState.State> {
|
||||
return this._onDidChangeState.event;
|
||||
this.setState(CodeActionsState.Empty, true);
|
||||
}
|
||||
|
||||
private _update(): void {
|
||||
@@ -205,9 +191,6 @@ export class CodeActionModel {
|
||||
this._codeActionOracle = undefined;
|
||||
}
|
||||
|
||||
if (this._state.type === CodeActionsState.Type.Triggered) {
|
||||
this._state.actions.cancel();
|
||||
}
|
||||
this.setState(CodeActionsState.Empty);
|
||||
|
||||
const model = this._editor.getModel();
|
||||
@@ -224,25 +207,46 @@ export class CodeActionModel {
|
||||
|
||||
this._supportedCodeActions.set(supportedActions.join(' '));
|
||||
|
||||
this._codeActionOracle = new CodeActionOracle(this._editor, this._markerService, newState => this.setState(newState), undefined, this._progressService);
|
||||
this._codeActionOracle = new CodeActionOracle(this._editor, this._markerService, trigger => {
|
||||
if (!trigger) {
|
||||
this.setState(CodeActionsState.Empty);
|
||||
return;
|
||||
}
|
||||
|
||||
const actions = createCancelablePromise(token => getCodeActions(model, trigger.selection, trigger.trigger, token));
|
||||
if (this._progressService && trigger.trigger.type === 'manual') {
|
||||
this._progressService.showWhile(actions, 250);
|
||||
}
|
||||
|
||||
this.setState(new CodeActionsState.Triggered(trigger.trigger, trigger.selection, trigger.position, actions));
|
||||
|
||||
}, undefined);
|
||||
this._codeActionOracle.trigger({ type: 'auto' });
|
||||
} else {
|
||||
this._supportedCodeActions.reset();
|
||||
}
|
||||
}
|
||||
|
||||
public trigger(trigger: CodeActionTrigger): Promise<CodeActionSet | undefined> {
|
||||
public trigger(trigger: CodeActionTrigger) {
|
||||
if (this._codeActionOracle) {
|
||||
return this._codeActionOracle.trigger(trigger);
|
||||
this._codeActionOracle.trigger(trigger);
|
||||
}
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
private setState(newState: CodeActionsState.State) {
|
||||
private setState(newState: CodeActionsState.State, skipNotify?: boolean) {
|
||||
if (newState === this._state) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Cancel old request
|
||||
if (this._state.type === CodeActionsState.Type.Triggered) {
|
||||
this._state.actions.cancel();
|
||||
}
|
||||
|
||||
this._state = newState;
|
||||
this._onDidChangeState.fire(newState);
|
||||
|
||||
if (!skipNotify) {
|
||||
this._onDidChangeState.fire(newState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user