diff --git a/src/commands/constants.ts b/src/commands/constants.ts index 385f2060..66be1cb6 100644 --- a/src/commands/constants.ts +++ b/src/commands/constants.ts @@ -6,132 +6,107 @@ export const COMMAND_NAME_MAX_LENGTH = 50; export const DEFAULT_INLINE_EDIT_COMMANDS: InlineEditCommandSettings[] = [ { name: "Fix grammar and spelling", - prompt: - `Fix the grammar and spelling of the text below. Preserve all formatting, line breaks, and special characters. Do not add or remove any content. Return only the corrected text.\n\n` + - `${SELECTED_TEXT_PLACEHOLDER}`, + prompt: `Fix the grammar and spelling of {}. Preserve all formatting, line breaks, and special characters. Do not add or remove any content. Return only the corrected text.`, showInContextMenu: true, }, { name: "Translate to Chinese", - prompt: - `Translate the text below into Chinese: + prompt: `Translate {} into Chinese: 1. Preserve the meaning and tone 2. Maintain appropriate cultural context 3. Keep formatting and structure - Return only the translated text.\n\n` + - `${SELECTED_TEXT_PLACEHOLDER}`, + Return only the translated text.`, showInContextMenu: true, }, { name: "Summarize", - prompt: - `Create a bullet-point summary of the text below. Each bullet point should capture a key point. Return only the bullet-point summary.\n\n` + - `${SELECTED_TEXT_PLACEHOLDER}`, + prompt: `Create a bullet-point summary of {}. Each bullet point should capture a key point. Return only the bullet-point summary.`, showInContextMenu: true, }, { name: "Simplify", - prompt: - `Simplify the text below to a 6th-grade reading level (ages 11-12). Use simple sentences, common words, and clear explanations. Maintain the original key concepts. Return only the simplified text.\n\n` + - `{copilot-selection}`, + prompt: `Simplify {} to a 6th-grade reading level (ages 11-12). Use simple sentences, common words, and clear explanations. Maintain the original key concepts. Return only the simplified text.`, showInContextMenu: true, }, { name: "Emojify", - prompt: - `Add relevant emojis to enhance the text below. Follow these rules: + prompt: `Add relevant emojis to enhance {}. Follow these rules: 1. Insert emojis at natural breaks in the text 2. Never place two emojis next to each other 3. Keep all original text unchanged 4. Choose emojis that match the context and tone - Return only the emojified text.\n\n` + `{copilot-selection}`, + Return only the emojified text.`, showInContextMenu: true, }, { name: "Make shorter", - prompt: - `Reduce the text below to half its length while preserving these elements: + prompt: `Reduce {} to half its length while preserving these elements: 1. Main ideas and key points 2. Essential details 3. Original tone and style - Return only the shortened text.\n\n` + - `${SELECTED_TEXT_PLACEHOLDER}`, + Return only the shortened text.`, showInContextMenu: true, }, { name: "Make longer", - prompt: - `Expand the text below to twice its length by: + prompt: `Expand {} to twice its length by: 1. Adding relevant details and examples 2. Elaborating on key points 3. Maintaining the original tone and style - Return only the expanded text.\n\n` + `${SELECTED_TEXT_PLACEHOLDER}`, + Return only the expanded text.`, showInContextMenu: true, }, { name: "Generate table of contents", - prompt: - `Generate a hierarchical table of contents for the text below. Use appropriate heading levels (H1, H2, H3, etc.). Include page numbers if present. Return only the table of contents.\n\n` + - `${SELECTED_TEXT_PLACEHOLDER}`, + prompt: `Generate a hierarchical table of contents for {}. Use appropriate heading levels (H1, H2, H3, etc.). Include page numbers if present. Return only the table of contents.`, showInContextMenu: false, }, { name: "Generate glossary", - prompt: - `Create a glossary of important terms, concepts, and phrases from the text below. Format each entry as "Term: Definition". Sort entries alphabetically. Return only the glossary.\n\n` + - `{copilot-selection}`, + prompt: `Create a glossary of important terms, concepts, and phrases from {}. Format each entry as "Term: Definition". Sort entries alphabetically. Return only the glossary.`, showInContextMenu: false, }, { name: "Remove URLs", - prompt: - `Remove all URLs from the text below. Preserve all other content and formatting. URLs may be in various formats (http, https, www). Return only the text with URLs removed.\n\n` + - `${SELECTED_TEXT_PLACEHOLDER}`, + prompt: `Remove all URLs from {}. Preserve all other content and formatting. URLs may be in various formats (http, https, www). Return only the text with URLs removed.`, showInContextMenu: false, }, { name: "Rewrite as tweet", - prompt: - `Rewrite the text below as a single tweet with these requirements: + prompt: `Rewrite {} as a single tweet with these requirements: 1. Maximum 280 characters 2. Use concise, impactful language 3. Maintain the core message - Return only the tweet text.\n\n` + `${SELECTED_TEXT_PLACEHOLDER}`, + Return only the tweet text.`, showInContextMenu: false, }, { name: "Rewrite as tweet thread", - prompt: - `Convert the text below into a Twitter thread following these rules: + prompt: `Convert {} into a Twitter thread following these rules: 1. Each tweet must be under 240 characters 2. Start with "THREAD START" on its own line 3. Separate tweets with "\n\n---\n\n" 4. End with "THREAD END" on its own line 5. Make content engaging and clear - Return only the formatted thread.\n\n` + - `${SELECTED_TEXT_PLACEHOLDER}`, + Return only the formatted thread.`, showInContextMenu: false, }, { name: "Explain like I am 5", - prompt: - `Explain the text below in simple terms that a 5-year-old would understand: + prompt: `Explain {} in simple terms that a 5-year-old would understand: 1. Use basic vocabulary 2. Include simple analogies 3. Break down complex concepts - Return only the simplified explanation.\n\n` + - `${SELECTED_TEXT_PLACEHOLDER}`, + Return only the simplified explanation.`, showInContextMenu: false, }, { name: "Rewrite as press release", - prompt: - `Transform the text below into a professional press release: + prompt: `Transform {} into a professional press release: 1. Use formal, journalistic style 2. Include headline and dateline 3. Follow inverted pyramid structure - Return only the press release format.\n\n` + - `${SELECTED_TEXT_PLACEHOLDER}`, + Return only the press release format.`, showInContextMenu: false, }, ]; diff --git a/src/commands/inlineEditCommandUtils.ts b/src/commands/inlineEditCommandUtils.ts index 4ce50d4e..4bc29170 100644 --- a/src/commands/inlineEditCommandUtils.ts +++ b/src/commands/inlineEditCommandUtils.ts @@ -1,8 +1,9 @@ import { COMMAND_NAME_MAX_LENGTH, DEFAULT_INLINE_EDIT_COMMANDS, - SELECTED_TEXT_PLACEHOLDER, + SELECTED_TEXT_PLACEHOLDER as LEGACY_SELECTED_TEXT_PLACEHOLDER, } from "@/commands/constants"; +import { processPrompt } from "@/customPromptProcessor"; import { InlineEditCommandSettings, getSettings, useSettingsValue } from "@/settings/model"; export function getCommandId(commandName: string) { @@ -54,16 +55,42 @@ export function useInlineEditCommands(): InlineEditCommandSettings[] { } /** - * Replace the {copilot-selection} placeholder with the selected text. - * If the placeholder is not found, append the selected text to the prompt. + * Process the command prompt. */ -export function processCommandPrompt(prompt: string, selectedText: string) { - const index = prompt.indexOf(SELECTED_TEXT_PLACEHOLDER); +export async function processCommandPrompt( + prompt: string, + selectedText: string, + skipAppendingSelectedText = false +) { + const processedPrompt = await processPrompt( + prompt, + selectedText, + app.vault, + app.workspace.getActiveFile() + ); + + if (processedPrompt.includes("{selectedText}") || skipAppendingSelectedText) { + // Containing {selectedText} means the prompt was using the custom prompt + // processor way of handling the selected text. No need to go through the + // legacy placeholder. + return processedPrompt; + } + + // This is the legacy custom command selected text placeholder. It replaced + // {copilot-selection} in the prompt with the selected text. This is different + // from the custom prompt processor which uses {} in the prompt and appends + // the selected text to the prompt. We cannot change user's custom commands + // that have the old placeholder, so we need to support both. + // Also, selected text is required for custom commands. If neither `{}` nor + // `{copilot-selection}` is found, append the selected text to the prompt. + const index = processedPrompt.indexOf(LEGACY_SELECTED_TEXT_PLACEHOLDER); if (index === -1) { - return prompt + "\n\n" + selectedText; + return processedPrompt + "\n\n" + selectedText; } return ( - prompt.slice(0, index) + selectedText + prompt.slice(index + SELECTED_TEXT_PLACEHOLDER.length) + processedPrompt.slice(0, index) + + selectedText + + processedPrompt.slice(index + LEGACY_SELECTED_TEXT_PLACEHOLDER.length) ); } diff --git a/src/components/CustomPromptSyntaxInstruction.tsx b/src/components/CustomPromptSyntaxInstruction.tsx new file mode 100644 index 00000000..86afb397 --- /dev/null +++ b/src/components/CustomPromptSyntaxInstruction.tsx @@ -0,0 +1,22 @@ +import React from "react"; + +export function CustomPromptSyntaxInstruction() { + return ( + + ); +} diff --git a/src/components/modals/AddPromptModal.tsx b/src/components/modals/AddPromptModal.tsx index 4f87a771..d158d340 100644 --- a/src/components/modals/AddPromptModal.tsx +++ b/src/components/modals/AddPromptModal.tsx @@ -5,6 +5,7 @@ import { err2String } from "@/utils"; import { Input } from "@/components/ui/input"; import { Textarea } from "@/components/ui/textarea"; import { Button } from "@/components/ui/button"; +import { CustomPromptSyntaxInstruction } from "@/components/CustomPromptSyntaxInstruction"; interface AddPromptModalContentProps { initialTitle?: string; @@ -97,21 +98,7 @@ function AddPromptModalContent({
Use the following syntax in your prompt:
-
- - {"{}"} represents the selected text (not required). - - {`{[[Note Title]]}`} represents a note. - - {`{activeNote}`} represents the active note. - - {`{FolderPath}`} represents a folder of notes. - - - {`{#tag1, #tag2}`} represents ALL notes with ANY of the specified tags in their - property (an OR operation).{" "} - -
- - Tip: turn on debug mode to show the processed prompt in the chat window. - -
-
+