230 lines
6.9 KiB
JavaScript
230 lines
6.9 KiB
JavaScript
const vscode = require('vscode');
|
||
|
||
let flutterTerminal = null;
|
||
|
||
function getTerminal() {
|
||
if (!flutterTerminal || flutterTerminal.exitStatus !== undefined) {
|
||
flutterTerminal = vscode.window.createTerminal('Flutter');
|
||
}
|
||
return flutterTerminal;
|
||
}
|
||
|
||
function runCommand(cmd) {
|
||
const terminal = getTerminal();
|
||
terminal.show();
|
||
terminal.sendText(cmd);
|
||
}
|
||
|
||
async function selectBuildPlatform() {
|
||
const platforms = [
|
||
{ label: '$(device-mobile) APK (Android)', value: 'apk' },
|
||
{ label: '$(apple) IPA (iOS)', value: 'ios' },
|
||
{ label: '$(globe) Web', value: 'web' },
|
||
{ label: '$(window) Windows', value: 'windows' },
|
||
{ label: '$(vm) macOS', value: 'macos' },
|
||
{ label: '$(terminal) Linux', value: 'linux' }
|
||
];
|
||
const selected = await vscode.window.showQuickPick(platforms, {
|
||
placeHolder: '选择构建平台'
|
||
});
|
||
return selected ? selected.value : null;
|
||
}
|
||
|
||
async function selectDevice() {
|
||
const terminal = getTerminal();
|
||
terminal.show();
|
||
terminal.sendText('flutter devices');
|
||
vscode.window.showInformationMessage('请在终端查看可用设备,然后输入设备ID');
|
||
const deviceId = await vscode.window.showInputBox({
|
||
placeHolder: '输入设备ID(留空使用默认设备)',
|
||
title: '选择运行设备'
|
||
});
|
||
return deviceId || null;
|
||
}
|
||
|
||
async function startDebugRun(deviceId) {
|
||
const workspaceFolders = vscode.workspace.workspaceFolders;
|
||
if (!workspaceFolders || workspaceFolders.length === 0) {
|
||
vscode.window.showErrorMessage('请先打开一个 Flutter 项目');
|
||
return;
|
||
}
|
||
const folder = workspaceFolders[0];
|
||
const debugConfig = {
|
||
type: 'dart',
|
||
name: 'Flutter (Debug)',
|
||
request: 'launch',
|
||
program: 'lib/main.dart',
|
||
flutterMode: 'debug'
|
||
};
|
||
if (deviceId) {
|
||
debugConfig.deviceId = deviceId;
|
||
}
|
||
const started = await vscode.debug.startDebugging(folder, debugConfig);
|
||
if (!started) {
|
||
vscode.window.showErrorMessage('启动调试失败,请确保已安装 Dart 扩展');
|
||
}
|
||
}
|
||
|
||
async function startProfileRun() {
|
||
const workspaceFolders = vscode.workspace.workspaceFolders;
|
||
if (!workspaceFolders || workspaceFolders.length === 0) {
|
||
vscode.window.showErrorMessage('请先打开一个 Flutter 项目');
|
||
return;
|
||
}
|
||
const folder = workspaceFolders[0];
|
||
const debugConfig = {
|
||
type: 'dart',
|
||
name: 'Flutter (Profile)',
|
||
request: 'launch',
|
||
program: 'lib/main.dart',
|
||
flutterMode: 'profile'
|
||
};
|
||
const started = await vscode.debug.startDebugging(folder, debugConfig);
|
||
if (!started) {
|
||
vscode.window.showErrorMessage('启动 Profile 模式失败');
|
||
}
|
||
}
|
||
|
||
function activate(context) {
|
||
const provider = new FlutterRunnerProvider();
|
||
context.subscriptions.push(
|
||
vscode.window.registerTreeDataProvider('flutterRunner', provider)
|
||
);
|
||
|
||
context.subscriptions.push(
|
||
vscode.commands.registerCommand('flutterRunner.run', async () => {
|
||
const deviceId = await selectDevice();
|
||
await startDebugRun(deviceId);
|
||
})
|
||
);
|
||
|
||
context.subscriptions.push(
|
||
vscode.commands.registerCommand('flutterRunner.runDebug', async () => {
|
||
await startDebugRun();
|
||
})
|
||
);
|
||
|
||
context.subscriptions.push(
|
||
vscode.commands.registerCommand('flutterRunner.runProfile', async () => {
|
||
await startProfileRun();
|
||
})
|
||
);
|
||
|
||
context.subscriptions.push(
|
||
vscode.commands.registerCommand('flutterRunner.hotReload', () => {
|
||
vscode.commands.executeCommand('flutter.hotReload');
|
||
})
|
||
);
|
||
|
||
context.subscriptions.push(
|
||
vscode.commands.registerCommand('flutterRunner.hotRestart', () => {
|
||
vscode.commands.executeCommand('flutter.hotRestart');
|
||
})
|
||
);
|
||
|
||
context.subscriptions.push(
|
||
vscode.commands.registerCommand('flutterRunner.stopDebug', () => {
|
||
if (vscode.debug.activeDebugSession) {
|
||
vscode.debug.stopDebugging();
|
||
} else {
|
||
vscode.window.showInformationMessage('没有正在运行的调试会话');
|
||
}
|
||
})
|
||
);
|
||
|
||
context.subscriptions.push(
|
||
vscode.commands.registerCommand('flutterRunner.clean', () => {
|
||
runCommand('flutter clean');
|
||
})
|
||
);
|
||
|
||
context.subscriptions.push(
|
||
vscode.commands.registerCommand('flutterRunner.pubGet', () => {
|
||
runCommand('flutter pub get');
|
||
})
|
||
);
|
||
|
||
context.subscriptions.push(
|
||
vscode.commands.registerCommand('flutterRunner.build', async () => {
|
||
const platform = await selectBuildPlatform();
|
||
if (platform) {
|
||
runCommand(`flutter build ${platform}`);
|
||
}
|
||
})
|
||
);
|
||
|
||
context.subscriptions.push(
|
||
vscode.commands.registerCommand('flutterRunner.refresh', () => {
|
||
provider.refresh();
|
||
})
|
||
);
|
||
|
||
vscode.debug.onDidChangeActiveDebugSession((session) => {
|
||
provider.refresh();
|
||
});
|
||
}
|
||
|
||
class FlutterRunnerProvider {
|
||
constructor() {
|
||
this._onDidChangeTreeData = new vscode.EventEmitter();
|
||
this.onDidChangeTreeData = this._onDidChangeTreeData.event;
|
||
}
|
||
|
||
refresh() {
|
||
this._onDidChangeTreeData.fire();
|
||
}
|
||
|
||
getTreeItem(element) {
|
||
return element;
|
||
}
|
||
|
||
getChildren(element) {
|
||
if (!element) {
|
||
const isDebugging = !!vscode.debug.activeDebugSession;
|
||
const items = [
|
||
this.createButtonItem('▶️ Run (Debug)', 'flutterRunner.runDebug', '调试模式运行(支持热重载、断点、调试控制台)'),
|
||
this.createButtonItem('📱 Run (选择设备)', 'flutterRunner.run', '选择设备后调试运行'),
|
||
this.createButtonItem('📊 Run (Profile)', 'flutterRunner.runProfile', 'Profile 模式运行(性能分析)'),
|
||
this.createSectionItem('── 调试控制 ──'),
|
||
this.createButtonItem('🔥 Hot Reload', 'flutterRunner.hotReload', '热重载(保持状态)'),
|
||
this.createButtonItem('🔄 Hot Restart', 'flutterRunner.hotRestart', '热重启(重置状态)'),
|
||
this.createButtonItem('⏹️ Stop', 'flutterRunner.stopDebug', '停止调试会话'),
|
||
this.createSectionItem('── 项目命令 ──'),
|
||
this.createButtonItem('🧹 Clean', 'flutterRunner.clean', '清理构建缓存'),
|
||
this.createButtonItem('📦 Pub Get', 'flutterRunner.pubGet', '获取依赖'),
|
||
this.createButtonItem('🔨 Build', 'flutterRunner.build', '构建发布包')
|
||
];
|
||
if (isDebugging) {
|
||
items.unshift(this.createStatusItem('🟢 调试运行中'));
|
||
} else {
|
||
items.unshift(this.createStatusItem('⚪ 未运行'));
|
||
}
|
||
return items;
|
||
}
|
||
return [];
|
||
}
|
||
|
||
createButtonItem(label, command, tooltip) {
|
||
const item = new vscode.TreeItem(label, vscode.TreeItemCollapsibleState.None);
|
||
item.command = { command, title: label };
|
||
item.tooltip = tooltip;
|
||
return item;
|
||
}
|
||
|
||
createSectionItem(label) {
|
||
const item = new vscode.TreeItem(label, vscode.TreeItemCollapsibleState.None);
|
||
item.tooltip = label;
|
||
return item;
|
||
}
|
||
|
||
createStatusItem(label) {
|
||
const item = new vscode.TreeItem(label, vscode.TreeItemCollapsibleState.None);
|
||
item.tooltip = label;
|
||
return item;
|
||
}
|
||
}
|
||
|
||
function deactivate() {}
|
||
|
||
module.exports = { activate, deactivate };
|