From a28c3fd5b8b32462dae63bca930f9a22dee2e307 Mon Sep 17 00:00:00 2001 From: Zef Hemel Date: Sun, 26 Jan 2025 07:35:41 +0100 Subject: [PATCH] Context sensitive slashCommands (with onlyContexts and exceptContexts) --- lib/manifest.ts | 6 ++- plugs/template/snippet.ts | 43 +++++++++++++------ plugs/template/types.ts | 8 ++++ web/hooks/slash_command.ts | 10 ++++- website/Library/Core/Snippet/code.md | 5 ++- .../Library/Core/Snippet/each-directive.md | 2 + website/Library/Core/Snippet/h1.md | 2 + website/Library/Core/Snippet/h2.md | 2 + website/Library/Core/Snippet/h3.md | 2 + website/Library/Core/Snippet/h4.md | 2 + website/Library/Core/Snippet/hr.md | 5 ++- website/Library/Core/Snippet/if-directive.md | 3 ++ .../Library/Core/Snippet/if-else-directive.md | 2 + website/Library/Core/Snippet/include-page.md | 5 ++- website/Library/Core/Snippet/item.md | 2 + website/Library/Core/Snippet/let-directive.md | 2 + website/Library/Core/Snippet/query.md | 5 ++- website/Library/Core/Snippet/table.md | 5 ++- website/Library/Core/Snippet/task.md | 2 + website/Library/Core/Snippet/template.md | 5 ++- 20 files changed, 95 insertions(+), 23 deletions(-) diff --git a/lib/manifest.ts b/lib/manifest.ts index 1f818896..d57036fd 100644 --- a/lib/manifest.ts +++ b/lib/manifest.ts @@ -53,8 +53,10 @@ export type SlashCommandDef = { name: string; description?: string; boost?: number; - // Parent AST nodes in which this slash command is available - contexts?: string[]; + // Parent AST nodes in which this slash command is available, defaults to everywhere + onlyContexts?: string[]; + // Parent AST nodes in which this slash command is not available + exceptContexts?: string[]; }; export type SlashCommandHookT = { slashCommand?: SlashCommandDef; diff --git a/plugs/template/snippet.ts b/plugs/template/snippet.ts index e14e9e38..3556895b 100644 --- a/plugs/template/snippet.ts +++ b/plugs/template/snippet.ts @@ -29,20 +29,37 @@ export async function snippetSlashComplete( // where hooks.snippet.slashCommand exists filter: ["attr", ["attr", ["attr", "hooks"], "snippet"], "slashCommand"], }, 5); - return { - options: allTemplates.map((template) => { - const snippetTemplate = template.hooks!.snippet!; + const options: SlashCompletionOption[] = []; + for (const template of allTemplates) { + const snippetTemplate = template.hooks!.snippet!; - return { - label: snippetTemplate.slashCommand, - detail: template.description, - order: snippetTemplate.order || 0, - templatePage: template.ref, - pageName: completeEvent.pageName, - invoke: "template.insertSnippetTemplate", - }; - }), - }; + if ( + snippetTemplate.onlyContexts && !snippetTemplate.onlyContexts.some( + (context) => + completeEvent.parentNodes.some((node) => node.startsWith(context)), + ) + ) { + continue; + } + if ( + snippetTemplate.exceptContexts && snippetTemplate.exceptContexts.some( + (context) => + completeEvent.parentNodes.some((node) => node.startsWith(context)), + ) + ) { + continue; + } + + options.push({ + label: snippetTemplate.slashCommand, + detail: template.description, + order: snippetTemplate.order || 0, + templatePage: template.ref, + pageName: completeEvent.pageName, + invoke: "template.insertSnippetTemplate", + }); + } + return { options }; } export async function insertSnippetTemplate( diff --git a/plugs/template/types.ts b/plugs/template/types.ts index ff02b04a..ec28b04d 100644 --- a/plugs/template/types.ts +++ b/plugs/template/types.ts @@ -31,6 +31,8 @@ export type SnippetConfig = CommandConfig & { // Deprecated: use matchRegex instead (for backwards compatibility) match?: string; insertAt?: "cursor" | "line-start" | "line-end" | "page-start" | "page-end"; // defaults to cursor + onlyContexts?: string[]; + exceptContexts?: string[]; }; export type WidgetConfig = { @@ -97,6 +99,12 @@ export const SnippetConfigSchema: JSONSchemaType = { order: { type: "number", nullable: true }, matchRegex: { type: "string", nullable: true }, match: { type: "string", nullable: true }, + onlyContexts: { type: "array", items: { type: "string" }, nullable: true }, + exceptContexts: { + type: "array", + items: { type: "string" }, + nullable: true, + }, insertAt: { type: "string", enum: [ diff --git a/web/hooks/slash_command.ts b/web/hooks/slash_command.ts index 2ba648a9..2dfb638c 100644 --- a/web/hooks/slash_command.ts +++ b/web/hooks/slash_command.ts @@ -110,10 +110,16 @@ export class SlashCommandHook implements Hook { // Check if the slash command is available in the current context const parentNodes = this.editor.extractParentNodes(ctx.state, currentNode); - // console.log("Parent nodes", parentNodes); for (const def of this.slashCommands.values()) { if ( - def.slashCommand.contexts && !def.slashCommand.contexts.some( + def.slashCommand.onlyContexts && !def.slashCommand.onlyContexts.some( + (context) => parentNodes.some((node) => node.startsWith(context)), + ) + ) { + continue; + } + if ( + def.slashCommand.exceptContexts && def.slashCommand.exceptContexts.some( (context) => parentNodes.some((node) => node.startsWith(context)), ) ) { diff --git a/website/Library/Core/Snippet/code.md b/website/Library/Core/Snippet/code.md index 4c75c523..e0909239 100644 --- a/website/Library/Core/Snippet/code.md +++ b/website/Library/Core/Snippet/code.md @@ -1,7 +1,10 @@ --- description: Insert a fenced code block tags: template -hooks.snippet.slashCommand: code +hooks.snippet: + slashCommand: code + exceptContexts: + - FencedCode --- ```|^| diff --git a/website/Library/Core/Snippet/each-directive.md b/website/Library/Core/Snippet/each-directive.md index a10fb5e6..5e2ae667 100644 --- a/website/Library/Core/Snippet/each-directive.md +++ b/website/Library/Core/Snippet/each-directive.md @@ -4,6 +4,8 @@ tags: template hooks.snippet: slashCommand: "#each" order: 10 + onlyContexts: + - FencedCode:template --- {{escapeDirective("#each |^|")}} diff --git a/website/Library/Core/Snippet/h1.md b/website/Library/Core/Snippet/h1.md index 55fc8495..e6c09862 100644 --- a/website/Library/Core/Snippet/h1.md +++ b/website/Library/Core/Snippet/h1.md @@ -4,5 +4,7 @@ description: Make this a level 1 heading hooks.snippet: slashCommand: h1 matchRegex: "^#*\\s*" + exceptContexts: + - FencedCode --- # \ No newline at end of file diff --git a/website/Library/Core/Snippet/h2.md b/website/Library/Core/Snippet/h2.md index e2b5a4e2..691d7cc2 100644 --- a/website/Library/Core/Snippet/h2.md +++ b/website/Library/Core/Snippet/h2.md @@ -4,5 +4,7 @@ description: Make this a level 2 heading hooks.snippet: slashCommand: h2 matchRegex: "^#*\\s*" + exceptContexts: + - FencedCode --- ## \ No newline at end of file diff --git a/website/Library/Core/Snippet/h3.md b/website/Library/Core/Snippet/h3.md index 5c23af5e..1cd3c284 100644 --- a/website/Library/Core/Snippet/h3.md +++ b/website/Library/Core/Snippet/h3.md @@ -4,5 +4,7 @@ description: Make this a level 3 heading hooks.snippet: slashCommand: h3 matchRegex: "^#*\\s*" + exceptContexts: + - FencedCode --- ### \ No newline at end of file diff --git a/website/Library/Core/Snippet/h4.md b/website/Library/Core/Snippet/h4.md index f9a47fce..f8d9c108 100644 --- a/website/Library/Core/Snippet/h4.md +++ b/website/Library/Core/Snippet/h4.md @@ -4,5 +4,7 @@ description: Make this a level 4 heading hooks.snippet: slashCommand: h4 matchRegex: "^#*\\s*" + exceptContexts: + - FencedCode --- #### \ No newline at end of file diff --git a/website/Library/Core/Snippet/hr.md b/website/Library/Core/Snippet/hr.md index b2ce4af3..d746a0eb 100644 --- a/website/Library/Core/Snippet/hr.md +++ b/website/Library/Core/Snippet/hr.md @@ -1,6 +1,9 @@ --- tags: template description: Insert a horizontal rule -hooks.snippet.slashCommand: hr +hooks.snippet: + slashCommand: hr + exceptContexts: + - FencedCode --- --- diff --git a/website/Library/Core/Snippet/if-directive.md b/website/Library/Core/Snippet/if-directive.md index 003990a5..60d8b6b3 100644 --- a/website/Library/Core/Snippet/if-directive.md +++ b/website/Library/Core/Snippet/if-directive.md @@ -4,6 +4,9 @@ tags: template hooks.snippet: slashCommand: "#if" order: 10 + onlyContexts: + - FencedCode:template + --- {{escapeDirective("#if |^|")}} diff --git a/website/Library/Core/Snippet/if-else-directive.md b/website/Library/Core/Snippet/if-else-directive.md index 638a231a..8809034d 100644 --- a/website/Library/Core/Snippet/if-else-directive.md +++ b/website/Library/Core/Snippet/if-else-directive.md @@ -4,6 +4,8 @@ tags: template hooks.snippet: slashCommand: "#if-else" order: 10 + onlyContexts: + - FencedCode:template --- {{escapeDirective("#if |^|")}} diff --git a/website/Library/Core/Snippet/include-page.md b/website/Library/Core/Snippet/include-page.md index 1d6d2593..396adff6 100644 --- a/website/Library/Core/Snippet/include-page.md +++ b/website/Library/Core/Snippet/include-page.md @@ -1,7 +1,10 @@ --- tags: template description: Add a live preview of a page -hooks.snippet.slashCommand: include-page +hooks.snippet: +slashCommand: include-page + exceptContexts: + - FencedCode --- ```include raw: "[[|^|]]" diff --git a/website/Library/Core/Snippet/item.md b/website/Library/Core/Snippet/item.md index 553b042f..4cba15b2 100644 --- a/website/Library/Core/Snippet/item.md +++ b/website/Library/Core/Snippet/item.md @@ -6,5 +6,7 @@ hooks.snippet: matchRegex: "^(\\s*)[\\-\\*]?\\s*" command: "Text: Turn into a bullet item" key: "Ctrl-q i" + exceptContexts: + - FencedCode --- $1* \ No newline at end of file diff --git a/website/Library/Core/Snippet/let-directive.md b/website/Library/Core/Snippet/let-directive.md index d0c0d807..79f4b00f 100644 --- a/website/Library/Core/Snippet/let-directive.md +++ b/website/Library/Core/Snippet/let-directive.md @@ -4,6 +4,8 @@ tags: template hooks.snippet: slashCommand: "#let" order: 10 + onlyContexts: + - FencedCode:template --- {{escapeDirective("#let @|^| = ")}} diff --git a/website/Library/Core/Snippet/query.md b/website/Library/Core/Snippet/query.md index 0648b34b..1ab4b7fd 100644 --- a/website/Library/Core/Snippet/query.md +++ b/website/Library/Core/Snippet/query.md @@ -1,7 +1,10 @@ --- description: Insert a live query tags: template -hooks.snippet.slashCommand: query +hooks.snippet: + slashCommand: query + exceptContexts: + - FencedCode --- ```query |^| diff --git a/website/Library/Core/Snippet/table.md b/website/Library/Core/Snippet/table.md index 0761950d..7c14cf4a 100644 --- a/website/Library/Core/Snippet/table.md +++ b/website/Library/Core/Snippet/table.md @@ -1,7 +1,10 @@ --- tags: template description: Insert a table -hooks.snippet.slashCommand: table +hooks.snippet: + slashCommand: table + exceptContexts: + - FencedCode --- | Header A | Header B | |----------|----------| diff --git a/website/Library/Core/Snippet/task.md b/website/Library/Core/Snippet/task.md index 108e4b43..8ec825cf 100644 --- a/website/Library/Core/Snippet/task.md +++ b/website/Library/Core/Snippet/task.md @@ -6,5 +6,7 @@ hooks.snippet: matchRegex: "^(\\s*)[\\-\\*]?\\s*(\\[[ xX]\\])?\\s*" command: "Text: Turn into task" key: "Ctrl-q t" + exceptContexts: + - FencedCode --- $1* [ ] \ No newline at end of file diff --git a/website/Library/Core/Snippet/template.md b/website/Library/Core/Snippet/template.md index 90ba62b0..d46fd74b 100644 --- a/website/Library/Core/Snippet/template.md +++ b/website/Library/Core/Snippet/template.md @@ -1,7 +1,10 @@ --- description: Insert a template tags: template -hooks.snippet.slashCommand: "template" +hooks.snippet: + slashCommand: "template" + exceptContexts: + - FencedCode --- ```template |^|