|
|
|
@ -72,8 +72,54 @@ export function activate(context: vscode.ExtensionContext) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 注册获取工作区文件列表的命令
|
|
|
|
|
|
|
|
const getFileListCommand = vscode.commands.registerCommand('ai-chat.getFileList', async () => {
|
|
|
|
|
|
|
|
if (panel && panel.webview) {
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
// 获取工作区根路径
|
|
|
|
|
|
|
|
const workspaceFolders = vscode.workspace.workspaceFolders;
|
|
|
|
|
|
|
|
if (!workspaceFolders || workspaceFolders.length === 0) {
|
|
|
|
|
|
|
|
panel.webview.postMessage({
|
|
|
|
|
|
|
|
command: 'fileList',
|
|
|
|
|
|
|
|
files: [],
|
|
|
|
|
|
|
|
error: '未找到工作区'
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const rootPath = workspaceFolders[0].uri;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 查找所有文件
|
|
|
|
|
|
|
|
const fileUris = await vscode.workspace.findFiles('**/*', '**/node_modules/**');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 转换为相对路径和基本信息
|
|
|
|
|
|
|
|
const files = fileUris.map(uri => {
|
|
|
|
|
|
|
|
const relativePath = vscode.workspace.asRelativePath(uri);
|
|
|
|
|
|
|
|
const isDirectory = uri.path.endsWith('/');
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
|
|
|
path: uri.fsPath,
|
|
|
|
|
|
|
|
relativePath: relativePath,
|
|
|
|
|
|
|
|
name: path.basename(uri.fsPath),
|
|
|
|
|
|
|
|
isDirectory: isDirectory
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
panel.webview.postMessage({
|
|
|
|
|
|
|
|
command: 'fileList',
|
|
|
|
|
|
|
|
files: files
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
|
|
panel.webview.postMessage({
|
|
|
|
|
|
|
|
command: 'fileList',
|
|
|
|
|
|
|
|
files: [],
|
|
|
|
|
|
|
|
error: error.message
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// 添加到 subscriptions
|
|
|
|
// 添加到 subscriptions
|
|
|
|
context.subscriptions.push(statusBarItem, openWebviewCommand, addToChatCommand,selectFileCommand);
|
|
|
|
context.subscriptions.push(statusBarItem, openWebviewCommand, addToChatCommand,selectFileCommand,getFileListCommand);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function openWebview(
|
|
|
|
function openWebview(
|
|
|
|
@ -163,6 +209,45 @@ function openWebview(
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'getFileList':
|
|
|
|
|
|
|
|
// 执行获取文件列表逻辑
|
|
|
|
|
|
|
|
const workspaceFolders = vscode.workspace.workspaceFolders;
|
|
|
|
|
|
|
|
if (workspaceFolders && workspaceFolders.length > 0) {
|
|
|
|
|
|
|
|
const fileUris = await vscode.workspace.findFiles('**/*', '**/node_modules/**');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const files = fileUris.map(uri => {
|
|
|
|
|
|
|
|
const relativePath = vscode.workspace.asRelativePath(uri);
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
|
|
|
path: uri.fsPath,
|
|
|
|
|
|
|
|
relativePath: relativePath,
|
|
|
|
|
|
|
|
name: path.basename(uri.fsPath),
|
|
|
|
|
|
|
|
isDirectory: false // 简化处理,实际可以根据扩展名判断
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
panel.webview.postMessage({
|
|
|
|
|
|
|
|
command: 'fileList',
|
|
|
|
|
|
|
|
files: files
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case 'selectFileByPath':
|
|
|
|
|
|
|
|
// 根据路径选择文件
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
const fileUri = vscode.Uri.file(message.filePath);
|
|
|
|
|
|
|
|
const fileContent = await vscode.workspace.fs.readFile(fileUri);
|
|
|
|
|
|
|
|
const decodedContent = new TextDecoder("utf-8").decode(fileContent);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
panel.webview.postMessage({
|
|
|
|
|
|
|
|
command: 'setContextFile',
|
|
|
|
|
|
|
|
fileName: fileUri.fsPath,
|
|
|
|
|
|
|
|
fileContent: decodedContent
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
|
|
vscode.window.showErrorMessage(`无法读取文件: ${error.message}`);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
undefined,
|
|
|
|
undefined,
|
|
|
|
@ -249,6 +334,25 @@ function getWebviewContent(styleUri: vscode.Uri, scriptUri: vscode.Uri,highlight
|
|
|
|
<button id="close-context-btn" class="close-btn" title="清除上下文">×</button>
|
|
|
|
<button id="close-context-btn" class="close-btn" title="清除上下文">×</button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 文件浏览器模态框 -->
|
|
|
|
|
|
|
|
<div id="file-browser-modal" class="modal hidden">
|
|
|
|
|
|
|
|
<div class="modal-content">
|
|
|
|
|
|
|
|
<div class="modal-header">
|
|
|
|
|
|
|
|
<h3>选择上下文文件</h3>
|
|
|
|
|
|
|
|
<span id="close-modal" class="close-modal">×</span>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="modal-body">
|
|
|
|
|
|
|
|
<div class="file-search">
|
|
|
|
|
|
|
|
<input type="text" id="file-search-input" placeholder="搜索文件..." />
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div id="file-list" class="file-list">
|
|
|
|
|
|
|
|
<div class="loading">加载中...</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 聊天输入表单 -->
|
|
|
|
<!-- 聊天输入表单 -->
|
|
|
|
<form id="chat-form">
|
|
|
|
<form id="chat-form">
|
|
|
|
<input type="text" id="user-input" placeholder="输入你的问题..." required />
|
|
|
|
<input type="text" id="user-input" placeholder="输入你的问题..." required />
|
|
|
|
|