Javascript and Typescript highlighting
This commit is contained in:
@@ -5,6 +5,10 @@ export function getCurrentPage(): Promise<string> {
|
||||
return syscall("editor.getCurrentPage");
|
||||
}
|
||||
|
||||
export function setPage(newName: string): Promise<void> {
|
||||
return syscall("editor.setPage", newName);
|
||||
}
|
||||
|
||||
export function getText(): Promise<string> {
|
||||
return syscall("editor.getText");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
functions:
|
||||
toggleDraftMode:
|
||||
path: "./draft.ts:toggleMode"
|
||||
command:
|
||||
name: "Draft: Toggle Mode"
|
||||
@@ -0,0 +1,7 @@
|
||||
import * as clientStore from "@silverbulletmd/plugos-silverbullet-syscall/clientStore";
|
||||
|
||||
export async function toggleMode() {
|
||||
let currentValue = !!(await clientStore.get("enableDraftMode"));
|
||||
console.log("New draft mode", !currentValue);
|
||||
await clientStore.set("enableDraftMode", !currentValue);
|
||||
}
|
||||
@@ -7,6 +7,7 @@ export class HttpSpacePrimitives implements SpacePrimitives {
|
||||
private plugUrl: string;
|
||||
|
||||
constructor(url: string) {
|
||||
console.log("UR", url);
|
||||
this.pageUrl = url + "/fs";
|
||||
this.plugUrl = url + "/plug";
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import { createSandbox } from "@silverbulletmd/plugos/environments/node_sandbox"
|
||||
import { jwtSyscalls } from "@silverbulletmd/plugos/syscalls/jwt";
|
||||
import buildMarkdown from "@silverbulletmd/web/parser";
|
||||
import { loadMarkdownExtensions } from "@silverbulletmd/web/markdown_ext";
|
||||
import http, { Server } from "http";
|
||||
|
||||
export class ExpressServer {
|
||||
app: Express;
|
||||
@@ -31,21 +32,19 @@ export class ExpressServer {
|
||||
private distDir: string;
|
||||
private eventHook: EventHook;
|
||||
private db: Knex<any, unknown[]>;
|
||||
private port: number;
|
||||
private server?: Server;
|
||||
|
||||
constructor(
|
||||
app: Express,
|
||||
rootPath: string,
|
||||
distDir: string,
|
||||
system: System<SilverBulletHooks>
|
||||
) {
|
||||
this.app = app;
|
||||
constructor(port: number, rootPath: string, distDir: string) {
|
||||
this.port = port;
|
||||
this.app = express();
|
||||
this.rootPath = rootPath;
|
||||
this.distDir = distDir;
|
||||
this.system = system;
|
||||
this.system = new System<SilverBulletHooks>("server");
|
||||
|
||||
// Setup system
|
||||
this.eventHook = new EventHook();
|
||||
system.addHook(this.eventHook);
|
||||
this.system.addHook(this.eventHook);
|
||||
this.space = new Space(
|
||||
new EventedSpacePrimitives(
|
||||
new DiskSpacePrimitives(rootPath),
|
||||
@@ -61,15 +60,15 @@ export class ExpressServer {
|
||||
useNullAsDefault: true,
|
||||
});
|
||||
|
||||
system.registerSyscalls(["shell"], shellSyscalls(rootPath));
|
||||
system.addHook(new NodeCronHook());
|
||||
this.system.registerSyscalls(["shell"], shellSyscalls(rootPath));
|
||||
this.system.addHook(new NodeCronHook());
|
||||
|
||||
system.registerSyscalls([], pageIndexSyscalls(this.db));
|
||||
system.registerSyscalls([], spaceSyscalls(this.space));
|
||||
system.registerSyscalls([], eventSyscalls(this.eventHook));
|
||||
system.registerSyscalls([], markdownSyscalls(buildMarkdown([])));
|
||||
system.registerSyscalls([], jwtSyscalls());
|
||||
system.addHook(new EndpointHook(app, "/_/"));
|
||||
this.system.registerSyscalls([], pageIndexSyscalls(this.db));
|
||||
this.system.registerSyscalls([], spaceSyscalls(this.space));
|
||||
this.system.registerSyscalls([], eventSyscalls(this.eventHook));
|
||||
this.system.registerSyscalls([], markdownSyscalls(buildMarkdown([])));
|
||||
this.system.registerSyscalls([], jwtSyscalls());
|
||||
this.system.addHook(new EndpointHook(this.app, "/_/"));
|
||||
|
||||
let throttledRebuildMdExtensions = throttle(() => {
|
||||
this.rebuildMdExtensions();
|
||||
@@ -79,14 +78,14 @@ export class ExpressServer {
|
||||
plugLoaded: (plugName, plug) => {
|
||||
safeRun(async () => {
|
||||
console.log("Plug load", plugName);
|
||||
await system.load(plugName, plug, createSandbox);
|
||||
await this.system.load(plugName, plug, createSandbox);
|
||||
});
|
||||
throttledRebuildMdExtensions();
|
||||
},
|
||||
plugUnloaded: (plugName) => {
|
||||
safeRun(async () => {
|
||||
console.log("Plug unload", plugName);
|
||||
await system.unload(plugName);
|
||||
await this.system.unload(plugName);
|
||||
});
|
||||
throttledRebuildMdExtensions();
|
||||
},
|
||||
@@ -105,10 +104,12 @@ export class ExpressServer {
|
||||
);
|
||||
}
|
||||
|
||||
async init() {
|
||||
async start() {
|
||||
await ensurePageIndexTable(this.db);
|
||||
console.log("Setting up router");
|
||||
|
||||
this.app.use("/", express.static(this.distDir));
|
||||
|
||||
let fsRouter = express.Router();
|
||||
|
||||
// Page list
|
||||
@@ -267,5 +268,29 @@ export class ExpressServer {
|
||||
}
|
||||
res.status(200).header("Content-Type", "text/html").send(cachedIndex);
|
||||
});
|
||||
|
||||
this.server = http.createServer(this.app);
|
||||
this.server.listen(this.port, () => {
|
||||
console.log(`Server listening on port ${this.port}`);
|
||||
});
|
||||
}
|
||||
|
||||
async stop() {
|
||||
if (this.server) {
|
||||
console.log("Stopping");
|
||||
await this.system.unloadAll();
|
||||
console.log("Stopped plugs");
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
this.server!.close((err) => {
|
||||
this.server = undefined;
|
||||
console.log("stopped server");
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import express from "express";
|
||||
import http from "http";
|
||||
import yargs from "yargs";
|
||||
import { hideBin } from "yargs/helpers";
|
||||
import { SilverBulletHooks } from "@silverbulletmd/common/manifest";
|
||||
import { ExpressServer } from "./api_server";
|
||||
import { System } from "@silverbulletmd/plugos/system";
|
||||
import path from "path";
|
||||
|
||||
let args = yargs(hideBin(process.argv))
|
||||
@@ -23,23 +19,10 @@ if (!args._.length) {
|
||||
|
||||
const pagesPath = args._[0] as string;
|
||||
|
||||
const app = express();
|
||||
const server = http.createServer(app);
|
||||
const system = new System<SilverBulletHooks>("server");
|
||||
|
||||
const port = args.port;
|
||||
const distDir = path.resolve(`${__dirname}/../../silverbullet-web/dist`);
|
||||
|
||||
app.use("/", express.static(distDir));
|
||||
|
||||
const expressServer = new ExpressServer(app, pagesPath, distDir, system);
|
||||
expressServer
|
||||
.init()
|
||||
.then(async () => {
|
||||
server.listen(port, () => {
|
||||
console.log(`Server listening on port ${port}`);
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error(e);
|
||||
});
|
||||
const expressServer = new ExpressServer(port, pagesPath, distDir);
|
||||
expressServer.start().catch((e) => {
|
||||
console.error(e);
|
||||
});
|
||||
|
||||
@@ -9,10 +9,7 @@ import { HttpSpacePrimitives } from "@silverbulletmd/common/spaces/http_space_pr
|
||||
// @ts-ignore
|
||||
let isDesktop = typeof window.desktop !== "undefined";
|
||||
|
||||
// @ts-ignore
|
||||
let url = isDesktop ? window.desktop.url : "";
|
||||
|
||||
let serverSpace = new Space(new HttpSpacePrimitives(url), true);
|
||||
let serverSpace = new Space(new HttpSpacePrimitives(""), true);
|
||||
serverSpace.watch();
|
||||
|
||||
// // @ts-ignore
|
||||
@@ -46,6 +43,6 @@ if (!isDesktop) {
|
||||
navigator.serviceWorker
|
||||
.register(new URL("service_worker.ts", import.meta.url), { type: "module" })
|
||||
.then((r) => {
|
||||
// console.log("Service worker registered", r);
|
||||
console.log("Service worker registered", r);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2,8 +2,7 @@ import { Tag } from "@codemirror/highlight";
|
||||
|
||||
export const WikiLinkTag = Tag.define();
|
||||
export const WikiLinkPageTag = Tag.define();
|
||||
export const TagTag = Tag.define();
|
||||
export const MentionTag = Tag.define();
|
||||
export const CodeInfoTag = Tag.define();
|
||||
export const TaskTag = Tag.define();
|
||||
export const TaskMarkerTag = Tag.define();
|
||||
export const CommentTag = Tag.define();
|
||||
|
||||
@@ -46,13 +46,24 @@ export class PathPageNavigator {
|
||||
cb();
|
||||
}
|
||||
|
||||
decodeURI(): [string, number] {
|
||||
let parts = decodeURI(location.pathname).substring(1).split("@");
|
||||
let page =
|
||||
parts.length > 1 ? parts.slice(0, parts.length - 1).join("@") : parts[0];
|
||||
let pos = parts.length > 1 ? parts[parts.length - 1] : "0";
|
||||
if (pos.match(/^\d+$/)) {
|
||||
return [page, +pos];
|
||||
} else {
|
||||
return [`${page}@${pos}`, 0];
|
||||
}
|
||||
}
|
||||
|
||||
getCurrentPage(): string {
|
||||
let [page] = decodeURI(location.pathname).substring(1).split("@");
|
||||
return decodePageUrl(page);
|
||||
return decodePageUrl(this.decodeURI()[0]);
|
||||
}
|
||||
|
||||
getCurrentPos(): number {
|
||||
let [, pos] = decodeURI(location.pathname).substring(1).split("@");
|
||||
return +pos || 0;
|
||||
console.log("Pos", this.decodeURI()[1]);
|
||||
return this.decodeURI()[1];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import * as ct from "./customtags";
|
||||
import { Language, LanguageDescription, LanguageSupport } from "@codemirror/language";
|
||||
import { StreamLanguage } from "@codemirror/stream-parser";
|
||||
import { yaml } from "@codemirror/legacy-modes/mode/yaml";
|
||||
import { javascriptLanguage } from "@codemirror/lang-javascript";
|
||||
import { javascriptLanguage, typescriptLanguage } from "@codemirror/lang-javascript";
|
||||
import { MDExt, mdExtensionStyleTags, mdExtensionSyntaxConfig } from "./markdown_ext";
|
||||
|
||||
export const pageLinkRegex = /^\[\[([^\]]+)\]\]/;
|
||||
@@ -87,6 +87,11 @@ export default function buildMarkdown(mdExtensions: MDExt[]): Language {
|
||||
alias: ["js"],
|
||||
support: new LanguageSupport(javascriptLanguage),
|
||||
}),
|
||||
LanguageDescription.of({
|
||||
name: "typescript",
|
||||
alias: ["ts"],
|
||||
support: new LanguageSupport(typescriptLanguage),
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
{
|
||||
@@ -101,6 +106,7 @@ export default function buildMarkdown(mdExtensions: MDExt[]): Language {
|
||||
t.processingInstruction,
|
||||
"TableHeader/...": t.heading,
|
||||
TableCell: t.content,
|
||||
CodeInfo: ct.CodeInfoTag,
|
||||
}),
|
||||
...mdExtensions.map((mdExt) =>
|
||||
styleTags(mdExtensionStyleTags(mdExt))
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import { KeyBinding } from "@codemirror/view";
|
||||
import { syntaxTree } from "@codemirror/language";
|
||||
|
||||
const straightQuoteContexts = ["CommentBlock", "FencedCode", "InlineCode"];
|
||||
|
||||
// TODO: Add support for selection (put quotes around or create blockquote block?)
|
||||
function keyBindingForQuote(
|
||||
@@ -11,6 +14,21 @@ function keyBindingForQuote(
|
||||
run: (target): boolean => {
|
||||
let cursorPos = target.state.selection.main.from;
|
||||
let chBefore = target.state.sliceDoc(cursorPos - 1, cursorPos);
|
||||
|
||||
// Figure out the context, if in some sort of code/comment fragment don't be smart
|
||||
let node = syntaxTree(target.state).resolveInner(cursorPos);
|
||||
while (node) {
|
||||
if (straightQuoteContexts.includes(node.type.name)) {
|
||||
return false;
|
||||
}
|
||||
if (node.parent) {
|
||||
node = node.parent;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Ok, still here, let's use a smart quote
|
||||
let quote = right;
|
||||
if (/\W/.exec(chBefore) && !/[!\?,\.\-=“]/.exec(chBefore)) {
|
||||
quote = left;
|
||||
|
||||
@@ -14,10 +14,9 @@ export default function highlightStyles(mdExtension: MDExt[]) {
|
||||
{ tag: t.url, class: "url" },
|
||||
{ tag: ct.WikiLinkTag, class: "wiki-link" },
|
||||
{ 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: ct.CodeInfoTag, class: "code-info" },
|
||||
{ tag: ct.CommentTag, class: "comment" },
|
||||
{ tag: ct.CommentMarkerTag, class: "comment-marker" },
|
||||
{ tag: t.emphasis, class: "emphasis" },
|
||||
@@ -28,12 +27,14 @@ export default function highlightStyles(mdExtension: MDExt[]) {
|
||||
{ tag: t.inserted, class: "inserted" },
|
||||
{ tag: t.deleted, class: "deleted" },
|
||||
{ tag: t.literal, class: "literal" },
|
||||
{ tag: t.keyword, class: "keyword" },
|
||||
{ tag: t.list, class: "list" },
|
||||
{ tag: t.definition, class: "li" },
|
||||
{ tag: t.string, class: "string" },
|
||||
{ tag: t.number, class: "number" },
|
||||
{ tag: [t.regexp, t.escape, t.special(t.string)], class: "string2" },
|
||||
{ tag: t.variableName, class: "variableName" },
|
||||
{ tag: t.typeName, class: "typeName" },
|
||||
{ tag: t.comment, class: "comment" },
|
||||
{ tag: t.invalid, class: "invalid" },
|
||||
{ tag: t.processingInstruction, class: "meta" },
|
||||
|
||||
@@ -87,6 +87,38 @@
|
||||
.code {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
// Set this to defaults
|
||||
.comment {
|
||||
color: #989797;
|
||||
background-color: transparent;
|
||||
border-radius: 0;
|
||||
font-style: inherit;
|
||||
font-size: inherit;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
.keyword {
|
||||
color: #830000;
|
||||
}
|
||||
|
||||
.variableName {
|
||||
color: #036d9b;
|
||||
}
|
||||
|
||||
.typeName {
|
||||
color: #038138;
|
||||
}
|
||||
|
||||
.string,.string2 {
|
||||
color: #440377;
|
||||
}
|
||||
|
||||
//.code-info {
|
||||
// background: black;
|
||||
// border-radius: 3px;
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
.meta {
|
||||
|
||||
@@ -31,6 +31,13 @@ export function editorSyscalls(editor: Editor): SysCallMapping {
|
||||
"editor.getCurrentPage": (): string => {
|
||||
return editor.currentPage!;
|
||||
},
|
||||
// sets the current page name, without changing the content
|
||||
"editor.setPage": (ctx, newName: string) => {
|
||||
return editor.viewDispatch({
|
||||
type: "page-loaded",
|
||||
name: newName,
|
||||
});
|
||||
},
|
||||
"editor.getText": () => {
|
||||
return editor.editorView?.state.sliceDoc();
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user