如果className只有一个,那直接是Styles.xx的形式,不需要模板字符串

如果已经是className={Styles.xx}的形式,提供转换为模板字符串的快速修复
This commit is contained in:
pqcqaq 2024-11-01 13:59:24 +08:00
parent 149a2deb5e
commit 1f589fb4b1
1 changed files with 88 additions and 20 deletions

View File

@ -12,36 +12,104 @@ class ClassNameConversionProvider implements vscode.CodeActionProvider {
return;
}
const fix = new vscode.CodeAction('转换为ModuleLess写法', vscode.CodeActionKind.QuickFix);
fix.edit = new vscode.WorkspaceEdit();
fix.edit.replace(
document.uri,
classNameAttr.range,
this.convertToModuleStyle(classNameAttr.text)
);
const actions: vscode.CodeAction[] = [];
return [fix];
if (classNameAttr.type === 'string') {
const fix = new vscode.CodeAction(
'转换为ModuleLess写法',
vscode.CodeActionKind.QuickFix
);
fix.edit = new vscode.WorkspaceEdit();
fix.edit.replace(
document.uri,
classNameAttr.range,
this.convertToModuleStyle(classNameAttr.text)
);
actions.push(fix);
} else if (classNameAttr.type === 'module') {
const fix = new vscode.CodeAction(
'转换为模板字符串',
vscode.CodeActionKind.QuickFix
);
fix.edit = new vscode.WorkspaceEdit();
fix.edit.replace(
document.uri,
classNameAttr.range,
this.convertToTemplateString(classNameAttr.text)
);
actions.push(fix);
}
return actions;
}
private getClassNameAttr(document: vscode.TextDocument, range: vscode.Range): { text: string, range: vscode.Range } | undefined {
private getClassNameAttr(
document: vscode.TextDocument,
range: vscode.Range
):
| { text: string; range: vscode.Range; type: 'string' | 'module' }
| undefined {
const line = document.lineAt(range.start.line);
const classNameMatch = line.text.match(/className\s*=\s*(['"])([^'"]+)(['"])/);
if (classNameMatch) {
const start = line.text.indexOf(classNameMatch[0]);
const end = start + classNameMatch[0].length;
const stringClassNameMatch = line.text.match(
/className\s*=\s*(['"])([^'"]+)(['"])/
);
if (stringClassNameMatch) {
const start = line.text.indexOf(stringClassNameMatch[0]);
const end = start + stringClassNameMatch[0].length;
return {
text: classNameMatch[0],
range: new vscode.Range(range.start.line, start, range.start.line, end)
text: stringClassNameMatch[0],
range: new vscode.Range(
range.start.line,
start,
range.start.line,
end
),
type: 'string',
};
}
const moduleClassNameMatch = line.text.match(
/className\s*=\s*\{Styles\.([^}]+)\}/
);
if (moduleClassNameMatch) {
const start = line.text.indexOf(moduleClassNameMatch[0]);
const end = start + moduleClassNameMatch[0].length;
return {
text: moduleClassNameMatch[0],
range: new vscode.Range(
range.start.line,
start,
range.start.line,
end
),
type: 'module',
};
}
}
private convertToModuleStyle(classNameAttr: string): string {
const classes = classNameAttr.match(/(['"])([^'"]+)(['"])/)?.[2];
const convertedClasses = classes?.split(' ')
.map(cls => `\${Styles.${cls}}`)
.join(' ');
return `className={\`${convertedClasses}\`}`;
if (!classes) {
return classNameAttr;
}
const classArray = classes.split(' ');
if (classArray.length === 1) {
return `className={Styles.${classArray[0]}}`;
} else {
const convertedClasses = classArray
.map((cls) => `\${Styles.${cls}}`)
.join(' ');
return `className={\`${convertedClasses}\`}`;
}
}
private convertToTemplateString(classNameAttr: string): string {
const className = classNameAttr.match(/Styles\.([^}]+)/)?.[1];
if (!className) {
return classNameAttr;
}
return `className={\`\${Styles.${className}}\`}`;
}
}
@ -49,7 +117,7 @@ const provider = vscode.languages.registerCodeActionsProvider(
{ scheme: 'file', language: 'typescriptreact' },
new ClassNameConversionProvider(),
{
providedCodeActionKinds: [vscode.CodeActionKind.QuickFix]
providedCodeActionKinds: [vscode.CodeActionKind.QuickFix],
}
);