Skip to content

Commit b61b3ff

Browse files
committed
Add diff-aware color fallback to preserve compare highlighting
1 parent 84d6c9f commit b61b3ff

File tree

5 files changed

+82
-1
lines changed

5 files changed

+82
-1
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ Global (Settings UI or `settings.json`):
100100
- `csv.cellPadding` (number, default `4`): Vertical cell padding in pixels.
101101
- `csv.columnColorMode` (string, default `type`): `type` keeps CSV’s type-based column colors; `theme` uses your theme foreground color for all columns.
102102
- `csv.columnColorPalette` (string, default `default`): Type-color palette when `csv.columnColorMode` is `type`. `cool` biases colors toward greens/blues; `warm` biases colors toward oranges/reds.
103+
- `csv.diffUseThemeForeground` (boolean, default `true`): In compare/diff views, use theme foreground color so diff highlighting remains readable.
103104
- `csv.clickableLinks` (boolean, default `true`): Make URLs in cells clickable. Ctrl/Cmd+click to open links.
104105
- `csv.showTrailingEmptyRow` (boolean, default `true`): Show the extra empty row at the end of the table. Turn this off to hide that visual append row.
105106
- `csv.separatorMode` (string, default `extension`): Separator selection mode when no per-file override exists. `extension` uses extension mapping, `auto` detects from content first, `default` always uses `csv.defaultSeparator`.

