1
0

Code complete fixes and changelog

This commit is contained in:
Zef Hemel 2023-10-04 17:14:24 +02:00
parent 371932e085
commit d8797aa805
9 changed files with 115 additions and 121 deletions

View File

@ -27,108 +27,68 @@ import {
} from "./deps.ts";
import { highlightingDirectiveParser } from "./markdown_parser/parser.ts";
const languageCache = new Map<string, Language>();
export const builtinLanguages: Record<string, Language> = {
"meta": StreamLanguage.define(yamlLanguage),
"yaml": StreamLanguage.define(yamlLanguage),
"template": StreamLanguage.define(yamlLanguage),
"embed": StreamLanguage.define(yamlLanguage),
"data": StreamLanguage.define(yamlLanguage),
"javascript": javascriptLanguage,
"js": javascriptLanguage,
"typescript": typescriptLanguage,
"ts": typescriptLanguage,
"sql": StreamLanguage.define(sqlLanguage),
"postgresql": StreamLanguage.define(postgresqlLanguage),
"pgsql": StreamLanguage.define(postgresqlLanguage),
"postgres": StreamLanguage.define(postgresqlLanguage),
"rust": StreamLanguage.define(rustLanguage),
"rs": StreamLanguage.define(rustLanguage),
"css": StreamLanguage.define(sqlLanguage),
"html": htmlLanguage,
"python": StreamLanguage.define(pythonLanguage),
"py": StreamLanguage.define(pythonLanguage),
"protobuf": StreamLanguage.define(protobufLanguage),
"proto": StreamLanguage.define(protobufLanguage),
"shell": StreamLanguage.define(shellLanguage),
"sh": StreamLanguage.define(shellLanguage),
"bash": StreamLanguage.define(shellLanguage),
"zsh": StreamLanguage.define(shellLanguage),
"fish": StreamLanguage.define(shellLanguage),
"swift": StreamLanguage.define(rustLanguage),
"toml": StreamLanguage.define(tomlLanguage),
"json": StreamLanguage.define(jsonLanguage),
"xml": StreamLanguage.define(xmlLanguage),
"c": StreamLanguage.define(cLanguage),
"cpp": StreamLanguage.define(cppLanguage),
"c++": StreamLanguage.define(cppLanguage),
"cxx": StreamLanguage.define(cppLanguage),
"java": StreamLanguage.define(javaLanguage),
"csharp": StreamLanguage.define(csharpLanguage),
"cs": StreamLanguage.define(csharpLanguage),
"c#": StreamLanguage.define(csharpLanguage),
"scala": StreamLanguage.define(scalaLanguage),
"kotlin": StreamLanguage.define(kotlinLanguage),
"objc": StreamLanguage.define(objectiveCLanguage),
"objective-c": StreamLanguage.define(objectiveCLanguage),
"objectivec": StreamLanguage.define(objectiveCLanguage),
"objcpp": StreamLanguage.define(objectiveCppLanguage),
"objective-cpp": StreamLanguage.define(objectiveCppLanguage),
"objectivecpp": StreamLanguage.define(objectiveCppLanguage),
"objective-c++": StreamLanguage.define(objectiveCppLanguage),
"objectivec++": StreamLanguage.define(objectiveCppLanguage),
"dart": StreamLanguage.define(dartLanguage),
"query": LRLanguage.define({
name: "query",
parser: highlightingDirectiveParser,
}),
};
export function languageFor(name: string): Language | null {
if (languageCache.has(name)) {
return languageCache.get(name)!;
if (builtinLanguages[name]) {
return builtinLanguages[name];
}
const language = languageLookup(name);
if (!language) {
return null;
}
languageCache.set(name, language);
return language;
}
function languageLookup(name: string): Language | null {
switch (name) {
case "meta":
case "yaml":
case "template":
case "embed":
case "data":
return StreamLanguage.define(yamlLanguage);
case "javascript":
case "js":
return javascriptLanguage;
case "typescript":
case "ts":
return typescriptLanguage;
case "sql":
return StreamLanguage.define(sqlLanguage);
case "postgresql":
case "pgsql":
case "postgres":
return StreamLanguage.define(postgresqlLanguage);
case "rust":
case "rs":
return StreamLanguage.define(rustLanguage);
case "css":
return StreamLanguage.define(sqlLanguage);
case "html":
return htmlLanguage;
case "python":
case "py":
return StreamLanguage.define(pythonLanguage);
case "protobuf":
case "proto":
return StreamLanguage.define(protobufLanguage);
case "shell":
case "sh":
case "bash":
case "zsh":
case "fish":
return StreamLanguage.define(shellLanguage);
case "swift":
return StreamLanguage.define(rustLanguage);
case "toml":
return StreamLanguage.define(tomlLanguage);
case "json":
return StreamLanguage.define(jsonLanguage);
case "xml":
return StreamLanguage.define(xmlLanguage);
case "c":
return StreamLanguage.define(cLanguage);
case "cpp":
case "c++":
case "cxx":
return StreamLanguage.define(cppLanguage);
case "java":
return StreamLanguage.define(javaLanguage);
case "csharp":
case "cs":
case "c#":
return StreamLanguage.define(csharpLanguage);
case "scala":
return StreamLanguage.define(scalaLanguage);
case "kotlin":
return StreamLanguage.define(kotlinLanguage);
case "objc":
case "objective-c":
case "objectivec":
return StreamLanguage.define(objectiveCLanguage);
case "objcpp":
case "objective-cpp":
case "objectivecpp":
case "objective-c++":
case "objectivec++":
return StreamLanguage.define(objectiveCppLanguage);
case "dart":
return StreamLanguage.define(dartLanguage);
case "query":
return LRLanguage.define({
name: "query",
parser: highlightingDirectiveParser,
});
default:
if (name.startsWith("#")) {
return StreamLanguage.define(yamlLanguage);
}
if (name.startsWith("#")) {
return StreamLanguage.define(yamlLanguage);
}
return null;
}

View File

@ -1,7 +1,7 @@
import { SysCallMapping } from "../../plugos/system.ts";
import { parse } from "../markdown_parser/parse_tree.ts";
import type { ParseTree } from "$sb/lib/tree.ts";
import { languageFor } from "../languages.ts";
import { builtinLanguages, languageFor } from "../languages.ts";
export function languageSyscalls(): SysCallMapping {
return {
@ -16,5 +16,10 @@ export function languageSyscalls(): SysCallMapping {
}
return parse(lang, code);
},
"language.listLanguages": (
_ctx,
): string[] => {
return Object.keys(builtinLanguages);
},
};
}

View File

@ -14,3 +14,7 @@ export function parseLanguage(
): Promise<ParseTree> {
return syscall("language.parseLanguage", language, code);
}
export function listLanguages(): Promise<string[]> {
return syscall("language.listLanguages");
}

View File

@ -34,14 +34,3 @@ functions:
path: command.ts:convertToLiveQuery
command:
name: "Directive: Convert Query to Live Query"
# Templates
insertEvalTemplate:
redirect: template.insertTemplateText
slashCommand:
name: eval
description: Evaluate a JavaScript expression
value: |
<!-- #eval |^| -->
<!-- /eval -->

View File

@ -1,5 +1,5 @@
import { CompleteEvent } from "$sb/app_event.ts";
import { events } from "$sb/syscalls.ts";
import { events, language } from "$sb/syscalls.ts";
import {
AttributeCompleteEvent,
AttributeCompletion,
@ -7,11 +7,12 @@ import {
export async function queryComplete(completeEvent: CompleteEvent) {
const fencedParent = completeEvent.parentNodes.find((node) =>
node === "FencedCode:query"
node.startsWith("FencedCode:query")
);
if (!fencedParent) {
return null;
}
// First let's try to match the query source
let querySourceMatch = /^\s*([\w\-_]*)$/.exec(
completeEvent.linePrefix,
);
@ -41,8 +42,10 @@ export async function queryComplete(completeEvent: CompleteEvent) {
};
}
querySourceMatch = /^\s*([\w\-_]*)/.exec(
completeEvent.linePrefix,
// If that doesn't work, let's try to match other bits of the query
// For this we do need to find the query source, though, so let's look for it in fencedParent
querySourceMatch = /^[\n\r\s]*([\w\-_]+)/.exec(
fencedParent.slice("FencedCode:query".length),
);
const whereMatch =
/(where|order\s+by|and|or|select(\s+[\w\s,]+)?)\s+([\w\-_]*)$/
@ -78,3 +81,23 @@ function attributeCompletionsToCMCompletion(
}),
);
}
export async function languageComplete(completeEvent: CompleteEvent) {
const languagePrefix = /^```(\w*)$/.exec(
completeEvent.linePrefix,
);
if (!languagePrefix) {
return null;
}
const allLanguages = await language.listLanguages();
return {
from: completeEvent.pos - languagePrefix[1].length,
options: allLanguages.map(
(lang) => ({
label: lang,
type: "language",
}),
),
};
}

View File

@ -15,6 +15,11 @@ functions:
events:
- editor:complete
languageComplete:
path: complete.ts:languageComplete
events:
- editor:complete
# Slash commands
insertQuery:
redirect: template.insertTemplateText

View File

@ -46,10 +46,10 @@ functions:
redirect: insertTemplateText
slashCommand:
name: code
description: Insert code block
description: Insert fenced code block
value: |
```
|^|
```|^|
```
insertHRTemplate:

View File

@ -640,9 +640,8 @@ export class Client {
let node: SyntaxNode | null = currentNode;
do {
if (node.name === "FencedCode") {
const code = editorState.sliceDoc(node.from + 3, node.to);
const fencedCodeLanguage = code.split("\n")[0];
parentNodes.push(`FencedCode:${fencedCodeLanguage}`);
const body = editorState.sliceDoc(node.from + 3, node.to - 3);
parentNodes.push(`FencedCode:${body}`);
} else {
parentNodes.push(node.name);
}

View File

@ -3,6 +3,15 @@ release.
---
## Next
* Fixes to auto-sizing of [[Live Queries]] and [[Live Templates]] widgets
* Fixed the combination of `limit` and `order by` not working well
* Auto complete for queries now works for queries split across multiple lines
* Auto complete for fenced code block languages (use the `/code` slash command)
* Slightly tweaked semantics for the `=` operator on arrays, see [[Live Queries]] for details
---
## 0.5.0
Oh boy, this is a big one. This release brings you the following: