- 新增个人规则管理模块 (personalRulesManager.ts) - 支持创建、编辑、删除多条规则 - 规则存储在用户目录 ~/.iccoder/rules/ - 对话时自动将规则传递给后端 - 添加后端对接文档和 webpack 优化指南
148 lines
4.0 KiB
TypeScript
148 lines
4.0 KiB
TypeScript
/**
|
||
* 个人规则管理工具
|
||
* 功能:读写个人规则文件
|
||
* 依赖:vscode, fs, path
|
||
* 使用场景:保存和加载用户的个人规则
|
||
*/
|
||
|
||
import * as vscode from 'vscode';
|
||
import * as fs from 'fs';
|
||
import * as path from 'path';
|
||
import * as os from 'os';
|
||
|
||
/**
|
||
* 获取规则目录路径
|
||
*/
|
||
function getRulesDir(): string {
|
||
return path.join(os.homedir(), '.iccoder', 'rules');
|
||
}
|
||
|
||
/**
|
||
* 确保规则目录存在
|
||
*/
|
||
function ensureRulesDir(): void {
|
||
const dir = getRulesDir();
|
||
if (!fs.existsSync(dir)) {
|
||
fs.mkdirSync(dir, { recursive: true });
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 从文件内容中提取规则名称
|
||
*/
|
||
function extractRuleName(content: string): string {
|
||
const lines = content.split('\n');
|
||
const firstLine = lines[0]?.trim();
|
||
if (firstLine && firstLine.startsWith('# ')) {
|
||
return firstLine.substring(2).trim();
|
||
}
|
||
return content.substring(0, 30) + (content.length > 30 ? '...' : '');
|
||
}
|
||
|
||
/**
|
||
* 保存新规则
|
||
*/
|
||
export async function savePersonalRule(name: string, content: string, enabled: boolean): Promise<boolean> {
|
||
try {
|
||
ensureRulesDir();
|
||
|
||
const timestamp = Date.now();
|
||
const filename = `rule-${timestamp}.md`;
|
||
const filePath = path.join(getRulesDir(), filename);
|
||
|
||
const fileContent = `# ${name}\n\n${content}`;
|
||
fs.writeFileSync(filePath, fileContent, 'utf-8');
|
||
|
||
await vscode.workspace.getConfiguration('ic-coder').update('personalRulesEnabled', enabled, vscode.ConfigurationTarget.Global);
|
||
|
||
vscode.window.showInformationMessage('规则已保存');
|
||
return true;
|
||
} catch (error) {
|
||
vscode.window.showErrorMessage(`保存规则失败: ${error}`);
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 更新规则
|
||
*/
|
||
export async function updatePersonalRule(filename: string, name: string, content: string, enabled: boolean): Promise<boolean> {
|
||
try {
|
||
const filePath = path.join(getRulesDir(), filename);
|
||
const fileContent = `# ${name}\n\n${content}`;
|
||
fs.writeFileSync(filePath, fileContent, 'utf-8');
|
||
|
||
await vscode.workspace.getConfiguration('ic-coder').update('personalRulesEnabled', enabled, vscode.ConfigurationTarget.Global);
|
||
|
||
vscode.window.showInformationMessage('规则已更新');
|
||
return true;
|
||
} catch (error) {
|
||
vscode.window.showErrorMessage(`更新规则失败: ${error}`);
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 删除规则
|
||
*/
|
||
export async function deletePersonalRule(filename: string): Promise<boolean> {
|
||
try {
|
||
const filePath = path.join(getRulesDir(), filename);
|
||
if (fs.existsSync(filePath)) {
|
||
fs.unlinkSync(filePath);
|
||
vscode.window.showInformationMessage('规则已删除');
|
||
return true;
|
||
}
|
||
return false;
|
||
} catch (error) {
|
||
vscode.window.showErrorMessage(`删除规则失败: ${error}`);
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 加载所有规则
|
||
*/
|
||
export function loadPersonalRules(): { rules: Array<{ filename: string; name: string; content: string }>; enabled: boolean } {
|
||
const enabled = vscode.workspace.getConfiguration('ic-coder').get<boolean>('personalRulesEnabled', true);
|
||
const dir = getRulesDir();
|
||
|
||
if (!fs.existsSync(dir)) {
|
||
return { rules: [], enabled };
|
||
}
|
||
|
||
try {
|
||
const files = fs.readdirSync(dir).filter(f => f.endsWith('.md'));
|
||
const rules = files.map(filename => {
|
||
const content = fs.readFileSync(path.join(dir, filename), 'utf-8');
|
||
const lines = content.split('\n');
|
||
let name = '';
|
||
let actualContent = content;
|
||
|
||
if (lines[0]?.trim().startsWith('# ')) {
|
||
name = lines[0].substring(2).trim();
|
||
actualContent = lines.slice(2).join('\n').trim();
|
||
} else {
|
||
name = extractRuleName(content);
|
||
}
|
||
|
||
return { filename, name, content: actualContent };
|
||
});
|
||
return { rules, enabled };
|
||
} catch (error) {
|
||
console.error('读取规则失败:', error);
|
||
return { rules: [], enabled };
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 获取当前生效的所有规则内容
|
||
*/
|
||
export function getActiveRules(): string | null {
|
||
const { rules, enabled } = loadPersonalRules();
|
||
if (!enabled || rules.length === 0) {
|
||
return null;
|
||
}
|
||
return rules.map(r => r.content).join('\n\n');
|
||
}
|