修复 断点异常
This commit is contained in:
25
flutter-runner/README.md
Normal file
25
flutter-runner/README.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# Flutter Runner
|
||||
|
||||
Flutter 命令快捷按钮面板,在 VS Code 侧边栏提供一键执行 Flutter 命令的功能。
|
||||
|
||||
## 功能
|
||||
|
||||
- ▶️ **Run** - 运行 `flutter run`
|
||||
- 🧹 **Clean** - 运行 `flutter clean`
|
||||
- 📦 **Pub Get** - 运行 `flutter pub get`
|
||||
- 🔨 **Build** - 构建 APK/IPA/Web/Windows/macOS/Linux
|
||||
|
||||
## 安装
|
||||
|
||||
1. 复制 `flutter-runner` 文件夹到 VS Code 扩展目录
|
||||
2. 重启 VS Code
|
||||
|
||||
或使用命令行安装:
|
||||
```bash
|
||||
code --install-extension flutter-runner
|
||||
```
|
||||
|
||||
## 使用
|
||||
|
||||
1. 点击侧边栏 Flutter Runner 图标
|
||||
2. 点击对应按钮执行命令
|
||||
229
flutter-runner/extension.js
Normal file
229
flutter-runner/extension.js
Normal file
@@ -0,0 +1,229 @@
|
||||
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 };
|
||||
BIN
flutter-runner/flutter-runner-1.1.0.vsix
Normal file
BIN
flutter-runner/flutter-runner-1.1.0.vsix
Normal file
Binary file not shown.
112
flutter-runner/package.json
Normal file
112
flutter-runner/package.json
Normal file
@@ -0,0 +1,112 @@
|
||||
{
|
||||
"name": "flutter-runner",
|
||||
"displayName": "Flutter Runner",
|
||||
"description": "Flutter 命令快捷按钮面板,支持调试、热重载、热重启",
|
||||
"version": "1.1.0",
|
||||
"publisher": "mom-kitchen",
|
||||
"engines": {
|
||||
"vscode": "^1.74.0"
|
||||
},
|
||||
"categories": ["Other"],
|
||||
"activationEvents": ["onView:flutterRunner"],
|
||||
"main": "./extension.js",
|
||||
"contributes": {
|
||||
"viewsContainers": {
|
||||
"activitybar": [
|
||||
{
|
||||
"id": "flutter-runner",
|
||||
"title": "Flutter Runner",
|
||||
"icon": "resources/icon.svg"
|
||||
}
|
||||
]
|
||||
},
|
||||
"views": {
|
||||
"flutter-runner": [
|
||||
{
|
||||
"id": "flutterRunner",
|
||||
"name": "Commands"
|
||||
}
|
||||
]
|
||||
},
|
||||
"commands": [
|
||||
{
|
||||
"command": "flutterRunner.run",
|
||||
"title": "Flutter: Run (选择设备)",
|
||||
"icon": "$(device-mobile)"
|
||||
},
|
||||
{
|
||||
"command": "flutterRunner.runDebug",
|
||||
"title": "Flutter: Run Debug",
|
||||
"icon": "$(play)"
|
||||
},
|
||||
{
|
||||
"command": "flutterRunner.runProfile",
|
||||
"title": "Flutter: Run Profile",
|
||||
"icon": "$(graph)"
|
||||
},
|
||||
{
|
||||
"command": "flutterRunner.hotReload",
|
||||
"title": "Flutter: Hot Reload",
|
||||
"icon": "$(refresh)"
|
||||
},
|
||||
{
|
||||
"command": "flutterRunner.hotRestart",
|
||||
"title": "Flutter: Hot Restart",
|
||||
"icon": "$(sync)"
|
||||
},
|
||||
{
|
||||
"command": "flutterRunner.stopDebug",
|
||||
"title": "Flutter: Stop Debug",
|
||||
"icon": "$(debug-stop)"
|
||||
},
|
||||
{
|
||||
"command": "flutterRunner.clean",
|
||||
"title": "Flutter: Clean",
|
||||
"icon": "$(trash)"
|
||||
},
|
||||
{
|
||||
"command": "flutterRunner.pubGet",
|
||||
"title": "Flutter: Pub Get",
|
||||
"icon": "$(package)"
|
||||
},
|
||||
{
|
||||
"command": "flutterRunner.build",
|
||||
"title": "Flutter: Build",
|
||||
"icon": "$(gear)"
|
||||
}
|
||||
],
|
||||
"menus": {
|
||||
"view/title": [
|
||||
{
|
||||
"command": "flutterRunner.runDebug",
|
||||
"when": "view == flutterRunner",
|
||||
"group": "navigation@1"
|
||||
},
|
||||
{
|
||||
"command": "flutterRunner.hotReload",
|
||||
"when": "view == flutterRunner",
|
||||
"group": "navigation@2"
|
||||
},
|
||||
{
|
||||
"command": "flutterRunner.stopDebug",
|
||||
"when": "view == flutterRunner",
|
||||
"group": "navigation@3"
|
||||
}
|
||||
]
|
||||
},
|
||||
"keybindings": [
|
||||
{
|
||||
"command": "flutterRunner.hotReload",
|
||||
"key": "ctrl+f5",
|
||||
"mac": "cmd+f5",
|
||||
"when": "debugType == dart"
|
||||
},
|
||||
{
|
||||
"command": "flutterRunner.hotRestart",
|
||||
"key": "ctrl+shift+f5",
|
||||
"mac": "cmd+shift+f5",
|
||||
"when": "debugType == dart"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
3
flutter-runner/resources/icon.svg
Normal file
3
flutter-runner/resources/icon.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="#007AFF" stroke-width="2">
|
||||
<polygon points="5 3 19 12 5 21 5 3"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 155 B |
Reference in New Issue
Block a user