Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions src/modules/LeetcodeConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ export interface LeetcodeConfig {
agentPromptExplain?: string;
/** Rich webview vs plain text editor when opening a problem from sidebar lists. */
problemViewMode?: "ui" | "text";
/** Automatically apply LCEX font settings to the workspace when a .leetcode folder is present. */
applyWorkspaceFontSettings?: boolean;
/** The font family to apply when applyWorkspaceFontSettings is true. Defaults to 'Fira Code iScript'. */
editorFontFamily?: string;
/** Whether to apply cursive italic textMate rules for comments and keywords. Defaults to true. */
editorCursiveItalics?: boolean;
}

const DEFAULTS: Required<
Expand Down Expand Up @@ -77,6 +83,9 @@ const DEFAULTS: Required<
"Load **lcex-dsa-analyze** and follow it. Analyze my current LeetCode solution implementation.",
agentPromptExplain:
"Explain my solution code for this LeetCode problem. Respond with: (1) Intuition — core idea in plain language; (2) Step-by-step dry run — walk through the algorithm with a small example, including loop/state changes; (3) Time and space complexity with brief justification. Do not rewrite the full solution unless needed for clarity.",
applyWorkspaceFontSettings: false,
editorFontFamily: "Fira Code iScript",
editorCursiveItalics: true,
};

function isValidStudyPlanEntry(obj: unknown): obj is { slug: string; name: string } {
Expand Down Expand Up @@ -334,6 +343,15 @@ export function parseLeetcodeConfig(workspaceFolders: readonly vscode.WorkspaceF
if (parsed.problemViewMode === "ui" || parsed.problemViewMode === "text") {
merged.problemViewMode = parsed.problemViewMode;
}
if (parsed.applyWorkspaceFontSettings !== undefined && typeof parsed.applyWorkspaceFontSettings === "boolean") {
merged.applyWorkspaceFontSettings = parsed.applyWorkspaceFontSettings;
}
if (parsed.editorFontFamily !== undefined && typeof parsed.editorFontFamily === "string") {
merged.editorFontFamily = parsed.editorFontFamily;
}
if (parsed.editorCursiveItalics !== undefined && typeof parsed.editorCursiveItalics === "boolean") {
merged.editorCursiveItalics = parsed.editorCursiveItalics;
}
} catch (e) {
Logger.log(`LeetcodeConfig: failed to parse ${configPath}, using defaults: ${e}`);
}
Expand Down Expand Up @@ -390,5 +408,8 @@ export function getEffectiveConfig(
problemViewMode: normalizeProblemViewMode(
leetcode.problemViewMode ?? vscodeConfig.get<string>("problemViewMode")
),
applyWorkspaceFontSettings: leetcode.applyWorkspaceFontSettings ?? DEFAULTS.applyWorkspaceFontSettings,
editorFontFamily: leetcode.editorFontFamily ?? DEFAULTS.editorFontFamily,
editorCursiveItalics: leetcode.editorCursiveItalics ?? DEFAULTS.editorCursiveItalics,
};
}
37 changes: 27 additions & 10 deletions src/modules/LeetcodePracticeEditorSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import * as path from "path";
import * as vscode from "vscode";
import type { SupportedLanguage } from "./interface/Problem";
import * as Logger from "./Logger";
import { getEffectiveConfig } from "./LeetcodeConfig";

const MARKER = ".leetcode";

Expand Down Expand Up @@ -84,11 +85,18 @@ function workspaceJsonEqual(a: unknown, b: unknown): boolean {
}

/**
* Sets Fira Code iScript and italic token rules for LeetCode practice workspaces (folder with `.leetcode`).
* Sets the configured font and token rules for LeetCode practice workspaces (folder with `.leetcode`).
* Only writes workspace-level settings when they differ from the LCEX defaults.
*/
export async function applyLcexEditorFontAndTokenSettingsIfNeeded(): Promise<void> {
if (!workspaceHasLeetcodeMarker()) return;
const folders = vscode.workspace.workspaceFolders;
if (!folders?.length || !workspaceHasLeetcodeMarker()) return;

const lcexCfg = getEffectiveConfig(folders);
if (!lcexCfg.applyWorkspaceFontSettings) return;

const fontToApply = lcexCfg.editorFontFamily || "Fira Code iScript";

const editorCfg = vscode.workspace.getConfiguration("editor", null);
const target = vscode.ConfigurationTarget.Workspace;

Expand All @@ -97,21 +105,30 @@ export async function applyLcexEditorFontAndTokenSettingsIfNeeded(): Promise<voi
const tokenInspect = editorCfg.inspect<Record<string, unknown>>("tokenColorCustomizations");
const workspaceToken = tokenInspect?.workspaceValue ?? tokenInspect?.workspaceFolderValue;

const desiredToken = JSON.parse(JSON.stringify(LCEX_EDITOR_TOKEN_COLOR_CUSTOMIZATIONS)) as Record<
string,
unknown
>;
const needsFont = workspaceFont !== LCEX_EDITOR_FONT_FAMILY;
const needsToken = !workspaceJsonEqual(workspaceToken, desiredToken);
const needsFont = workspaceFont !== fontToApply;

// Only apply italic settings if the user has enabled them
let desiredToken: Record<string, unknown> = {};
let needsToken = false;
if (lcexCfg.editorCursiveItalics) {
desiredToken = JSON.parse(JSON.stringify(LCEX_EDITOR_TOKEN_COLOR_CUSTOMIZATIONS)) as Record<string, unknown>;
needsToken = !workspaceJsonEqual(workspaceToken, desiredToken);
} else if (workspaceToken && workspaceJsonEqual(workspaceToken, JSON.parse(JSON.stringify(LCEX_EDITOR_TOKEN_COLOR_CUSTOMIZATIONS)))) {
// If they were previously set by us, clear them out now that the font changed
needsToken = true;
desiredToken = {}; // or undefined, but VS Code API allows updating to {}
}

if (!needsFont && !needsToken) return;

try {
if (needsFont) {
await editorCfg.update("fontFamily", LCEX_EDITOR_FONT_FAMILY, target);
await editorCfg.update("fontFamily", fontToApply, target);
}
if (needsToken) {
await editorCfg.update("tokenColorCustomizations", desiredToken, target);
// update with {} clears the properties we set if there were no others,
// wait, updating with undefined deletes the setting entirely, which is better.
await editorCfg.update("tokenColorCustomizations", Object.keys(desiredToken).length > 0 ? desiredToken : undefined, target);
}
} catch (e) {
Logger.logError("LCEX editor font/token settings: failed to update workspace settings", e);
Expand Down