Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Binary file added images/preview-demo.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@
]
},
"commands": [
{
"title": "Show Transformations with Preview",
"category": "String Manipulation",
"command": "string-manipulation.showTransformationsWithPreview"
},
{
"title": "Titleize",
"category": "String Manipulation",
Expand Down Expand Up @@ -212,6 +217,11 @@
{
"submenu": "string-manipulation",
"group": "7_modification"
},
{
"command": "string-manipulation.showTransformationsWithPreview",
"group": "7_modification",
"when": "editorHasSelection"
}
],
"string-manipulation": [
Expand Down
157 changes: 157 additions & 0 deletions src/commands/preview.ts
Original file line number Diff line number Diff line change
@@ -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<void> {
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);
}
4 changes: 4 additions & 0 deletions src/extension.ts
Original file line number Diff line number Diff line change
@@ -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(
Expand Down