mirror of
https://github.com/Microsoft/vscode
synced 2024-09-13 13:46:13 +00:00
Making move to
code action appear less often (#198864)
taking code from other pr
This commit is contained in:
parent
13075044a0
commit
30ac9a452d
|
@ -21,6 +21,8 @@ import { nulToken } from '../utils/cancellation';
|
|||
import FormattingOptionsManager from './fileConfigurationManager';
|
||||
import { conditionalRegistration, requireSomeCapability } from './util/dependentRegistration';
|
||||
import { EditorChatFollowUp, EditorChatFollowUp_Args, CompositeCommand } from './util/copilot';
|
||||
import * as PConst from '../tsServer/protocol/protocol.const';
|
||||
import { CachedResponse } from '../tsServer/cachedResponse';
|
||||
|
||||
function toWorkspaceEdit(client: ITypeScriptServiceClient, edits: readonly Proto.FileCodeEdits[]): vscode.WorkspaceEdit {
|
||||
const workspaceEdit = new vscode.WorkspaceEdit();
|
||||
|
@ -455,8 +457,44 @@ type TsCodeAction = InlinedCodeAction | MoveToFileCodeAction | SelectCodeAction;
|
|||
|
||||
class TypeScriptRefactorProvider implements vscode.CodeActionProvider<TsCodeAction> {
|
||||
|
||||
private static readonly _declarationKinds = new Set([
|
||||
PConst.Kind.module,
|
||||
PConst.Kind.class,
|
||||
PConst.Kind.interface,
|
||||
PConst.Kind.function,
|
||||
PConst.Kind.enum,
|
||||
PConst.Kind.type,
|
||||
PConst.Kind.const,
|
||||
PConst.Kind.variable,
|
||||
PConst.Kind.let,
|
||||
]);
|
||||
|
||||
private static isOnSignatureName(node: Proto.NavigationTree, range: vscode.Range): boolean {
|
||||
if (this._declarationKinds.has(node.kind)) {
|
||||
// Show when on the name span
|
||||
if (node.nameSpan) {
|
||||
const convertedSpan = typeConverters.Range.fromTextSpan(node.nameSpan);
|
||||
if (range.intersection(convertedSpan)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Show when on the same line as an exported symbols without a name (handles default exports)
|
||||
if (!node.nameSpan && /\bexport\b/.test(node.kindModifiers) && node.spans.length) {
|
||||
const convertedSpan = typeConverters.Range.fromTextSpan(node.spans[0]);
|
||||
if (range.intersection(new vscode.Range(convertedSpan.start.line, 0, convertedSpan.start.line, Number.MAX_SAFE_INTEGER))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Show if on the signature of any children
|
||||
return node.childItems?.some(child => this.isOnSignatureName(child, range)) ?? false;
|
||||
}
|
||||
|
||||
constructor(
|
||||
private readonly client: ITypeScriptServiceClient,
|
||||
private readonly cachedNavTree: CachedResponse<Proto.NavTreeResponse>,
|
||||
private readonly formattingOptionsManager: FormattingOptionsManager,
|
||||
commandManager: CommandManager,
|
||||
telemetryReporter: TelemetryReporter
|
||||
|
@ -516,20 +554,38 @@ class TypeScriptRefactorProvider implements vscode.CodeActionProvider<TsCodeActi
|
|||
return undefined;
|
||||
}
|
||||
|
||||
const actions = Array.from(this.convertApplicableRefactors(document, response.body, rangeOrSelection)).filter(action => {
|
||||
const applicableRefactors = this.convertApplicableRefactors(document, response.body, rangeOrSelection);
|
||||
const actions = coalesce(await Promise.all(Array.from(applicableRefactors, async action => {
|
||||
if (this.client.apiVersion.lt(API.v430)) {
|
||||
// Don't show 'infer return type' refactoring unless it has been explicitly requested
|
||||
// https://github.com/microsoft/TypeScript/issues/42993
|
||||
if (!context.only && action.kind?.value === 'refactor.rewrite.function.returnType') {
|
||||
return false;
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
// Don't include move actions on auto light bulb unless you are on a declaration name
|
||||
if (this.client.apiVersion.lt(API.v540) && context.triggerKind === vscode.CodeActionTriggerKind.Automatic) {
|
||||
if (action.kind?.value === Move_NewFile.kind.value || action.kind?.value === Move_File.kind.value) {
|
||||
const file = this.client.toOpenTsFilePath(document);
|
||||
if (!file) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const navTree = await this.cachedNavTree.execute(document, () => this.client.execute('navtree', { file }, token));
|
||||
if (navTree.type !== 'response' || !navTree.body || !TypeScriptRefactorProvider.isOnSignatureName(navTree.body, rangeOrSelection)) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return action;
|
||||
})));
|
||||
|
||||
if (!context.only) {
|
||||
return actions;
|
||||
}
|
||||
|
||||
return this.pruneInvalidActions(this.appendInvalidActions(actions), context.only, /* numberOfInvalid = */ 5);
|
||||
}
|
||||
|
||||
|
@ -719,6 +775,7 @@ class TypeScriptRefactorProvider implements vscode.CodeActionProvider<TsCodeActi
|
|||
export function register(
|
||||
selector: DocumentSelector,
|
||||
client: ITypeScriptServiceClient,
|
||||
cachedNavTree: CachedResponse<Proto.NavTreeResponse>,
|
||||
formattingOptionsManager: FormattingOptionsManager,
|
||||
commandManager: CommandManager,
|
||||
telemetryReporter: TelemetryReporter,
|
||||
|
@ -727,7 +784,7 @@ export function register(
|
|||
requireSomeCapability(client, ClientCapability.Semantic),
|
||||
], () => {
|
||||
return vscode.languages.registerCodeActionsProvider(selector.semantic,
|
||||
new TypeScriptRefactorProvider(client, formattingOptionsManager, commandManager, telemetryReporter),
|
||||
new TypeScriptRefactorProvider(client, cachedNavTree, formattingOptionsManager, commandManager, telemetryReporter),
|
||||
TypeScriptRefactorProvider.metadata);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -57,17 +57,17 @@ export default class LanguageProvider extends Disposable {
|
|||
private async registerProviders(): Promise<void> {
|
||||
const selector = this.documentSelector;
|
||||
|
||||
const cachedResponse = new CachedResponse();
|
||||
const cachedNavTreeResponse = new CachedResponse();
|
||||
|
||||
await Promise.all([
|
||||
import('./languageFeatures/callHierarchy').then(provider => this._register(provider.register(selector, this.client))),
|
||||
import('./languageFeatures/codeLens/implementationsCodeLens').then(provider => this._register(provider.register(selector, this.description, this.client, cachedResponse))),
|
||||
import('./languageFeatures/codeLens/referencesCodeLens').then(provider => this._register(provider.register(selector, this.description, this.client, cachedResponse))),
|
||||
import('./languageFeatures/codeLens/implementationsCodeLens').then(provider => this._register(provider.register(selector, this.description, this.client, cachedNavTreeResponse))),
|
||||
import('./languageFeatures/codeLens/referencesCodeLens').then(provider => this._register(provider.register(selector, this.description, this.client, cachedNavTreeResponse))),
|
||||
import('./languageFeatures/completions').then(provider => this._register(provider.register(selector, this.description, this.client, this.typingsStatus, this.fileConfigurationManager, this.commandManager, this.telemetryReporter, this.onCompletionAccepted))),
|
||||
import('./languageFeatures/definitions').then(provider => this._register(provider.register(selector, this.client))),
|
||||
import('./languageFeatures/directiveCommentCompletions').then(provider => this._register(provider.register(selector, this.client))),
|
||||
import('./languageFeatures/documentHighlight').then(provider => this._register(provider.register(selector, this.client))),
|
||||
import('./languageFeatures/documentSymbol').then(provider => this._register(provider.register(selector, this.client, cachedResponse))),
|
||||
import('./languageFeatures/documentSymbol').then(provider => this._register(provider.register(selector, this.client, cachedNavTreeResponse))),
|
||||
import('./languageFeatures/fileReferences').then(provider => this._register(provider.register(this.client, this.commandManager))),
|
||||
import('./languageFeatures/fixAll').then(provider => this._register(provider.register(selector, this.client, this.fileConfigurationManager, this.client.diagnosticsManager))),
|
||||
import('./languageFeatures/folding').then(provider => this._register(provider.register(selector, this.client))),
|
||||
|
@ -80,7 +80,7 @@ export default class LanguageProvider extends Disposable {
|
|||
import('./languageFeatures/mappedCodeEditProvider').then(provider => this._register(provider.register(selector, this.client))),
|
||||
import('./languageFeatures/organizeImports').then(provider => this._register(provider.register(selector, this.client, this.commandManager, this.fileConfigurationManager, this.telemetryReporter))),
|
||||
import('./languageFeatures/quickFix').then(provider => this._register(provider.register(selector, this.client, this.fileConfigurationManager, this.commandManager, this.client.diagnosticsManager, this.telemetryReporter))),
|
||||
import('./languageFeatures/refactor').then(provider => this._register(provider.register(selector, this.client, this.fileConfigurationManager, this.commandManager, this.telemetryReporter))),
|
||||
import('./languageFeatures/refactor').then(provider => this._register(provider.register(selector, this.client, cachedNavTreeResponse, this.fileConfigurationManager, this.commandManager, this.telemetryReporter))),
|
||||
import('./languageFeatures/references').then(provider => this._register(provider.register(selector, this.client))),
|
||||
import('./languageFeatures/rename').then(provider => this._register(provider.register(selector, this.description, this.client, this.fileConfigurationManager))),
|
||||
import('./languageFeatures/semanticTokens').then(provider => this._register(provider.register(selector, this.client))),
|
||||
|
|
Loading…
Reference in a new issue