如何在 vscode 中实现忙碌指示器?
How to implement a busy indicator in vscode?
对于一个较长的 运行 过程,我想在 Visual Studio 代码中显示一个繁忙的指示器。拥有类似打字稿扩展使用的东西就足够了:
但是,使用正常的状态栏项目并没有像预期的那样工作。我什至无法在开始操作之前立即显示该项目,因为它似乎需要将控制权返回给 vscode。
我试过的是这样的:
...
busyIndicator = window.createStatusBarItem(StatusBarAlignment.Left, 1000);
busyIndicator.text = "##";
busyIndicator.show();
...
workspace.onDidSaveTextDocument((doc: TextDocument) => {
if (doc.languageId === "antlr") {
//busyIndicator.show();
busyIndicator.text = "X";
let tempPath = Utils.createTempFolder();
let result = backend.generate(doc.fileName, { outputDir: tempPath, listeners: false, visitors: false });
Utils.deleteFolderRecursive(tempPath);
//busyIndicator.hide();
busyIndicator.text = "Y";
}
});
永远不会显示值 X,并且在操作结束时出现 Y(如预期的那样)。如果连一个简单的文本更新都不起作用,我怎么能显示动画呢?
没有已发布的 API 类似于 Tasks
所做的(在 StatusBar 中显示旋转)。但是查看 VSCode 源代码,特别是 task.contributions.ts
你可以看到它结合了 setInterval
和 EventEmitter
来处理 progress 和 状态栏更新.
Webpack Progress extension 是如何执行此操作的一个很好的示例。
基本上,您必须创建希望更新 StatusBar 的时间间隔。这里将是您的 backend
进程监控:
initializeWacher() {
this.timer = setInterval(() => {
this.progress++;
fs.stat(tempPath, (err, state) => {
if(err && err.code === "ENOENT") {
this.emit("progressFinish")
} else {
this.emit("progressChange", this.percentage)
}
});
}, 300);
}
处理间隔发出的事件:
watcher.initializeWacher();
watcher.on("progressChange", (progress) => {
progress.updateProgress(progress);
});
watcher.on("progressFinish", () => {
progress.finishProgress();
watcher.dispose();
});
并在事件发生时更新 StatusBar(旋转本身):
private static progressChars: string = '|/-\';
...
updateProgress(percentage) {
...
let index = percentage % BusyIndicatorItem.progressChars.length;
let chars = BusyIndicatorItem.progressChars.charAt(index);
busyIndicator.text = "Backend processing " + chars;
}
finishProgress() {
this.statusBarItem.text = "Backend finished";
}
现在看到 https://code.visualstudio.com/updates/v1_22#_show-long-running-operations-as-notifications-with-cancellation-support 不是状态栏而是通知。
**
Show long running operations as notifications with cancellation
support
**
We added a new API to show long running operations in the Notification
Center with optional cancellation support. The benefits of showing
long running operations here are: Multiple operations can report
progress at the same time. You can show operation progress. The user
has the option to cancel the operation.
Call window.withProgress
with the new progress location
ProgressLocation.Notification
. Set cancellable to true to show a
cancel button and check for cancellation on the provided
CancellationToken
in the callback. To display progress, leverage the
increment value when reporting progress. See the progress sample for
an extension using this new API.
我无法弄清楚何时添加了对在状态栏中使用 withProgress
的支持,但我今天可以执行以下操作。
编辑 我发现添加对此的支持时是 2017 年 4 月。请参阅 vscode 发行说明 here
vscode.window.withProgress({
location: vscode.ProgressLocation.Window,
cancellable: false,
title: 'Loading customers'
}, async (progress) => {
progress.report({ increment: 0 });
await Promise.resolve();
progress.report({ increment: 100 });
});
在下图中查看实际效果
对于一个较长的 运行 过程,我想在 Visual Studio 代码中显示一个繁忙的指示器。拥有类似打字稿扩展使用的东西就足够了:
但是,使用正常的状态栏项目并没有像预期的那样工作。我什至无法在开始操作之前立即显示该项目,因为它似乎需要将控制权返回给 vscode。
我试过的是这样的:
...
busyIndicator = window.createStatusBarItem(StatusBarAlignment.Left, 1000);
busyIndicator.text = "##";
busyIndicator.show();
...
workspace.onDidSaveTextDocument((doc: TextDocument) => {
if (doc.languageId === "antlr") {
//busyIndicator.show();
busyIndicator.text = "X";
let tempPath = Utils.createTempFolder();
let result = backend.generate(doc.fileName, { outputDir: tempPath, listeners: false, visitors: false });
Utils.deleteFolderRecursive(tempPath);
//busyIndicator.hide();
busyIndicator.text = "Y";
}
});
永远不会显示值 X,并且在操作结束时出现 Y(如预期的那样)。如果连一个简单的文本更新都不起作用,我怎么能显示动画呢?
没有已发布的 API 类似于 Tasks
所做的(在 StatusBar 中显示旋转)。但是查看 VSCode 源代码,特别是 task.contributions.ts
你可以看到它结合了 setInterval
和 EventEmitter
来处理 progress 和 状态栏更新.
Webpack Progress extension 是如何执行此操作的一个很好的示例。
基本上,您必须创建希望更新 StatusBar 的时间间隔。这里将是您的 backend
进程监控:
initializeWacher() {
this.timer = setInterval(() => {
this.progress++;
fs.stat(tempPath, (err, state) => {
if(err && err.code === "ENOENT") {
this.emit("progressFinish")
} else {
this.emit("progressChange", this.percentage)
}
});
}, 300);
}
处理间隔发出的事件:
watcher.initializeWacher();
watcher.on("progressChange", (progress) => {
progress.updateProgress(progress);
});
watcher.on("progressFinish", () => {
progress.finishProgress();
watcher.dispose();
});
并在事件发生时更新 StatusBar(旋转本身):
private static progressChars: string = '|/-\';
...
updateProgress(percentage) {
...
let index = percentage % BusyIndicatorItem.progressChars.length;
let chars = BusyIndicatorItem.progressChars.charAt(index);
busyIndicator.text = "Backend processing " + chars;
}
finishProgress() {
this.statusBarItem.text = "Backend finished";
}
现在看到 https://code.visualstudio.com/updates/v1_22#_show-long-running-operations-as-notifications-with-cancellation-support 不是状态栏而是通知。
**
Show long running operations as notifications with cancellation support
**
We added a new API to show long running operations in the Notification Center with optional cancellation support. The benefits of showing long running operations here are: Multiple operations can report progress at the same time. You can show operation progress. The user has the option to cancel the operation.
Call
window.withProgress
with the new progress locationProgressLocation.Notification
. Set cancellable to true to show a cancel button and check for cancellation on the providedCancellationToken
in the callback. To display progress, leverage the increment value when reporting progress. See the progress sample for an extension using this new API.
我无法弄清楚何时添加了对在状态栏中使用 withProgress
的支持,但我今天可以执行以下操作。
编辑 我发现添加对此的支持时是 2017 年 4 月。请参阅 vscode 发行说明 here
vscode.window.withProgress({
location: vscode.ProgressLocation.Window,
cancellable: false,
title: 'Loading customers'
}, async (progress) => {
progress.report({ increment: 0 });
await Promise.resolve();
progress.report({ increment: 100 });
});
在下图中查看实际效果