diff --git a/package.json b/package.json index 38fa512..46a2099 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ "@types/vscode": "1.73.0", "@zardoy/vscode-utils": "^0.0.48", "got": "^12.6.0", + "jsonc-parser": "^3.2.0", "lodash": "^4.17.21", "openai": "^3.2.1", "source-map": "^0.7.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 78f433c..bbb9a0d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12,10 +12,13 @@ dependencies: version: 1.73.0 '@zardoy/vscode-utils': specifier: ^0.0.48 - version: 0.0.48(@types/vscode@1.73.0)(vscode-framework@0.0.18) + version: 0.0.48(@types/vscode@1.73.0)(jsonc-parser@3.2.0)(vscode-framework@0.0.18) got: specifier: ^12.6.0 version: 12.6.0 + jsonc-parser: + specifier: ^3.2.0 + version: 3.2.0 lodash: specifier: ^4.17.21 version: 4.17.21 @@ -293,7 +296,7 @@ packages: type-fest: 2.19.0 dev: false - /@zardoy/vscode-utils@0.0.48(@types/vscode@1.73.0)(vscode-framework@0.0.18): + /@zardoy/vscode-utils@0.0.48(@types/vscode@1.73.0)(jsonc-parser@3.2.0)(vscode-framework@0.0.18): resolution: {integrity: sha512-jtW1QhkiZVp534vm3wufFB87S4wj2MOV3JqjLL56qhSqlHbuDZhZ4SsQrs6m9OSNqj3fz7qMpQmWyG0+gw6MDQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} hasBin: true @@ -319,6 +322,7 @@ packages: commander: 9.5.0 execa: 5.1.1 fs-extra: 10.1.0 + jsonc-parser: 3.2.0 lodash.throttle: 4.1.1 modify-json-file: 1.2.2 path-browserify: 1.0.1 diff --git a/src/configurationType.ts b/src/configurationType.ts index 782bd34..907cd17 100644 --- a/src/configurationType.ts +++ b/src/configurationType.ts @@ -61,9 +61,9 @@ export type Configuration = { /** * @default {} */ - // overrideActivationEvents: { - // [id: string]: string[] - // } + overrideActivationEvents: { + [id: string]: string[] + } /** * @default [] */ diff --git a/src/extension.ts b/src/extension.ts index 86083a4..3d37dd3 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1,7 +1,11 @@ +import * as fs from 'fs' + import * as vscode from 'vscode' -import { extensionCtx, getExtensionSetting, registerExtensionCommand } from 'vscode-framework' +import { extensionCtx, getExtensionSetting, getExtensionSettingId, registerExtensionCommand } from 'vscode-framework' import { watchExtensionSettings } from '@zardoy/vscode-utils/build/settings' import { doPatch, removeAllPatches } from './patch' +import { parseTree, findNodeAtOffset, getNodePath, getLocation } from 'jsonc-parser' +import { join } from 'path' export const activate = async () => { const getNewConfig = () => { @@ -31,11 +35,75 @@ export const activate = async () => { }) // #endregion + vscode.languages.registerCompletionItemProvider( + { + pattern: '**/settings.json', + }, + { + provideCompletionItems(document, position, token, context) { + const root = parseTree(document.getText(), []) + if (!root) { + return + } + const node = findNodeAtOffset(root, document.offsetAt(position)) + if (node?.type !== 'string') { + return + } + + let path = getNodePath(node) + const pathMatches = (compare: string[], useStartsWith = false) => { + if (!useStartsWith && compare.length !== path.length) { + return undefined + } + return compare.every((item, i) => item === '*' || item === path[i]) + } + if ( + (pathMatches([getExtensionSettingId('overrideActivationEvents'), '*']) && node.parent?.type === 'property') || + pathMatches([getExtensionSettingId('disableProviders'), '*', '*']) + ) { + const start = document.positionAt(node.offset + 1) + const end = document.positionAt(node.offset + 1 + node.length - 2) + const range = new vscode.Range(start, end) + return vscode.extensions.all.map(ext => ({ + label: ext.id, + detail: ext.packageJSON.displayName, + filterText: `${ext.id}${ext.packageJSON.displayName}`, + range, + })) + } + return [] + }, + }, + ) + // Main activation actions - // todo continue impl - // for (const [id, expected] of Object.entries(getExtensionSetting('overrideActivationEvents'))) { - // } + let reloadExtHostExtensions = false + for (const [id, expected] of Object.entries(getExtensionSetting('overrideActivationEvents'))) { + const ext = vscode.extensions.getExtension(id) + if (!ext) continue + const { activationEvents = [] } = ext.packageJSON + if (JSON.stringify(expected.sort()) !== JSON.stringify(activationEvents.sort())) { + const packageJson = join(ext.extensionPath, 'package.json') + fs.writeFileSync( + packageJson, + JSON.stringify( + { + ...ext.packageJSON, + activationEvents: expected, + }, + undefined, + 4, + ), + ) + reloadExtHostExtensions = true + } + } + if (reloadExtHostExtensions) { + vscode.window.showInformationMessage('Restarting extension host as activation events were patched...') + await vscode.commands.executeCommand('workbench.action.restartExtensionHost') + return + } const extVersion = extensionCtx.extension.packageJSON.version const currentLoadedConfig = process.env.VSC_CONTROL_EXT_CONFIG && JSON.parse(process.env.VSC_CONTROL_EXT_CONFIG)