diff --git a/CHANGELOG.md b/CHANGELOG.md index 6982e24..5c773d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [1.0.1] - Unreleased +### Added: + +- Code actions: Support for JSONC files +- Code lens: Support for JSONC files + ### Changed: - Snippets: All snippets that reference schemas updated to use `v1.0.0` schema diff --git a/src/codeactions.ts b/src/codeactions.ts index 866ba47..da4d14a 100644 --- a/src/codeactions.ts +++ b/src/codeactions.ts @@ -4,101 +4,129 @@ import {DevProxyInstall} from './types'; export const registerCodeActions = (context: vscode.ExtensionContext) => { const devProxyInstall = context.globalState.get('devProxyInstall'); + if (!devProxyInstall) { return; } + const devProxyVersion = devProxyInstall.isBeta ? devProxyInstall.version.split('-')[0] : devProxyInstall.version; + registerInvalidSchemaFixes(devProxyVersion, context); + registerDeprecatedPluginPathFixes(context); +}; + +function registerInvalidSchemaFixes( + devProxyVersion: string, + context: vscode.ExtensionContext, +) { + const invalidSchema: vscode.CodeActionProvider = { + provideCodeActions: (document, range, context, token) => { + const diagnostic = context.diagnostics.find(diagnostic => { + return diagnostic.code === 'invalidSchema'; + }); + if (diagnostic) { + const fix = new vscode.CodeAction( + 'Update schema', + vscode.CodeActionKind.QuickFix, + ); + fix.edit = new vscode.WorkspaceEdit(); + fix.edit.replace( + document.uri, + new vscode.Range(diagnostic.range.start, diagnostic.range.end), + `https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v${devProxyVersion}/rc.schema.json`, + ); + return [fix]; + } + }, + }; + // Code action for invalid schema context.subscriptions.push( - vscode.languages.registerCodeActionsProvider('json', { - provideCodeActions: (document, range, context, token) => { - const diagnostic = context.diagnostics.find(diagnostic => { - return diagnostic.code === 'invalidSchema'; - }); - if (diagnostic) { - const fix = new vscode.CodeAction( - 'Update schema', - vscode.CodeActionKind.QuickFix, - ); - fix.edit = new vscode.WorkspaceEdit(); - fix.edit.replace( - document.uri, - new vscode.Range(diagnostic.range.start, diagnostic.range.end), - `https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v${devProxyVersion}/rc.schema.json`, - ); - return [fix]; - } - }, - }), + vscode.languages.registerCodeActionsProvider('json', invalidSchema), ); - // Code action for deprecated plugin paths (individual and bulk updates) context.subscriptions.push( - vscode.languages.registerCodeActionsProvider('json', { - provideCodeActions: (document, range, context, token) => { - const correctPluginPath = '~appFolder/plugins/DevProxy.Plugins.dll'; - - // Check if the current range intersects with a deprecated plugin path diagnostic - const currentDiagnostic = context.diagnostics.find(diagnostic => { - return diagnostic.code === 'deprecatedPluginPath' && - diagnostic.range.intersection(range); - }); + vscode.languages.registerCodeActionsProvider('jsonc', invalidSchema), + ); +} - // Only provide deprecated plugin path actions if user is on a deprecated plugin path diagnostic - if (!currentDiagnostic) { - return []; - } +function registerDeprecatedPluginPathFixes(context: vscode.ExtensionContext) { + const deprecatedPluginPaths: vscode.CodeActionProvider = { + provideCodeActions: (document, range, context, token) => { + const correctPluginPath = '~appFolder/plugins/DevProxy.Plugins.dll'; + + // Check if the current range intersects with a deprecated plugin path diagnostic + const currentDiagnostic = context.diagnostics.find(diagnostic => { + return ( + diagnostic.code === 'deprecatedPluginPath' && + diagnostic.range.intersection(range) + ); + }); - const fixes: vscode.CodeAction[] = []; + // Only provide deprecated plugin path actions if user is on a deprecated plugin path diagnostic + if (!currentDiagnostic) { + return []; + } - // Individual fix for the current diagnostic - const individualFix = new vscode.CodeAction( - 'Update plugin path', + const fixes: vscode.CodeAction[] = []; + + // Individual fix for the current diagnostic + const individualFix = new vscode.CodeAction( + 'Update plugin path', + vscode.CodeActionKind.QuickFix, + ); + individualFix.edit = new vscode.WorkspaceEdit(); + individualFix.edit.replace( + document.uri, + new vscode.Range( + currentDiagnostic.range.start, + currentDiagnostic.range.end, + ), + correctPluginPath, + ); + fixes.push(individualFix); + + // Bulk fix for all deprecated plugin paths in the document (only show when on a deprecated plugin path) + const allDeprecatedPluginPathDiagnostics = vscode.languages + .getDiagnostics(document.uri) + .filter(diagnostic => { + return diagnostic.code === 'deprecatedPluginPath'; + }); + + if (allDeprecatedPluginPathDiagnostics.length > 1) { + const bulkFix = new vscode.CodeAction( + `Update all plugin paths`, vscode.CodeActionKind.QuickFix, ); - individualFix.edit = new vscode.WorkspaceEdit(); - individualFix.edit.replace( - document.uri, - new vscode.Range( - currentDiagnostic.range.start, - currentDiagnostic.range.end, - ), - correctPluginPath, - ); - fixes.push(individualFix); - - // Bulk fix for all deprecated plugin paths in the document (only show when on a deprecated plugin path) - const allDeprecatedPluginPathDiagnostics = vscode.languages - .getDiagnostics(document.uri) - .filter(diagnostic => { - return diagnostic.code === 'deprecatedPluginPath'; - }); - - if (allDeprecatedPluginPathDiagnostics.length > 1) { - const bulkFix = new vscode.CodeAction( - `Update all plugin paths`, - vscode.CodeActionKind.QuickFix, + bulkFix.edit = new vscode.WorkspaceEdit(); + + // Update all deprecated plugin paths + allDeprecatedPluginPathDiagnostics.forEach(diagnostic => { + bulkFix.edit!.replace( + document.uri, + new vscode.Range(diagnostic.range.start, diagnostic.range.end), + correctPluginPath, ); - bulkFix.edit = new vscode.WorkspaceEdit(); - - // Update all deprecated plugin paths - allDeprecatedPluginPathDiagnostics.forEach(diagnostic => { - bulkFix.edit!.replace( - document.uri, - new vscode.Range(diagnostic.range.start, diagnostic.range.end), - correctPluginPath, - ); - }); - - bulkFix.isPreferred = true; - fixes.push(bulkFix); - } - - return fixes; - }, - }), + }); + + bulkFix.isPreferred = true; + fixes.push(bulkFix); + } + + return fixes; + }, + }; + // Code action for deprecated plugin paths (individual and bulk updates) + context.subscriptions.push( + vscode.languages.registerCodeActionsProvider('json', deprecatedPluginPaths), ); -}; + + context.subscriptions.push( + vscode.languages.registerCodeActionsProvider( + 'jsonc', + deprecatedPluginPaths, + ), + ); +} diff --git a/src/codelens.ts b/src/codelens.ts index 4cecc20..d7ea606 100644 --- a/src/codelens.ts +++ b/src/codelens.ts @@ -10,6 +10,13 @@ export const registerCodeLens = (context: vscode.ExtensionContext) => { pluginLensProvider ) ); + + context.subscriptions.push( + vscode.languages.registerCodeLensProvider( + {scheme: 'file', language: 'jsonc'}, + pluginLensProvider, + ), + ); }; export const pluginLensProvider: vscode.CodeLensProvider = { diff --git a/src/test/examples/devproxyrc.jsonc b/src/test/examples/devproxyrc.jsonc new file mode 100644 index 0000000..1b895b6 --- /dev/null +++ b/src/test/examples/devproxyrc.jsonc @@ -0,0 +1,16 @@ +{ + "$schema": "https://raw.githubusercontent.com/dotnet/dev-proxy/main/schemas/v0.29.2/rc.schema.json", + "plugins": [ + { + "name": "LatencyPlugin", + "enabled": true, + "pluginPath": "~appFolder/plugins/DevProxy.Plugins.dll" + } + ], + "urlsToWatch": [ + "https://jsonplaceholder.typicode.com/*" + ], + "logLevel": "information", + "newVersionNotification": "stable", + "showSkipMessages": true +}