Skip to content

Commit ebc26b3

Browse files
committed
fix: restore CM6 editor visual consistency with CM5 #4144
1 parent 291d438 commit ebc26b3

3 files changed

Lines changed: 81 additions & 6 deletions

File tree

client/modules/IDE/components/Editor/codemirror.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,16 @@ export default function useCodeMirror({
9999

100100
// When settings change, we pass those changes into CodeMirror.
101101
useEffect(() => {
102-
cmView.current.dom.style['font-size'] = `${fontSize}px`;
102+
const reconfigureEffect = (fileState) =>
103+
fileState.fontSizeCpt.reconfigure(
104+
EditorView.theme({ '&': { fontSize: `${fontSize}px` } })
105+
);
106+
updateFileStates({
107+
fileStates: fileStates.current,
108+
cmView: cmView.current,
109+
file,
110+
reconfigureEffect
111+
});
103112
}, [fontSize]);
104113
useEffect(() => {
105114
const reconfigureEffect = (fileState) =>
@@ -171,7 +180,8 @@ export default function useCodeMirror({
171180
autocomplete: autocompleteHinter,
172181
onUpdateLinting,
173182
onViewUpdate,
174-
referenceBaseUrl
183+
referenceBaseUrl,
184+
fontSize
175185
}
176186
);
177187
}

client/modules/IDE/components/Editor/stateUtils.js

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,14 @@ export const createAutocompleteOptions = (referenceBaseUrl) => ({
402402
]
403403
});
404404

405+
// Uses window.document explicitly to avoid shadowing by the `document`
406+
// parameter in createNewFileState below.
407+
function createFoldMarker(open) {
408+
const span = window.document.createElement('span');
409+
span.className = open ? 'cm-fold-open' : 'cm-fold-closed';
410+
return span;
411+
}
412+
405413
/**
406414
* Creates a new CodeMirror editor state with configurations,
407415
* extensions, and keymaps tailored to the file type and settings.
@@ -416,12 +424,14 @@ export function createNewFileState(filename, document, settings) {
416424
autocloseBracketsQuotes,
417425
onUpdateLinting,
418426
onViewUpdate,
419-
referenceBaseUrl
427+
referenceBaseUrl,
428+
fontSize
420429
} = settings;
421430
const lineNumbersCpt = new Compartment();
422431
const lineWrappingCpt = new Compartment();
423432
const closeBracketsCpt = new Compartment();
424433
const autocompleteCpt = new Compartment();
434+
const fontSizeCpt = new Compartment();
425435

426436
// Depending on the file mode, we have a different tidier function.
427437
// Keep this binding local to each file state so modes don't accumulate
@@ -469,6 +479,7 @@ export function createNewFileState(filename, document, settings) {
469479
// https://github.com/codemirror/basic-setup/blob/main/src/codemirror.ts
470480
const extensions = [
471481
// The first few extensions can be toggled on or off.
482+
fontSizeCpt.of(EditorView.theme({ '&': { fontSize: `${fontSize}px` } })),
472483
lineNumbersCpt.of(lineNumbers ? lineNumbersExt() : []),
473484
lineWrappingCpt.of(linewrap ? EditorView.lineWrapping : []),
474485
closeBracketsCpt.of(autocloseBracketsQuotes ? closeBrackets() : []),
@@ -495,7 +506,7 @@ export function createNewFileState(filename, document, settings) {
495506
EditorState.allowMultipleSelections.of(true),
496507
// Gutter extensions
497508
gutters({ fixed: false }),
498-
foldGutter(),
509+
foldGutter({ markerDOM: createFoldMarker }),
499510
// Misc extensions
500511
indentOnInput(),
501512
bracketMatching(),
@@ -557,7 +568,8 @@ export function createNewFileState(filename, document, settings) {
557568
lineNumbersCpt,
558569
lineWrappingCpt,
559570
closeBracketsCpt,
560-
autocompleteCpt
571+
autocompleteCpt,
572+
fontSizeCpt
561573
};
562574
}
563575

client/styles/components/_editor.scss

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,60 @@
155155
}
156156
}
157157

158-
// TODO: Add fold gutter styling back.
158+
// CM5: .CodeMirror-foldgutter-open, .CodeMirror-foldgutter-folded
159+
.cm-foldGutter {
160+
padding-right: #{math.div(3, $base-font-size)}rem;
161+
}
162+
163+
.cm-foldGutter .cm-gutterElement {
164+
cursor: pointer;
165+
// !important needed to override CM6's inline display style on gutter elements
166+
display: flex !important;
167+
align-items: center !important;
168+
justify-content: center !important;
169+
}
170+
171+
// CM5: .CodeMirror-foldgutter-open:after / .CodeMirror-foldgutter-folded:after
172+
.cm-fold-open,
173+
.cm-fold-closed {
174+
display: inline-block;
175+
width: #{math.div(10, $base-font-size)}rem;
176+
height: #{math.div(10, $base-font-size)}rem;
177+
background-size: #{math.div(10, $base-font-size)}rem #{math.div(10, $base-font-size)}rem;
178+
background-repeat: no-repeat;
179+
background-position: center center;
180+
opacity: 0.4;
181+
}
182+
183+
.cm-fold-open {
184+
@include themify() {
185+
background-image: getThemifyVariable('codefold-icon-open');
186+
}
187+
}
188+
189+
.cm-fold-closed {
190+
@include themify() {
191+
background-image: getThemifyVariable('codefold-icon-closed');
192+
}
193+
}
194+
195+
// CM5: .CodeMirror-foldmarker
196+
.cm-foldPlaceholder {
197+
display: inline-block;
198+
vertical-align: middle;
199+
height: 0.85em;
200+
line-height: 0.7;
201+
border-radius: 5px;
202+
padding: 0 #{math.div(5, $base-font-size)}rem;
203+
font-family: serif;
204+
cursor: pointer;
205+
opacity: 0.75;
206+
207+
@include themify() {
208+
background-color: getThemifyVariable('primary-text-color');
209+
color: getThemifyVariable('background-color');
210+
}
211+
}
159212

160213
.editor-holder {
161214
height: calc(100% - #{math.div(29, $base-font-size)}rem);

0 commit comments

Comments
 (0)