0
0
mirror of https://github.com/naturalcrit/homebrewery.git synced 2026-03-26 10:28:13 +00:00

this should fold

This commit is contained in:
Víctor Losada Hernández
2026-03-25 21:07:21 +01:00
parent 52f2f532a7
commit b45795fac2
3 changed files with 55 additions and 73 deletions

View File

@@ -10,6 +10,7 @@ import {
scrollPastEnd,
Decoration,
ViewPlugin,
WidgetType,
} from '@codemirror/view';
import { EditorState, Compartment } from '@codemirror/state';
import { foldGutter, foldKeymap, syntaxHighlighting, HighlightStyle } from '@codemirror/language';
@@ -97,6 +98,59 @@ const customHighlightPlugin = ViewPlugin.fromClass(
},
);
// ######################### FOLDING ###############################
import { foldService } from '@codemirror/language';
class FoldPreviewWidget extends WidgetType {
constructor(text) {
super();
this.text = text;
}
toDOM() {
console.log(this.text);
const span = document.createElement('span');
span.className = 'cm-fold-placeholder';
span.textContent = this.text;
return span;
}
}
const homebreweryFold = foldService.of((state, lineStart)=>{
const doc = state.doc;
const matcher = /^(?=\\page(?:break)?(?: *{[^\n{}]*})?$)/m;
const startLine = doc.lineAt(lineStart);
const prevLineText = startLine.number > 1 ? doc.line(startLine.number - 1).text : '';
if(startLine.number > 1 && !matcher.test(prevLineText)) return null;
let endLine = startLine.number;
while (endLine < doc.lines && !matcher.test(doc.line(endLine + 1).text)) {
endLine++;
}
if(endLine === startLine.number) return null;
let preview = '';
for (let i = startLine.number; i <= endLine; i++) {
const text = doc.line(i).text.trim();
if(text.length > 0) {
preview = text;
break;
}
}
if(!preview) preview = `Lines ${startLine.number}-${endLine}`;
preview = preview.replace('{', '').trim();
if(preview.length > 50) preview = `${preview.slice(0, 50)}...`;
preview = `${preview}`;
return { from: startLine.from, to: doc.line(endLine).to, placeholder: new FoldPreviewWidget(preview) };
});
// ######################### COMPONENT #############################
const CodeEditor = forwardRef(
@@ -174,6 +228,7 @@ const CodeEditor = forwardRef(
keymap.of(foldKeymap),
foldGutter(),
lineNumbers(),
homebreweryFold,
themeCompartment.of(themeExtension), // 👈 key line

View File

@@ -24,35 +24,6 @@
font-size: 16px;
}
/* Line numbers and gutters */
.cm-gutters {
background-color: #f0f0f0;
color: #555;
border-right: 1px solid #ddd;
}
/* Folding gutter */
.cm-foldGutter {
cursor: pointer;
color: grey;
font-weight: 600;
transition: background 0.1s;
&:hover {
background: #dddddd;
}
}
/* Active line */
.cm-activeLine {
background-color: #f5f5f5;
}
.cm-activeLineGutter {
background-color: #e0e0e0;
}
/* Flash animation for source moves */
.sourceMoveFlash .cm-line {
animation-name: sourceMoveAnimation;

View File

@@ -1,44 +0,0 @@
export default {
registerHomebreweryHelper : function(CodeMirror) {
CodeMirror.registerHelper('fold', 'homebrewerycss', function(cm, start) {
// BRACE FOLDING
const startMatcher = /\{[ \t]*$/;
const endMatcher = /\}[ \t]*$/;
const activeLine = cm.getLine(start.line);
if(activeLine.match(startMatcher)) {
const lastLineNo = cm.lastLine();
let end = start.line + 1;
let braceCount = 1;
while (end < lastLineNo) {
const curLine = cm.getLine(end);
if(curLine.match(startMatcher)) braceCount++;
if(curLine.match(endMatcher)) braceCount--;
if(braceCount == 0) break;
++end;
}
return {
from : CodeMirror.Pos(start.line, 0),
to : CodeMirror.Pos(end, cm.getLine(end).length)
};
}
// @import and data-url folding
const importMatcher = /^@import.*?;/;
const dataURLMatcher = /url\(.*?data\:.*\)/;
if(activeLine.match(importMatcher) || activeLine.match(dataURLMatcher)) {
return {
from : CodeMirror.Pos(start.line, 0),
to : CodeMirror.Pos(start.line, activeLine.length)
};
}
return null;
});
}
};