Task lists
parent
84fcd0aeed
commit
5e3bdca3ee
|
@ -1,3 +1,4 @@
|
|||
Home page
|
||||
|
||||
[[Great Parenting]]
|
||||
[[1:1s]]
|
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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,
|
||||
}),
|
||||
],
|
||||
},
|
||||
|
|
|
@ -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" },
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue