@silverbulletmd/silverbullet 2.9.0 → 2.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -23
- package/client/plugos/hooks/syscall.ts +24 -10
- package/client/plugos/syscalls/asset.ts +61 -23
- package/client/plugos/syscalls/clientStore.ts +32 -6
- package/client/plugos/syscalls/client_code_widget.ts +9 -4
- package/client/plugos/syscalls/code_widget.ts +26 -11
- package/client/plugos/syscalls/config.ts +146 -30
- package/client/plugos/syscalls/datastore.ts +146 -40
- package/client/plugos/syscalls/editor.ts +1432 -711
- package/client/plugos/syscalls/event.ts +46 -13
- package/client/plugos/syscalls/fetch.ts +123 -82
- package/client/plugos/syscalls/index.ts +242 -116
- package/client/plugos/syscalls/jsonschema.ts +107 -8
- package/client/plugos/syscalls/language.ts +38 -12
- package/client/plugos/syscalls/markdown.ts +166 -50
- package/client/plugos/syscalls/mq.ts +93 -20
- package/client/plugos/syscalls/schema_introspection.ts +33 -0
- package/client/plugos/syscalls/service_registry.ts +74 -20
- package/client/plugos/syscalls/shell.ts +51 -20
- package/client/plugos/syscalls/space.ts +169 -113
- package/client/plugos/syscalls/sync.ts +50 -19
- package/client/plugos/syscalls/system.ts +236 -139
- package/client/plugos/system.ts +21 -5
- package/client/space_lua/api_documentation.ts +107 -0
- package/client/space_lua/ast.ts +13 -0
- package/client/space_lua/eval.ts +12 -4
- package/client/space_lua/parse.ts +243 -108
- package/client/space_lua/pretty_print.ts +128 -54
- package/client/space_lua/query_collection.ts +4 -4
- package/client/space_lua/render_widget.ts +156 -0
- package/client/space_lua/runtime.ts +83 -22
- package/client/space_lua/stdlib/crypto.ts +8 -3
- package/client/space_lua/stdlib/encoding.ts +27 -9
- package/client/space_lua/stdlib/js.ts +137 -22
- package/client/space_lua/stdlib/load.ts +24 -15
- package/client/space_lua/stdlib/math.ts +323 -118
- package/client/space_lua/stdlib/net.ts +57 -9
- package/client/space_lua/stdlib/os.ts +111 -44
- package/client/space_lua/stdlib/space_lua.ts +344 -20
- package/client/space_lua/stdlib/string.ts +282 -104
- package/client/space_lua/stdlib/string_pack.ts +58 -19
- package/client/space_lua/stdlib/table.ts +195 -40
- package/client/space_lua/stdlib.ts +335 -93
- package/client/space_lua/syscalls.ts +270 -0
- package/dist/plug-compile.js +1 -1
- package/package.json +3 -3
- package/plug-api/lib/ref.ts +96 -0
- package/plug-api/lib/shortcut.ts +2 -1
- package/plug-api/syscalls/config.ts +5 -3
- package/plug-api/syscalls/editor.ts +16 -0
- package/plug-api/syscalls/index.ts +17 -1
- package/plug-api/syscalls/jsonschema.ts +9 -0
- package/plug-api/syscalls/lua.ts +7 -0
- package/plug-api/syscalls/shell.ts +0 -1
- package/plug-api/syscalls/system.ts +7 -0
- package/plug-api/system_mock.ts +2 -2
- package/plug-api/types/index.ts +52 -1
- package/plug-api/types/manifest.ts +22 -4
- package/plug-api/ui/cx.ts +1 -3
- package/plug-api/ui/index.ts +3 -0
- package/plug-api/ui/panel_styles.ts +4 -3
- package/plug-api/ui/slugify.ts +44 -0
- package/client/plugos/syscalls/lua.ts +0 -81
|
@@ -282,38 +282,71 @@ function luaFormatTime(fmt: string, d: Date, utc: boolean): string {
|
|
|
282
282
|
}
|
|
283
283
|
|
|
284
284
|
export const osApi = new LuaTable({
|
|
285
|
-
time: new LuaBuiltinFunction(
|
|
286
|
-
|
|
287
|
-
if (
|
|
288
|
-
|
|
285
|
+
time: new LuaBuiltinFunction({
|
|
286
|
+
callback: (_sf, tbl?: LuaTable) => {
|
|
287
|
+
if (tbl) {
|
|
288
|
+
if (!tbl.has("year")) {
|
|
289
|
+
throw new Error("time(): year is required");
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
if (!tbl.has("month")) {
|
|
293
|
+
throw new Error("time(): month is required");
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
if (!tbl.has("day")) {
|
|
297
|
+
throw new Error("time(): day is required");
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
const year = tbl.get("year");
|
|
301
|
+
const month = tbl.get("month");
|
|
302
|
+
const day = tbl.get("day");
|
|
303
|
+
const hour = tbl.get("hour") ?? 12;
|
|
304
|
+
const min = tbl.get("min") ?? 0;
|
|
305
|
+
const sec = tbl.get("sec") ?? 0;
|
|
306
|
+
const date = new Date(year, month - 1, day, hour, min, sec);
|
|
307
|
+
|
|
308
|
+
return Math.floor(date.getTime() / 1000);
|
|
289
309
|
}
|
|
290
310
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
+
return Math.floor(Date.now() / 1000);
|
|
312
|
+
},
|
|
313
|
+
description:
|
|
314
|
+
"Returns the current Unix timestamp or one built from a local date table.",
|
|
315
|
+
signatures: ["os.time(): integer", "os.time(dateTable): integer"],
|
|
316
|
+
parameters: [
|
|
317
|
+
{
|
|
318
|
+
name: "dateTable",
|
|
319
|
+
type: "table",
|
|
320
|
+
description:
|
|
321
|
+
"Local date fields `year`, `month`, `day`, and optional `hour`, `min`, and `sec`.",
|
|
322
|
+
optional: true,
|
|
323
|
+
},
|
|
324
|
+
],
|
|
325
|
+
returns: [
|
|
326
|
+
{ type: "integer", description: "Seconds since the Unix epoch." },
|
|
327
|
+
],
|
|
328
|
+
examples: [
|
|
329
|
+
{
|
|
330
|
+
code: "local timestamp = os.time({year = 2020, month = 1, day = 1})",
|
|
331
|
+
},
|
|
332
|
+
],
|
|
311
333
|
}),
|
|
312
334
|
|
|
313
335
|
// Returns the difference, from time `t1` to time `t2` in seconds
|
|
314
336
|
// In POSIX and some other systems, this value is exactly $t2-t1$.
|
|
315
|
-
difftime: new LuaBuiltinFunction(
|
|
316
|
-
|
|
337
|
+
difftime: new LuaBuiltinFunction({
|
|
338
|
+
callback: (_sf, t2: number, t1: number): number => {
|
|
339
|
+
return t2 - t1;
|
|
340
|
+
},
|
|
341
|
+
description:
|
|
342
|
+
"Returns the difference in seconds from timestamp `t1` to `t2`.",
|
|
343
|
+
parameters: [
|
|
344
|
+
{ name: "t2", type: "number" },
|
|
345
|
+
{ name: "t1", type: "number" },
|
|
346
|
+
],
|
|
347
|
+
returns: [
|
|
348
|
+
{ type: "number", description: "The value `t2 - t1` in seconds." },
|
|
349
|
+
],
|
|
317
350
|
}),
|
|
318
351
|
|
|
319
352
|
// Returns a string or a table containing date and time, formatted
|
|
@@ -336,29 +369,63 @@ export const osApi = new LuaTable({
|
|
|
336
369
|
// Otherwise, format specifiers follow ISO C `strftime`.
|
|
337
370
|
//
|
|
338
371
|
// If format is absent, it defaults to `%c`.
|
|
339
|
-
date: new LuaBuiltinFunction(
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
372
|
+
date: new LuaBuiltinFunction({
|
|
373
|
+
callback: (_sf, format?: string, timestamp?: number) => {
|
|
374
|
+
let fmt = format ?? "%c";
|
|
375
|
+
let utc = false;
|
|
376
|
+
|
|
377
|
+
if (fmt.startsWith("!")) {
|
|
378
|
+
utc = true;
|
|
379
|
+
fmt = fmt.slice(1);
|
|
380
|
+
}
|
|
347
381
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
382
|
+
const d =
|
|
383
|
+
timestamp !== undefined && timestamp !== null
|
|
384
|
+
? new Date(timestamp * 1000)
|
|
385
|
+
: new Date();
|
|
352
386
|
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
387
|
+
if (fmt === "*t") {
|
|
388
|
+
return dateTable(d, utc);
|
|
389
|
+
}
|
|
356
390
|
|
|
357
|
-
|
|
391
|
+
return luaFormatTime(fmt, d, utc);
|
|
392
|
+
},
|
|
393
|
+
description:
|
|
394
|
+
"Formats a timestamp as a date string or date table, optionally in UTC.",
|
|
395
|
+
parameters: [
|
|
396
|
+
{
|
|
397
|
+
name: "format",
|
|
398
|
+
type: "string",
|
|
399
|
+
description:
|
|
400
|
+
"`strftime`-style format, `*t` for a table, and optional leading `!` for UTC.",
|
|
401
|
+
optional: true,
|
|
402
|
+
},
|
|
403
|
+
{
|
|
404
|
+
name: "timestamp",
|
|
405
|
+
type: "number",
|
|
406
|
+
description: "Unix timestamp; defaults to the current time.",
|
|
407
|
+
optional: true,
|
|
408
|
+
},
|
|
409
|
+
],
|
|
410
|
+
returns: [
|
|
411
|
+
{ type: "string|table", description: "Formatted date or date fields." },
|
|
412
|
+
],
|
|
413
|
+
examples: [
|
|
414
|
+
{ code: 'print(os.date("%Y-%m-%d"))\nlocal utc = os.date("!*t")' },
|
|
415
|
+
],
|
|
358
416
|
}),
|
|
359
417
|
|
|
360
418
|
// Returns an approximation of CPU time used by the program in seconds.
|
|
361
|
-
clock: new LuaBuiltinFunction(
|
|
362
|
-
|
|
419
|
+
clock: new LuaBuiltinFunction({
|
|
420
|
+
callback: (_sf): number => {
|
|
421
|
+
return performance.now() / 1000.0;
|
|
422
|
+
},
|
|
423
|
+
description: "Returns a high-resolution elapsed time value in seconds.",
|
|
424
|
+
returns: [
|
|
425
|
+
{
|
|
426
|
+
type: "number",
|
|
427
|
+
description: "Browser performance timer in seconds.",
|
|
428
|
+
},
|
|
429
|
+
],
|
|
363
430
|
}),
|
|
364
431
|
});
|
|
@@ -1,12 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { LuaFunctionInfo } from "../../../plug-api/types/index.ts";
|
|
2
|
+
import { renderApiDocumentationMarkdown } from "../api_documentation.ts";
|
|
2
3
|
import type { LuaBlock, LuaExpression } from "../ast.ts";
|
|
3
4
|
import { evalExpression } from "../eval.ts";
|
|
5
|
+
import { parseBlock, parseExpressionString } from "../parse.ts";
|
|
4
6
|
import {
|
|
5
7
|
type PrintOptions,
|
|
6
8
|
prettyPrintBlock,
|
|
7
9
|
prettyPrintExpression,
|
|
8
10
|
} from "../pretty_print.ts";
|
|
9
11
|
import {
|
|
12
|
+
type ILuaFunction,
|
|
13
|
+
isILuaFunction,
|
|
10
14
|
jsToLuaValue,
|
|
11
15
|
LuaBuiltinFunction,
|
|
12
16
|
LuaEnv,
|
|
@@ -45,6 +49,112 @@ function createAugmentedEnv(
|
|
|
45
49
|
return env;
|
|
46
50
|
}
|
|
47
51
|
|
|
52
|
+
function globalEnv(sf: LuaStackFrame): LuaEnv {
|
|
53
|
+
const env = sf.threadLocal.get("_GLOBAL");
|
|
54
|
+
if (!(env instanceof LuaEnv)) {
|
|
55
|
+
throw new Error("_GLOBAL not defined");
|
|
56
|
+
}
|
|
57
|
+
return env;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function resolveApiValue(
|
|
61
|
+
sf: LuaStackFrame,
|
|
62
|
+
path: string,
|
|
63
|
+
): ILuaFunction | LuaTable | LuaEnv | null {
|
|
64
|
+
let value: any = globalEnv(sf);
|
|
65
|
+
for (const part of path.split(".")) {
|
|
66
|
+
if (value instanceof LuaEnv || value instanceof LuaTable) {
|
|
67
|
+
value = value.get(part, sf);
|
|
68
|
+
} else {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
if (value && typeof value.then === "function") {
|
|
72
|
+
throw new Error("Cannot describe asynchronously resolved API values");
|
|
73
|
+
}
|
|
74
|
+
if (value === null || value === undefined) return null;
|
|
75
|
+
}
|
|
76
|
+
return value;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function functionInfo(
|
|
80
|
+
value: unknown,
|
|
81
|
+
resolvedName?: string,
|
|
82
|
+
): LuaFunctionInfo | null {
|
|
83
|
+
if (!isILuaFunction(value)) return null;
|
|
84
|
+
return {
|
|
85
|
+
...(value.info ?? { kind: "builtin" }),
|
|
86
|
+
name: value.info?.name ?? resolvedName,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function describeFunction(
|
|
91
|
+
value: unknown,
|
|
92
|
+
resolvedName?: string,
|
|
93
|
+
): LuaTable | null {
|
|
94
|
+
const info = functionInfo(value, resolvedName);
|
|
95
|
+
return info ? (jsToLuaValue(info) as LuaTable) : null;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function listFunctionInfo(
|
|
99
|
+
sf: LuaStackFrame,
|
|
100
|
+
target?: LuaTable | string,
|
|
101
|
+
): LuaFunctionInfo[] {
|
|
102
|
+
let namespace: LuaTable | LuaEnv;
|
|
103
|
+
let prefix = "";
|
|
104
|
+
if (typeof target === "string") {
|
|
105
|
+
const resolved = resolveApiValue(sf, target);
|
|
106
|
+
if (!(resolved instanceof LuaTable) && !(resolved instanceof LuaEnv)) {
|
|
107
|
+
return [];
|
|
108
|
+
}
|
|
109
|
+
namespace = resolved;
|
|
110
|
+
prefix = `${target}.`;
|
|
111
|
+
} else if (target instanceof LuaTable) {
|
|
112
|
+
namespace = target;
|
|
113
|
+
} else {
|
|
114
|
+
namespace = globalEnv(sf);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const functions: LuaFunctionInfo[] = [];
|
|
118
|
+
for (const key of [...new Set(namespace.keys())].sort()) {
|
|
119
|
+
const value = namespace.get(key, sf);
|
|
120
|
+
if (value && typeof (value as any).then === "function") continue;
|
|
121
|
+
const info = functionInfo(value, `${prefix}${key}`);
|
|
122
|
+
if (info) functions.push(info);
|
|
123
|
+
}
|
|
124
|
+
return functions;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function functionNamespace(info: LuaFunctionInfo): string | undefined {
|
|
128
|
+
const separator = info.name?.lastIndexOf(".") ?? -1;
|
|
129
|
+
return separator > 0 ? info.name!.slice(0, separator) : undefined;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function apiDocumentationTarget(
|
|
133
|
+
sf: LuaStackFrame,
|
|
134
|
+
target?: ILuaFunction | LuaTable | string,
|
|
135
|
+
): { functions: LuaFunctionInfo[]; context?: string } {
|
|
136
|
+
if (typeof target === "string") {
|
|
137
|
+
const resolved = resolveApiValue(sf, target);
|
|
138
|
+
const info = functionInfo(resolved, target);
|
|
139
|
+
if (info) {
|
|
140
|
+
return { functions: [info], context: functionNamespace(info) };
|
|
141
|
+
}
|
|
142
|
+
if (resolved instanceof LuaTable || resolved instanceof LuaEnv) {
|
|
143
|
+
return { functions: listFunctionInfo(sf, target), context: target };
|
|
144
|
+
}
|
|
145
|
+
return { functions: [], context: target };
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const info = functionInfo(target);
|
|
149
|
+
if (info) {
|
|
150
|
+
return { functions: [info], context: functionNamespace(info) };
|
|
151
|
+
}
|
|
152
|
+
if (target instanceof LuaTable) {
|
|
153
|
+
return { functions: listFunctionInfo(sf, target) };
|
|
154
|
+
}
|
|
155
|
+
return { functions: listFunctionInfo(sf) };
|
|
156
|
+
}
|
|
157
|
+
|
|
48
158
|
/**
|
|
49
159
|
* Interpolates a string with lua expressions and returns the result.
|
|
50
160
|
*
|
|
@@ -126,6 +236,93 @@ function toPrintOptions(
|
|
|
126
236
|
}
|
|
127
237
|
|
|
128
238
|
export const spaceluaApi = new LuaTable({
|
|
239
|
+
describe: new LuaBuiltinFunction({
|
|
240
|
+
callback: (sf, target: ILuaFunction | string) => {
|
|
241
|
+
const value =
|
|
242
|
+
typeof target === "string" ? resolveApiValue(sf, target) : target;
|
|
243
|
+
return describeFunction(
|
|
244
|
+
value,
|
|
245
|
+
typeof target === "string" ? target : undefined,
|
|
246
|
+
);
|
|
247
|
+
},
|
|
248
|
+
description:
|
|
249
|
+
"Returns structured documentation for a Lua function value or dotted API name.",
|
|
250
|
+
parameters: [
|
|
251
|
+
{
|
|
252
|
+
name: "functionOrName",
|
|
253
|
+
type: "function|string",
|
|
254
|
+
description: "Function value or dotted API name to inspect.",
|
|
255
|
+
},
|
|
256
|
+
],
|
|
257
|
+
returns: [
|
|
258
|
+
{
|
|
259
|
+
type: "table|nil",
|
|
260
|
+
description:
|
|
261
|
+
"Structured function metadata, or `nil` when the target is not a function.",
|
|
262
|
+
},
|
|
263
|
+
],
|
|
264
|
+
examples: [
|
|
265
|
+
{
|
|
266
|
+
code: 'local info = spacelua.describe(editor.getText)\nprint(info.name, info.kind, info.see)\n\nlocal sameInfo = spacelua.describe("editor.getText")',
|
|
267
|
+
},
|
|
268
|
+
],
|
|
269
|
+
see: "API/spacelua",
|
|
270
|
+
}),
|
|
271
|
+
listFunctions: new LuaBuiltinFunction({
|
|
272
|
+
callback: (sf, target?: LuaTable | string) =>
|
|
273
|
+
jsToLuaValue(listFunctionInfo(sf, target)),
|
|
274
|
+
description:
|
|
275
|
+
"Lists documented functions in the global environment or an API namespace.",
|
|
276
|
+
parameters: [
|
|
277
|
+
{
|
|
278
|
+
name: "namespace",
|
|
279
|
+
type: "table|string",
|
|
280
|
+
description: "Namespace table or dotted name; omit for globals.",
|
|
281
|
+
optional: true,
|
|
282
|
+
},
|
|
283
|
+
],
|
|
284
|
+
returns: [{ type: "table", description: "Function metadata records." }],
|
|
285
|
+
examples: [
|
|
286
|
+
{
|
|
287
|
+
code: 'for info in each(spacelua.listFunctions("editor")) do\n print(info.name, info.description or info.see)\nend',
|
|
288
|
+
},
|
|
289
|
+
],
|
|
290
|
+
see: "API/spacelua",
|
|
291
|
+
}),
|
|
292
|
+
renderApiDocumentation: new LuaBuiltinFunction({
|
|
293
|
+
callback: (sf, target?: ILuaFunction | LuaTable | string): string => {
|
|
294
|
+
const selection = apiDocumentationTarget(sf, target);
|
|
295
|
+
return renderApiDocumentationMarkdown(
|
|
296
|
+
selection.functions,
|
|
297
|
+
selection.context,
|
|
298
|
+
);
|
|
299
|
+
},
|
|
300
|
+
description:
|
|
301
|
+
"Renders API documentation for a function, namespace, or the global environment as Markdown.",
|
|
302
|
+
parameters: [
|
|
303
|
+
{
|
|
304
|
+
name: "target",
|
|
305
|
+
type: "function|table|string",
|
|
306
|
+
description:
|
|
307
|
+
"Function value, namespace table, or dotted API name to document; omit for globals.",
|
|
308
|
+
optional: true,
|
|
309
|
+
},
|
|
310
|
+
],
|
|
311
|
+
returns: [{ type: "string", description: "Rendered Markdown." }],
|
|
312
|
+
examples: [
|
|
313
|
+
{
|
|
314
|
+
code: '${spacelua.renderApiDocumentation("lua")}',
|
|
315
|
+
description: "Render a namespace as a live API-page directive.",
|
|
316
|
+
language: "markdown",
|
|
317
|
+
},
|
|
318
|
+
{
|
|
319
|
+
code: '${spacelua.renderApiDocumentation("editor.getText")}',
|
|
320
|
+
description: "Render one function by its dotted API name.",
|
|
321
|
+
language: "markdown",
|
|
322
|
+
},
|
|
323
|
+
],
|
|
324
|
+
see: "API/spacelua",
|
|
325
|
+
}),
|
|
129
326
|
/**
|
|
130
327
|
* Parses a lua expression and returns the parsed expression.
|
|
131
328
|
*
|
|
@@ -133,8 +330,25 @@ export const spaceluaApi = new LuaTable({
|
|
|
133
330
|
* @param luaExpression - The lua expression to parse.
|
|
134
331
|
* @returns The parsed expression.
|
|
135
332
|
*/
|
|
136
|
-
parseExpression: new LuaBuiltinFunction(
|
|
137
|
-
|
|
333
|
+
parseExpression: new LuaBuiltinFunction({
|
|
334
|
+
callback: (_sf, luaExpression: string) => {
|
|
335
|
+
return parseExpressionString(luaExpression);
|
|
336
|
+
},
|
|
337
|
+
description: "Parses a Lua expression and returns its AST.",
|
|
338
|
+
parameters: [
|
|
339
|
+
{
|
|
340
|
+
name: "luaExpression",
|
|
341
|
+
type: "string",
|
|
342
|
+
description: "Lua expression to parse.",
|
|
343
|
+
},
|
|
344
|
+
],
|
|
345
|
+
returns: [{ type: "table", description: "Parsed expression AST." }],
|
|
346
|
+
examples: [
|
|
347
|
+
{
|
|
348
|
+
code: 'local parsed = spacelua.parseExpression("1 + 1")',
|
|
349
|
+
},
|
|
350
|
+
],
|
|
351
|
+
see: "API/spacelua",
|
|
138
352
|
}),
|
|
139
353
|
/**
|
|
140
354
|
* Parses a lua chunk (block) and returns the parsed AST block.
|
|
@@ -143,8 +357,22 @@ export const spaceluaApi = new LuaTable({
|
|
|
143
357
|
* @param code - The lua code to parse.
|
|
144
358
|
* @returns The parsed block.
|
|
145
359
|
*/
|
|
146
|
-
parseBlock: new LuaBuiltinFunction(
|
|
147
|
-
|
|
360
|
+
parseBlock: new LuaBuiltinFunction({
|
|
361
|
+
callback: (_sf, code: string): LuaBlock => {
|
|
362
|
+
return parseBlock(code);
|
|
363
|
+
},
|
|
364
|
+
description:
|
|
365
|
+
"Parses a Lua chunk and returns its AST. Blocks retain comments in source order with their exact text, kind, and source range.",
|
|
366
|
+
parameters: [
|
|
367
|
+
{ name: "code", type: "string", description: "Lua code to parse." },
|
|
368
|
+
],
|
|
369
|
+
returns: [{ type: "table", description: "Parsed block AST." }],
|
|
370
|
+
examples: [
|
|
371
|
+
{
|
|
372
|
+
code: 'local parsed = spacelua.parseBlock("local x = 1\\nreturn x + 2")',
|
|
373
|
+
},
|
|
374
|
+
],
|
|
375
|
+
see: "API/spacelua",
|
|
148
376
|
}),
|
|
149
377
|
/**
|
|
150
378
|
* Pretty-prints a parsed lua block AST back to formatted source.
|
|
@@ -154,11 +382,30 @@ export const spaceluaApi = new LuaTable({
|
|
|
154
382
|
* @param opts - Optional formatting options.
|
|
155
383
|
* @returns The formatted lua source.
|
|
156
384
|
*/
|
|
157
|
-
prettyPrintBlock: new LuaBuiltinFunction(
|
|
158
|
-
(sf, block: LuaBlock, opts?: LuaTable): string => {
|
|
385
|
+
prettyPrintBlock: new LuaBuiltinFunction({
|
|
386
|
+
callback: (sf, block: LuaBlock, opts?: LuaTable): string => {
|
|
159
387
|
return prettyPrintBlock(block, toPrintOptions(sf, opts));
|
|
160
388
|
},
|
|
161
|
-
|
|
389
|
+
description:
|
|
390
|
+
"Pretty-prints a parsed Lua block AST. Comments are preserved while their placement and indentation are normalized.",
|
|
391
|
+
parameters: [
|
|
392
|
+
{ name: "block", type: "table", description: "Parsed block AST." },
|
|
393
|
+
{
|
|
394
|
+
name: "options",
|
|
395
|
+
type: "table",
|
|
396
|
+
description:
|
|
397
|
+
"Formatting options: `indentWidth`, `quote`, and `trailingComma`.",
|
|
398
|
+
optional: true,
|
|
399
|
+
},
|
|
400
|
+
],
|
|
401
|
+
returns: [{ type: "string", description: "Formatted Lua source." }],
|
|
402
|
+
examples: [
|
|
403
|
+
{
|
|
404
|
+
code: 'local formatted = spacelua.prettyPrintBlock(spacelua.parseBlock("if a then return 1 end"))\nprint(formatted)',
|
|
405
|
+
},
|
|
406
|
+
],
|
|
407
|
+
see: "API/spacelua",
|
|
408
|
+
}),
|
|
162
409
|
/**
|
|
163
410
|
* Pretty-prints a parsed lua expression AST back to formatted source.
|
|
164
411
|
*
|
|
@@ -167,11 +414,33 @@ export const spaceluaApi = new LuaTable({
|
|
|
167
414
|
* @param opts - Optional formatting options.
|
|
168
415
|
* @returns The formatted lua source.
|
|
169
416
|
*/
|
|
170
|
-
prettyPrintExpression: new LuaBuiltinFunction(
|
|
171
|
-
(sf, expr: LuaExpression, opts?: LuaTable): string => {
|
|
417
|
+
prettyPrintExpression: new LuaBuiltinFunction({
|
|
418
|
+
callback: (sf, expr: LuaExpression, opts?: LuaTable): string => {
|
|
172
419
|
return prettyPrintExpression(expr, toPrintOptions(sf, opts));
|
|
173
420
|
},
|
|
174
|
-
|
|
421
|
+
description: "Pretty-prints a parsed Lua expression AST.",
|
|
422
|
+
parameters: [
|
|
423
|
+
{
|
|
424
|
+
name: "parsedExpr",
|
|
425
|
+
type: "table",
|
|
426
|
+
description: "Parsed expression AST.",
|
|
427
|
+
},
|
|
428
|
+
{
|
|
429
|
+
name: "options",
|
|
430
|
+
type: "table",
|
|
431
|
+
description:
|
|
432
|
+
"Formatting options: `indentWidth`, `quote`, and `trailingComma`.",
|
|
433
|
+
optional: true,
|
|
434
|
+
},
|
|
435
|
+
],
|
|
436
|
+
returns: [{ type: "string", description: "Formatted Lua source." }],
|
|
437
|
+
examples: [
|
|
438
|
+
{
|
|
439
|
+
code: 'local parsed = spacelua.parseExpression("{a=1,b=2}")\nprint(spacelua.prettyPrintExpression(parsed))',
|
|
440
|
+
},
|
|
441
|
+
],
|
|
442
|
+
see: "API/spacelua",
|
|
443
|
+
}),
|
|
175
444
|
/**
|
|
176
445
|
* Evaluates a parsed lua expression and returns the result.
|
|
177
446
|
*
|
|
@@ -180,28 +449,83 @@ export const spaceluaApi = new LuaTable({
|
|
|
180
449
|
* @param envAugmentation - An optional environment to augment the global environment with.
|
|
181
450
|
* @returns The result of the evaluated expression.
|
|
182
451
|
*/
|
|
183
|
-
evalExpression: new LuaBuiltinFunction(
|
|
184
|
-
async (
|
|
452
|
+
evalExpression: new LuaBuiltinFunction({
|
|
453
|
+
callback: async (
|
|
454
|
+
sf,
|
|
455
|
+
parsedExpr: LuaExpression,
|
|
456
|
+
envAugmentation?: LuaTable,
|
|
457
|
+
) => {
|
|
185
458
|
const env = createAugmentedEnv(sf, envAugmentation);
|
|
186
459
|
return luaValueToJS(await evalExpression(parsedExpr, env, sf), sf);
|
|
187
460
|
},
|
|
188
|
-
|
|
461
|
+
description:
|
|
462
|
+
"Evaluates a parsed Lua expression, optionally with additional environment values.",
|
|
463
|
+
parameters: [
|
|
464
|
+
{
|
|
465
|
+
name: "parsedExpr",
|
|
466
|
+
type: "table",
|
|
467
|
+
description: "Parsed expression AST.",
|
|
468
|
+
},
|
|
469
|
+
{
|
|
470
|
+
name: "envAugmentation",
|
|
471
|
+
type: "table",
|
|
472
|
+
description: "Values added to the expression environment.",
|
|
473
|
+
optional: true,
|
|
474
|
+
},
|
|
475
|
+
],
|
|
476
|
+
returns: [{ description: "Evaluated result." }],
|
|
477
|
+
examples: [
|
|
478
|
+
{
|
|
479
|
+
code: 'local parsed = spacelua.parseExpression("x + y")\nlocal result = spacelua.evalExpression(parsed, {x = 1, y = 2})\nprint(result)',
|
|
480
|
+
},
|
|
481
|
+
],
|
|
482
|
+
see: "API/spacelua",
|
|
483
|
+
}),
|
|
189
484
|
/**
|
|
190
485
|
* Interpolates a string with lua expressions and returns the result.
|
|
191
486
|
*/
|
|
192
|
-
interpolate: new LuaBuiltinFunction(
|
|
193
|
-
(sf, template: string, envAugmentation?: LuaTable | any) => {
|
|
487
|
+
interpolate: new LuaBuiltinFunction({
|
|
488
|
+
callback: (sf, template: string, envAugmentation?: LuaTable | any) => {
|
|
194
489
|
if (envAugmentation && !(envAugmentation instanceof LuaTable)) {
|
|
195
490
|
envAugmentation = jsToLuaValue(envAugmentation);
|
|
196
491
|
}
|
|
197
492
|
return interpolateLuaString(sf, template, envAugmentation);
|
|
198
493
|
},
|
|
199
|
-
|
|
494
|
+
description:
|
|
495
|
+
"Interpolates `${...}` Lua expressions in a string, optionally with additional environment values.",
|
|
496
|
+
parameters: [
|
|
497
|
+
{
|
|
498
|
+
name: "template",
|
|
499
|
+
type: "string",
|
|
500
|
+
description: "Template containing `${...}` expressions.",
|
|
501
|
+
},
|
|
502
|
+
{
|
|
503
|
+
name: "envAugmentation",
|
|
504
|
+
type: "table",
|
|
505
|
+
description: "Values added to the interpolation environment.",
|
|
506
|
+
optional: true,
|
|
507
|
+
},
|
|
508
|
+
],
|
|
509
|
+
returns: [{ type: "string", description: "Interpolated string." }],
|
|
510
|
+
examples: [
|
|
511
|
+
{
|
|
512
|
+
code: 'local greeting = spacelua.interpolate("Hello ${name}!", {name = "Pete"})\nprint(greeting)',
|
|
513
|
+
},
|
|
514
|
+
],
|
|
515
|
+
see: "API/spacelua",
|
|
516
|
+
}),
|
|
200
517
|
/**
|
|
201
518
|
* Returns your SilverBullet instance's base URL
|
|
202
519
|
*/
|
|
203
|
-
baseUrl: new LuaBuiltinFunction(
|
|
204
|
-
|
|
205
|
-
|
|
520
|
+
baseUrl: new LuaBuiltinFunction({
|
|
521
|
+
callback: () => {
|
|
522
|
+
//NOTE: Removing trailing slash to stay compatible with original code: `location.protocol + "//" + location.host;`
|
|
523
|
+
return document.baseURI.replace(/\/*$/, "");
|
|
524
|
+
},
|
|
525
|
+
description:
|
|
526
|
+
"Returns the SilverBullet instance's base URL, or `nil` when run on the server.",
|
|
527
|
+
returns: [{ type: "string|nil" }],
|
|
528
|
+
examples: [{ code: "local url = spacelua.baseUrl()\nprint(url)" }],
|
|
529
|
+
see: "API/spacelua",
|
|
206
530
|
}),
|
|
207
531
|
});
|