From 6543c43e052274cf45df7504058599756d9b0d5a Mon Sep 17 00:00:00 2001 From: uga-rosa Date: Sat, 2 Dec 2023 23:50:49 +0900 Subject: [PATCH] Support *.code-snippets - VSCode global snippet files --- denops/denippet/loader.ts | 66 +++++++++++++++++++++++++++++---------- 1 file changed, 50 insertions(+), 16 deletions(-) diff --git a/denops/denippet/loader.ts b/denops/denippet/loader.ts index c8d250c..1983415 100644 --- a/denops/denippet/loader.ts +++ b/denops/denippet/loader.ts @@ -39,6 +39,23 @@ const isTSSnippet = is.ObjectOf({ export type TSSnippet = u.PredicateType; +// For compatibility with VSCode global snippet files (*.code-snippets) +const isGlobalSnippet = is.ObjectOf({ + prefix: is.OptionalOf(isStringOrArray), + body: isStringOrArray, + description: is.OptionalOf(is.String), + scope: is.OptionalOf(is.String), +}); + +export type GlobalSnippet = u.PredicateType; + +function langToFt(lang: string): string { + return { + csharp: "cs", + shellscript: "sh", + }[lang] ?? lang; +} + export type NormalizedSnippet = { name: string; prefix: string[]; @@ -105,21 +122,8 @@ export async function load( ): Promise { const extension = filepath.split(".").pop()!; let snippets: NormalizedSnippet[] = []; - if (["json", "toml", "yaml"].includes(extension)) { - const raw = await Deno.readTextFile(filepath); - const content = extension === "json" - ? JSON.parse(raw) - : extension === "toml" - ? TOML.parse(raw) - : YAML.parse(raw); - u.assert(content, is.RecordOf(isRawSnippet)); - snippets = Object.entries(content).map(([name, snip]) => ({ - ...snip, - name, - prefix: toArray(snip.prefix ?? name), - body: toString(snip.body), - })); - } else if (extension === "ts") { + + if (extension === "ts") { const content = await import(filepath).then((module) => module.snippets); u.assert(content, is.RecordOf(isTSSnippet)); snippets = Object.entries(content).map(([name, snip]) => ({ @@ -133,7 +137,37 @@ export async function load( }, })); } else { - throw new Error(`Unknown extension: ${extension}`); + const raw = await Deno.readTextFile(filepath); + if (["json", "toml", "yaml"].includes(extension)) { + const content = (extension === "json") + ? JSON.parse(raw) + : extension === "toml" + ? TOML.parse(raw) + : YAML.parse(raw); + u.assert(content, is.RecordOf(isRawSnippet)); + snippets = Object.entries(content).map(([name, snip]) => ({ + ...snip, + name, + prefix: toArray(snip.prefix ?? name), + body: toString(snip.body), + })); + } else if (extension === "code-snippets") { + const content = JSON.parse(raw); + u.assert(content, is.RecordOf(isGlobalSnippet)); + for (const [name, snippet] of Object.entries(content)) { + const ft = snippet.scope ? snippet.scope.split(",").map(langToFt) : "*"; + const snip = { + ...snippet, + name, + prefix: toArray(snippet.prefix ?? name), + body: toString(snippet.body), + }; + setSnippets(ft, [snip]); + } + return; + } else { + throw new Error(`Unknown extension: ${extension}`); + } } setSnippets(filetype, snippets);