mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-12 02:58:31 -05:00
Merge from vscode 1fbacccbc900bb59ba8a8f26a4128d48a1c97842
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { equals, flatten, isNonEmptyArray, mergeSort } from 'vs/base/common/arrays';
|
||||
import { equals, flatten, isNonEmptyArray, mergeSort, coalesce } from 'vs/base/common/arrays';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { illegalArgument, isPromiseCanceledError, onUnexpectedExternalError } from 'vs/base/common/errors';
|
||||
import { Disposable, DisposableStore, IDisposable } from 'vs/base/common/lifecycle';
|
||||
@@ -27,6 +27,8 @@ export interface CodeActionSet extends IDisposable {
|
||||
readonly validActions: readonly modes.CodeAction[];
|
||||
readonly allActions: readonly modes.CodeAction[];
|
||||
readonly hasAutoFix: boolean;
|
||||
|
||||
readonly documentation: readonly modes.Command[];
|
||||
}
|
||||
|
||||
class ManagedCodeActionSet extends Disposable implements CodeActionSet {
|
||||
@@ -48,7 +50,11 @@ class ManagedCodeActionSet extends Disposable implements CodeActionSet {
|
||||
public readonly validActions: readonly modes.CodeAction[];
|
||||
public readonly allActions: readonly modes.CodeAction[];
|
||||
|
||||
public constructor(actions: readonly modes.CodeAction[], disposables: DisposableStore) {
|
||||
public constructor(
|
||||
actions: readonly modes.CodeAction[],
|
||||
public readonly documentation: readonly modes.Command[],
|
||||
disposables: DisposableStore,
|
||||
) {
|
||||
super();
|
||||
this._register(disposables);
|
||||
this.allActions = mergeSort([...actions], ManagedCodeActionSet.codeActionsComparator);
|
||||
@@ -80,17 +86,23 @@ export function getCodeActions(
|
||||
const promises = providers.map(async provider => {
|
||||
try {
|
||||
const providedCodeActions = await provider.provideCodeActions(model, rangeOrSelection, codeActionContext, cts.token);
|
||||
if (cts.token.isCancellationRequested || !providedCodeActions) {
|
||||
return [];
|
||||
if (providedCodeActions) {
|
||||
disposables.add(providedCodeActions);
|
||||
}
|
||||
disposables.add(providedCodeActions);
|
||||
return providedCodeActions.actions.filter(action => action && filtersAction(filter, action));
|
||||
|
||||
if (cts.token.isCancellationRequested) {
|
||||
return { actions: [] as modes.CodeAction[], documentation: undefined };
|
||||
}
|
||||
|
||||
const filteredActions = (providedCodeActions?.actions || []).filter(action => action && filtersAction(filter, action));
|
||||
const documentation = getDocumentation(provider, filteredActions, filter.include);
|
||||
return { actions: filteredActions, documentation };
|
||||
} catch (err) {
|
||||
if (isPromiseCanceledError(err)) {
|
||||
throw err;
|
||||
}
|
||||
onUnexpectedExternalError(err);
|
||||
return [];
|
||||
return { actions: [] as modes.CodeAction[], documentation: undefined };
|
||||
}
|
||||
});
|
||||
|
||||
@@ -101,9 +113,11 @@ export function getCodeActions(
|
||||
}
|
||||
});
|
||||
|
||||
return Promise.all(promises)
|
||||
.then(flatten)
|
||||
.then(actions => new ManagedCodeActionSet(actions, disposables))
|
||||
return Promise.all(promises).then(actions => {
|
||||
const allActions = flatten(actions.map(x => x.actions));
|
||||
const allDocumentation = coalesce(actions.map(x => x.documentation));
|
||||
return new ManagedCodeActionSet(allActions, allDocumentation, disposables);
|
||||
})
|
||||
.finally(() => {
|
||||
listener.dispose();
|
||||
cts.dispose();
|
||||
@@ -125,6 +139,52 @@ function getCodeActionProviders(
|
||||
});
|
||||
}
|
||||
|
||||
function getDocumentation(
|
||||
provider: modes.CodeActionProvider,
|
||||
providedCodeActions: readonly modes.CodeAction[],
|
||||
only?: CodeActionKind
|
||||
): modes.Command | undefined {
|
||||
if (!provider.documentation) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const documentation = provider.documentation.map(entry => ({ kind: new CodeActionKind(entry.kind), command: entry.command }));
|
||||
|
||||
if (only) {
|
||||
let currentBest: { readonly kind: CodeActionKind, readonly command: modes.Command } | undefined;
|
||||
for (const entry of documentation) {
|
||||
if (entry.kind.contains(only)) {
|
||||
if (!currentBest) {
|
||||
currentBest = entry;
|
||||
} else {
|
||||
// Take best match
|
||||
if (currentBest.kind.contains(entry.kind)) {
|
||||
currentBest = entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (currentBest) {
|
||||
return currentBest?.command;
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, check to see if any of the provided actions match.
|
||||
for (const action of providedCodeActions) {
|
||||
if (!action.kind) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const entry of documentation) {
|
||||
if (entry.kind.contains(new CodeActionKind(action.kind))) {
|
||||
return entry.command;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
registerLanguageCommand('_executeCodeActionProvider', async function (accessor, args): Promise<ReadonlyArray<modes.CodeAction>> {
|
||||
const { resource, rangeOrSelection, kind } = args;
|
||||
if (!(resource instanceof URI)) {
|
||||
|
||||
Reference in New Issue
Block a user