269 lines
6.8 KiB
TypeScript
269 lines
6.8 KiB
TypeScript
import * as vscode from "vscode";
|
|
import { getWebviewContent } from "./webviewContent";
|
|
import {
|
|
handleUserMessage,
|
|
insertCodeToEditor,
|
|
handleReadFile,
|
|
handleCreateFile,
|
|
} from "../utils/messageHandler";
|
|
|
|
/**
|
|
* 创建并显示IC 侧边栏视图
|
|
*/
|
|
export function showICHelperPanel(content: vscode.ExtensionContext) {
|
|
// 创建WebView面板
|
|
const panel = vscode.window.createWebviewPanel(
|
|
"icCoder", // 面板ID
|
|
"IC Coder", // 面板标题
|
|
vscode.ViewColumn.Beside, // 显示在旁边
|
|
{
|
|
enableScripts: true,
|
|
retainContextWhenHidden: true,
|
|
localResourceRoots: [vscode.Uri.joinPath(content.extensionUri, "media")],
|
|
}
|
|
);
|
|
|
|
// 设置标签页图标
|
|
panel.iconPath = vscode.Uri.joinPath(
|
|
content.extensionUri,
|
|
"media",
|
|
"图案(方底).png"
|
|
);
|
|
|
|
// 获取页面内图标URI
|
|
const iconUri = panel.webview.asWebviewUri(
|
|
vscode.Uri.joinPath(content.extensionUri, "media", "图案(方底).png")
|
|
);
|
|
// 设置HTML内容
|
|
panel.webview.html = getWebviewContent(iconUri.toString());
|
|
|
|
// 处理消息
|
|
panel.webview.onDidReceiveMessage(
|
|
(message) => {
|
|
switch (message.command) {
|
|
case "sendMessage":
|
|
handleUserMessage(panel, message.text);
|
|
break;
|
|
case "readFile":
|
|
handleReadFile(panel, message.filePath);
|
|
break;
|
|
case "insertCode":
|
|
insertCodeToEditor(message.code);
|
|
break;
|
|
case "createFile":
|
|
handleCreateFile(
|
|
panel,
|
|
message.filePath,
|
|
message.content,
|
|
message.overwrite
|
|
);
|
|
break;
|
|
case "showInfo":
|
|
vscode.window.showInformationMessage(message.text);
|
|
break;
|
|
}
|
|
},
|
|
undefined,
|
|
content.subscriptions
|
|
);
|
|
}
|
|
|
|
/**
|
|
* 侧边栏视图提供者
|
|
*/
|
|
export class ICViewProvider implements vscode.WebviewViewProvider {
|
|
constructor(private readonly extensionUri: vscode.Uri) {}
|
|
|
|
resolveWebviewView(webviewView: vscode.WebviewView) {
|
|
webviewView.webview.options = {
|
|
enableScripts: true,
|
|
localResourceRoots: [vscode.Uri.joinPath(this.extensionUri, "media")],
|
|
};
|
|
|
|
webviewView.webview.html = this.getWebviewContent(webviewView.webview);
|
|
|
|
// 处理侧边栏的消息
|
|
webviewView.webview.onDidReceiveMessage((message) => {
|
|
if (message.command === "openChat") {
|
|
vscode.commands.executeCommand("ic-coder.openChat");
|
|
}
|
|
});
|
|
}
|
|
|
|
private getWebviewContent(webview: vscode.Webview): string {
|
|
const logoUri = webview.asWebviewUri(
|
|
vscode.Uri.joinPath(this.extensionUri, "media", "ICCoder主页标志.png")
|
|
);
|
|
|
|
return `
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<style>
|
|
body {
|
|
margin: 0;
|
|
padding: 0;
|
|
font-family: var(--vscode-font-family);
|
|
color: var(--vscode-foreground);
|
|
height: 100vh;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
background: linear-gradient(135deg,
|
|
var(--vscode-editor-background) 0%,
|
|
color-mix(in srgb, var(--vscode-editor-background) 85%, var(--vscode-button-background) 15%) 50%,
|
|
color-mix(in srgb, var(--vscode-editor-background) 90%, var(--vscode-button-background) 10%) 100%);
|
|
}
|
|
.container {
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: center;
|
|
align-items: center;
|
|
text-align: center;
|
|
padding: 20px;
|
|
}
|
|
.container img {
|
|
margin-bottom: 16px;
|
|
}
|
|
.container h2 {
|
|
margin: 0 0 16px 0;
|
|
}
|
|
.btn {
|
|
width: 200px;
|
|
padding: 8px 12px;
|
|
margin: 4px 0;
|
|
background: var(--vscode-button-background);
|
|
color: var(--vscode-button-foreground);
|
|
border: none;
|
|
border-radius: 4px;
|
|
cursor: pointer;
|
|
text-align: center;
|
|
}
|
|
.btn:hover {
|
|
background: var(--vscode-button-hoverBackground);
|
|
}
|
|
h3 {
|
|
margin: 0 0 8px 0;
|
|
font-size: 12px;
|
|
color: var(--vscode-descriptionForeground);
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<img src="${logoUri}" alt="IC Coder" width="120" />
|
|
<h2>欢迎使用 IC Coder</h2>
|
|
<button class="btn" onclick="openChat()">开始创作</button>
|
|
</div>
|
|
|
|
<script>
|
|
const vscode = acquireVsCodeApi();
|
|
|
|
function openChat() {
|
|
vscode.postMessage({ command: 'openChat' });
|
|
}
|
|
|
|
function generateCode(type) {
|
|
const code = getCodeTemplate(type);
|
|
vscode.postMessage({
|
|
command: 'insertCode',
|
|
code: code
|
|
});
|
|
}
|
|
|
|
function getCodeTemplate(type) {
|
|
const templates = {
|
|
counter: \`module counter #(
|
|
parameter WIDTH = 4
|
|
)(
|
|
input wire clk,
|
|
input wire rst_n,
|
|
input wire enable,
|
|
output reg [WIDTH-1:0] count
|
|
);
|
|
always @(posedge clk or negedge rst_n) begin
|
|
if (!rst_n) begin
|
|
count <= 0;
|
|
end else if (enable) begin
|
|
count <= count + 1;
|
|
end
|
|
end
|
|
endmodule\`,
|
|
fsm: \`module fsm (
|
|
input wire clk,
|
|
input wire rst_n,
|
|
input wire start,
|
|
output reg done
|
|
);
|
|
parameter IDLE = 2'b00;
|
|
parameter STATE1 = 2'b01;
|
|
parameter STATE2 = 2'b10;
|
|
|
|
reg [1:0] state, next_state;
|
|
|
|
always @(posedge clk or negedge rst_n) begin
|
|
if (!rst_n) begin
|
|
state <= IDLE;
|
|
end else begin
|
|
state <= next_state;
|
|
end
|
|
end
|
|
|
|
always @(*) begin
|
|
case (state)
|
|
IDLE: next_state = start ? STATE1 : IDLE;
|
|
STATE1: next_state = STATE2;
|
|
STATE2: next_state = IDLE;
|
|
default: next_state = IDLE;
|
|
endcase
|
|
end
|
|
|
|
assign done = (state == STATE2);
|
|
endmodule\`,
|
|
fifo: \`module sync_fifo #(
|
|
parameter DATA_WIDTH = 8,
|
|
parameter DEPTH = 16
|
|
)(
|
|
input wire clk,
|
|
input wire rst_n,
|
|
input wire wr_en,
|
|
input wire [DATA_WIDTH-1:0] din,
|
|
input wire rd_en,
|
|
output reg [DATA_WIDTH-1:0] dout,
|
|
output wire full,
|
|
output wire empty
|
|
);
|
|
reg [DATA_WIDTH-1:0] mem [0:DEPTH-1];
|
|
reg [$clog2(DEPTH):0] wr_ptr, rd_ptr;
|
|
|
|
assign full = (wr_ptr == rd_ptr + DEPTH);
|
|
assign empty = (wr_ptr == rd_ptr);
|
|
|
|
always @(posedge clk) begin
|
|
if (!rst_n) wr_ptr <= 0;
|
|
else if (wr_en && !full) begin
|
|
mem[wr_ptr] <= din;
|
|
wr_ptr <= wr_ptr + 1;
|
|
end
|
|
end
|
|
|
|
always @(posedge clk) begin
|
|
if (!rst_n) begin
|
|
rd_ptr <= 0;
|
|
dout <= 0;
|
|
end else if (rd_en && !empty) begin
|
|
dout <= mem[rd_ptr];
|
|
rd_ptr <= rd_ptr + 1;
|
|
end
|
|
end
|
|
endmodule\`
|
|
};
|
|
return templates[type] || '// 代码模板';
|
|
}
|
|
</script>
|
|
</body>
|
|
</html>
|
|
`;
|
|
}
|
|
}
|