дзеркало
https://github.com/l0ng-ai/openidea.git
синхронізовано 2026-11-09 11:15:40 +02:00
fix(ui): Match PyCharm project view, matched tags and text weight
- Project widget initials follow IDEA's AvatarUtils.initials ("idea" → "I").
- "Show directories with changed descendants" is off by default, as in IDEA.
- FileEntry gains `excluded`: only excluded folders get the excluded icon and
dimming; git-ignored ones keep the plain icon and the ignored colour.
- `.github` folders get IDEA's GitHub folder icon.
- Matched tag names are never bold and use their own background
(MATCHED_TAG_NAME); matched braces are bold in dark schemes only.
- Revert Greyscale antialiasing to `antialiased` for UI and editor; `auto`
rendered text heavier than PyCharm.
Claude-Session: https://claude.ai/code/session_01SaPPsVPuk6ZTNsoUCNCbMv
Цей коміт міститься в:
1 джерело
cacddee19d
коміт
046fd37064
26 files changed
+143
-36
No files matched your search
@@ -2,8 +2,9 @@
|
||||
* The base extension set of every text editor, with compartments for the
|
||||
* parts that change at runtime (language, settings, contributions).
|
||||
*/
|
||||
import { Compartment, EditorState, Prec, type Extension } from "@codemirror/state";
|
||||
import { Compartment, EditorState, Prec, type Extension, type Range } from "@codemirror/state";
|
||||
import {
|
||||
Decoration,
|
||||
EditorView,
|
||||
dropCursor,
|
||||
highlightActiveLineGutter,
|
||||
@@ -11,7 +12,14 @@ import {
|
||||
keymap,
|
||||
lineNumbers,
|
||||
} from "@codemirror/view";
|
||||
import { bracketMatching, indentOnInput, indentUnit, syntaxHighlighting, type LanguageSupport } from "@codemirror/language";
|
||||
import {
|
||||
bracketMatching,
|
||||
indentOnInput,
|
||||
indentUnit,
|
||||
syntaxHighlighting,
|
||||
type LanguageSupport,
|
||||
type MatchResult,
|
||||
} from "@codemirror/language";
|
||||
import { defaultKeymap, history, historyKeymap, indentWithTab } from "@codemirror/commands";
|
||||
import { closeBrackets, closeBracketsKeymap } from "@codemirror/autocomplete";
|
||||
import { highlightSelectionMatches } from "@codemirror/search";
|
||||
@@ -172,11 +180,24 @@ export function stickyExtension(settings: EditorSettings | undefined): Extension
|
||||
return settings?.stickyScroll === false || isDistractionFree() ? [] : [stickyScroll, stickyMaxLines.of(prefsOf(settings).codeEditing.stickyLinesMax)];
|
||||
}
|
||||
|
||||
const matchingBracket = Decoration.mark({ class: "cm-matchingBracket" });
|
||||
const matchingTag = Decoration.mark({ class: "cm-matchingBracket cm-matchingTag" });
|
||||
const nonmatchingBracket = Decoration.mark({ class: "cm-nonmatchingBracket" });
|
||||
|
||||
/** Like the default, but matched tag names (HTML / XML / JSX) get their own mark, as IDEA's MATCHED_TAG_NAME. */
|
||||
function renderMatch(match: MatchResult, state: EditorState): readonly Range<Decoration>[] {
|
||||
const mark = (from: number, to: number) =>
|
||||
!match.matched ? nonmatchingBracket : /^[()[\]{}]$/.test(state.sliceDoc(from, to)) ? matchingBracket : matchingTag;
|
||||
const out = [mark(match.start.from, match.start.to).range(match.start.from, match.start.to)];
|
||||
if (match.end) out.push(mark(match.end.from, match.end.to).range(match.end.from, match.end.to));
|
||||
return out;
|
||||
}
|
||||
|
||||
export function heavyExtension(docLength: number, settings?: EditorSettings): Extension {
|
||||
if (docLength > HEAVY_LIMIT) return [];
|
||||
const prefs = prefsOf(settings);
|
||||
return [
|
||||
prefs.codeEditing.highlightBraces ? bracketMatching() : [],
|
||||
prefs.codeEditing.highlightBraces ? bracketMatching({ renderMatch }) : [],
|
||||
prefs.appearance.indentGuides ? indentGuides : [],
|
||||
prefs.codeEditing.highlightSelection ? highlightSelectionMatches({ minSelectionLength: 2, maxMatches: 500 }) : [],
|
||||
];
|
||||
|
||||
@@ -67,12 +67,17 @@ export const openideaTheme = EditorView.theme({
|
||||
},
|
||||
".cm-activeLine": { backgroundColor: "var(--editor-caret-row)" },
|
||||
".cm-selectionMatch": { backgroundColor: "var(--bg-identifier-under-caret, color-mix(in srgb, var(--fg) 9%, transparent))" },
|
||||
// IDEA's MATCHED_BRACE_ATTRIBUTES (bold in dark schemes only) and MATCHED_TAG_NAME (never bold).
|
||||
".cm-matchingBracket, &.cm-focused .cm-matchingBracket": {
|
||||
backgroundColor: "var(--editor-brace)",
|
||||
color: "inherit",
|
||||
fontWeight: "700",
|
||||
fontWeight: "var(--matched-brace-weight, 700)",
|
||||
borderRadius: "1px",
|
||||
},
|
||||
".cm-matchingTag, &.cm-focused .cm-matchingTag": {
|
||||
backgroundColor: "var(--bg-matched-tag, var(--editor-brace))",
|
||||
fontWeight: "inherit",
|
||||
},
|
||||
".cm-nonmatchingBracket, &.cm-focused .cm-nonmatchingBracket": {
|
||||
color: "var(--danger)",
|
||||
backgroundColor: "color-mix(in srgb, var(--danger) 14%, transparent)",
|
||||
|
||||
@@ -17,7 +17,7 @@ describe("navigation bar popup model", () => {
|
||||
});
|
||||
|
||||
it("lists folder children without IDE-hidden names, and symbol children", () => {
|
||||
const e = (name: string, kind: FileEntry["kind"]) => ({ name, path: `/p/${name}`, kind, size: 0, mtimeMs: 0, ignored: false, hidden: false }) as FileEntry;
|
||||
const e = (name: string, kind: FileEntry["kind"]) => ({ name, path: `/p/${name}`, kind, size: 0, mtimeMs: 0, ignored: false, excluded: false, hidden: false }) as FileEntry;
|
||||
expect(dirChildren([e(".git", "dir"), e("src", "dir"), e("a.ts", "file")]).map((c) => `${c.kind}:${c.label}`)).toEqual(["dir:src", "file:a.ts"]);
|
||||
expect(symbolChildren("/p/a.ts", [sym("A", [sym("b")])]).map((c) => c.label)).toEqual(["A"]);
|
||||
});
|
||||
|
||||
Reference in new issue
Заблокувати користувача