vscode多主题色功能实现机制

这篇具有很好参考价值的文章主要介绍了vscode多主题色功能实现机制。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

vscode的页面分为两部分,一部分是插件提供,一部分是主体。那么vscode在多主题实现上就要考虑把这两部分结合起来管理,相对来说要比单纯的网页实现多主题功能要复杂一些。

主体部分实现

我们先看下vscode主体部分样式是如何画出来了

registerThemingParticipant((theme, collector) => {
	const activitybarTextForeground = theme.getColor(foreground);
	if (activitybarTextForeground) {
		/**
		 * color --> vscode原生
		 * background-color --> 插件
		 */
		collector.addRule(`
			.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-item .action-label {
				color: ${activitybarTextForeground} !important;
			}
		`);
		...
	}

这是出于activitybar部分的样式代码,theme获取颜色,collector收集样式,最后都会插入到全局的style里面完成样式设置。

我们到getColor方法里面看下

src/vs/workbench/services/themes/common/colorThemeData.ts

public getColor(colorId: ColorIdentifier, useDefault?: boolean): Color | undefined {
	let color: Color | undefined = this.customColorMap[colorId];
	if (color) {
		return color;
	}
	color = this.colorMap[colorId];
	if (useDefault !== false && types.isUndefined(color)) {
		color = this.getDefault(colorId);
	}
	return color;
}

colorMap来至哪里呢,重点来了!
vscode的多主题其实都是通过主题插件来管理的
vscode多主题色功能实现机制,vscode,ide,编辑器
vscode多主题色功能实现机制,vscode,ide,编辑器
所有颜色都是取于themes目录下的json文件。

{
	"type": "dark",
	"colors": {
		"dropdown.background": "#525252",
		"list.activeSelectionBackground": "#707070",
		"quickInputList.focusBackground": "#707070",
		"list.inactiveSelectionBackground": "#4e4e4e",
		...
		}
	}	

这里面都是防止的颜色变量。

颜色的注册在大部分这个文件里面
src/vs/platform/theme/common/colorRegistry.ts

...
// 基础颜色
export const secondForeground = registerColor('second.foreground', { light: '#737373', dark: '#fff', hcDark: '#fff', hcLight: '#737373' }, nls.localize('secondForeground', "Color for text separators."));
...

vscode的主题大概分为四类深色主题、浅色主题、深色高亮主题、浅色高亮主题

所以这里设置了四个默认值,如果插件里面取不到值的话就会找默认值。

好,这里是主体部分的颜色设置,下面我们看看插件里面的颜色设置。

插件部分

.search-warapper .searchInput .search-btn {
	...
	background-color: var(--vscode-productMain-color);
}

插件部分使用的是css的var函数。

CSS var函数是一种自定义属性值的语法,用于插入自定义属性的值,而不是另一个属性的值的任何部分。它可以使您在不更改样式表的情况下更改样式,从而提高了可维护性和可重用性。 变量值继承至父类。

vscode多主题色功能实现机制,vscode,ide,编辑器
从主题插件里面获取到的样式全部写入了html的style里面。

这下就都懂了叭~

主题样式切换

vscode多主题色功能实现机制,vscode,ide,编辑器
唤醒颜色选择器
src/vs/workbench/contrib/themes/browser/themes.contribution.ts

override async run(accessor: ServicesAccessor) {
		const themeService = accessor.get(IWorkbenchThemeService);

		const installMessage = localize('installColorThemes', "Install Additional Color Themes...");
		const browseMessage = '$(plus) ' + localize('browseColorThemes', "Browse Additional Color Themes...");
		const placeholderMessage = localize('themes.selectTheme', "Select Color Theme (Up/Down Keys to Preview)");
		const marketplaceTag = 'category:themes';
		const setTheme = (theme: IWorkbenchTheme | undefined, settingsTarget: ThemeSettingTarget) => themeService.setColorTheme(theme as IWorkbenchColorTheme, settingsTarget);
		const getMarketplaceColorThemes = (publisher: string, name: string, version: string) => themeService.getMarketplaceColorThemes(publisher, name, version);

		const instantiationService = accessor.get(IInstantiationService);
		const picker = instantiationService.createInstance(InstalledThemesPicker, installMessage, browseMessage, placeholderMessage, marketplaceTag, setTheme, getMarketplaceColorThemes);

		const themes = await themeService.getColorThemes();
		const currentTheme = themeService.getColorTheme();

		const picks: QuickPickInput<ThemeItem>[] = [
			...toEntries(themes.filter(t => t.type === ColorScheme.LIGHT), localize('themes.category.light', "light themes")),
			...toEntries(themes.filter(t => t.type === ColorScheme.DARK), localize('themes.category.dark', "dark themes")),
			...toEntries(themes.filter(t => isHighContrast(t.type)), localize('themes.category.hc', "high contrast themes")),
		];
		await picker.openQuickPick(picks, currentTheme);
	}

上下选择的时候触发了这个事件

quickpick.onDidChangeActive(themes => selectTheme(themes[0]?.theme, false));

继续跟进去
src/vs/workbench/services/themes/browser/workbenchThemeService.ts

public setColorTheme(themeIdOrTheme: string | undefined | IWorkbenchColorTheme, settingsTarget: ThemeSettingTarget): Promise<IWorkbenchColorTheme | null> {
		return this.colorThemeSequencer.queue(async () => {
			return this.internalSetColorTheme(themeIdOrTheme, settingsTarget);
		});
	}
private async internalSetColorTheme(themeIdOrTheme: string | undefined | IWorkbenchColorTheme, settingsTarget: ThemeSettingTarget): Promise<IWorkbenchColorTheme | null> {
		if (!themeIdOrTheme) {
			return null;
		}
		const themeId = types.isString(themeIdOrTheme) ? validateThemeId(themeIdOrTheme) : themeIdOrTheme.id;
		if (this.currentColorTheme.isLoaded && themeId === this.currentColorTheme.id) {
			if (settingsTarget !== 'preview') {
				this.currentColorTheme.toStorage(this.storageService);
			}
			return this.settings.setColorTheme(this.currentColorTheme, settingsTarget);
		}

		let themeData = this.colorThemeRegistry.findThemeById(themeId);
		if (!themeData) {
			if (themeIdOrTheme instanceof ColorThemeData) {
				themeData = themeIdOrTheme;
			} else {
				return null;
			}
		}
		try {
			await themeData.ensureLoaded(this.extensionResourceLoaderService);
			themeData.setCustomizations(this.settings);
			return this.applyTheme(themeData, settingsTarget);
		} catch (error) {
			throw new Error(nls.localize('error.cannotloadtheme', "Unable to load {0}: {1}", themeData.location?.toString(), error.message));
		}

	}

看看在themeData.ensureLoade方法里面做了什么

src/vs/workbench/services/themes/common/colorThemeData.ts

public ensureLoaded(extensionResourceLoaderService: IExtensionResourceLoaderService): Promise<void> {
		return !this.isLoaded ? this.load(extensionResourceLoaderService) : Promise.resolve(undefined);
	}

	public reload(extensionResourceLoaderService: IExtensionResourceLoaderService): Promise<void> {
		return this.load(extensionResourceLoaderService);
	}

	private load(extensionResourceLoaderService: IExtensionResourceLoaderService): Promise<void> {
		if (!this.location) {
			return Promise.resolve(undefined);
		}
		this.themeTokenColors = [];
		this.clearCaches();

		const result = {
			colors: {},
			textMateRules: [],
			semanticTokenRules: [],
			semanticHighlighting: false
		};
		return _loadColorTheme(extensionResourceLoaderService, this.location, result).then(_ => {
			this.isLoaded = true;
			this.semanticTokenRules = result.semanticTokenRules;
			this.colorMap = result.colors; //生成colorMap
			this.themeTokenColors = result.textMateRules;
			this.themeSemanticHighlighting = result.semanticHighlighting;
		});
	}

上文中vscode主体部分colorMap就是在这里生成的

接着往下走

	private updateDynamicCSSRules(themeData: IColorTheme) {
		...
		themingRegistry.getThemingParticipants().forEach(p => p(themeData, ruleCollector, this.environmentService));

		const colorVariables: string[] = [];
		for (const item of getColorRegistry().getColors()) {
			const color = themeData.getColor(item.id, true);
			if (color) {
				colorVariables.push(`${asCssVariableName(item.id)}: ${color.toString()};`);
			}
		}
		ruleCollector.addRule(`.monaco-workbench { ${colorVariables.join('\n')} }`);

		_applyRules([...cssRules].join('\n'), colorThemeRulesClassName);
	}

这里的

themingRegistry.getThemingParticipants().forEach(p => p(themeData, ruleCollector, this.environmentService));

很重要,这里重新调用了样式收集器代码,重新放进了collector里面

registerThemingParticipant((theme, collector) => {
	const activitybarTextForeground = theme.getColor(foreground);
	if (activitybarTextForeground) {
		/**
		 * color --> vscode原生
		 * background-color --> 插件
		 */
		collector.addRule(`
			.monaco-workbench .activitybar > .content :not(.monaco-menu) > .monaco-action-bar .action-item .action-label {
				color: ${activitybarTextForeground} !important;
			}
		`);
		...
	}

src/vs/workbench/services/themes/browser/workbenchThemeService.ts

function _applyRules(styleSheetContent: string, rulesClassName: string) {
	const themeStyles = document.head.getElementsByClassName(rulesClassName);
	if (themeStyles.length === 0) {
		const elStyle = document.createElement('style');
		elStyle.type = 'text/css';
		elStyle.className = rulesClassName;
		elStyle.textContent = styleSheetContent;
		document.head.appendChild(elStyle);
	} else {
		(<HTMLStyleElement>themeStyles[0]).textContent = styleSheetContent;
	}
}

这里可以看到样式重新写入了style里。
主题切换完成!文章来源地址https://www.toymoban.com/news/detail-539842.html

兄弟萌给个关注奥

到了这里,关于vscode多主题色功能实现机制的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • IntelliJ IDE 插件开发 | (五)VFS 与编辑器

    IntelliJ IDE 插件开发 |(一)快速入门 IntelliJ IDE 插件开发 |(二)UI 界面与数据持久化 IntelliJ IDE 插件开发 |(三)消息通知与事件监听 IntelliJ IDE 插件开发 |(四)来查收你的 IDEA 使用报告吧 IntelliJ IDE 插件开发 |(五)VFS 与编辑器 在前几篇文章中主要介绍了关于 IntelliJ IDE 插

    2024年01月25日
    浏览(45)
  • C#时间轴曲线图形编辑器开发2-核心功能实现

    目录 三、关键帧编辑 1、新建Winform工程 (1)界面布局  (2)全局变量 2、关键帧添加和删除 (1)鼠标在曲线上识别 (2)键盘按键按下捕捉 (3)关键帧添加、删除  (4)修改关键帧值 3、曲线插值 (1)三次样条插值 (2)工程代码下载链接 四、曲线数据导出和读取 1、数

    2024年02月15日
    浏览(32)
  • IDE /Qt Creator 文本编辑器之文件编码设置

    在 Qt Creator 工具 - 选项 - 文本编辑器 - 行为选项卡中,存在一个叫作 “文件编码” 的配置项。其默认配置如下, 我是栽了不少坑之后,才理解到它的用途和作用方式的。这是一个有用的配置项,尤其是在使用 Qt Creator + MSVC 组成的集成开发环境时。我是在整理 《IDE/warning:

    2024年02月13日
    浏览(43)
  • 轻量级 IDE & 文本编辑器 Geany 发布 2.0

    导读 Geany 是功能强大、稳定、轻量的开发者专用文本编辑器,支持 Linux、Windows 和 macOS,内置支持 50 多种编程语言。 2005 年Geany 发布首个版本 0.1。上周四刚好是 Geany 诞生 18 周年纪念日,官方发布了 2.0 正式版以表庆祝。 下载地址:https://www.geany.org/download/releases/ Geany 2.0 主

    2024年02月07日
    浏览(30)
  • QT Creator更改主题和编辑器风格(附几款黑色主题免费下载)

    适用于qtcreator 打开Qt选择\\\"工具\\\"-\\\"选项\\\"; 2. 选择\\\"环境\\\"-\\\"Theme\\\"切换不同的主题风格 这里切换的是外边框的风格,如果编辑器中有同名的风格,编辑器的风格也会被切换  切换为dark风格 3. 选择\\\"文本编辑器\\\"后设置红色下拉框即可设置编辑器风格代码风格。 这里切换的是代码界面

    2024年02月05日
    浏览(46)
  • vscode多主题色功能实现机制

    vscode的页面分为两部分,一部分是插件提供,一部分是主体。那么vscode在多主题实现上就要考虑把这两部分结合起来管理,相对来说要比单纯的网页实现多主题功能要复杂一些。 主体部分实现 我们先看下vscode主体部分样式是如何画出来了 这是出于activitybar部分的样式代码,

    2024年02月13日
    浏览(15)
  • IDE + ChatGPT,这款编辑器真的做到可以自动写代码了

    介绍 Cursor 是集成了 GPT-4 的 IDE 工具,目前免费并且无需 API Key,支持 Win、Mac、Linux 平台,可以按要求生成代码,或者让 AI 帮助优化代码,分析代码。Cursor目前已经集成了openai的GPT-4,它或将彻底改变我们写代码的方式。 以前程序员被调侃是“CV”工程师,以后我们恐怕要成

    2023年04月25日
    浏览(34)
  • vue项目百度ueditor编辑器集成135和秀米,主题图标美化

    本文介绍vue项目里引入百度Ueditor富文本编辑器,集成135编辑器和秀米编辑器,使内容编辑更加丰富,跳转体验更加丝滑。再封装成组件,使用更加快捷。 编辑器主界面 弹框打开135编辑器 弹框打开秀米编辑器 操作说明:ueditor编辑器菜单栏集成135和秀米图标,点击分别弹框打

    2024年02月05日
    浏览(46)
  • 【Linux应用部署篇】在CSDN云IDE平台部署Etherpad文档编辑器

    官网网址:CSDN开发云IDE平台 CSDN云IDE平台是一个在线的集成开发环境,可用于编写、测试和部署代码。CSDN云IDE平台支持多种语言和框架,包括Java、Python、Node.js等,提供了丰富的编辑器、调试器和版本管理工具,帮助开发者快速创建和部署应用程序。CSDN云IDE平台在云端运行,

    2024年02月11日
    浏览(37)
  • vue代码编辑器vue-codemirror的简单使用更改样式和切换主题等

    可以查看官网演示:vue-codemirror | Homepage 支持的语言mode:CodeMirror: Language Modes  支持的主题样式:CodeMirror: Theme Demo  开始安装和使用:  基础使用 注册全局组件 注册局部组件 使用组件 实现的效果: 编辑器默认高度是300px,如果想更改高度和字体大小:添加样式  更改主题的

    2024年02月13日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包