package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,11 @@
140140
"default": "default",
141141
"description": "Type-color palette when csv.columnColorMode is 'type'. 'default' keeps the original palette, 'cool' biases colors toward greens/blues, and 'warm' biases colors toward oranges/reds."
142142
},
143+
"csv.diffUseThemeForeground": {
144+
"type": "boolean",
145+
"default": true,
146+
"description": "When CSV is opened in a diff/compare view, use the current theme foreground color for cell text so diff highlighting stays visible."
147+
},
143148
"csv.clickableLinks": {
144149
"type": "boolean",
145150
"default": true,

src/CsvEditorProvider.ts

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class CsvEditorController {
2828
private currentWebviewPanel: vscode.WebviewPanel | undefined;
2929
private document!: vscode.TextDocument;
3030
private separatorCache: { version: number; configKey: string; separator: string } | undefined;
31+
private isDiffContext = false;
3132

3233
constructor(private readonly context: vscode.ExtensionContext) {}
3334

@@ -61,6 +62,7 @@ class CsvEditorController {
6162
localResourceRoots: [vscode.Uri.file(path.join(this.context.extensionPath, 'media'))]
6263
};
6364

65+
this.refreshDiffContext(webviewPanel);
6466
this.updateWebviewContent();
6567

6668
if (webviewPanel.active) {
@@ -70,6 +72,10 @@ class CsvEditorController {
7072
webviewPanel.webview.postMessage({ type: 'focus' });
7173
webviewPanel.onDidChangeViewState(e => {
7274
if (e.webviewPanel.active) {
75+
const diffChanged = this.refreshDiffContext(e.webviewPanel);
76+
if (diffChanged) {
77+
this.updateWebviewContent();
78+
}
7379
e.webviewPanel.webview.postMessage({ type: 'focus' });
7480
CsvEditorProvider.currentActive = this;
7581
}
@@ -270,6 +276,54 @@ class CsvEditorController {
270276
return !!this.currentWebviewPanel?.active;
271277
}
272278

279+
private refreshDiffContext(webviewPanel: vscode.WebviewPanel): boolean {
280+
const next = this.isLikelyDiffContext(webviewPanel, this.document.uri);
281+
const changed = next !== this.isDiffContext;
282+
this.isDiffContext = next;
283+
return changed;
284+
}
285+
286+
private isLikelyDiffContext(webviewPanel: vscode.WebviewPanel, uri: vscode.Uri): boolean {
287+
if (uri.scheme === 'git') {
288+
return true;
289+
}
290+
291+
const title = webviewPanel.title || '';
292+
if (title.includes('↔')) {
293+
return true;
294+
}
295+
296+
const key = uri.toString();
297+
const tabGroups = (vscode.window as any)?.tabGroups?.all;
298+
if (!Array.isArray(tabGroups)) {
299+
return false;
300+
}
301+
for (const group of tabGroups) {
302+
const activeTab: any = group?.activeTab;
303+
const input: any = activeTab?.input;
304+
const original: unknown = input?.original;
305+
const modified: unknown = input?.modified;
306+
if (original instanceof vscode.Uri && modified instanceof vscode.Uri) {
307+
if (original.toString() === key || modified.toString() === key) {
308+
return true;
309+
}
310+
}
311+
}
312+
return false;
313+
}
314+
315+
private static resolveEffectiveColumnColorMode(
316+
baseMode: string,
317+
isDiffContext: boolean,
318+
useThemeForegroundInDiff: boolean
319+
): 'type' | 'theme' {
320+
const normalizedBase: 'type' | 'theme' = baseMode === 'theme' ? 'theme' : 'type';
321+
if (isDiffContext && useThemeForegroundInDiff) {
322+
return 'theme';
323+
}
324+
return normalizedBase;
325+
}
326+
273327
public getDocumentUri(): vscode.Uri {
274328
return this.document.uri;
275329
}
@@ -974,7 +1028,13 @@ class CsvEditorController {
9741028
const data = this.trimTrailingEmptyRows((parsed.data || []) as string[][]);
9751029
const treatHeader = this.getEffectiveHeader(data, hiddenRows);
9761030
const clickableLinks = config.get<boolean>('clickableLinks', true);
977-
const columnColorMode = config.get<string>('columnColorMode', 'type');
1031+
const configuredColumnColorMode = config.get<string>('columnColorMode', 'type');
1032+
const diffUseThemeForeground = config.get<boolean>('diffUseThemeForeground', true);
1033+
const columnColorMode = CsvEditorController.resolveEffectiveColumnColorMode(
1034+
configuredColumnColorMode,
1035+
this.isDiffContext,
1036+
diffUseThemeForeground
1037+
);
9781038
const columnColorPalette = config.get<string>('columnColorPalette', 'default');
9791039
const showTrailingEmptyRow = config.get<boolean>('showTrailingEmptyRow', true);
9801040

@@ -2216,6 +2276,9 @@ export class CsvEditorProvider implements vscode.CustomTextEditorProvider {
22162276
const c: any = new (CsvEditorController as any)({} as any);
22172277
return c.getColumnColor(t, dark, i, palette);
22182278
},
2279+
resolveEffectiveColumnColorMode(baseMode: string, isDiffContext: boolean, diffUseThemeForeground: boolean): 'type' | 'theme' {
2280+
return (CsvEditorController as any).resolveEffectiveColumnColorMode(baseMode, isDiffContext, diffUseThemeForeground);
2281+
},
22192282
hslToHex(h: number, s: number, l: number): string {
22202283
const c: any = new (CsvEditorController as any)({} as any);
22212284
return c.hslToHex(h, s, l);

src/extension.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,9 @@ export function activate(context: vscode.ExtensionContext) {
9191
'csv.cellPadding',
9292
'csv.columnColorMode',
9393
'csv.columnColorPalette',
94+
'csv.diffUseThemeForeground',
9495
'csv.clickableLinks',
96+
'csv.showTrailingEmptyRow',
9597
'csv.separatorMode',
9698
'csv.defaultSeparator',
9799
'csv.separatorByExtension'

src/test/provider-utils.test.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,16 @@ describe('CsvEditorProvider utility methods', () => {
138138
assert.notStrictEqual(def, warm);
139139
});
140140

141+
it('resolves effective column color mode for diff contexts', () => {
142+
const resolveMode = CsvEditorProvider.__test.resolveEffectiveColumnColorMode;
143+
assert.strictEqual(resolveMode('type', false, true), 'type');
144+
assert.strictEqual(resolveMode('theme', false, true), 'theme');
145+
assert.strictEqual(resolveMode('type', true, true), 'theme');
146+
assert.strictEqual(resolveMode('theme', true, true), 'theme');
147+
assert.strictEqual(resolveMode('type', true, false), 'type');
148+
assert.strictEqual(resolveMode('invalid', false, false), 'type');
149+
});
150+
141151
it('hslToHex converts known colors', () => {
142152
const hslToHex = CsvEditorProvider.__test.hslToHex;
143153
assert.strictEqual(hslToHex(0, 100, 50), '#ff0000'); // red

0 commit comments

Comments
 (0)