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

simplify fold export & restore legacy higlights

This commit is contained in:
Víctor Losada Hernández
2026-03-27 19:11:52 +01:00
parent 4da270616d
commit 4bce4a9489
7 changed files with 160 additions and 139 deletions

View File

@@ -24,16 +24,16 @@ import { autocompleteEmoji } from './autocompleteEmoji.js';
import { searchKeymap, search } from '@codemirror/search';
import * as themesImport from '@uiw/codemirror-themes-all';
import { defaultCM5Theme } from '@themes/codeMirror/customThemes/default.js';
import defaultCM5Theme from '@themes/codeMirror/customThemes/default.js';
const themes = { default: defaultCM5Theme, ...themesImport };
const themeCompartment = new Compartment();
const highlightCompartment = new Compartment();
import { customKeymap } from './customKeyMap.js';
import { homebreweryFold, hbFolding } from './customFolding.js';
import customKeymap from './customKeyMap.js';
import pageFoldExtension from './customFolding.js';
import { customHighlightStyle, tokenizeCustomMarkdown, tokenizeCustomCSS } from './customHighlight.js';
import { legacyCustomHighlightStyle, legacyTokenizeCustomMarkdown } from './legacyCustomHighlight.js'; //only makes highlight for
import { legacyCustomHighlightStyle, legacyTokenizeCustomMarkdown } from './legacyCustomHighlight.js';
const createHighlightPlugin = (renderer, tab)=>{
let tokenize;
@@ -131,7 +131,7 @@ const CodeEditor = forwardRef(
const prevTabRef = useRef(tab);
const createExtensions = ({ onChange, language, editorTheme })=>{
const updateListener = EditorView.updateListener.of((update)=>{
const setEventListeners = EditorView.updateListener.of((update)=>{
if(update.docChanged) {
onChange(update.state.doc.toString());
}
@@ -155,26 +155,17 @@ const CodeEditor = forwardRef(
const customHighlightPlugin = createHighlightPlugin(renderer, tab);
const combinedHighlight = [
customHighlightPlugin,
highlightExtension,
];
const languageExtension = language === 'css' ? [css(), cssLanguage] : markdown({ base: markdownLanguage, codeLanguages: languages });
const themeExtension = Array.isArray(themes[editorTheme]) ? themes[editorTheme] : [];
return [
history(),
updateListener,
history(), //allows for undo and redo
setEventListeners,
EditorView.lineWrapping,
scrollPastEnd(),
languageExtension,
lineNumbers(),
homebreweryFold,
hbFolding,
pageFoldExtension,
foldGutter({
openText : '▾',
@@ -183,7 +174,7 @@ const CodeEditor = forwardRef(
highlightActiveLine(),
highlightActiveLineGutter(),
highlightCompartment.of(combinedHighlight),
highlightCompartment.of([customHighlightPlugin,highlightExtension]),
themeCompartment.of(themeExtension),
...(tab !== 'brewStyles' ? [autocompleteEmoji] : []),
search(),

View File

@@ -1,50 +1,46 @@
import { foldService } from '@codemirror/language';
import { codeFolding } from '@codemirror/language';
import { foldService, codeFolding } from '@codemirror/language';
export function getFoldPreview(state, from, to) {
const doc = state.doc;
const start = doc.lineAt(from).number;
const end = doc.lineAt(to).number;
const pageFoldExtension = [
foldService.of((state, lineStart)=>{
const doc = state.doc;
const matcher = /^(?=\\page(?:break)?(?: *{[^\n{}]*})?$)/m;
if(doc.line(start).text.trim()) return ` ↤ Lines ${start}-${end}`;
const startLine = doc.lineAt(lineStart);
const prevLineText = startLine.number > 1 ? doc.line(startLine.number - 1).text : '';
const preview = Array.from({ length: end - start }, (_, i)=>doc.line(start + 1 + i).text.trim())
.find(Boolean) || `Lines ${start}-${end}`;
if(startLine.number > 1 && !matcher.test(prevLineText)) return null;
return `${preview.replace('{', '').slice(0, 50).trim()}${preview.length > 50 ? '...' : ''}`;
}
let endLine = startLine.number;
while (endLine < doc.lines && !matcher.test(doc.line(endLine + 1).text)) {
endLine++;
}
export const homebreweryFold = foldService.of((state, lineStart)=>{
const doc = state.doc;
const matcher = /^(?=\\page(?:break)?(?: *{[^\n{}]*})?$)/m;
if(endLine === startLine.number) return null;
const startLine = doc.lineAt(lineStart);
const prevLineText = startLine.number > 1 ? doc.line(startLine.number - 1).text : '';
return { from: startLine.from, to: doc.line(endLine).to };
}),
codeFolding({
preparePlaceholder : (state, range)=>{
const doc = state.doc;
const start = doc.lineAt(range.from).number;
const end = doc.lineAt(range.to).number;
if(startLine.number > 1 && !matcher.test(prevLineText)) return null;
if(doc.line(start).text.trim()) return ` ↤ Lines ${start}-${end}`;
let endLine = startLine.number;
while (endLine < doc.lines && !matcher.test(doc.line(endLine + 1).text)) {
endLine++;
}
const preview = Array.from({ length: end - start }, (_, i)=>doc.line(start + 1 + i).text.trim()
).find(Boolean) || `Lines ${start}-${end}`;
if(endLine === startLine.number) return null;
return `${preview.replace('{', '').slice(0, 50).trim()}${preview.length > 50 ? '...' : ''}`;
},
placeholderDOM(view, onclick, prepared) {
const span = document.createElement('span');
span.className = 'cm-fold-placeholder';
span.textContent = prepared;
span.onclick = onclick;
span.style.color = '#989898';
return span;
},
}),
];
const widgetObject = { from: startLine.from, to: doc.line(endLine).to };
return widgetObject;
});
export const hbFolding = codeFolding({
preparePlaceholder : (state, range)=>{
return getFoldPreview(state, range.from, range.to);
},
placeholderDOM(view, onclick, prepared) {
const span = document.createElement('span');
span.className = 'cm-fold-placeholder';
span.textContent = prepared;
span.onclick = onclick;
span.style.color = '#989898';
return span;
},
});
export default pageFoldExtension;

View File

@@ -19,7 +19,7 @@ const customTags = {
//CSS
variable : 'variable',
variable : 'variable',
};
export function tokenizeCustomMarkdown(text) {
@@ -262,13 +262,15 @@ export const customHighlightStyle = HighlightStyle.define([
{ tag: tags.heading4, class: 'cm-header cm-header-4' },
{ tag: tags.heading5, class: 'cm-header cm-header-5' },
{ tag: tags.heading6, class: 'cm-header cm-header-6' },
{ tag: tags.link, class: 'cm-link' },
{ tag: tags.string, class: 'cm-string' },
{ tag: tags.url, class: 'cm-string cm-url' },
{ tag: tags.list, class: 'cm-list' },
{ tag: tags.strong, class: 'cm-strong' },
{ tag: tags.emphasis, class: 'cm-em' },
{ tag: tags.quote, class: 'cm-quote' },
//css tags
{ tag: tags.tagName, class: 'cm-tag' },
{ tag: tags.className, class: 'cm-class' },
@@ -284,6 +286,8 @@ export const customHighlightStyle = HighlightStyle.define([
{ tag: tags.invalid, class: 'cm-error' },
{ tag: tags.comment, class: 'cm-comment' },
//custom tags
{ tag: customTags.pageLine, color: '#f0a' },
{ tag: customTags.snippetLine, class: 'cm-snippetLine', color: '#0af' },
{ tag: customTags.inlineBlock, class: 'cm-inline-block' },

View File

@@ -207,7 +207,7 @@ const newPage = (view)=>{
return true;
};
export const customKeymap = keymap.of([
export default keymap.of([
{ key: 'Tab', run: insertTabAtCursor },
{ key: 'Shift-Tab', run: indentMore },
{ key: 'Mod-Shift-Tab', run: indentLess },

View File

@@ -20,8 +20,39 @@ export function legacyTokenizeCustomMarkdown(text) {
}
export const legacyCustomHighlightStyle = HighlightStyle.define([
{ tag: tags.heading1, color: '#000', fontWeight: '700' },
{ tag: tags.keyword, color: '#07a' }, // example for your markdown headings
{ tag: tags.heading, class: 'cm-header' },
{ tag: tags.heading1, class: 'cm-header cm-header-1' },
{ tag: tags.heading2, class: 'cm-header cm-header-2' },
{ tag: tags.heading3, class: 'cm-header cm-header-3' },
{ tag: tags.heading4, class: 'cm-header cm-header-4' },
{ tag: tags.heading5, class: 'cm-header cm-header-5' },
{ tag: tags.heading6, class: 'cm-header cm-header-6' },
{ tag: tags.link, class: 'cm-link' },
{ tag: tags.string, class: 'cm-string' },
{ tag: tags.url, class: 'cm-string cm-url' },
{ tag: tags.list, class: 'cm-list' },
{ tag: tags.strong, class: 'cm-strong' },
{ tag: tags.emphasis, class: 'cm-em' },
{ tag: tags.quote, class: 'cm-quote' },
//css tags
{ tag: tags.tagName, class: 'cm-tag' },
{ tag: tags.className, class: 'cm-class' },
{ tag: tags.propertyName, class: 'cm-property' },
{ tag: tags.attributeValue, class: 'cm-value' },
{ tag: tags.keyword, class: 'cm-keyword' },
{ tag: tags.atom, class: 'cm-atom' },
{ tag: tags.integer, class: 'cm-integer' },
{ tag: tags.unit, class: 'cm-unit' },
{ tag: tags.color, class: 'cm-color' },
{ tag: tags.paren, class: 'cm-paren' },
{ tag: tags.variableName, class: 'cm-variable' },
{ tag: tags.invalid, class: 'cm-error' },
{ tag: tags.comment, class: 'cm-comment' },
//custom tags
{ tag: customTags.pageLine, color: '#f0a' },
{ tag: customTags.snippetLine, class: 'cm-snippetLine', color: '#0af' },
]);

View File

@@ -25,7 +25,7 @@ const ThemeSnippets = {
//import EditorThemes from '../../../../build/homebrew/codeMirror/editorThemes.json';
import * as themesImport from '@uiw/codemirror-themes-all';
import { defaultCM5Theme } from '@themes/codeMirror/customThemes/default.js';
import defaultCM5Theme from '@themes/codeMirror/customThemes/default.js';
const themes = { default: defaultCM5Theme, ...themesImport };