|
| 1 | +import * as vscode from 'vscode' |
| 2 | +import { watchExtensionSetting } from '@zardoy/vscode-utils/build/settings' |
| 3 | +import { getExtensionSetting, registerActiveDevelopmentCommand } from 'vscode-framework' |
| 4 | + |
| 5 | +// todo respect enabled setting, deactivate |
| 6 | +export default () => { |
| 7 | + const provider = new (class implements vscode.InlayHintsProvider { |
| 8 | + eventEmitter = new vscode.EventEmitter<void>() |
| 9 | + onDidChangeInlayHints = this.eventEmitter.event |
| 10 | + provideInlayHints(document: vscode.TextDocument, range: vscode.Range, token: vscode.CancellationToken): vscode.ProviderResult<vscode.InlayHint[]> { |
| 11 | + const diagnostics = vscode.languages.getDiagnostics(document.uri) |
| 12 | + const jsxMissingAttributesErrors = diagnostics.filter(({ code, source }) => (code === 2740 || code === 2739) && source === 'ts') |
| 13 | + return jsxMissingAttributesErrors |
| 14 | + .flatMap(({ range, message }) => { |
| 15 | + const regex = /: (?<prop>[\w, ]+)(?:, and (?<more>\d+) more)?\.?$/ |
| 16 | + const match = regex.exec(message) |
| 17 | + if (!match) return null as never |
| 18 | + const props = match.groups!.prop!.split(', ') |
| 19 | + const { more } = match.groups! |
| 20 | + let text = ` ${props.map(prop => `${prop}!`).join(', ')}` |
| 21 | + if (more) text += `, and ${more} more` |
| 22 | + return { |
| 23 | + kind: vscode.InlayHintKind.Type, |
| 24 | + label: text, |
| 25 | + tooltip: `Inlay hint: Missing attributes`, |
| 26 | + position: range.end, |
| 27 | + paddingLeft: true, |
| 28 | + } satisfies vscode.InlayHint |
| 29 | + // return [...props, ...(more ? [more] : [])].map((prop) => ({ |
| 30 | + // kind: vscode.InlayHintKind.Type, |
| 31 | + // label: prop, |
| 32 | + // tooltip: 'Missing attribute', |
| 33 | + // position: |
| 34 | + // })) |
| 35 | + }) |
| 36 | + .filter(Boolean) |
| 37 | + } |
| 38 | + })() |
| 39 | + let disposables = [] as vscode.Disposable[] |
| 40 | + |
| 41 | + const manageEnablement = () => { |
| 42 | + if (getExtensionSetting('inlayHints.missingJsxAttributes.enabled')) { |
| 43 | + vscode.languages.registerInlayHintsProvider('typescriptreact,javascript,javascriptreact'.split(','), provider) |
| 44 | + vscode.languages.onDidChangeDiagnostics(e => { |
| 45 | + for (const uri of e.uris) { |
| 46 | + if (uri === vscode.window.activeTextEditor?.document.uri) provider.eventEmitter.fire() |
| 47 | + } |
| 48 | + }) |
| 49 | + } else { |
| 50 | + for (const d of disposables) d.dispose() |
| 51 | + disposables = [] |
| 52 | + } |
| 53 | + } |
| 54 | + |
| 55 | + manageEnablement() |
| 56 | + watchExtensionSetting('inlayHints.missingJsxAttributes.enabled', manageEnablement) |
| 57 | +} |
0 commit comments