vscode#CodeActionProvider TypeScript Examples
The following examples show how to use
vscode#CodeActionProvider.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: actions.ts From format-imports-vscode with MIT License | 6 votes |
export default class SortActionProvider implements CodeActionProvider {
static readonly ACTION_ID = 'source.organizeImports.sortImports';
static readonly ACTION_KINDS = CODE_ACTIONS.map(action => action.kind);
static readonly ACTION_COMMANDS = CODE_ACTIONS.map(({ title, kind, command }) => {
const action = new CodeAction(title, kind);
const from: TriggeredFrom = 'codeAction';
action.command = { command, title, arguments: [from] };
return action;
});
provideCodeActions(): ProviderResult<(CodeAction | Command)[]> {
return SortActionProvider.ACTION_COMMANDS;
}
}
Example #2
Source File: codeActionProvider.ts From dendron with GNU Affero General Public License v3.0 | 6 votes |
doctorFrontmatterProvider: CodeActionProvider = {
provideCodeActions: sentryReportingCallback(
(
_document: TextDocument,
_range: Range | Selection,
context: CodeActionContext,
_token: CancellationToken
) => {
// No-op if we're not in a Dendron Workspace
if (!DendronExtension.isActive()) {
return;
}
// Only provide fix frontmatter action if the diagnostic is correct
const diagnostics = context.diagnostics.filter(
(item) => item.code === BAD_FRONTMATTER_CODE
);
if (diagnostics.length !== 0) {
const action: CodeAction = {
title: "Fix the frontmatter",
diagnostics,
isPreferred: true,
kind: CodeActionKind.QuickFix,
command: {
command: new DoctorCommand(ExtensionProvider.getExtension()).key,
title: "Fix the frontmatter",
arguments: [
{ scope: "file", action: DoctorActionsEnum.FIX_FRONTMATTER },
],
},
};
return [action];
}
return undefined;
}
),
}
Example #3
Source File: codeActionProvider.ts From memo with MIT License | 6 votes |
codeActionProvider: CodeActionProvider = {
provideCodeActions(document, range) {
if (range.isEmpty) {
return [];
}
return [
{
title: 'Extract range to a new note',
command: 'memo.extractRangeToNewNote',
arguments: [document, range],
},
];
},
}
Example #4
Source File: ObjIdConfigCodeActionProvider.ts From al-objid with MIT License | 6 votes |
export class ObjIdConfigActionProvider implements CodeActionProvider {
public async provideCodeActions(
document: TextDocument,
range: Range,
context: CodeActionContext
): Promise<CodeAction[] | undefined> {
const ninjaIssues = context.diagnostics.filter(diagnostic => diagnostic.source === "Ninja");
if (ninjaIssues.length === 0) {
return;
}
const app = WorkspaceManager.instance.getALAppFromUri(document.uri);
if (!app) {
return;
}
const actions: CodeAction[] = [];
for (let issue of ninjaIssues) {
const action = QuickFix[issue.code as string]({ actions, app, document, range });
if (action instanceof Promise) {
await action;
}
}
return actions;
}
}
Example #5
Source File: ALDocumentationQuickFix.ts From vscode-alxmldocumentation with MIT License | 4 votes |
export class ALDocumentationQuickFixProvider implements CodeActionProvider {
// XML documentation CodeActions
private QuickFixActions: CodeAction[] = [];
public provideCodeActions(document: TextDocument, range: Range | Selection, context: CodeActionContext, token: CancellationToken): ProviderResult<(CodeAction | Command)[]> {
this.QuickFixActions = [];
return new Promise(resolve => {
resolve(this.ProvideCodeActionsAsync(document, range, context, token));
});
}
private async ProvideCodeActionsAsync(document: TextDocument, range: Range | Selection, context: CodeActionContext, token: CancellationToken): Promise<(CodeAction | Command)[] | null | undefined> {
let alObject: ALObject | null = await ALSyntaxUtil.GetALObject(document);
if (alObject === null) {
return;
}
context.diagnostics.filter(diagnostics => diagnostics.source === ALXmlDocDiagnosticPrefix).forEach(diagnostic => {
if (diagnostic === undefined) {
return;
}
let diagCodes: Array<string> = [];
if (diagnostic.code!.toString().indexOf(',') !== -1) { // multiple diagnostic codes
diagnostic.code!.toString().split(', ').forEach(diagnosticCode => {
diagCodes.push(diagnosticCode);
});
} else { // just one diagnostic code
diagCodes.push(diagnostic.code!.toString());
}
diagCodes.forEach(diagnosticCode => {
let alProcedure: ALProcedure | undefined;
if ((diagnosticCode !== ALXmlDocDiagnosticCode.ObjectDocumentationMissing) && (diagnosticCode !== ALXmlDocDiagnosticCode.ParameterUnnecessary)) {
alProcedure = alObject?.Procedures?.find(alProcedure => (alProcedure.LineNo === range.start.line));
if (alProcedure === undefined) {
console.error(`[ProvideCodeActionsAsync] - Unable to locate ALProcedure object for diagnostics entry. Please report this error at https://github.com/365businessdev/vscode-alxmldocumentation/issues`);
return;
}
}
switch (diagnosticCode) {
case ALXmlDocDiagnosticCode.DocumentationMissing:
this.AddDocumentationMissingCodeAction(alProcedure, diagnostic);
break;
case ALXmlDocDiagnosticCode.SummaryMissing:
this.AddSummaryDocumentationMissingCodeAction(alProcedure, diagnostic);
break;
case ALXmlDocDiagnosticCode.ParameterMissing:
this.AddParameterDocumentationMissingCodeAction(alProcedure, diagnostic);
break;
case ALXmlDocDiagnosticCode.ReturnTypeMissing:
this.AddReturnDocumentationMissingCodeAction(alProcedure, diagnostic);
break;
case ALXmlDocDiagnosticCode.ParameterUnnecessary:
this.AddUnnecessaryParameterDocumentationMissingCodeAction(alProcedure, diagnostic);
break;
case ALXmlDocDiagnosticCode.ObjectDocumentationMissing:
this.AddObjectDocumentationMissingCodeAction(alObject, diagnostic);
break;
}
});
});
return this.QuickFixActions;
}
/**
* Add Code Action to fix Object XML Documentation missing.
* @param alProcedure AL Procedure.
* @param diagnostic Diagnostic entry.
*/
private AddObjectDocumentationMissingCodeAction(alObject: ALObject | null, diagnostic: Diagnostic) {
let action: CodeAction = new CodeAction('Add XML documentation', CodeActionKind.QuickFix);
action.command = {
command: `${ALXmlDocConfigurationPrefix}.fixObjectDocumentation`,
title: 'Add object XML documentation',
tooltip: `Automatically fix missing XML documentation for object ${alObject?.Name}.`,
arguments: [alObject]
};
action.diagnostics = [diagnostic];
action.isPreferred = true;
this.QuickFixActions.push(action);
}
/**
* Add Code Action to fix Procedure XML Documentation missing.
* @param alProcedure AL Procedure.
* @param diagnostic Diagnostic entry.
*/
private AddDocumentationMissingCodeAction(alProcedure: ALProcedure | undefined, diagnostic: Diagnostic) {
let action: CodeAction = new CodeAction('Add XML documentation', CodeActionKind.QuickFix);
action.command = {
command: `${ALXmlDocConfigurationPrefix}.fixDocumentation`,
title: 'Add procedure XML documentation',
tooltip: `Automatically fix missing XML documentation for procedure ${alProcedure?.Name}.`,
arguments: [alProcedure]
};
action.diagnostics = [diagnostic];
action.isPreferred = true;
this.QuickFixActions.push(action);
}
/**
* Add Code Action to fix Summary XML Documentation missing.
* @param alProcedure AL Procedure.
* @param diagnostic Diagnostic entry.
*/
private AddSummaryDocumentationMissingCodeAction(alProcedure: ALProcedure | undefined, diagnostic: Diagnostic) {
let action: CodeAction = new CodeAction('Add summary XML documentation', CodeActionKind.QuickFix);
action.command = {
command: `${ALXmlDocConfigurationPrefix}.fixSummaryDocumentation`,
title: 'Add procedure summary XML documentation',
tooltip: `Automatically fix missing summary XML documentation for procedure ${alProcedure?.Name}.`,
arguments: [alProcedure]
};
action.diagnostics = [diagnostic];
action.isPreferred = true;
this.QuickFixActions.push(action);
}
/**
* Add Code Action to fix Parameter XML Documentation missing.
* @param alProcedure AL Procedure.
* @param diagnostic Diagnostic entry.
*/
private AddParameterDocumentationMissingCodeAction(alProcedure: ALProcedure | undefined, diagnostic: Diagnostic) {
let action: CodeAction = new CodeAction('Add parameter XML documentation', CodeActionKind.QuickFix);
action.command = {
command: `${ALXmlDocConfigurationPrefix}.fixParameterDocumentation`,
title: 'Add parameter XML documentation',
tooltip: `Automatically fix missing parameter XML documentation for procedure ${alProcedure?.Name}.`,
arguments: [alProcedure]
};
action.diagnostics = [diagnostic];
action.isPreferred = true;
this.QuickFixActions.push(action);
}
/**
* Add Code Action to fix Return Value XML Documentation missing.
* @param alProcedure AL Procedure.
* @param diagnostic Diagnostic entry.
*/
private AddReturnDocumentationMissingCodeAction(alProcedure: ALProcedure | undefined, diagnostic: Diagnostic) {
let action: CodeAction = new CodeAction('Add return value XML documentation', CodeActionKind.QuickFix);
action.command = {
command: `${ALXmlDocConfigurationPrefix}.fixReturnDocumentation`,
title: 'Add return value XML documentation',
tooltip: `Automatically fix missing return value XML documentation for procedure ${alProcedure?.Name}.`,
arguments: [alProcedure]
};
action.diagnostics = [diagnostic];
action.isPreferred = true;
this.QuickFixActions.push(action);
}
/**
* Add Code Action to fix unnecessary Parameter XML Documentation missing.
* @param alProcedure AL Procedure.
* @param diagnostic Diagnostic entry.
*/
private AddUnnecessaryParameterDocumentationMissingCodeAction(alProcedure: ALProcedure | undefined, diagnostic: Diagnostic) {
let action: CodeAction = new CodeAction('Remove unnecessary parameter XML documentation', CodeActionKind.QuickFix);
action.command = {
command: `${ALXmlDocConfigurationPrefix}.fixUnnecessaryParameterDocumentation`,
title: 'Remove unnecessary parameter XML documentation',
tooltip: `Automatically fix unnecessary parameter XML documentation for procedure ${alProcedure?.Name}.`,
arguments: [alProcedure, diagnostic.range]
};
action.diagnostics = [diagnostic];
action.isPreferred = true;
this.QuickFixActions.push(action);
}
}
Example #6
Source File: codeActionProvider.ts From dendron with GNU Affero General Public License v3.0 | 4 votes |
refactorProvider: CodeActionProvider = {
provideCodeActions: sentryReportingCallback(
async (
_document: TextDocument,
_range: Range | Selection,
_context: CodeActionContext,
_token: CancellationToken
) => {
// No-op if we're not in a Dendron Workspace
const ext = ExtensionProvider.getExtension();
if (!(await ext.isActiveAndIsDendronNote(_document.uri.fsPath))) {
return;
}
const { editor, selection, text } = VSCodeUtils.getSelection();
if (!editor || !selection) return;
const header = getHeaderAt({
document: editor.document,
position: selection.start,
});
// action declaration
const renameHeaderAction = {
title: "Rename Header",
isPreferred: true,
kind: CodeActionKind.RefactorInline,
command: {
command: new RenameHeaderCommand().key,
title: "Rename Header",
arguments: [{ source: ContextualUIEvents.ContextualUICodeAction }],
},
};
const brokenWikilinkAction = {
title: "Add missing note for wikilink declaration",
isPreferred: true,
kind: CodeActionKind.RefactorExtract,
command: {
command: new GotoNoteCommand(ExtensionProvider.getExtension()).key,
title: "Add missing note for wikilink declaration",
arguments: [{ source: ContextualUIEvents.ContextualUICodeAction }],
},
};
const createNewNoteAction = {
title: "Extract text to new note",
isPreferred: true,
kind: CodeActionKind.RefactorExtract,
command: {
command: new NoteLookupCommand().key,
title: "Extract text to new note",
arguments: [
{
selectionType: LookupSelectionTypeEnum.selectionExtract,
source: ContextualUIEvents.ContextualUICodeAction,
},
],
},
};
const copyHeaderRefAction = {
title: "Copy Header Reference",
isPreferred: true,
kind: CodeActionKind.RefactorInline,
command: {
command: new CopyNoteRefCommand().key,
title: "Copy Header Reference",
arguments: [{ source: ContextualUIEvents.ContextualUICodeAction }],
},
};
const WrapAsMarkdownLink = {
title: "Wrap as Markdown Link",
isPreferred: true,
kind: CodeActionKind.RefactorInline,
command: {
command: new PasteLinkCommand().key,
title: "Wrap as Markdown Link",
arguments: [
{
source: ContextualUIEvents.ContextualUICodeAction,
link: text,
selection,
},
],
},
};
if (_range.isEmpty) {
const { engine } = ext.getDWorkspace();
const note = new WSUtilsV2(ext).getActiveNote();
//return a code action for create note if user clicked next to a broken wikilink
if (
note &&
(await isBrokenWikilink({ editor, engine, note, selection }))
) {
return [brokenWikilinkAction];
}
//return a code action for rename header and copy header ref if user clicks next to a header
if (!_.isUndefined(header)) {
return [renameHeaderAction, copyHeaderRefAction];
}
// return if none
return;
} else {
//regex for url
if (!_.isUndefined(text) && isUrl(text)) {
return [WrapAsMarkdownLink];
}
return !_.isUndefined(header)
? [createNewNoteAction, renameHeaderAction, copyHeaderRefAction]
: [createNewNoteAction];
}
}
),
}
Example #7
Source File: holes.ts From vscode-lean4 with Apache License 2.0 | 4 votes |
export class LeanHoles implements Disposable, CodeActionProvider {
private holes: HoleCommands[] = [];
private collection: DiagnosticCollection;
private subscriptions: Disposable[] = [];
private executeHoleCommand = 'lean.executeHole';
constructor(private server: Server, private leanDocs: DocumentSelector) {
this.subscriptions.push(
this.collection = languages.createDiagnosticCollection('lean holes'),
commands.registerCommand(this.executeHoleCommand, (file, line, column, action) =>
this.execute(file, line, column, action)),
languages.registerCodeActionsProvider(this.leanDocs, this),
window.onDidChangeVisibleTextEditors(() => this.refresh()),
this.server.statusChanged.on(() => this.refresh()),
);
}
private async refresh() {
const ress = await Promise.all(window.visibleTextEditors
.filter((editor) => languages.match(this.leanDocs, editor.document))
.map((editor) => this.server.allHoleCommands(editor.document.fileName)));
this.holes = [];
for (const res of ress) {
[].push.apply(this.holes, res.holes);
}
const holesPerFile = new Map<string, HoleCommands[]>();
for (const hole of this.holes) {
if (!holesPerFile.get(hole.file)) { holesPerFile.set(hole.file, []); }
holesPerFile.get(hole.file).push(hole);
}
this.collection.clear();
for (const file of holesPerFile.keys()) {
this.collection.set(Uri.file(file),
holesPerFile.get(file).map((hole) =>
new Diagnostic(mkRange(hole),
'Hole: ' + hole.results.map((a) => a.name).join('/'),
DiagnosticSeverity.Hint)));
}
}
private async execute(file: string, line: number, column: number, action: string) {
let res: HoleResponse;
try {
res = await this.server.hole(file, line, column, action);
} catch (e) {
return window.showErrorMessage(`Error while executing hole command: ${e}`);
}
if (res.message) {
void window.showInformationMessage(res.message);
}
if (res.replacements && res.replacements.alternatives) {
// TODO(gabriel): ask user if more than one alternative
for (const editor of window.visibleTextEditors) {
if (editor.document.fileName === file) {
await editor.edit((builder) => {
builder.replace(mkRange(res.replacements),
res.replacements.alternatives[0].code);
});
}
}
}
}
provideCodeActions(document: TextDocument, range: Range): Command[] {
const cmds: Command[] = [];
for (const hole of this.holes) {
if (!range.intersection(mkRange(hole))) { continue; }
for (const action of hole.results) {
cmds.push({
title: action.description,
command: this.executeHoleCommand,
arguments: [hole.file, hole.start.line, hole.start.column, action.name],
});
}
}
return cmds;
}
dispose(): void {
for (const s of this.subscriptions) { s.dispose(); }
}
}
Example #8
Source File: actionProvider.ts From typescript-explicit-types with GNU General Public License v3.0 | 4 votes |
export class GenereateTypeProvider implements CodeActionProvider {
public static readonly fixAllCodeActionKind = CodeActionKind.SourceFixAll.append('tslint');
public static metadata: CodeActionProviderMetadata = {
providedCodeActionKinds: [CodeActionKind.QuickFix],
};
public async provideCodeActions(document: TextDocument, range: Range | Selection, context: CodeActionContext): Promise<CodeAction[]> {
const config = workspace.getConfiguration(configurationId);
const isPreferrable = config.get<boolean>(ConfigurationKey.preferable);
const allDefinitions: Location[] = [];
for (let lineNumber = range.start.line; lineNumber <= range.end.line; lineNumber++) {
const line = document.lineAt(lineNumber);
const startCharNumber = lineNumber === range.start.line ? range.start.character : 0;
const endCharNumber = lineNumber === range.end.line ? range.end.character : line.range.end.character;
for (let charNumber = startCharNumber; charNumber <= endCharNumber; charNumber++) {
const foundDefinitions = await executeDefinitionProvider(document.uri, new Position(lineNumber, charNumber));
if (foundDefinitions?.length) allDefinitions.push(foundDefinitions[0]);
}
}
if (!allDefinitions.length) return [];
const definitions = uniqWith(allDefinitions, (a, b) => a.originSelectionRange.isEqual(b.originSelectionRange));
const symbols = await executeSymbolProvider(document.uri);
const generateTypeInfos: GenerateTypeInfo[] = [];
for (const definition of definitions) {
const hoverRes = await executeHoverProvider(document.uri, definition.originSelectionRange.start);
if (!hoverRes) continue;
// check if definition has a typescript annotation
const tsHoverContent = hoverRes
.reduce<string[]>((acc, val) => acc.concat(val.contents.map((x) => x.value)), [])
.find((x) => x.includes('typescript'));
if (!tsHoverContent) continue;
const word = document.getText(definition.originSelectionRange);
const lineText = document.getText(document.lineAt(definition.originSelectionRange.start.line).range);
// => is recognized as a definition, but it's type is usually defined before, unlike all other types
if (word === '=>') {
// check that there are arrow functions without type on this line
const regexp = /\)\s*=>/gm;
const matches = findMatches(regexp, lineText);
const indexes = matches.map((x) => x.index);
if (!matches.length) continue;
const passedIndex = indexes.find((i) => i > definition.originSelectionRange.start.character);
// look for a potential index of a match
// there might be several arrow functions on the same line & this definition might actually be one with a type
const potentialIndexIndex = passedIndex ? indexes.indexOf(passedIndex) - 1 : indexes.length - 1;
if (potentialIndexIndex < 0) continue;
// check that our match contains the definition
const potentialIndex = indexes[potentialIndexIndex];
const definitionMatch = matches![potentialIndexIndex];
if (
potentialIndex >= definition.originSelectionRange.start.character ||
potentialIndex + definitionMatch[0].length <= definition.originSelectionRange.start.character
)
continue;
generateTypeInfos.push({
isFunction: true,
typescriptHoverResult: tsHoverContent,
typePosition: new Position(definition.originSelectionRange.start.line, potentialIndex + 1),
});
continue;
}
const symbol = symbols?.find((x) => x.selectionRange.contains(definition.originSelectionRange));
const trailingSlice = document.getText(new Range(definition.originSelectionRange.end, definition.targetRange.end));
const isFollowedByBracket = !!trailingSlice.match(/^(\s|\\[rn])*\(/);
if (symbol?.kind === SymbolKind.Function || word === 'function' || isFollowedByBracket) {
// find out suitable type position by looking for a closing bracket of the function
const offset = document.offsetAt(definition.originSelectionRange.end);
const firstBracket = trailingSlice.indexOf('(');
const closingBracketIndex = findClosingBracketMatchIndex(trailingSlice, firstBracket);
const isFunctionTyped = trailingSlice.slice(closingBracketIndex + 1).match(/^\s*:/);
if (isFunctionTyped) continue;
const definitionSlice = document.getText(definition.targetRange);
const firstSymbol = definitionSlice.match(/^\w+/);
generateTypeInfos.push({
typescriptHoverResult: tsHoverContent,
typePosition: document.positionAt(offset + closingBracketIndex + 1),
isFunction: !firstSymbol || !functionHandlerExceptions.includes(firstSymbol[0]),
});
} else {
// check if type annotation is already present
const typePosition = new Position(definition.originSelectionRange.end.line, definition.originSelectionRange.end.character);
const slice = lineText.slice(typePosition.character);
const match = slice.match(/^\s*:/g);
if (match?.length) continue;
generateTypeInfos.push({
typescriptHoverResult: tsHoverContent,
typePosition,
});
}
}
if (!generateTypeInfos.length) return [];
const action = new CodeAction('Generate explicit type', CodeActionKind.QuickFix);
const args: Parameters<typeof commandHandler> = [generateTypeInfos];
action.command = { command: 'extension.generateExplicitType', title: 'Generate explicit type', arguments: args };
action.isPreferred = isPreferrable;
return [action];
}
}