mirror of
https://github.com/naturalcrit/homebrewery.git
synced 2026-03-28 14:28:12 +00:00
simplify fold export & restore legacy higlights
This commit is contained in:
@@ -24,16 +24,16 @@ import { autocompleteEmoji } from './autocompleteEmoji.js';
|
|||||||
import { searchKeymap, search } from '@codemirror/search';
|
import { searchKeymap, search } from '@codemirror/search';
|
||||||
|
|
||||||
import * as themesImport from '@uiw/codemirror-themes-all';
|
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 themes = { default: defaultCM5Theme, ...themesImport };
|
||||||
const themeCompartment = new Compartment();
|
const themeCompartment = new Compartment();
|
||||||
const highlightCompartment = new Compartment();
|
const highlightCompartment = new Compartment();
|
||||||
|
|
||||||
import { customKeymap } from './customKeyMap.js';
|
import customKeymap from './customKeyMap.js';
|
||||||
import { homebreweryFold, hbFolding } from './customFolding.js';
|
import pageFoldExtension from './customFolding.js';
|
||||||
import { customHighlightStyle, tokenizeCustomMarkdown, tokenizeCustomCSS } from './customHighlight.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)=>{
|
const createHighlightPlugin = (renderer, tab)=>{
|
||||||
let tokenize;
|
let tokenize;
|
||||||
@@ -131,7 +131,7 @@ const CodeEditor = forwardRef(
|
|||||||
const prevTabRef = useRef(tab);
|
const prevTabRef = useRef(tab);
|
||||||
|
|
||||||
const createExtensions = ({ onChange, language, editorTheme })=>{
|
const createExtensions = ({ onChange, language, editorTheme })=>{
|
||||||
const updateListener = EditorView.updateListener.of((update)=>{
|
const setEventListeners = EditorView.updateListener.of((update)=>{
|
||||||
if(update.docChanged) {
|
if(update.docChanged) {
|
||||||
onChange(update.state.doc.toString());
|
onChange(update.state.doc.toString());
|
||||||
}
|
}
|
||||||
@@ -155,26 +155,17 @@ const CodeEditor = forwardRef(
|
|||||||
|
|
||||||
const customHighlightPlugin = createHighlightPlugin(renderer, tab);
|
const customHighlightPlugin = createHighlightPlugin(renderer, tab);
|
||||||
|
|
||||||
const combinedHighlight = [
|
|
||||||
customHighlightPlugin,
|
|
||||||
highlightExtension,
|
|
||||||
];
|
|
||||||
|
|
||||||
const languageExtension = language === 'css' ? [css(), cssLanguage] : markdown({ base: markdownLanguage, codeLanguages: languages });
|
const languageExtension = language === 'css' ? [css(), cssLanguage] : markdown({ base: markdownLanguage, codeLanguages: languages });
|
||||||
|
|
||||||
const themeExtension = Array.isArray(themes[editorTheme]) ? themes[editorTheme] : [];
|
const themeExtension = Array.isArray(themes[editorTheme]) ? themes[editorTheme] : [];
|
||||||
|
|
||||||
return [
|
return [
|
||||||
history(),
|
history(), //allows for undo and redo
|
||||||
|
setEventListeners,
|
||||||
updateListener,
|
|
||||||
EditorView.lineWrapping,
|
EditorView.lineWrapping,
|
||||||
scrollPastEnd(),
|
scrollPastEnd(),
|
||||||
languageExtension,
|
languageExtension,
|
||||||
|
|
||||||
lineNumbers(),
|
lineNumbers(),
|
||||||
homebreweryFold,
|
pageFoldExtension,
|
||||||
hbFolding,
|
|
||||||
|
|
||||||
foldGutter({
|
foldGutter({
|
||||||
openText : '▾',
|
openText : '▾',
|
||||||
@@ -183,7 +174,7 @@ const CodeEditor = forwardRef(
|
|||||||
|
|
||||||
highlightActiveLine(),
|
highlightActiveLine(),
|
||||||
highlightActiveLineGutter(),
|
highlightActiveLineGutter(),
|
||||||
highlightCompartment.of(combinedHighlight),
|
highlightCompartment.of([customHighlightPlugin,highlightExtension]),
|
||||||
themeCompartment.of(themeExtension),
|
themeCompartment.of(themeExtension),
|
||||||
...(tab !== 'brewStyles' ? [autocompleteEmoji] : []),
|
...(tab !== 'brewStyles' ? [autocompleteEmoji] : []),
|
||||||
search(),
|
search(),
|
||||||
|
|||||||
@@ -1,50 +1,46 @@
|
|||||||
import { foldService } from '@codemirror/language';
|
import { foldService, codeFolding } from '@codemirror/language';
|
||||||
import { codeFolding } from '@codemirror/language';
|
|
||||||
|
|
||||||
export function getFoldPreview(state, from, to) {
|
const pageFoldExtension = [
|
||||||
const doc = state.doc;
|
foldService.of((state, lineStart)=>{
|
||||||
const start = doc.lineAt(from).number;
|
const doc = state.doc;
|
||||||
const end = doc.lineAt(to).number;
|
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())
|
if(startLine.number > 1 && !matcher.test(prevLineText)) return null;
|
||||||
.find(Boolean) || `Lines ${start}-${end}`;
|
|
||||||
|
|
||||||
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)=>{
|
if(endLine === startLine.number) return null;
|
||||||
const doc = state.doc;
|
|
||||||
const matcher = /^(?=\\page(?:break)?(?: *{[^\n{}]*})?$)/m;
|
|
||||||
|
|
||||||
const startLine = doc.lineAt(lineStart);
|
return { from: startLine.from, to: doc.line(endLine).to };
|
||||||
const prevLineText = startLine.number > 1 ? doc.line(startLine.number - 1).text : '';
|
}),
|
||||||
|
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;
|
const preview = Array.from({ length: end - start }, (_, i)=>doc.line(start + 1 + i).text.trim()
|
||||||
while (endLine < doc.lines && !matcher.test(doc.line(endLine + 1).text)) {
|
).find(Boolean) || `Lines ${start}-${end}`;
|
||||||
endLine++;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 };
|
export default pageFoldExtension;
|
||||||
|
|
||||||
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;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
@@ -19,7 +19,7 @@ const customTags = {
|
|||||||
|
|
||||||
//CSS
|
//CSS
|
||||||
|
|
||||||
variable : 'variable',
|
variable : 'variable',
|
||||||
};
|
};
|
||||||
|
|
||||||
export function tokenizeCustomMarkdown(text) {
|
export function tokenizeCustomMarkdown(text) {
|
||||||
@@ -262,13 +262,15 @@ export const customHighlightStyle = HighlightStyle.define([
|
|||||||
{ tag: tags.heading4, class: 'cm-header cm-header-4' },
|
{ tag: tags.heading4, class: 'cm-header cm-header-4' },
|
||||||
{ tag: tags.heading5, class: 'cm-header cm-header-5' },
|
{ tag: tags.heading5, class: 'cm-header cm-header-5' },
|
||||||
{ tag: tags.heading6, class: 'cm-header cm-header-6' },
|
{ tag: tags.heading6, class: 'cm-header cm-header-6' },
|
||||||
|
|
||||||
{ tag: tags.link, class: 'cm-link' },
|
{ tag: tags.link, class: 'cm-link' },
|
||||||
{ tag: tags.string, class: 'cm-string' },
|
{ tag: tags.string, class: 'cm-string' },
|
||||||
{ tag: tags.url, class: 'cm-string cm-url' },
|
{ tag: tags.url, class: 'cm-string cm-url' },
|
||||||
{ tag: tags.list, class: 'cm-list' },
|
{ tag: tags.list, class: 'cm-list' },
|
||||||
{ tag: tags.strong, class: 'cm-strong' },
|
{ tag: tags.strong, class: 'cm-strong' },
|
||||||
{ tag: tags.emphasis, class: 'cm-em' },
|
{ tag: tags.emphasis, class: 'cm-em' },
|
||||||
|
{ tag: tags.quote, class: 'cm-quote' },
|
||||||
|
|
||||||
|
//css tags
|
||||||
|
|
||||||
{ tag: tags.tagName, class: 'cm-tag' },
|
{ tag: tags.tagName, class: 'cm-tag' },
|
||||||
{ tag: tags.className, class: 'cm-class' },
|
{ tag: tags.className, class: 'cm-class' },
|
||||||
@@ -284,6 +286,8 @@ export const customHighlightStyle = HighlightStyle.define([
|
|||||||
{ tag: tags.invalid, class: 'cm-error' },
|
{ tag: tags.invalid, class: 'cm-error' },
|
||||||
{ tag: tags.comment, class: 'cm-comment' },
|
{ tag: tags.comment, class: 'cm-comment' },
|
||||||
|
|
||||||
|
//custom tags
|
||||||
|
|
||||||
{ tag: customTags.pageLine, color: '#f0a' },
|
{ tag: customTags.pageLine, color: '#f0a' },
|
||||||
{ tag: customTags.snippetLine, class: 'cm-snippetLine', color: '#0af' },
|
{ tag: customTags.snippetLine, class: 'cm-snippetLine', color: '#0af' },
|
||||||
{ tag: customTags.inlineBlock, class: 'cm-inline-block' },
|
{ tag: customTags.inlineBlock, class: 'cm-inline-block' },
|
||||||
|
|||||||
@@ -207,7 +207,7 @@ const newPage = (view)=>{
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const customKeymap = keymap.of([
|
export default keymap.of([
|
||||||
{ key: 'Tab', run: insertTabAtCursor },
|
{ key: 'Tab', run: insertTabAtCursor },
|
||||||
{ key: 'Shift-Tab', run: indentMore },
|
{ key: 'Shift-Tab', run: indentMore },
|
||||||
{ key: 'Mod-Shift-Tab', run: indentLess },
|
{ key: 'Mod-Shift-Tab', run: indentLess },
|
||||||
|
|||||||
@@ -20,8 +20,39 @@ export function legacyTokenizeCustomMarkdown(text) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const legacyCustomHighlightStyle = HighlightStyle.define([
|
export const legacyCustomHighlightStyle = HighlightStyle.define([
|
||||||
{ tag: tags.heading1, color: '#000', fontWeight: '700' },
|
{ tag: tags.heading, class: 'cm-header' },
|
||||||
{ tag: tags.keyword, color: '#07a' }, // example for your markdown headings
|
{ 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.pageLine, color: '#f0a' },
|
||||||
{ tag: customTags.snippetLine, class: 'cm-snippetLine', color: '#0af' },
|
{ tag: customTags.snippetLine, class: 'cm-snippetLine', color: '#0af' },
|
||||||
]);
|
]);
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ const ThemeSnippets = {
|
|||||||
|
|
||||||
//import EditorThemes from '../../../../build/homebrew/codeMirror/editorThemes.json';
|
//import EditorThemes from '../../../../build/homebrew/codeMirror/editorThemes.json';
|
||||||
import * as themesImport from '@uiw/codemirror-themes-all';
|
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 themes = { default: defaultCM5Theme, ...themesImport };
|
||||||
|
|
||||||
|
|||||||
@@ -1,81 +1,80 @@
|
|||||||
// themes/codeMirror/customThemes/default.js
|
// themes/codeMirror/customThemes/default.js
|
||||||
import { EditorView } from '@codemirror/view';
|
import { EditorView } from '@codemirror/view';
|
||||||
import { Compartment } from '@codemirror/state';
|
|
||||||
|
|
||||||
export const themeCompartment = new Compartment();
|
//This theme is made of the base css for the codemirror 5 editor
|
||||||
|
|
||||||
export const defaultCM5Theme = EditorView.theme({
|
export default EditorView.theme({
|
||||||
"&": {
|
'&' : {
|
||||||
backgroundColor: "white",
|
backgroundColor : 'white',
|
||||||
color: "black",
|
color : 'black',
|
||||||
},
|
},
|
||||||
".cm-content": {
|
'.cm-content' : {
|
||||||
padding: "4px 0",
|
padding : '4px 0',
|
||||||
fontFamily: "monospace",
|
fontFamily : 'monospace',
|
||||||
fontSize: "13px",
|
fontSize : '13px',
|
||||||
lineHeight: "1",
|
lineHeight : '1',
|
||||||
},
|
},
|
||||||
".cm-line": {
|
'.cm-line' : {
|
||||||
padding: "0 4px",
|
padding : '0 4px',
|
||||||
},
|
},
|
||||||
".cm-gutters": {
|
'.cm-gutters' : {
|
||||||
borderRight: "1px solid #ddd",
|
borderRight : '1px solid #ddd',
|
||||||
backgroundColor: "#f7f7f7",
|
backgroundColor : '#f7f7f7',
|
||||||
whiteSpace: "nowrap",
|
whiteSpace : 'nowrap',
|
||||||
},
|
},
|
||||||
".cm-linenumber": {
|
'.cm-linenumber' : {
|
||||||
padding: "0 3px 0 5px",
|
padding : '0 3px 0 5px',
|
||||||
minWidth: "20px",
|
minWidth : '20px',
|
||||||
textAlign: "right",
|
textAlign : 'right',
|
||||||
color: "#999",
|
color : '#999',
|
||||||
whiteSpace: "nowrap",
|
whiteSpace : 'nowrap',
|
||||||
},
|
},
|
||||||
".cm-cursor": {
|
'.cm-cursor' : {
|
||||||
borderLeft: "1px solid black",
|
borderLeft : '1px solid black',
|
||||||
},
|
},
|
||||||
".cm-fat-cursor": {
|
'.cm-fat-cursor' : {
|
||||||
width: "auto",
|
width : 'auto',
|
||||||
backgroundColor: "#7e7",
|
backgroundColor : '#7e7',
|
||||||
caretColor: "transparent",
|
caretColor : 'transparent',
|
||||||
},
|
},
|
||||||
".cm-activeline-background": {
|
'.cm-activeline-background' : {
|
||||||
backgroundColor: "#e8f2ff",
|
backgroundColor : '#e8f2ff',
|
||||||
},
|
},
|
||||||
".cm-selected": {
|
'.cm-selected' : {
|
||||||
backgroundColor: "#d7d4f0",
|
backgroundColor : '#d7d4f0',
|
||||||
},
|
},
|
||||||
".cm-foldmarker": {
|
'.cm-foldmarker' : {
|
||||||
color: "blue",
|
color : 'blue',
|
||||||
fontFamily: "arial",
|
fontFamily : 'arial',
|
||||||
lineHeight: "0.3",
|
lineHeight : '0.3',
|
||||||
cursor: "pointer",
|
cursor : 'pointer',
|
||||||
},
|
},
|
||||||
|
|
||||||
// Semantic classes
|
// Semantic classes
|
||||||
".cm-header": { color: "blue", fontWeight: "bold" },
|
'.cm-header' : { color: 'blue', fontWeight: 'bold' },
|
||||||
".cm-strong": { fontWeight: "bold" },
|
'.cm-strong' : { fontWeight: 'bold' },
|
||||||
".cm-em": { fontStyle: "italic" },
|
'.cm-em' : { fontStyle: 'italic' },
|
||||||
".cm-quote": { color: "#090" },
|
'.cm-keyword' : { color: '#708' },
|
||||||
".cm-keyword": { color: "#708" },
|
'.cm-atom, cm-value, cm-color' : { color: '#219' },
|
||||||
".cm-atom, cm-value, cm-color": { color: "#219" },
|
'.cm-number' : { color: '#164' },
|
||||||
".cm-number": { color: "#164" },
|
'.cm-def' : { color: '#00f' },
|
||||||
".cm-def": { color: "#00f" },
|
'.cm-list' : { color: '#05a' },
|
||||||
".cm-list": { color: "#05a" },
|
'.cm-variable, .cm-type' : { color: '#085' },
|
||||||
".cm-variable, .cm-type": { color: "#085" },
|
'.cm-comment' : { color: '#a50' },
|
||||||
".cm-comment": { color: "#a50" },
|
'.cm-link' : { color: '#00c', textDecoration: 'underline' },
|
||||||
".cm-link": { color: "#00c", textDecoration: "underline" },
|
'.cm-string' : { color: '#a11', textDecoration: 'none' },
|
||||||
".cm-string": { color: "#a11", textDecoration: "none" },
|
'.cm-string-2' : { color: '#f50', textDecoration: 'none' },
|
||||||
".cm-string-2": { color: "#f50", textDecoration: "none" },
|
'.cm-meta, .cm-qualifier, .cm-class' : { color: '#555' },
|
||||||
".cm-meta, .cm-qualifier, .cm-class": { color: "#555" },
|
'.cm-builtin' : { color: '#30a' },
|
||||||
".cm-builtin": { color: "#30a" },
|
'.cm-bracket' : { color: '#997' },
|
||||||
".cm-bracket": { color: "#997" },
|
'.cm-tag' : { color: '#170' },
|
||||||
".cm-tag": { color: "#170" },
|
'.cm-attribute' : { color: '#00c' },
|
||||||
".cm-attribute": { color: "#00c" },
|
'.cm-hr' : { color: '#999' },
|
||||||
".cm-hr": { color: "#999" },
|
'.cm-negative' : { color: '#d44' },
|
||||||
".cm-negative": { color: "#d44" },
|
'.cm-positive' : { color: '#292' },
|
||||||
".cm-positive": { color: "#292" },
|
'.cm-error, .cm-invalidchar' : { color: '#f00' },
|
||||||
".cm-error, .cm-invalidchar": { color: "#f00" },
|
'.cm-matchingbracket' : { color: '#0b0' },
|
||||||
".cm-matchingbracket": { color: "#0b0" },
|
'.cm-nonmatchingbracket' : { color: '#a22' },
|
||||||
".cm-nonmatchingbracket": { color: "#a22" },
|
'.cm-matchingtag' : { backgroundColor: 'rgba(255, 150, 0, 0.3)' },
|
||||||
".cm-matchingtag": { backgroundColor: "rgba(255, 150, 0, 0.3)" },
|
'.cm-quote' : { color: '#090' },
|
||||||
}, { dark: false });
|
}, { dark: false });
|
||||||
Reference in New Issue
Block a user