Skip to content
This repository has been archived by the owner on Nov 16, 2023. It is now read-only.

Commit

Permalink
Implement fix all using Source.fixAll instead of onWillSave
Browse files Browse the repository at this point in the history
Follow up on #43
  • Loading branch information
mjbvz committed Jan 23, 2019
1 parent c241dd4 commit 90f505a
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 69 deletions.
6 changes: 0 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -144,12 +144,6 @@
"tslint.suppressWhileTypeErrorsPresent": {
"type": "boolean",
"description": "Always show rule failures as warnings, independent of the tslint configuration."
},
"tslint.autoFixOnSave": {
"type": "boolean",
"default": false,
"description": "Turns auto fix on save on or off.",
"scope": "resource"
}
}
}
Expand Down
64 changes: 64 additions & 0 deletions src/fixAll.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@

import * as vscode from 'vscode';
import { isTypeScriptDocument, isEnabledForJavaScriptDocument } from './utils';

function executeCodeActionProvider(uri: vscode.Uri, range: vscode.Range) {
return vscode.commands.executeCommand<vscode.CodeAction[]>('vscode.executeCodeActionProvider', uri, range);
}


async function getTsLintFixAllCodeAction(document: vscode.TextDocument): Promise<vscode.CodeAction | undefined> {
const diagnostics = vscode.languages
.getDiagnostics(document.uri)
.filter(diagnostic => diagnostic.source === 'tslint');

for (const diagnostic of diagnostics) {
const codeActions = await executeCodeActionProvider(document.uri, diagnostic.range);
if (codeActions) {
const fixAll = codeActions.filter(action => action.title === 'Fix all auto-fixable tslint failures');
if (fixAll.length > 0) {
return fixAll[0];
}
}
}
return undefined;
}


const fixAllCodeActionKind = vscode.CodeActionKind.Source.append('fixAll').append('tslint');

export class FixAllProvider implements vscode.CodeActionProvider {
public static metadata: vscode.CodeActionProviderMetadata = {
providedCodeActionKinds: [fixAllCodeActionKind],
};

async provideCodeActions(
document: vscode.TextDocument,
_range: vscode.Range | vscode.Selection,
context: vscode.CodeActionContext,
_token: vscode.CancellationToken
): Promise<vscode.CodeAction[]> {
if (!context.only) {
return [];
}

if (!context.only.contains(fixAllCodeActionKind) && !fixAllCodeActionKind.contains(context.only)) {
return [];
}

if (!isTypeScriptDocument(document) && !isEnabledForJavaScriptDocument(document)) {
return [];
}

const fixAllAction = await getTsLintFixAllCodeAction(document);
if (!fixAllAction) {
return [];
}

return [{
...fixAllAction,
title: 'Fix All TSLint',
kind: fixAllCodeActionKind,
}];
}
}
40 changes: 14 additions & 26 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as vscode from 'vscode';
import { isTypeScriptDocument, isEnabledForJavaScriptDocument, fixAll } from './utils';
import { FixAllProvider } from './fixAll';

const typeScriptExtensionId = 'vscode.typescript-language-features';
const pluginId = 'typescript-tslint-plugin';
Expand Down Expand Up @@ -29,14 +29,20 @@ export async function activate(context: vscode.ExtensionContext) {
return;
}

vscode.workspace.onDidChangeConfiguration(e => {
if (e.affectsConfiguration(configurationSection)) {
synchronizeConfiguration(api);
}
}, undefined, context.subscriptions);

const selector: vscode.DocumentFilter[] = [];
for (const language of ['javascript', 'javascriptreact', 'typescript', 'typescriptreact']) {
selector.push({ language, scheme: 'file' });
selector.push({ language, scheme: 'untitled' });
}

context.subscriptions.push(
vscode.workspace.onDidChangeConfiguration(e => {
if (e.affectsConfiguration(configurationSection)) {
synchronizeConfiguration(api);
}
}, undefined, context.subscriptions),
vscode.workspace.onWillSaveTextDocument(willSaveTextDocument)
);
vscode.languages.registerCodeActionsProvider(selector, new FixAllProvider(), FixAllProvider.metadata));

synchronizeConfiguration(api);
}
Expand Down Expand Up @@ -80,21 +86,3 @@ function withConfigValue<C, K extends Extract<keyof C, string>>(
outConfig[key] = value;
}
}

async function willSaveTextDocument(e: vscode.TextDocumentWillSaveEvent) {
const config = vscode.workspace.getConfiguration('tslint', e.document.uri);
const autoFix = config.get('autoFixOnSave', false);
if (autoFix) {
const document = e.document;

// only auto fix when the document was manually saved by the user
if (!(isTypeScriptDocument(document) || isEnabledForJavaScriptDocument(document))
|| e.reason !== vscode.TextDocumentSaveReason.Manual) {
return;
}

const promise = fixAll(document);
e.waitUntil(promise);
await promise;
}
}
38 changes: 1 addition & 37 deletions src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { CodeAction, Command, commands, languages, Range, TextDocument, TextEdit, Uri, window, workspace } from 'vscode';
import { TextDocument, workspace } from 'vscode';

export function isTypeScriptDocument(document: TextDocument) {
return document.languageId === 'typescript' || document.languageId === 'typescriptreact';
Expand All @@ -15,39 +15,3 @@ export function isEnabledForJavaScriptDocument(document: TextDocument) {
}
return false;
}

function executeCodeActionProvider(uri: Uri, range: Range) {
return commands.executeCommand<(CodeAction | Command)[]>('vscode.executeCodeActionProvider', uri, range);
}

export async function fixAll(document: TextDocument) {
const diagnostics = languages
.getDiagnostics(document.uri)
.filter(diagnostic => diagnostic.source === 'tslint');

for (let diagnostic of diagnostics) {
const codeActions = await executeCodeActionProvider(
document.uri,
diagnostic.range
);
if (codeActions) {
const fixAll = codeActions.filter(
({ title }) => title === 'Fix all auto-fixable tslint failures'
);
if (fixAll.length) {
const codeActionOrCommand = fixAll[0];
if (codeActionOrCommand instanceof CodeAction) {
if (codeActionOrCommand.edit) {
await workspace.applyEdit(codeActionOrCommand.edit);
}
}
const command = codeActionOrCommand instanceof CodeAction ? codeActionOrCommand.command : codeActionOrCommand;
if (command) {
const args = ('arguments' in command) ? command.arguments || [] : [];
await commands.executeCommand(command.command, ...args);
}
break;
}
}
}
}
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"target": "es2016",
"jsx": "preserve",
"strict": true,
"noUnusedLocals": true,
"outDir": "./out",
"sourceMap": true
},
Expand Down

0 comments on commit 90f505a

Please sign in to comment.