【发布时间】:2022-11-18 07:35:09
【问题描述】:
我在我的扩展中添加了我自己的资源管理器视图。 在这里我添加了节点/树视图项目但是我没有找到任何方法来自定义和选择资源管理器视图中树视图项目的颜色。 知道如何实现这一目标吗? 应该有一些方法,因为当某个文件有错误时,它的颜色被设置为与其他打开的文件不同。
【问题讨论】:
标签: visual-studio-code vscode-extensions
我在我的扩展中添加了我自己的资源管理器视图。 在这里我添加了节点/树视图项目但是我没有找到任何方法来自定义和选择资源管理器视图中树视图项目的颜色。 知道如何实现这一目标吗? 应该有一些方法,因为当某个文件有错误时,它的颜色被设置为与其他打开的文件不同。
【问题讨论】:
标签: visual-studio-code vscode-extensions
[我假设这是你的 github 问题:Not able to use FileDecorationProvider for tree view item。]
这是我对自定义 TreeView 使用 FileDecorationProvider 的尝试。需要注意的是,我是 typescript 和 FileDecorations 的新手。
如果您看过Support proposed DecorationProvider api on custom views,您就会知道使用FileDecorationProvider 为TreeItem 着色是有限制的——主要是装饰/着色不能限于您的树视图——无论resourceUri apeears,就像在资源管理器中一样,您的 fileDecoration 将被应用。这是非常不幸的,但我认为目前没有任何方法可以避免这种情况。
首先,在你的TreeItem课程中,你必须给你想要装饰的任何物品一个resourceUri。像这样:
export class TreeTab extends vscode.TreeItem {
constructor( public readonly tab: vscode.Tab, public index: number = 0 ) {
super(tab.label, vscode.TreeItemCollapsibleState.None);
this.tab = tab;
if (tab.input instanceof vscode.TabInputText) {
this.resourceUri = tab.input.uri;
}
}
忽略我的扩展代码的细节,重点是:
this.resourceUri = <some vscode.Uri>;
其次,这就是我设置 FileDecoration 类的方式:
import {window, Tab, TabInputText, Uri, Disposable, Event, EventEmitter, FileDecoration, FileDecorationProvider, ThemeColor} from 'vscode';
export class TreeFileDecorationProvider implements FileDecorationProvider {
private disposables: Array<Disposable> = [];
private readonly _onDidChangeFileDecorations: EventEmitter<Uri | Uri[]> = new EventEmitter< Uri | Uri[]>();
readonly onDidChangeFileDecorations: Event<Uri | Uri[]> = this._onDidChangeFileDecorations.event;
constructor() {
this.disposables = [];
this.disposables.push(window.registerFileDecorationProvider(this));
}
async updateActiveEditor(activeTab: Tab): Promise<void> {
if (activeTab.input instanceof TabInputText)
this._onDidChangeFileDecorations.fire(activeTab.input.uri);
// filter to get only non-activeTabs
activeTab.group.tabs.map( tab => {
if (!tab.isActive && tab.input instanceof TabInputText)
this._onDidChangeFileDecorations.fire(tab.input.uri);
});
}
async provideFileDecoration(uri: Uri): Promise<FileDecoration | undefined> {
const activeEditor = window.activeTextEditor.document.uri;
if (uri.fsPath === activeEditor.fsPath) {
return {
badge: "⇐",
color: new ThemeColor("charts.red"),
// color: new vscode.ThemeColor("tab.activeBackground"),
// tooltip: ""
};
}
else return null; // to get rid of the custom fileDecoration
}
dispose() {
this.disposables.forEach((d) => d.dispose());
}
}
provideFileDecoration(uri: Uri) 进行实际的装饰。它只找到某些文件并修饰它们,并通过返回 null 重置以前修饰的 uri(由 uri 参数提供)。
updateActiveEditor() 是一个导出方法,当我想更改文件装饰时,我会在扩展的其他部分调用它。所以在其他地方我在另一个文件中有这个:
import { TreeFileDecorationProvider } from './fileDecorator';
export class EditorManager {
public TreeItemDecorator: TreeFileDecorationProvider;
// and then on a listener that gets triggered when I need to make a change to some things including the FileDecoration for a uri
this.TreeItemDecorator.updateActiveEditor(activeTab);
this.TreeItemDecorator.updateActiveEditor(activeTab);调用TreeFileDecorationProvider类中的updateActiveEditor方法,该类调用this._onDidChangeFileDecorations.fire(<some uri>);方法用于需要应用装饰的uri以及需要移除装饰的uri。
this._onDidChangeFileDecorations.fire(<some uri>); 将调用 provideFileDecoration(uri: Uri),根据该 uri 的某些状态应用或删除实际装饰。
onDidChangeFileDecorations()(如果您不需要像我那样对 uri 进行任何预处理。我只是还没想到还不知道如何构造该函数的参数。也许有人会在这一点上提供帮助。
你可以在这里看到:
color: new ThemeColor("charts.red"),
// color: new vscode.ThemeColor("tab.activeBackground"),
如何选择颜色 - 它必须是一些ThemeColor。 charts主题色有几个基本色,方便参考。参见theme color references, Charts therein。
badge 选项最多可以包含 2 个字符,但如您所见,我为自己复制/粘贴了一个 unicode 字符,并且有效。
正如我提到的,我的 FileDecorationProvider 是从 eventListener 调用的,但对于您的用例,您可能不需要它 - 如果装饰不必像我的情况那样根据用户操作添加和删除。因此,您可以直接从您的 extension.ts activate() 呼叫您的 FileDecorationProvider,如下所示:
import * as vscode from 'vscode';
import { TreeFileDecorationProvider } from './fileDecorator';
export async function activate(context: vscode.ExtensionContext) {
new TreeFileDecorationProvider();
}
其他参考:
【讨论】: