mirror of
https://github.com/naturalcrit/homebrewery.git
synced 2026-03-29 09:58:11 +00:00
this should fold
This commit is contained in:
@@ -10,6 +10,7 @@ import {
|
|||||||
scrollPastEnd,
|
scrollPastEnd,
|
||||||
Decoration,
|
Decoration,
|
||||||
ViewPlugin,
|
ViewPlugin,
|
||||||
|
WidgetType,
|
||||||
} from '@codemirror/view';
|
} from '@codemirror/view';
|
||||||
import { EditorState, Compartment } from '@codemirror/state';
|
import { EditorState, Compartment } from '@codemirror/state';
|
||||||
import { foldGutter, foldKeymap, syntaxHighlighting, HighlightStyle } from '@codemirror/language';
|
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 #############################
|
// ######################### COMPONENT #############################
|
||||||
|
|
||||||
const CodeEditor = forwardRef(
|
const CodeEditor = forwardRef(
|
||||||
@@ -174,6 +228,7 @@ const CodeEditor = forwardRef(
|
|||||||
keymap.of(foldKeymap),
|
keymap.of(foldKeymap),
|
||||||
foldGutter(),
|
foldGutter(),
|
||||||
lineNumbers(),
|
lineNumbers(),
|
||||||
|
homebreweryFold,
|
||||||
|
|
||||||
themeCompartment.of(themeExtension), // 👈 key line
|
themeCompartment.of(themeExtension), // 👈 key line
|
||||||
|
|
||||||
|
|||||||
@@ -24,35 +24,6 @@
|
|||||||
font-size: 16px;
|
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 */
|
/* Flash animation for source moves */
|
||||||
.sourceMoveFlash .cm-line {
|
.sourceMoveFlash .cm-line {
|
||||||
animation-name: sourceMoveAnimation;
|
animation-name: sourceMoveAnimation;
|
||||||
|
|||||||
@@ -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;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Reference in New Issue
Block a user