✨ feat(vscode): 预览里代码的上色和卡片种类色跟着当前颜色主题走

This commit is contained in:
cruldra committed 2026-10-13 11:27:24 +11:00
1 parent 19302bbed0
commit dff38ee0c5
26 files changed
+1286 -75

No files matched your search

@@ -3,6 +3,7 @@ import type { DiffBase, OpenedFrom } from '../diff/diffBase'
import type { ProfileChoice } from '../qa/askProfiles'
import type { RewriteRequest } from '../qa/codeQa'
import type { SymbolNode } from '../symbolLinks'
import type { CodeColors } from '../theme/codeColors'
import type { ExtensionToWebview, WebviewToExtension } from './messages'
import { describe, expect, it, vi } from 'vitest'
import { window, workspace } from 'vscode'
@@ -62,6 +63,7 @@ function preview(rewrite: (uri: unknown, request: RewriteRequest) => Promise<str
{},
{},
{ subscribe },
{ subscribe },
async () => [],
qa,
async () => [],
@@ -162,8 +164,27 @@ function profileSet(selected: string) {
}
}
const COLORS = { roles: { keyword: '#C586C0' }, kinds: { loop: '#C586C0' } } as unknown as CodeColors
/** 共用的代码配色:眼下是 colors,publish 模拟换了颜色主题、通知订阅的预览 */
function themeColors(colors: CodeColors) {
const listeners = new Set<(value: CodeColors) => void>()
let current = colors
return {
current: async () => current,
subscribe: (listener: (value: CodeColors) => void) => {
listeners.add(listener)
return { dispose: () => listeners.delete(listener) }
},
publish: (value: CodeColors) => {
current = value
listeners.forEach(listener => listener(value))
},
}
}
/** 对比基准只认从「未提交的更改」点开的:从那儿点开的对比上一次提交,别处打开的不比 */
function opening(profiles = { ask: profileSet(''), rewrite: profileSet('') }) {
function opening(profiles = { ask: profileSet(''), rewrite: profileSet('') }, colors = themeColors(COLORS)) {
const subscribe = () => ({ dispose: () => {} })
const diffBase = vi.fn((_uri: unknown, from: OpenedFrom): DiffBase | undefined => from === 'uncommitted' ? HEAD_BASE : undefined)
const qa = {
@@ -179,6 +200,7 @@ function opening(profiles = { ask: profileSet(''), rewrite: profileSet('') }) {
{},
{},
{ subscribe, current: { excluded: {}, onlyChanges: false } },
colors,
async () => [],
qa,
async () => [],
@@ -314,6 +336,28 @@ describe('预览对比什么看这个标签页是从哪儿打开的', () => {
})
})
describe('代码配色跟着当前颜色主题', () => {
it('ready 后先于第一份文档发;换了主题发给 ready 了的预览,还没 ready 的等 ready 时发眼下的', async () => {
const colors = themeColors(COLORS)
const { provider, document } = opening(undefined, colors)
const page = tab()
provider.resolveCustomTextEditor(document as never, page.panel)
const light = { roles: { keyword: '#AF00DB' }, kinds: { loop: '#AF00DB' } } as unknown as CodeColors
colors.publish(light)
expect(page.posted()).toEqual([])
await page.send({ type: 'ready' })
const types = page.posted().map(message => message.type)
expect(page.posted()).toContainEqual({ type: 'codeColors', ...light })
expect(types.indexOf('codeColors')).toBeGreaterThanOrEqual(0)
expect(types.indexOf('codeColors')).toBeLessThan(types.indexOf('document'))
page.clear()
colors.publish(COLORS)
expect(page.posted()).toEqual([{ type: 'codeColors', ...COLORS }])
})
})
describe('问 AI 和重写注释的 profile 下拉各管各的', () => {
it('ready 后两套各发一次;哪一套变了只发哪一套', async () => {
const profiles = { ask: profileSet('sonnet'), rewrite: profileSet('dsflash') }