Task lists

pull/3/head
Zef Hemel 2022-02-22 17:36:24 +01:00
parent 84fcd0aeed
commit 5e3bdca3ee
6 changed files with 54 additions and 6 deletions

View File

@ -1,3 +1,4 @@
Home page
[[Great Parenting]]
[[Great Parenting]]
[[1:1s]]

View File

@ -28,6 +28,7 @@ import { Action, AppViewState } from "./types";
import { syntaxTree } from "@codemirror/language";
import * as util from "./util";
import { NoteMeta } from "./types";
const fs = new HttpFileSystem("http://localhost:2222/fs");
@ -39,10 +40,13 @@ const initialViewState: AppViewState = {
allNotes: [],
};
import { CompletionContext, CompletionResult } from "@codemirror/autocomplete";
class Editor {
view: EditorView;
currentNote: string;
dispatch: React.Dispatch<Action>;
allNotes: NoteMeta[];
constructor(
parent: Element,
@ -56,6 +60,7 @@ class Editor {
});
this.currentNote = currentNote;
this.dispatch = dispatch;
this.allNotes = [];
}
createEditorState(text: string): EditorState {
@ -71,7 +76,9 @@ class Editor {
customMarkdownStyle,
bracketMatching(),
closeBrackets(),
autocompletion(),
autocompletion({
override: [this.noteCompleter.bind(this)],
}),
EditorView.lineWrapping,
lineWrapper([
{ selector: "ATXHeading1", class: "line-h1" },
@ -161,6 +168,22 @@ class Editor {
});
}
noteCompleter(ctx: CompletionContext): CompletionResult | null {
let prefix = ctx.matchBefore(/\[\[\w*/);
if (!prefix) {
return null;
}
// TODO: Lots of optimization potential here
// TODO: put something in the cm-completionIcon-note style
return {
from: prefix.from + 2,
options: this.allNotes.map((noteMeta) => ({
label: noteMeta.name,
type: "note",
})),
};
}
update(value: null, transaction: Transaction): null {
if (transaction.docChanged) {
this.dispatch({
@ -184,6 +207,18 @@ class Editor {
let noteName = view.state.sliceDoc(node.from, node.to);
this.navigate(noteName);
}
if (node && node.name === "TaskMarker") {
let checkBoxText = view.state.sliceDoc(node.from, node.to);
if (checkBoxText === "[x]" || checkBoxText === "[X]") {
view.dispatch({
changes: { from: node.from, to: node.to, insert: "[ ]" },
});
} else {
view.dispatch({
changes: { from: node.from, to: node.to, insert: "[x]" },
});
}
}
return false;
}
}
@ -202,6 +237,7 @@ class Editor {
async loadNoteList() {
let notesMeta = await fs.listNotes();
this.allNotes = notesMeta;
this.dispatch({
type: "notes-listed",
notes: notesMeta,

View File

@ -4,3 +4,5 @@ export const WikiLinkTag = Tag.define();
export const WikiLinkPageTag = Tag.define();
export const TagTag = Tag.define();
export const MentionTag = Tag.define();
export const TaskTag = Tag.define();
export const TaskMarkerTag = Tag.define();

View File

@ -1,5 +1,5 @@
import { styleTags } from "@codemirror/highlight";
import { MarkdownConfig } from "@lezer/markdown";
import { MarkdownConfig, TaskList } from "@lezer/markdown";
import { commonmark, mkLang } from "./markdown/markdown";
import * as ct from "./customtags";
@ -49,7 +49,7 @@ const AtMention: MarkdownConfig = {
],
};
const TagLink: MarkdownConfig = {
defineNodes: ["TagLink"],
defineNodes: ["Checkbox"],
parseInline: [
{
name: "TagLink",
@ -71,6 +71,7 @@ const WikiMarkdown = commonmark.configure([
WikiLink,
AtMention,
TagLink,
TaskList,
{
props: [
styleTags({
@ -78,6 +79,8 @@ const WikiMarkdown = commonmark.configure([
WikiLinkPage: ct.WikiLinkPageTag,
AtMention: ct.MentionTag,
TagLink: ct.TagTag,
Task: ct.TaskTag,
TaskMarker: ct.TaskMarkerTag,
}),
],
},

View File

@ -13,6 +13,8 @@ export default HighlightStyle.define([
{ tag: ct.WikiLinkPageTag, class: "wiki-link-page" },
{ tag: ct.TagTag, class: "tag" },
{ tag: ct.MentionTag, class: "mention" },
{ tag: ct.TaskTag, class: "task" },
{ tag: ct.TaskMarkerTag, class: "task-marker" },
{ tag: t.emphasis, class: "emphasis" },
{ tag: t.strong, class: "strong" },
{ tag: t.atom, class: "atom" },

View File

@ -1,8 +1,8 @@
:root {
--ident: 18px;
--editor-font: "Avenir";
/* --editor-font: "Avenir"; */
--editor-font: "Menlo";
--top-bar-bg: rgb(41, 41, 41);
/* --editor-font: "Menlo"; */
}
html,
@ -148,6 +148,10 @@ body {
margin-left: var(--ident);
}
.cm-editor .task-marker {
background-color: #ddd;
}
.current-note {
font-family: var(--editor-font);
margin-left: 10px;