diff --git a/README.md b/README.md index b913d3d..b2f7615 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,22 @@ To use these commands, press โŒ˜+p and enter any of the commands above while tex ![String Manipulation Screencast](images/demo.gif) +## Preview Transformations + +The extension now includes a powerful preview feature that allows you to see how each transformation will affect your text before applying it. + +### How to Use the Preview Feature + +1. Select the text you want to transform +2. Right-click to open the context menu +3. Choose "Show Transformations with Preview" +4. Browse through the available transformations with instant previews +5. Select a transformation to apply it to your text + +This feature makes it easier to find the right transformation without trial and error. + +![String Manipulation Preview Feature](images/preview-demo.gif) + ## ๐Ÿงช Introducing Labs Features Introducing String Manipulation Labs diff --git a/images/preview-demo.gif b/images/preview-demo.gif new file mode 100644 index 0000000..e4ed4ad Binary files /dev/null and b/images/preview-demo.gif differ diff --git a/package.json b/package.json index 6c04354..59b1a5a 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,11 @@ ] }, "commands": [ + { + "title": "Show Transformations with Preview", + "category": "String Manipulation", + "command": "string-manipulation.showTransformationsWithPreview" + }, { "title": "Titleize", "category": "String Manipulation", @@ -212,6 +217,11 @@ { "submenu": "string-manipulation", "group": "7_modification" + }, + { + "command": "string-manipulation.showTransformationsWithPreview", + "group": "7_modification", + "when": "editorHasSelection" } ], "string-manipulation": [ diff --git a/src/commands/preview.ts b/src/commands/preview.ts new file mode 100644 index 0000000..1fdd08c --- /dev/null +++ b/src/commands/preview.ts @@ -0,0 +1,157 @@ +import * as vscode from "vscode"; +import { commandNameFunctionMap } from "./index"; +import { functionNamesWithArgument, numberFunctionNames } from "./types"; +import { stringFunction } from "./index"; + +/** + * Maximum length for preview text in context menu + */ +const MAX_PREVIEW_LENGTH = 30; + +/** + * Truncates a string to a maximum length and adds ellipsis if needed + */ +export function truncateForPreview( + text: string, + maxLength = MAX_PREVIEW_LENGTH +): string { + if (text.length <= maxLength) { + return text; + } + return text.substring(0, maxLength - 3) + "..."; +} + +/** + * Gets a preview of the transformation for the selected text + */ +export function getTransformationPreview( + commandName: string, + selectedText: string +): string | undefined { + if (!selectedText || selectedText.trim() === "") { + return undefined; + } + + // Skip preview for functions that require user input + if (functionNamesWithArgument.includes(commandName)) { + return undefined; + } + + // Skip preview for special functions that don't work well with simple previews + if ( + commandName === "duplicateAndIncrement" || + commandName === "duplicateAndDecrement" || + commandName === "sequence" + ) { + return undefined; + } + + try { + let stringFunc: (str: string) => string; + + if (numberFunctionNames.includes(commandName)) { + stringFunc = (str: string) => + (commandNameFunctionMap[commandName] as Function)(str, {}); + } else { + stringFunc = commandNameFunctionMap[commandName] as ( + str: string + ) => string; + } + + // Get the first line of text for preview + const firstLine = selectedText.split("\n")[0]; + const transformed = stringFunc(firstLine); + + return truncateForPreview(transformed); + } catch (error) { + console.error(`Error generating preview for ${commandName}:`, error); + return undefined; + } +} + +// Extended QuickPickItem interface to include the command name +interface TransformationQuickPickItem extends vscode.QuickPickItem { + commandName: string; +} + +/** + * Shows a quick pick menu with previews of all transformations + */ +export async function showTransformationQuickPick( + context: vscode.ExtensionContext +): Promise { + const editor = vscode.window.activeTextEditor; + if (!editor || editor.selections.length === 0) { + vscode.window.showInformationMessage("No text selected"); + return; + } + + // Get the selected text + const selection = editor.selection; + const selectedText = editor.document.getText(selection); + + if (!selectedText || selectedText.trim() === "") { + vscode.window.showInformationMessage("No text selected"); + return; + } + + // Create quick pick items with previews + const quickPickItems: TransformationQuickPickItem[] = []; + + for (const commandName of Object.keys(commandNameFunctionMap)) { + try { + const preview = getTransformationPreview(commandName, selectedText); + + // Format the command name for display + const displayName = commandName + .replace(/([A-Z])/g, " $1") + .replace(/^./, (str) => str.toUpperCase()); + + // Create the quick pick item + const item: TransformationQuickPickItem = { + label: displayName, + description: preview ? `โ†’ ${preview}` : undefined, + detail: preview ? "Preview of transformation" : "No preview available", + commandName: commandName, // Store the actual command name + }; + + quickPickItems.push(item); + } catch (error) { + console.error( + `Error creating quick pick item for ${commandName}:`, + error + ); + } + } + + // Show the quick pick + const selectedItem = await vscode.window.showQuickPick(quickPickItems, { + placeHolder: "Select a string transformation (with preview)", + matchOnDescription: true, + matchOnDetail: true, + }); + + if (selectedItem) { + try { + // Use the stored command name directly + await stringFunction(selectedItem.commandName, context); + } catch (error: any) { + console.error("Error applying transformation:", error); + vscode.window.showErrorMessage( + `Failed to apply transformation: ${error.message || String(error)}` + ); + } + } +} + +/** + * Registers the command to show the transformation quick pick + */ +export function registerPreviewCommand(context: vscode.ExtensionContext): void { + const command = vscode.commands.registerCommand( + "string-manipulation.showTransformationsWithPreview", + () => showTransformationQuickPick(context) + ); + + context.subscriptions.push(command); +} diff --git a/src/extension.ts b/src/extension.ts index b4c7d2c..b80d050 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1,10 +1,14 @@ import * as vscode from "vscode"; import { StringManipulationSidebar } from "./sidebar"; import { activate as stringManipulationActivate } from "./commands/index"; +import { registerPreviewCommand } from "./commands/preview"; export function activate(context: vscode.ExtensionContext) { stringManipulationActivate(context); + // Register command to show transformations with previews + registerPreviewCommand(context); + const sidebarProvider = new StringManipulationSidebar(context); context.subscriptions.push(