Mostly working except yaml codeblocks

This commit is contained in:
Zef Hemel
2022-06-13 18:31:36 +02:00
parent 24ac6bbd25
commit c25a53357d
36 changed files with 4893 additions and 43235 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
import { Tag } from "@codemirror/highlight";
import { Tag } from "@lezer/highlight";
export const WikiLinkTag = Tag.define();
export const WikiLinkPageTag = Tag.define();
+16 -34
View File
@@ -1,4 +1,9 @@
import { ChangeSpec, EditorSelection, StateCommand, Text } from "@codemirror/state";
import {
StateCommand,
Text,
EditorSelection,
ChangeSpec,
} from "@codemirror/state";
import { syntaxTree } from "@codemirror/language";
import { SyntaxNode, Tree } from "@lezer/common";
import { markdownLanguage } from "./markdown";
@@ -20,11 +25,8 @@ class Context {
blank(trailing: boolean = true) {
let result = this.spaceBefore;
if (this.node.name == "Blockquote") {
result += ">";
} else if (this.node.name == "Comment") {
result += "%%";
} else
if (this.node.name == "Blockquote") result += ">";
else
for (
let i = this.to - this.from - result.length - this.spaceAfter.length;
i > 0;
@@ -50,12 +52,7 @@ function getContext(node: SyntaxNode, line: string, doc: Text) {
cur && cur.name != "Document";
cur = cur.parent
) {
if (
cur.name == "ListItem" ||
cur.name == "Blockquote" ||
cur.name == "Comment"
)
nodes.push(cur);
if (cur.name == "ListItem" || cur.name == "Blockquote") nodes.push(cur);
}
let context = [],
pos = 0;
@@ -69,12 +66,6 @@ function getContext(node: SyntaxNode, line: string, doc: Text) {
) {
pos += match[0].length;
context.push(new Context(node, start, pos, "", match[1], ">", null));
} else if (
node.name == "Comment" &&
(match = /^[ \t]*%%( ?)/.exec(line.slice(pos)))
) {
pos += match[0].length;
context.push(new Context(node, start, pos, "", match[1], "%%", null));
} else if (
node.name == "ListItem" &&
node.parent!.name == "OrderedList" &&
@@ -93,17 +84,21 @@ function getContext(node: SyntaxNode, line: string, doc: Text) {
} else if (
node.name == "ListItem" &&
node.parent!.name == "BulletList" &&
(match = /^([ \t]*)([-+*])([ \t]+)/.exec(nodeStart(node, doc)))
(match = /^([ \t]*)([-+*])([ \t]{1,4}\[[ xX]\])?([ \t]+)/.exec(
nodeStart(node, doc)
))
) {
let after = match[3],
let after = match[4],
len = match[0].length;
if (after.length > 4) {
after = after.slice(0, after.length - 4);
len -= 4;
}
let type = match[2];
if (match[3]) type += match[3].replace(/[xX]/, " ");
pos += len;
context.push(
new Context(node.parent!, start, pos, match[1], after, match[2], node)
new Context(node.parent!, start, pos, match[1], after, type, node)
);
}
}
@@ -229,19 +224,6 @@ export const insertNewlineContinueMarkup: StateCommand = ({
}
}
if (inner.node.name == "Comment" && emptyLine && line.from) {
let prevLine = doc.lineAt(line.from - 1),
commented = /%%\s*$/.exec(prevLine.text);
// Two aligned empty quoted lines in a row
if (commented && commented.index == inner.from) {
let changes = state.changes([
{ from: prevLine.from + commented.index, to: prevLine.to },
{ from: line.from + inner.from, to: line.to },
]);
return { range: range.map(changes), changes };
}
}
let changes: ChangeSpec[] = [];
if (inner.node.name == "OrderedList")
renumberList(inner.item!, doc, changes);
+22 -10
View File
@@ -1,11 +1,19 @@
import { Prec } from "@codemirror/state";
import { KeyBinding, keymap } from "@codemirror/view";
import { Language, LanguageDescription, LanguageSupport } from "@codemirror/language";
import {
Language,
LanguageSupport,
LanguageDescription,
} from "@codemirror/language";
import { MarkdownExtension, MarkdownParser, parseCode } from "@lezer/markdown";
import { html } from "@codemirror/lang-html";
import { commonmarkLanguage, getCodeParser, markdownLanguage, mkLang } from "./markdown";
import { deleteMarkupBackward, insertNewlineContinueMarkup } from "./commands";
import {
commonmarkLanguage,
markdownLanguage,
mkLang,
getCodeParser,
} from "./markdown";
import { insertNewlineContinueMarkup, deleteMarkupBackward } from "./commands";
export {
commonmarkLanguage,
markdownLanguage,
@@ -30,11 +38,15 @@ export function markdown(
/// When given, this language will be used by default to parse code
/// blocks.
defaultCodeLanguage?: Language | LanguageSupport;
/// A collection of language descriptions to search through for a
/// matching language (with
/// [`LanguageDescription.matchLanguageName`](#language.LanguageDescription^matchLanguageName))
/// when a fenced code block has an info string.
codeLanguages?: readonly LanguageDescription[];
/// A source of language support for highlighting fenced code
/// blocks. When it is an array, the parser will use
/// [`LanguageDescription.matchLanguageName`](#language.LanguageDescription^matchLanguageName)
/// with the fenced code info to find a matching language. When it
/// is a function, will be called with the info string and may
/// return a language or `LanguageDescription` object.
codeLanguages?:
| readonly LanguageDescription[]
| ((info: string) => Language | LanguageDescription | null);
/// Set this to false to disable installation of the Markdown
/// [keymap](#lang-markdown.markdownKeymap).
addKeymap?: boolean;
@@ -68,7 +80,7 @@ export function markdown(
}
let codeParser =
codeLanguages || defaultCode
? getCodeParser(codeLanguages || [], defaultCode)
? getCodeParser(codeLanguages, defaultCode)
: undefined;
extensions.push(
parseCode({ codeParser, htmlParser: htmlNoMatch.language.parser })
+28 -61
View File
@@ -1,43 +1,25 @@
import {
Language,
defineLanguageFacet,
languageDataProp,
foldNodeProp,
indentNodeProp,
Language,
languageDataProp,
LanguageDescription,
ParseContext
ParseContext,
} from "@codemirror/language";
import { styleTags, tags as t } from "@codemirror/highlight";
import { Emoji, GFM, MarkdownParser, parser as baseParser, Subscript, Superscript } from "@lezer/markdown";
import {
parser as baseParser,
MarkdownParser,
GFM,
Subscript,
Superscript,
Emoji,
} from "@lezer/markdown";
const data = defineLanguageFacet({ block: { open: "<!--", close: "-->" } });
export const commonmark = baseParser.configure({
props: [
styleTags({
"Blockquote/...": t.quote,
HorizontalRule: t.contentSeparator,
"ATXHeading1/... SetextHeading1/...": t.heading1,
"ATXHeading2/... SetextHeading2/...": t.heading2,
"ATXHeading3/...": t.heading3,
"ATXHeading4/...": t.heading4,
"ATXHeading5/...": t.heading5,
"ATXHeading6/...": t.heading6,
"Comment CommentBlock": t.comment,
Escape: t.escape,
Entity: t.character,
"Emphasis/...": t.emphasis,
"StrongEmphasis/...": t.strong,
"Link/... Image/...": t.link,
"OrderedList/... BulletList/...": t.list,
"InlineCode CodeText": t.monospace,
URL: t.url,
"HeaderMark HardBreak QuoteMark ListMark LinkMark EmphasisMark CodeMark":
t.processingInstruction,
"CodeInfo LinkLabel": t.labelName,
LinkTitle: t.string,
Paragraph: t.content,
}),
foldNodeProp.add((type) => {
if (!type.is("Block") || type.is("Document")) return undefined;
return (tree, state) => ({
@@ -55,51 +37,36 @@ export const commonmark = baseParser.configure({
});
export function mkLang(parser: MarkdownParser) {
return new Language(
data,
parser,
parser.nodeSet.types.find((t) => t.name == "Document")!
);
return new Language(data, parser);
}
/// Language support for strict CommonMark.
export const commonmarkLanguage = mkLang(commonmark);
const extended = commonmark.configure([
GFM,
Subscript,
Superscript,
Emoji,
{
props: [
styleTags({
"TableDelimiter SubscriptMark SuperscriptMark StrikethroughMark":
t.processingInstruction,
"TableHeader/...": t.heading,
"Strikethrough/...": t.strikethrough,
TaskMarker: t.atom,
Task: t.list,
Emoji: t.character,
"Subscript Superscript": t.special(t.content),
TableCell: t.content,
}),
],
},
]);
const extended = commonmark.configure([GFM, Subscript, Superscript, Emoji]);
/// Language support for [GFM](https://github.github.com/gfm/) plus
/// subscript, superscript, and emoji syntax.
export const markdownLanguage = mkLang(extended);
export function getCodeParser(
languages: readonly LanguageDescription[],
languages:
| readonly LanguageDescription[]
| ((info: string) => Language | LanguageDescription | null)
| undefined,
defaultLanguage?: Language
) {
return (info: string) => {
let found =
info && LanguageDescription.matchLanguageName(languages, info, true);
if (!found) return defaultLanguage ? defaultLanguage.parser : null;
if (found.support) return found.support.language.parser;
return ParseContext.getSkippingParser(found.load());
if (info && languages) {
let found = null;
if (typeof languages == "function") found = languages(info);
else found = LanguageDescription.matchLanguageName(languages, info, true);
if (found instanceof LanguageDescription)
return found.support
? found.support.language.parser
: ParseContext.getSkippingParser(found.load());
else if (found) return found.parser;
}
return defaultLanguage ? defaultLanguage.parser : null;
};
}
+1 -1
View File
@@ -1,4 +1,4 @@
import { Tag } from "@codemirror/highlight";
import { Tag } from "@lezer/highlight";
import type { MarkdownConfig } from "@lezer/markdown";
import { System } from "@plugos/plugos/system";
import { Manifest } from "@silverbulletmd/common/manifest";
+12 -6
View File
@@ -7,11 +7,17 @@
"version": "0.0.1",
"license": "MIT",
"dependencies": {
"@codemirror/highlight": "^0.19.0",
"@codemirror/language": "^0.19.0",
"@codemirror/stream-parser": "^0.19.9",
"@codemirror/lang-javascript": "^0.19.7",
"@codemirror/legacy-modes": "^0.19.1",
"@lezer/markdown": "^0.15.0"
"@codemirror/autocomplete": "6.0.1",
"@codemirror/commands": "6.0.0",
"@codemirror/lang-html": "6.0.0",
"@codemirror/lang-javascript": "6.0.0",
"@codemirror/language": "6.0.0",
"@codemirror/legacy-modes": "6.0.0",
"@codemirror/search": "6.0.0",
"@codemirror/state": "6.0.0",
"@codemirror/view": "6.0.0",
"@lezer/highlight": "1.0.0",
"@lezer/markdown": "1.0.0",
"@lezer/common": "1.0.0"
}
}
+2 -2
View File
@@ -1,4 +1,4 @@
import { styleTags, tags as t } from "@codemirror/highlight";
import { styleTags, tags as t } from "@lezer/highlight";
import {
BlockContext,
LeafBlock,
@@ -15,7 +15,7 @@ import {
LanguageDescription,
LanguageSupport,
} from "@codemirror/language";
import { StreamLanguage } from "@codemirror/stream-parser";
import { StreamLanguage } from "@codemirror/language";
import { yaml } from "@codemirror/legacy-modes/mode/yaml";
import {
javascriptLanguage,
+1 -1
View File
@@ -64,7 +64,7 @@
"typescript": "^4.6.2"
},
"devDependencies": {
"@lezer/lr": "^0.15.0",
"@lezer/lr": "1.0.0",
"@parcel/optimizer-data-url": "2.6.0",
"@parcel/packager-raw-url": "2.6.0",
"@parcel/service-worker": "2.6.0",
+2 -2
View File
@@ -32,8 +32,8 @@
},
"dependencies": {
"@jest/globals": "^27.5.1",
"@lezer/generator": "^0.15.4",
"@lezer/lr": "^0.15.8",
"@lezer/generator": "1.0.0",
"@lezer/lr": "1.0.0",
"@mattermost/client": "^6.7.0-0",
"@mattermost/types": "^6.7.0-0",
"@types/yaml": "^1.9.7",
-18660
View File
File diff suppressed because it is too large Load Diff
+4 -6
View File
@@ -37,13 +37,11 @@
}
},
"dependencies": {
"@codemirror/lang-javascript": "^0.19.7",
"@codemirror/lang-markdown": "^0.19.6",
"@codemirror/language": "^0.19.0",
"@codemirror/legacy-modes": "^0.19.1",
"@codemirror/stream-parser": "^0.19.9",
"@codemirror/lang-javascript": "6.0.0",
"@codemirror/language": "6.0.0",
"@codemirror/legacy-modes": "6.0.0",
"@jest/globals": "^27.5.1",
"@lezer/markdown": "^0.15.0",
"@lezer/markdown": "1.0.0",
"@silverbulletmd/web": "^0.0.2",
"better-sqlite3": "^7.5.0",
"body-parser": "^1.19.2",
+1 -1
View File
@@ -1,5 +1,5 @@
import { EditorSelection, StateCommand, Transaction } from "@codemirror/state";
import { Text } from "@codemirror/text";
import { Text } from "@codemirror/state";
export function insertMarker(marker: string): StateCommand {
return ({ state, dispatch }) => {
+9 -4
View File
@@ -3,10 +3,14 @@ import {
completionKeymap,
CompletionResult,
} from "@codemirror/autocomplete";
import { closeBrackets, closeBracketsKeymap } from "@codemirror/closebrackets";
import { closeBrackets, closeBracketsKeymap } from "@codemirror/autocomplete";
import { indentWithTab, standardKeymap } from "@codemirror/commands";
import { history, historyKeymap } from "@codemirror/history";
import { bracketMatching } from "@codemirror/matchbrackets";
import { history, historyKeymap } from "@codemirror/commands";
import {
bracketMatching,
defaultHighlightStyle,
syntaxHighlighting,
} from "@codemirror/language";
import { searchKeymap } from "@codemirror/search";
import { EditorSelection, EditorState } from "@codemirror/state";
import {
@@ -315,7 +319,8 @@ export class Editor {
history(),
drawSelection(),
dropCursor(),
customMarkdownStyle(this.mdExtensions),
syntaxHighlighting(customMarkdownStyle(this.mdExtensions)),
// syntaxHighlighting(defaultHighlightStyle),
bracketMatching(),
closeBrackets(),
autocompletion({
+10 -4
View File
@@ -1,7 +1,13 @@
import { syntaxTree } from "@codemirror/language";
import { Decoration, DecorationSet, EditorView, ViewPlugin, ViewUpdate } from "@codemirror/view";
import {
Decoration,
DecorationSet,
EditorView,
ViewPlugin,
ViewUpdate,
} from "@codemirror/view";
import { Range } from "@codemirror/rangeset";
import { Range } from "@codemirror/state";
interface WrapElement {
selector: string;
@@ -17,7 +23,7 @@ function wrapLines(view: EditorView, wrapElements: WrapElement[]) {
syntaxTree(view.state).iterate({
from,
to,
enter: (type, from, to) => {
enter: ({ type, from, to }) => {
const bodyText = doc.sliceString(from, to);
for (let wrapElement of wrapElements) {
if (type.name == wrapElement.selector) {
@@ -41,7 +47,7 @@ function wrapLines(view: EditorView, wrapElements: WrapElement[]) {
}
}
},
leave(type, from: number, to: number) {
leave({ type }) {
for (let wrapElement of wrapElements) {
if (type.name == wrapElement.selector && wrapElement.nesting) {
elementStack.pop();
-14606
View File
File diff suppressed because it is too large Load Diff
+11 -17
View File
@@ -26,27 +26,21 @@
"dist"
],
"dependencies": {
"@codemirror/autocomplete": "^0.19.1",
"@codemirror/closebrackets": "^0.19.1",
"@codemirror/commands": "^0.19.8",
"@codemirror/highlight": "^0.19.0",
"@codemirror/history": "^0.19.2",
"@codemirror/lang-html": "^0.19.4",
"@codemirror/lang-javascript": "^0.19.7",
"@codemirror/lang-markdown": "^0.19.6",
"@codemirror/language": "^0.19.0",
"@codemirror/legacy-modes": "^0.19.1",
"@codemirror/matchbrackets": "^0.19.4",
"@codemirror/search": "^0.19.9",
"@codemirror/state": "^0.19.7",
"@codemirror/stream-parser": "^0.19.9",
"@codemirror/text": "^0.19.6",
"@codemirror/view": "^0.19.42",
"@codemirror/autocomplete": "6.0.1",
"@codemirror/commands": "6.0.0",
"@codemirror/lang-javascript": "6.0.0",
"@codemirror/lang-markdown": "6.0.0",
"@codemirror/language": "6.0.0",
"@codemirror/legacy-modes": "6.0.0",
"@codemirror/search": "6.0.0",
"@codemirror/state": "6.0.0",
"@codemirror/view": "6.0.0",
"@fortawesome/fontawesome-svg-core": "1.3.0",
"@fortawesome/free-solid-svg-icons": "6.0.0",
"@fortawesome/react-fontawesome": "0.1.17",
"@jest/globals": "^27.5.1",
"@lezer/markdown": "^0.15.0",
"@lezer/highlight": "1.0.0",
"@lezer/markdown": "1.0.0",
"fake-indexeddb": "^3.1.7",
"fuzzysort": "^1.9.0",
"jest": "^27.5.1",
+12 -3
View File
@@ -1,9 +1,10 @@
import { HighlightStyle, tags as t } from "@codemirror/highlight";
import { HighlightStyle } from "@codemirror/language";
import { tags as t } from "@lezer/highlight";
import * as ct from "@silverbulletmd/common/customtags";
import { MDExt } from "@silverbulletmd/common/markdown_ext";
export default function highlightStyles(mdExtension: MDExt[]) {
return HighlightStyle.define([
const hls = HighlightStyle.define([
{ tag: t.heading1, class: "h1" },
{ tag: t.heading2, class: "h2" },
{ tag: t.heading3, class: "h3" },
@@ -29,7 +30,7 @@ export default function highlightStyles(mdExtension: MDExt[]) {
{ tag: t.literal, class: "literal" },
{ tag: t.keyword, class: "keyword" },
{ tag: t.list, class: "list" },
{ tag: t.definition, class: "li" },
// { tag: t.def, class: "li" },
{ tag: t.string, class: "string" },
{ tag: t.number, class: "number" },
{ tag: [t.regexp, t.escape, t.special(t.string)], class: "string2" },
@@ -44,4 +45,12 @@ export default function highlightStyles(mdExtension: MDExt[]) {
return { tag: mdExt.tag, ...mdExt.styles };
}),
]);
const fn0 = hls.style;
// Hack: https://discuss.codemirror.net/t/highlighting-that-seems-ignored-in-cm6/4320/16
// @ts-ignore
hls.style = (tags) => {
return fn0(tags || []);
};
return hls;
}