From cf64faf949f1ca59106a9d2499d3904a0d202eba Mon Sep 17 00:00:00 2001 From: axetroy Date: Fri, 28 Aug 2020 09:04:28 +0800 Subject: [PATCH 1/9] add linter --- core/configuration.test.ts | 5 +++ core/configuration.ts | 4 ++ package.json | 10 +++++ server/src/bridge.ts | 2 + server/src/deno.ts | 59 ++++++++++++++++++++++++++++++ server/src/language/diagnostics.ts | 48 +++++++++++++++++++++++- 6 files changed, 127 insertions(+), 1 deletion(-) diff --git a/core/configuration.test.ts b/core/configuration.test.ts index f5d975ca..e0418b0e 100644 --- a/core/configuration.test.ts +++ b/core/configuration.test.ts @@ -15,6 +15,7 @@ test("core / configuration / resolveFromVscode if it is a valid file", async () enable: true, unstable: true, import_map: "./import_map.json", + lint: false, } as ConfigurationField); }); @@ -29,6 +30,7 @@ test("core / configuration / resolveFromVscode if valid section", async () => { enable: true, unstable: false, import_map: null, + lint: false, } as ConfigurationField); }); @@ -51,6 +53,7 @@ test("core / configuration / resolveFromVscode if config file is empty", async ( enable: false, unstable: false, import_map: null, + lint: false, } as ConfigurationField); }); @@ -65,6 +68,7 @@ test("core / configuration / resolveFromVscode if field is invalid", async () => enable: true, unstable: true, import_map: "1,2,3", + lint: false, } as ConfigurationField); }); @@ -87,5 +91,6 @@ test("core / configuration / update", async () => { enable: true, unstable: false, import_map: null, + lint: false, } as ConfigurationField); }); diff --git a/core/configuration.ts b/core/configuration.ts index 7c5d1c60..3f138c3b 100644 --- a/core/configuration.ts +++ b/core/configuration.ts @@ -11,12 +11,14 @@ export const DenoPluginConfigurationField: (keyof ConfigurationField)[] = [ "enable", "unstable", "import_map", + "lint", ]; export type ConfigurationField = { enable?: boolean; unstable?: boolean; import_map?: string | null; + lint?: boolean; }; interface ConfigurationInterface { @@ -31,6 +33,7 @@ export class Configuration implements ConfigurationInterface { enable: false, unstable: false, import_map: null, + lint: false, }; private readonly _configUpdatedListeners = new Set<() => void>(); @@ -76,6 +79,7 @@ export class Configuration implements ConfigurationInterface { // Make sure the type of each configuration item is correct this._configuration.enable = !!this._configuration.enable; this._configuration.unstable = !!this._configuration.unstable; + this._configuration.lint = !!this._configuration.lint; this._configuration.import_map = this._configuration.import_map ? this._configuration.import_map + "" : null; diff --git a/package.json b/package.json index 3557b6fd..f4b34ae9 100644 --- a/package.json +++ b/package.json @@ -117,6 +117,16 @@ true, false ] + }, + "deno.lint": { + "type": "boolean", + "default": false, + "markdownDescription": "Controls if enabled `deno lint`. It is currently experimental, make sure `deno.unstable: true` to enabled. \n\n**Not recommended in global configuration**", + "scope": "resource", + "examples": [ + true, + false + ] } } }, diff --git a/server/src/bridge.ts b/server/src/bridge.ts index 0be77201..16b6d8f1 100644 --- a/server/src/bridge.ts +++ b/server/src/bridge.ts @@ -6,6 +6,8 @@ import { Request } from "../../core/const"; type Configuration = { enable: boolean; import_map?: string; + unstable?: boolean; + lint?: boolean; }; /** diff --git a/server/src/deno.ts b/server/src/deno.ts index 3020594d..323e9fe7 100644 --- a/server/src/deno.ts +++ b/server/src/deno.ts @@ -15,6 +15,28 @@ type FormatOptions = { cwd: string; }; +interface LintDiagnostic { + location: { + filename: string; + line: number; + col: number; + }; + message: string; + code: string; + line_src: string; + snippet_length: number; +} + +interface LintError { + file_path: string; + message: string; +} + +interface LintOutput { + diagnostics: LintDiagnostic[]; + errors: LintError[]; +} + class Deno { public version!: Version | void; public executablePath!: string | void; @@ -88,6 +110,43 @@ class Deno { return formattedCode; } + + // TODO: We should read the file content from stdin + public async lintFile(filepath: string): Promise { + const subprocess = execa( + this.executablePath as string, + ["lint", "--unstable", "--json", filepath], + { + stdout: "pipe", + stderr: "pipe", + } + ); + + const output = await new Promise((resolve, reject) => { + let stdout = ""; + let stderr = ""; + subprocess.on("exit", (exitCode: number) => { + if (exitCode !== 0) { + resolve(stderr); + } else { + resolve(stdout); + } + }); + subprocess.on("error", (err: Error) => { + reject(err); + }); + subprocess.stdout?.on("data", (data: Buffer) => { + stdout += data; + }); + + subprocess.stderr?.on("data", (data: Buffer) => { + stderr += data; + }); + }); + + return JSON.parse(output) as LintOutput; + } + private async getExecutablePath(): Promise { const denoPath = await which("deno").catch(() => Promise.resolve(undefined) diff --git a/server/src/language/diagnostics.ts b/server/src/language/diagnostics.ts index cf40b1d1..93869ccb 100644 --- a/server/src/language/diagnostics.ts +++ b/server/src/language/diagnostics.ts @@ -19,6 +19,7 @@ import { pathExists, isHttpURL, isValidDenoDocument } from "../../../core/util"; import { ImportMap } from "../../../core/import_map"; import { getImportModules, Range } from "../../../core/deno_deps"; import { Notification } from "../../../core/const"; +import { deno } from "../deno"; type Fix = { title: string; @@ -108,6 +109,42 @@ export class Diagnostics { documents.onDidOpen((params) => this.diagnosis(params.document)); documents.onDidChangeContent((params) => this.diagnosis(params.document)); } + /** + * lint document + * @param document + */ + async lint(document: TextDocument): Promise { + const uri = URI.parse(document.uri); + + const lintOutput = await deno.lintFile(uri.fsPath); + + this.connection.console.log(JSON.stringify(lintOutput)); + + return lintOutput.diagnostics.map((v) => { + const location: Range = { + start: { + line: v.location.line - 1, + character: v.location.col, + }, + end: { + line: v.location.line - 1, + character: v.location.col + v.snippet_length, + }, + }; + + return Diagnostic.create( + location, + v.message, + DiagnosticSeverity.Error, + v.code, + this.name + ); + }); + } + /** + * generate diagnostic for a document + * @param document + */ async generate(document: TextDocument): Promise { if (!isValidDenoDocument(document.languageId)) { return []; @@ -123,6 +160,16 @@ export class Diagnostics { return []; } + const diagnosticsForThisDocument: Diagnostic[] = []; + + if (config.unstable && config.lint) { + const denoLinterResult = await this.lint(document); + + for (const v of denoLinterResult) { + diagnosticsForThisDocument.push(v); + } + } + const importMapFilepath = config.import_map ? path.isAbsolute(config.import_map) ? config.import_map @@ -142,7 +189,6 @@ export class Diagnostics { const importModules = getImportModules(ts)(sourceFile); - const diagnosticsForThisDocument: Diagnostic[] = []; const resolver = ModuleResolver.create(uri.fsPath, importMapFilepath); const handle = async (originModuleName: string, location: Range) => { From 1f3b540e50fdb456a4a168692455f87f306f9fea Mon Sep 17 00:00:00 2001 From: axetroy Date: Sat, 5 Sep 2020 12:48:04 +0800 Subject: [PATCH 2/9] update --- README.md | 15 ++++ client/src/extension.ts | 68 ++++++++++++++---- server/src/deno.ts | 109 +++++++++++++++++------------ server/src/language/diagnostics.ts | 94 ++++++++++++++----------- 4 files changed, 184 insertions(+), 102 deletions(-) diff --git a/README.md b/README.md index 9e01e037..d733296f 100644 --- a/README.md +++ b/README.md @@ -133,6 +133,8 @@ console.log("concat Array", M.concat([1, 2], [2, 3])); - `deno.unstable` - If Deno's unstable mode is enabled. Default is `false` +- `deno.lint` - If Deno's lint is enabled. `deno.unstable = true` is required. Default is `false` + We recommend that you do not set global configuration. It should be configured in `.vscode/settings.json` in the project directory: ```json5 @@ -158,6 +160,19 @@ This extension also provides Deno's formatting tools, settings are in `.vscode/s } ``` +This extension also provides Deno's lint tools, settings are in `.vscode/settings.json`: + +NOTE: Since Lint is still an experimental feature, So you need to set `deno.unstable = true`. And this function may change in the future. + +```json5 +// .vscode/settings.json +{ + "deno.enable": true, + "deno.unstable": true, + "deno.lint": true, +} +``` + ## Contribute Follow these steps to contribute, the community needs your strength. diff --git a/client/src/extension.ts b/client/src/extension.ts index 7b97faec..c0f88d04 100644 --- a/client/src/extension.ts +++ b/client/src/extension.ts @@ -20,6 +20,7 @@ import { TextDocument, languages, env, + Position, } from "vscode"; import { LanguageClient, @@ -348,29 +349,39 @@ Executable ${this.denoInfo.executablePath}`; [command: string]: ( editor: TextEditor, text: string, - range: Range + range: Range, + ...args: unknown[] ) => void | Promise; }) { for (const command in map) { const handler = map[command]; - this.registerCommand(command, async (uri: string, range: Range) => { - const textEditor = window.activeTextEditor; + this.registerCommand( + command, + async (uri: string, range: Range, ...args: unknown[]) => { + const textEditor = window.activeTextEditor; - if (!textEditor || textEditor.document.uri.toString() !== uri) { - return; - } + if (!textEditor || textEditor.document.uri.toString() !== uri) { + return; + } - range = new Range( - range.start.line, - range.start.character, - range.end.line, - range.end.character - ); + range = new Range( + range.start.line, + range.start.character, + range.end.line, + range.end.character + ); - const rangeText = textEditor.document.getText(range); + const rangeText = textEditor.document.getText(range); - return await handler.call(this, textEditor, rangeText, range); - }); + return await handler.call( + this, + textEditor, + rangeText, + range, + ...args + ); + } + ); } } // update diagnostic for a Document @@ -580,6 +591,33 @@ Executable ${this.denoInfo.executablePath}`; this.updateDiagnostic(editor.document.uri); }, + _ignore_text_line_lint: async (editor, _, range, rule: unknown) => { + editor.edit((edit) => { + const currentLineText = editor.document.lineAt(range.start.line); + const lastLineText = editor.document.lineAt(range.start.line - 1); + + const offsetEmpty = + currentLineText.text.length - currentLineText.text.trim().length; + + edit.replace( + lastLineText.range, + lastLineText.text + + "\n" + + `${" ".repeat(offsetEmpty)}// deno-lint-ignore-next-line ${rule}` + ); + }); + return; + }, + _ignore_entry_file: async (editor) => { + editor.edit((edit) => { + const firstLineText = editor.document.lineAt(0); + edit.insert( + new Position(0, 0), + "// deno-lint-ignore-file" + (firstLineText.text ? "\n" : "") + ); + }); + return; + }, }); this.watchConfiguration(() => { diff --git a/server/src/deno.ts b/server/src/deno.ts index 323e9fe7..77d5b4a3 100644 --- a/server/src/deno.ts +++ b/server/src/deno.ts @@ -3,6 +3,7 @@ import { Readable } from "stream"; import execa from "execa"; import which from "which"; import * as semver from "semver"; +import { Cache } from "../../core/cache"; type Version = { deno: string; @@ -15,16 +16,19 @@ type FormatOptions = { cwd: string; }; +interface LintLocation { + line: number; // one base number + col: number; // zero base number +} + interface LintDiagnostic { - location: { - filename: string; - line: number; - col: number; - }; - message: string; code: string; - line_src: string; - snippet_length: number; + filename: string; + message: string; + range: { + start: LintLocation; + end: LintLocation; + }; } interface LintError { @@ -37,6 +41,9 @@ interface LintOutput { errors: LintError[]; } +// caching Deno lint's rules for 120s or 100 referenced times +const denoLintRulesCache = Cache.create(1000 * 120, 100); + class Deno { public version!: Version | void; public executablePath!: string | void; @@ -55,9 +62,9 @@ class Deno { return; } - // If the currently used Deno is less than 0.33.0 + // If the currently used Deno is less than 1.3.3 // We will give an warning to upgrade. - const minimumDenoVersion = "0.35.0"; + const minimumDenoVersion = "1.3.3"; if (!semver.gte(this.version.deno, minimumDenoVersion)) { throw new Error(`Please upgrade to Deno ${minimumDenoVersion} or above.`); } @@ -65,15 +72,13 @@ class Deno { public async getTypes(unstable: boolean): Promise { const { stdout } = await execa(this.executablePath as string, [ "types", - ...(unstable && this.version && semver.gte(this.version.deno, "0.43.0") - ? ["--unstable"] - : []), + ...(unstable ? ["--unstable"] : []), ]); return Buffer.from(stdout, "utf8"); } // format code - // echo "console.log(123)" | deno fmt --stdin + // echo "console.log(123)" | deno fmt - public async format(code: string, options: FormatOptions): Promise { const reader = Readable.from([code]); @@ -94,54 +99,66 @@ class Deno { resolve(stdout); } }); - subprocess.on("error", (err: Error) => { - reject(err); - }); - subprocess.stdout?.on("data", (data: Buffer) => { - stdout += data; - }); - - subprocess.stderr?.on("data", (data: Buffer) => { - stderr += data; - }); - + subprocess.on("error", (err: Error) => reject(err)); + subprocess.stdout?.on("data", (data: Buffer) => (stdout += data)); + subprocess.stderr?.on("data", (data: Buffer) => (stderr += data)); subprocess.stdin && reader.pipe(subprocess.stdin); })) as string; return formattedCode; } - // TODO: We should read the file content from stdin - public async lintFile(filepath: string): Promise { + public async getLintRules(): Promise { + const cachedRules = denoLintRulesCache.get(); + if (cachedRules) { + return cachedRules; + } const subprocess = execa( this.executablePath as string, - ["lint", "--unstable", "--json", filepath], + ["lint", "--unstable", "--rules"], { stdout: "pipe", - stderr: "pipe", } ); const output = await new Promise((resolve, reject) => { let stdout = ""; - let stderr = ""; - subprocess.on("exit", (exitCode: number) => { - if (exitCode !== 0) { - resolve(stderr); - } else { - resolve(stdout); - } - }); - subprocess.on("error", (err: Error) => { - reject(err); - }); - subprocess.stdout?.on("data", (data: Buffer) => { - stdout += data; - }); + subprocess.on("exit", () => resolve(stdout)); + subprocess.on("error", (err: Error) => reject(err)); + subprocess.stdout?.on("data", (data: Buffer) => (stdout += data)); + }); - subprocess.stderr?.on("data", (data: Buffer) => { - stderr += data; - }); + const rules = output + .split("\n") + .map((v) => v.trim()) + .filter((v) => v.startsWith("-")) + .map((v) => v.replace(/^-\s+/, "")); + + denoLintRulesCache.set(rules); + + return rules; + } + + // lint code + // echo "console.log(123)" | deno lint --unstable --json - + public async lint(code: string): Promise { + const reader = Readable.from([code]); + + const subprocess = execa( + this.executablePath as string, + ["lint", "--unstable", "--json", "-"], + { + stdin: "pipe", + stderr: "pipe", + } + ); + + const output = await new Promise((resolve, reject) => { + let stderr = ""; + subprocess.on("exit", () => resolve(stderr)); + subprocess.on("error", (err: Error) => reject(err)); + subprocess.stderr?.on("data", (data: Buffer) => (stderr += data)); + subprocess.stdin && reader.pipe(subprocess.stdin); }); return JSON.parse(output) as LintOutput; diff --git a/server/src/language/diagnostics.ts b/server/src/language/diagnostics.ts index 93869ccb..bbfbe563 100644 --- a/server/src/language/diagnostics.ts +++ b/server/src/language/diagnostics.ts @@ -8,6 +8,8 @@ import { CodeActionKind, Command, TextDocuments, + Range, + Position, } from "vscode-languageserver"; import { TextDocument } from "vscode-languageserver-textdocument"; import * as ts from "typescript"; @@ -17,7 +19,7 @@ import { Bridge } from "../bridge"; import { ModuleResolver } from "../../../core/module_resolver"; import { pathExists, isHttpURL, isValidDenoDocument } from "../../../core/util"; import { ImportMap } from "../../../core/import_map"; -import { getImportModules, Range } from "../../../core/deno_deps"; +import { getImportModules } from "../../../core/deno_deps"; import { Notification } from "../../../core/const"; import { deno } from "../deno"; @@ -59,19 +61,14 @@ export class Diagnostics { return; } - const actions: CodeAction[] = denoDiagnostics - .map((v) => { - const code = v.code; - - if (!code) { - return; - } + const rules = await deno.getLintRules(); - const fixItem: Fix = FixItems[+code]; + const actions: CodeAction[] = []; - if (!fixItem) { - return; - } + const documentAction = denoDiagnostics + .filter((v) => v.code && FixItems[+v.code]) + .map((v) => { + const fixItem: Fix = FixItems[+(v.code as string)]; const action = CodeAction.create( `${fixItem.title} (${this.name})`, @@ -80,25 +77,51 @@ export class Diagnostics { fixItem.command, // argument textDocument.uri, - { - start: { - line: v.range.start.line, - character: v.range.start.character, - }, - end: { - line: v.range.end.line, - character: v.range.end.character, - }, - } + v.range + ), + CodeActionKind.QuickFix + ); + + return action; + }); + + const denoLintAction = denoDiagnostics + .filter((v) => v.code && rules.includes(v.code as string)) + .map((v) => { + const action = CodeAction.create( + `ignore next line rule \`${v.code}\` (${this.name})`, + Command.create( + "Fix lint", + `deno._ignore_text_line_lint`, + // argument + textDocument.uri, + v.range, + v.code ), CodeActionKind.QuickFix ); return action; - }) - .filter((v) => v) as CodeAction[]; + }); - return actions; + if (denoLintAction.length) { + denoLintAction.push( + CodeAction.create( + `ignore entry file (${this.name})`, + Command.create( + "Fix lint", + `deno._ignore_entry_file`, + // argument + textDocument.uri, + Range.create(Position.create(0, 0), Position.create(0, 0)), + "deno_lint" + ), + CodeActionKind.QuickFix + ) + ); + } + + return actions.concat(documentAction).concat(denoLintAction); }); connection.onNotification(Notification.diagnostic, (uri: string) => { @@ -114,26 +137,15 @@ export class Diagnostics { * @param document */ async lint(document: TextDocument): Promise { - const uri = URI.parse(document.uri); - - const lintOutput = await deno.lintFile(uri.fsPath); - - this.connection.console.log(JSON.stringify(lintOutput)); + const lintOutput = await deno.lint(document.getText()); return lintOutput.diagnostics.map((v) => { - const location: Range = { - start: { - line: v.location.line - 1, - character: v.location.col, - }, - end: { - line: v.location.line - 1, - character: v.location.col + v.snippet_length, - }, - }; + const start = Position.create(v.range.start.line - 1, v.range.start.col); + const end = Position.create(v.range.end.line - 1, v.range.end.col); + const range = Range.create(start, end); return Diagnostic.create( - location, + range, v.message, DiagnosticSeverity.Error, v.code, From d4a96fcdbcd4d3fec235f260483b2b88ceac5bbc Mon Sep 17 00:00:00 2001 From: axetroy Date: Sat, 5 Sep 2020 16:58:18 +0800 Subject: [PATCH 3/9] fix directive --- client/src/extension.ts | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/client/src/extension.ts b/client/src/extension.ts index c0f88d04..f29a90da 100644 --- a/client/src/extension.ts +++ b/client/src/extension.ts @@ -594,17 +594,24 @@ Executable ${this.denoInfo.executablePath}`; _ignore_text_line_lint: async (editor, _, range, rule: unknown) => { editor.edit((edit) => { const currentLineText = editor.document.lineAt(range.start.line); - const lastLineText = editor.document.lineAt(range.start.line - 1); + const previousLineText = editor.document.lineAt(range.start.line - 1); - const offsetEmpty = + const offset = currentLineText.text.length - currentLineText.text.trim().length; - edit.replace( - lastLineText.range, - lastLineText.text + - "\n" + - `${" ".repeat(offsetEmpty)}// deno-lint-ignore-next-line ${rule}` - ); + if (/^\s*\/\/\s+deno-lint-ignore\s*/.test(previousLineText.text)) { + edit.replace( + previousLineText.range, + previousLineText.text + " " + rule + ); + } else { + edit.replace( + previousLineText.range, + previousLineText.text + + "\n" + + `${" ".repeat(offset)}// deno-lint-ignore ${rule}` + ); + } }); return; }, From 0cf7a3b87b393fded245beab370d93f1c4842168 Mon Sep 17 00:00:00 2001 From: axetroy Date: Sat, 5 Sep 2020 17:05:11 +0800 Subject: [PATCH 4/9] fix typo --- client/src/extension.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/extension.ts b/client/src/extension.ts index f29a90da..a1a69f8d 100644 --- a/client/src/extension.ts +++ b/client/src/extension.ts @@ -591,7 +591,7 @@ Executable ${this.denoInfo.executablePath}`; this.updateDiagnostic(editor.document.uri); }, - _ignore_text_line_lint: async (editor, _, range, rule: unknown) => { + _ignore_next_line_lint: async (editor, _, range, rule: unknown) => { editor.edit((edit) => { const currentLineText = editor.document.lineAt(range.start.line); const previousLineText = editor.document.lineAt(range.start.line - 1); From d595140e16e2164a56de40646e99c9940b57051c Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Sun, 6 Sep 2020 14:07:41 +0200 Subject: [PATCH 5/9] Updated descriptions --- README.md | 4 ++-- package.json | 2 +- server/src/language/diagnostics.ts | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index f6facc7d..5b9d2878 100644 --- a/README.md +++ b/README.md @@ -166,9 +166,9 @@ This extension also provides Deno's formatting tools, settings are in `.vscode/s } ``` -This extension also provides Deno's lint tools, settings are in `.vscode/settings.json`: +This extension also provides inline `deno lint` diagnostics. You can enable this in `.vscode/settings.json`: -NOTE: Since Lint is still an experimental feature, So you need to set `deno.unstable = true`. And this function may change in the future. +NOTE: Since `deno lint` is still an experimental feature, you need to set `deno.unstable = true` in your VS Code settings. This function may change in the future. ```json5 // .vscode/settings.json diff --git a/package.json b/package.json index e0b16210..c9482eec 100644 --- a/package.json +++ b/package.json @@ -126,7 +126,7 @@ "deno.lint": { "type": "boolean", "default": false, - "markdownDescription": "Controls if enabled `deno lint`. It is currently experimental, make sure `deno.unstable: true` to enabled. \n\n**Not recommended in global configuration**", + "markdownDescription": "Controls if `deno lint` is enabled. It is currently experimental, so make sure `deno.unstable: true` is enabled. \n\n**Not recommended in global configuration**", "scope": "resource", "examples": [ true, diff --git a/server/src/language/diagnostics.ts b/server/src/language/diagnostics.ts index bbfbe563..5c958c0d 100644 --- a/server/src/language/diagnostics.ts +++ b/server/src/language/diagnostics.ts @@ -89,7 +89,7 @@ export class Diagnostics { .filter((v) => v.code && rules.includes(v.code as string)) .map((v) => { const action = CodeAction.create( - `ignore next line rule \`${v.code}\` (${this.name})`, + `ignore \`${v.code}\` for this line (${this.name})`, Command.create( "Fix lint", `deno._ignore_text_line_lint`, @@ -107,7 +107,7 @@ export class Diagnostics { if (denoLintAction.length) { denoLintAction.push( CodeAction.create( - `ignore entry file (${this.name})`, + `ignore entire file (${this.name})`, Command.create( "Fix lint", `deno._ignore_entry_file`, From 0de60e6e4048c9df0d7ff76efe1b463aeda7f09e Mon Sep 17 00:00:00 2001 From: axetroy Date: Sun, 6 Sep 2020 22:13:54 +0800 Subject: [PATCH 6/9] fix typo --- server/src/language/diagnostics.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/language/diagnostics.ts b/server/src/language/diagnostics.ts index 5c958c0d..ef7d4e96 100644 --- a/server/src/language/diagnostics.ts +++ b/server/src/language/diagnostics.ts @@ -92,7 +92,7 @@ export class Diagnostics { `ignore \`${v.code}\` for this line (${this.name})`, Command.create( "Fix lint", - `deno._ignore_text_line_lint`, + `deno._ignore_next_line_lint`, // argument textDocument.uri, v.range, From 98bd0ec01fef5829bfdf963b7eb713b3723ea5f3 Mon Sep 17 00:00:00 2001 From: axetroy Date: Sun, 6 Sep 2020 22:16:04 +0800 Subject: [PATCH 7/9] update linter name --- server/src/language/diagnostics.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/language/diagnostics.ts b/server/src/language/diagnostics.ts index ef7d4e96..f672e30a 100644 --- a/server/src/language/diagnostics.ts +++ b/server/src/language/diagnostics.ts @@ -149,7 +149,7 @@ export class Diagnostics { v.message, DiagnosticSeverity.Error, v.code, - this.name + "deno_lint" ); }); } From 43a23749b2d3ba2273b91ed94e76784d22f44e58 Mon Sep 17 00:00:00 2001 From: axetroy Date: Sun, 6 Sep 2020 22:36:41 +0800 Subject: [PATCH 8/9] rename to deno_lint --- client/src/extension.ts | 5 ++++- server/src/language/diagnostics.ts | 17 ++++++++++------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/client/src/extension.ts b/client/src/extension.ts index eb1e9428..81a73bf9 100644 --- a/client/src/extension.ts +++ b/client/src/extension.ts @@ -245,7 +245,10 @@ export class Extension { } const denoDiagnostics: Diagnostic[] = []; for (const diagnostic of context.diagnostics) { - if (diagnostic.source === "Deno Language Server") { + if ( + diagnostic.source === "Deno Language Server" || + diagnostic.source === "deno_lint" + ) { denoDiagnostics.push(diagnostic); } } diff --git a/server/src/language/diagnostics.ts b/server/src/language/diagnostics.ts index f672e30a..f06602bd 100644 --- a/server/src/language/diagnostics.ts +++ b/server/src/language/diagnostics.ts @@ -45,6 +45,8 @@ const FixItems: { [code: number]: Fix } = { }, }; +const DENO_LINT = "deno_lint"; + export class Diagnostics { constructor( private name: string, @@ -55,7 +57,9 @@ export class Diagnostics { connection.onCodeAction(async (params) => { const { context, textDocument } = params; const { diagnostics } = context; - const denoDiagnostics = diagnostics.filter((v) => v.source === this.name); + const denoDiagnostics = diagnostics.filter( + (v) => v.source === this.name || v.source === DENO_LINT + ); if (!denoDiagnostics.length) { return; @@ -89,7 +93,7 @@ export class Diagnostics { .filter((v) => v.code && rules.includes(v.code as string)) .map((v) => { const action = CodeAction.create( - `ignore \`${v.code}\` for this line (${this.name})`, + `ignore \`${v.code}\` for this line (${DENO_LINT})`, Command.create( "Fix lint", `deno._ignore_next_line_lint`, @@ -107,14 +111,13 @@ export class Diagnostics { if (denoLintAction.length) { denoLintAction.push( CodeAction.create( - `ignore entire file (${this.name})`, + `ignore entire file (${DENO_LINT})`, Command.create( - "Fix lint", + "Fix lint for entry file", `deno._ignore_entry_file`, // argument textDocument.uri, - Range.create(Position.create(0, 0), Position.create(0, 0)), - "deno_lint" + Range.create(Position.create(0, 0), Position.create(0, 0)) ), CodeActionKind.QuickFix ) @@ -149,7 +152,7 @@ export class Diagnostics { v.message, DiagnosticSeverity.Error, v.code, - "deno_lint" + DENO_LINT ); }); } From a53e02aa933e30d6f9e0c5270ef3167ab51f2ad2 Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Sun, 6 Sep 2020 17:32:14 +0200 Subject: [PATCH 9/9] update readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5b9d2878..56208fb3 100644 --- a/README.md +++ b/README.md @@ -139,7 +139,7 @@ console.log("concat Array", M.concat([1, 2], [2, 3])); - `deno.unstable` - If Deno's unstable mode is enabled. Default is `false` -- `deno.lint` - If Deno's lint is enabled. `deno.unstable = true` is required. Default is `false` +- `deno.lint` - If inline `deno lint` diagnostics are enabled. Because this is experimental, `deno.unstable = true` is required. Default is `false` We recommend that you do not set global configuration. It should be configured in `.vscode/settings.json` in the project directory: