mirror of
https://github.com/l0ng-ai/openidea.git
synced 2026-11-06 08:07:49 +00:00
fix(vcs): follow the editor font settings in diff and merge viewers (#253)
The VCS viewers (diff, merge, local history) hard-coded the default mono font, size and line height, so Settings > Editor > Font had no effect on them. Read the editor font variables like the main editor does, and apply fontExtension next to the caret, kept in step with the settings. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { EditorState } from "@codemirror/state";
|
||||
import { EditorView } from "@codemirror/view";
|
||||
import { useProject } from "@/platform/project";
|
||||
import type { Settings } from "@/platform/ipc";
|
||||
import { viewerBase } from "../cm";
|
||||
|
||||
const previous = useProject.getState().settings;
|
||||
const views: EditorView[] = [];
|
||||
|
||||
afterEach(() => {
|
||||
views.splice(0).forEach((v) => v.destroy());
|
||||
useProject.setState({ settings: previous });
|
||||
});
|
||||
|
||||
const setEditor = (editor: object) => useProject.setState({ settings: { editor } as unknown as Settings });
|
||||
|
||||
describe("viewer font", () => {
|
||||
it("follows the editor's font settings, also when they change", () => {
|
||||
setEditor({ fontFamily: "Fira Code", fontSize: 16, lineHeight: 22 });
|
||||
const view = new EditorView({
|
||||
state: EditorState.create({ doc: "a", extensions: viewerBase({ readOnly: true }) }),
|
||||
});
|
||||
views.push(view);
|
||||
const style = () => view.dom.style;
|
||||
expect(style().getPropertyValue("--openidea-editor-font")).toContain("Fira Code");
|
||||
expect(style().getPropertyValue("--openidea-editor-font-size")).toBe("16px");
|
||||
expect(style().getPropertyValue("--openidea-editor-line-height")).toBe("22px");
|
||||
expect(view.dom.classList.contains("cm-openidea-ligatures")).toBe(false);
|
||||
|
||||
setEditor({ fontSize: 11, ligatures: true });
|
||||
expect(style().getPropertyValue("--openidea-editor-font")).toBe("");
|
||||
expect(style().getPropertyValue("--openidea-editor-font-size")).toBe("11px");
|
||||
expect(view.dom.classList.contains("cm-openidea-ligatures")).toBe(true);
|
||||
});
|
||||
});
|
||||
+31
-8
@@ -8,6 +8,7 @@ import {
|
||||
EditorState,
|
||||
RangeSet,
|
||||
RangeSetBuilder,
|
||||
StateEffect,
|
||||
StateField,
|
||||
type Extension,
|
||||
type Line,
|
||||
@@ -30,6 +31,7 @@ import { search, searchKeymap } from "@codemirror/search";
|
||||
import { tags as t } from "@lezer/highlight";
|
||||
import { findExtension } from "@/editor/core/cm/find";
|
||||
import { caretExtension } from "@/editor/core/cm/prefs";
|
||||
import { fontExtension } from "@/editor/core/cm/setup";
|
||||
import { caretStyles, findLocals, findStyles } from "@/editor/core/cm/theme";
|
||||
import { editorPrefs } from "@/platform/editorSettings";
|
||||
import { useProject } from "@/platform/project";
|
||||
@@ -145,10 +147,16 @@ export const viewerTheme = EditorView.theme(
|
||||
height: "100%",
|
||||
backgroundColor: "var(--bg-app)",
|
||||
color: "var(--fg)",
|
||||
fontSize: "var(--fs-code)",
|
||||
fontSize: "var(--openidea-editor-font-size, var(--fs-code))",
|
||||
...findLocals,
|
||||
},
|
||||
".cm-scroller": { fontFamily: "var(--font-mono)", fontWeight: "var(--fw-code, 400)", lineHeight: "var(--lh-code)" },
|
||||
".cm-scroller": {
|
||||
fontFamily: "var(--openidea-editor-font, var(--font-mono))",
|
||||
fontWeight: "var(--fw-code, 400)",
|
||||
lineHeight: "var(--openidea-editor-line-height, var(--lh-code))",
|
||||
fontVariantLigatures: "none",
|
||||
},
|
||||
"&.cm-openidea-ligatures .cm-scroller": { fontVariantLigatures: "normal" },
|
||||
".cm-content": { caretColor: "var(--caret, var(--fg-strong))", WebkitUserSelect: "text", userSelect: "text" },
|
||||
...caretStyles,
|
||||
"&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground, .cm-selectionBackground, ::selection": {
|
||||
@@ -231,18 +239,33 @@ export const viewerTheme = EditorView.theme(
|
||||
);
|
||||
|
||||
const caretSlot = new Compartment();
|
||||
const fontSlot = new Compartment();
|
||||
|
||||
/** The editor's caret (Settings › Editor › General › Appearance), kept in step with the settings. */
|
||||
function viewerCaret(): Extension {
|
||||
const editorSettings = () => useProject.getState().settings?.editor;
|
||||
|
||||
/**
|
||||
* The editor's caret (Settings › Editor › General › Appearance) and font
|
||||
* (Settings › Editor › Font), kept in step with the settings.
|
||||
*/
|
||||
function viewerEditorLook(): Extension {
|
||||
return [
|
||||
caretSlot.of(caretExtension(editorPrefs())),
|
||||
fontSlot.of(fontExtension(editorSettings())),
|
||||
ViewPlugin.define((view) => {
|
||||
let appearance = editorPrefs().appearance;
|
||||
let editor = editorSettings();
|
||||
const unsubscribe = useProject.subscribe(() => {
|
||||
const effects: StateEffect<unknown>[] = [];
|
||||
const next = editorPrefs();
|
||||
if (JSON.stringify(next.appearance) === JSON.stringify(appearance)) return;
|
||||
appearance = next.appearance;
|
||||
view.dispatch({ effects: caretSlot.reconfigure(caretExtension(next)) });
|
||||
if (JSON.stringify(next.appearance) !== JSON.stringify(appearance)) {
|
||||
appearance = next.appearance;
|
||||
effects.push(caretSlot.reconfigure(caretExtension(next)));
|
||||
}
|
||||
if (editorSettings() !== editor) {
|
||||
editor = editorSettings();
|
||||
effects.push(fontSlot.reconfigure(fontExtension(editor)));
|
||||
}
|
||||
if (effects.length) view.dispatch({ effects });
|
||||
});
|
||||
return { destroy: unsubscribe };
|
||||
}),
|
||||
@@ -256,7 +279,7 @@ function viewerCaret(): Extension {
|
||||
export function viewerBase(opts: { readOnly: boolean; lineNumbers?: boolean; findBar?: boolean }): Extension[] {
|
||||
return [
|
||||
opts.lineNumbers === false ? [] : lineNumbers(),
|
||||
viewerCaret(),
|
||||
viewerEditorLook(),
|
||||
highlightActiveLine(),
|
||||
opts.findBar
|
||||
? [findExtension(), keymap.of(defaultKeymap)]
|
||||
|
||||
Reference in New Issue
Block a user