feat:codeToChat
This commit is contained in:
@ -10,10 +10,42 @@ import { initCreditsService } from "./services/creditsService";
|
||||
import { isTokenExpired } from "./utils/jwtUtils";
|
||||
import { NotificationService } from "./services/notificationService";
|
||||
import { InvitationService } from "./services/invitationService";
|
||||
import { ICCoderCodeActionProvider } from "./providers/codeActionProvider";
|
||||
|
||||
export async function activate(context: vscode.ExtensionContext) {
|
||||
console.log("🎉 IC Coder 插件已激活!");
|
||||
|
||||
// 创建装饰类型(代码旁边的提示)
|
||||
const decorationType = vscode.window.createTextEditorDecorationType({
|
||||
after: {
|
||||
contentText: ' Ctrl+L 添加到 IC Coder 对话',
|
||||
color: '#888',
|
||||
fontStyle: 'italic',
|
||||
margin: '0 0 0 1em'
|
||||
}
|
||||
});
|
||||
|
||||
// 更新装饰
|
||||
const updateDecorations = () => {
|
||||
const editor = vscode.window.activeTextEditor;
|
||||
if (!editor) return;
|
||||
|
||||
if (!editor.selection.isEmpty) {
|
||||
const range = new vscode.Range(editor.selection.end, editor.selection.end);
|
||||
const decoration = { range };
|
||||
editor.setDecorations(decorationType, [decoration]);
|
||||
} else {
|
||||
editor.setDecorations(decorationType, []);
|
||||
}
|
||||
};
|
||||
|
||||
context.subscriptions.push(
|
||||
vscode.window.onDidChangeTextEditorSelection(updateDecorations),
|
||||
vscode.window.onDidChangeActiveTextEditor(updateDecorations)
|
||||
);
|
||||
|
||||
updateDecorations();
|
||||
|
||||
// 初始化通知服务
|
||||
const notificationService = NotificationService.getInstance(context);
|
||||
console.log('[Extension] 通知服务已初始化');
|
||||
@ -250,6 +282,48 @@ export async function activate(context: vscode.ExtensionContext) {
|
||||
}
|
||||
);
|
||||
|
||||
// 注册命令:将选中代码添加到对话
|
||||
const addCodeToChat = vscode.commands.registerCommand(
|
||||
"ic-coder.addCodeToChat",
|
||||
async () => {
|
||||
const editor = vscode.window.activeTextEditor;
|
||||
if (!editor) return;
|
||||
|
||||
const selection = editor.selection;
|
||||
const selectedText = editor.document.getText(selection);
|
||||
|
||||
if (!selectedText) {
|
||||
vscode.window.showWarningMessage("请先选择代码");
|
||||
return;
|
||||
}
|
||||
|
||||
const fileName = editor.document.fileName;
|
||||
const startLine = selection.start.line + 1;
|
||||
const endLine = selection.end.line + 1;
|
||||
|
||||
// 检查是否已有打开的面板
|
||||
let panel = (global as any).currentICHelperPanel;
|
||||
if (!panel || panel._isDisposed) {
|
||||
await showICHelperPanel(context);
|
||||
panel = (global as any).currentICHelperPanel;
|
||||
}
|
||||
|
||||
// 发送代码上下文
|
||||
setTimeout(() => {
|
||||
if (panel?.webview) {
|
||||
panel.webview.postMessage({
|
||||
command: 'addCodeContext',
|
||||
fileName,
|
||||
startLine,
|
||||
endLine,
|
||||
code: selectedText,
|
||||
languageId: editor.document.languageId
|
||||
});
|
||||
}
|
||||
}, 300);
|
||||
}
|
||||
);
|
||||
|
||||
// 注册命令:查看会话历史
|
||||
// TODO: 这些命令需要根据新的任务架构重新实现
|
||||
// 暂时注释掉,等待重新实现
|
||||
@ -312,6 +386,13 @@ export async function activate(context: vscode.ExtensionContext) {
|
||||
// 注册 VCD 自定义编辑器
|
||||
const vcdEditorProvider = VCDViewerEditorProvider.register(context, vcdFileServer);
|
||||
|
||||
// 注册 Code Action Provider
|
||||
const codeActionProvider = vscode.languages.registerCodeActionsProvider(
|
||||
{ scheme: 'file' },
|
||||
new ICCoderCodeActionProvider(),
|
||||
{ providedCodeActionKinds: [vscode.CodeActionKind.RefactorRewrite] }
|
||||
);
|
||||
|
||||
// 添加到订阅
|
||||
context.subscriptions.push(
|
||||
openPanelCommand,
|
||||
@ -322,6 +403,7 @@ export async function activate(context: vscode.ExtensionContext) {
|
||||
logoutCommand,
|
||||
changeInvitationCodeCommand,
|
||||
testNotificationCommand,
|
||||
addCodeToChat,
|
||||
// testTrialUserCommand,
|
||||
// testExpiredUserCommand,
|
||||
// TODO: 等待重新实现这些命令
|
||||
@ -332,7 +414,8 @@ export async function activate(context: vscode.ExtensionContext) {
|
||||
// clearHistoryCommand,
|
||||
// searchSessionCommand,
|
||||
viewRegistration,
|
||||
vcdEditorProvider
|
||||
vcdEditorProvider,
|
||||
codeActionProvider
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -143,6 +143,9 @@ export async function showICHelperPanel(
|
||||
},
|
||||
);
|
||||
|
||||
// 保存 panel 引用到全局
|
||||
(global as any).currentICHelperPanel = panel;
|
||||
|
||||
// 为面板生成唯一ID
|
||||
const panelId = `panel_${Date.now()}_${Math.random()
|
||||
.toString(36)
|
||||
|
||||
26
src/providers/codeActionProvider.ts
Normal file
26
src/providers/codeActionProvider.ts
Normal file
@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Code Action Provider - 为选中代码提供快捷操作
|
||||
* 功能:在小灯泡菜单中显示"添加到 IC Coder 对话"选项
|
||||
*/
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
export class ICCoderCodeActionProvider implements vscode.CodeActionProvider {
|
||||
provideCodeActions(
|
||||
document: vscode.TextDocument,
|
||||
range: vscode.Range
|
||||
): vscode.CodeAction[] {
|
||||
const selectedText = document.getText(range);
|
||||
if (!selectedText) return [];
|
||||
|
||||
const action = new vscode.CodeAction(
|
||||
'💬 添加到 IC Coder 对话',
|
||||
vscode.CodeActionKind.RefactorRewrite
|
||||
);
|
||||
action.command = {
|
||||
command: 'ic-coder.addCodeToChat',
|
||||
title: '添加到对话'
|
||||
};
|
||||
|
||||
return [action];
|
||||
}
|
||||
}
|
||||
@ -126,6 +126,11 @@ export function getContextDisplayScript(): string {
|
||||
return '<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"><path d="M832 64H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V96c0-17.7-14.3-32-32-32z" fill="currentColor"/></svg>';
|
||||
}
|
||||
|
||||
// 获取代码图标 SVG
|
||||
function getCodeIcon() {
|
||||
return '<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"><path d="M880 112H144c-17.7 0-32 14.3-32 32v736c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V144c0-17.7-14.3-32-32-32z m-40 728H184V184h656v656z m-484.7-122.1l39.6-39.5 113.1 113.1-39.6 39.5-113.1-113.1z m226.4-290.2l113.1 113.1-39.6 39.5-113.1-113.1 39.6-39.5z" fill="currentColor"/></svg>';
|
||||
}
|
||||
|
||||
// 获取删除图标 SVG
|
||||
function getRemoveIcon() {
|
||||
return '<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"><path d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9c-4.4 5.2-.7 13.1 6.1 13.1h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z" fill="currentColor"/></svg>';
|
||||
@ -172,10 +177,11 @@ export function getContextDisplayScript(): string {
|
||||
case 'folder': icon = getFolderIcon(); break;
|
||||
case 'image': icon = getImageIcon(); break;
|
||||
case 'document': icon = getDocumentIcon(); break;
|
||||
case 'code': icon = getCodeIcon(); break;
|
||||
}
|
||||
|
||||
return \`
|
||||
<div class="context-item" title="\${item.path}">
|
||||
<div class="context-item" title="\${item.path || item.displayPath}">
|
||||
\${icon}
|
||||
<span class="context-item-name">\${item.displayPath || getFileName(item.path)}</span>
|
||||
<span class="context-item-remove" onclick="removeContextItem(\${item.id})">
|
||||
@ -211,6 +217,18 @@ export function getContextDisplayScript(): string {
|
||||
message.documents.forEach(doc => addContextItem('document', doc));
|
||||
}
|
||||
break;
|
||||
case 'addCodeContext':
|
||||
// 添加代码上下文
|
||||
const displayName = \`\${message.fileName.split(/[\\\\/]/).pop()}:\${message.startLine}-\${message.endLine}\`;
|
||||
const codeData = {
|
||||
fileName: message.fileName,
|
||||
startLine: message.startLine,
|
||||
endLine: message.endLine,
|
||||
code: message.code,
|
||||
languageId: message.languageId
|
||||
};
|
||||
addContextItem('code', JSON.stringify(codeData), displayName);
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user