Skip to content

Commit 2a7b6a2

Browse files
author
Marc Lipovsky
authored
Merge pull request #63 from marclipovsky/feature/context-menu
Feature/context menu
2 parents 9b11a57 + 5734d7c commit 2a7b6a2

File tree

5 files changed

+187
-0
lines changed

5 files changed

+187
-0
lines changed

README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,22 @@ To use these commands, press ⌘+p and enter any of the commands above while tex
5151

5252
![String Manipulation Screencast](images/demo.gif)
5353

54+
## Preview Transformations
55+
56+
The extension now includes a powerful preview feature that allows you to see how each transformation will affect your text before applying it.
57+
58+
### How to Use the Preview Feature
59+
60+
1. Select the text you want to transform
61+
2. Right-click to open the context menu
62+
3. Choose "Show Transformations with Preview"
63+
4. Browse through the available transformations with instant previews
64+
5. Select a transformation to apply it to your text
65+
66+
This feature makes it easier to find the right transformation without trial and error.
67+
68+
![String Manipulation Preview Feature](images/preview-demo.gif)
69+
5470
## 🧪 Introducing Labs Features
5571

5672
Introducing String Manipulation Labs

images/preview-demo.gif

909 KB
Loading

package.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@
4545
]
4646
},
4747
"commands": [
48+
{
49+
"title": "Show Transformations with Preview",
50+
"category": "String Manipulation",
51+
"command": "string-manipulation.showTransformationsWithPreview"
52+
},
4853
{
4954
"title": "Titleize",
5055
"category": "String Manipulation",
@@ -212,6 +217,11 @@
212217
{
213218
"submenu": "string-manipulation",
214219
"group": "7_modification"
220+
},
221+
{
222+
"command": "string-manipulation.showTransformationsWithPreview",
223+
"group": "7_modification",
224+
"when": "editorHasSelection"
215225
}
216226
],
217227
"string-manipulation": [

src/commands/preview.ts

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
import * as vscode from "vscode";
2+
import { commandNameFunctionMap } from "./index";
3+
import { functionNamesWithArgument, numberFunctionNames } from "./types";
4+
import { stringFunction } from "./index";
5+
6+
/**
7+
* Maximum length for preview text in context menu
8+
*/
9+
const MAX_PREVIEW_LENGTH = 30;
10+
11+
/**
12+
* Truncates a string to a maximum length and adds ellipsis if needed
13+
*/
14+
export function truncateForPreview(
15+
text: string,
16+
maxLength = MAX_PREVIEW_LENGTH
17+
): string {
18+
if (text.length <= maxLength) {
19+
return text;
20+
}
21+
return text.substring(0, maxLength - 3) + "...";
22+
}
23+
24+
/**
25+
* Gets a preview of the transformation for the selected text
26+
*/
27+
export function getTransformationPreview(
28+
commandName: string,
29+
selectedText: string
30+
): string | undefined {
31+
if (!selectedText || selectedText.trim() === "") {
32+
return undefined;
33+
}
34+
35+
// Skip preview for functions that require user input
36+
if (functionNamesWithArgument.includes(commandName)) {
37+
return undefined;
38+
}
39+
40+
// Skip preview for special functions that don't work well with simple previews
41+
if (
42+
commandName === "duplicateAndIncrement" ||
43+
commandName === "duplicateAndDecrement" ||
44+
commandName === "sequence"
45+
) {
46+
return undefined;
47+
}
48+
49+
try {
50+
let stringFunc: (str: string) => string;
51+
52+
if (numberFunctionNames.includes(commandName)) {
53+
stringFunc = (str: string) =>
54+
(commandNameFunctionMap[commandName] as Function)(str, {});
55+
} else {
56+
stringFunc = commandNameFunctionMap[commandName] as (
57+
str: string
58+
) => string;
59+
}
60+
61+
// Get the first line of text for preview
62+
const firstLine = selectedText.split("\n")[0];
63+
const transformed = stringFunc(firstLine);
64+
65+
return truncateForPreview(transformed);
66+
} catch (error) {
67+
console.error(`Error generating preview for ${commandName}:`, error);
68+
return undefined;
69+
}
70+
}
71+
72+
// Extended QuickPickItem interface to include the command name
73+
interface TransformationQuickPickItem extends vscode.QuickPickItem {
74+
commandName: string;
75+
}
76+
77+
/**
78+
* Shows a quick pick menu with previews of all transformations
79+
*/
80+
export async function showTransformationQuickPick(
81+
context: vscode.ExtensionContext
82+
): Promise<void> {
83+
const editor = vscode.window.activeTextEditor;
84+
if (!editor || editor.selections.length === 0) {
85+
vscode.window.showInformationMessage("No text selected");
86+
return;
87+
}
88+
89+
// Get the selected text
90+
const selection = editor.selection;
91+
const selectedText = editor.document.getText(selection);
92+
93+
if (!selectedText || selectedText.trim() === "") {
94+
vscode.window.showInformationMessage("No text selected");
95+
return;
96+
}
97+
98+
// Create quick pick items with previews
99+
const quickPickItems: TransformationQuickPickItem[] = [];
100+
101+
for (const commandName of Object.keys(commandNameFunctionMap)) {
102+
try {
103+
const preview = getTransformationPreview(commandName, selectedText);
104+
105+
// Format the command name for display
106+
const displayName = commandName
107+
.replace(/([A-Z])/g, " $1")
108+
.replace(/^./, (str) => str.toUpperCase());
109+
110+
// Create the quick pick item
111+
const item: TransformationQuickPickItem = {
112+
label: displayName,
113+
description: preview ? `→ ${preview}` : undefined,
114+
detail: preview ? "Preview of transformation" : "No preview available",
115+
commandName: commandName, // Store the actual command name
116+
};
117+
118+
quickPickItems.push(item);
119+
} catch (error) {
120+
console.error(
121+
`Error creating quick pick item for ${commandName}:`,
122+
error
123+
);
124+
}
125+
}
126+
127+
// Show the quick pick
128+
const selectedItem = await vscode.window.showQuickPick(quickPickItems, {
129+
placeHolder: "Select a string transformation (with preview)",
130+
matchOnDescription: true,
131+
matchOnDetail: true,
132+
});
133+
134+
if (selectedItem) {
135+
try {
136+
// Use the stored command name directly
137+
await stringFunction(selectedItem.commandName, context);
138+
} catch (error: any) {
139+
console.error("Error applying transformation:", error);
140+
vscode.window.showErrorMessage(
141+
`Failed to apply transformation: ${error.message || String(error)}`
142+
);
143+
}
144+
}
145+
}
146+
147+
/**
148+
* Registers the command to show the transformation quick pick
149+
*/
150+
export function registerPreviewCommand(context: vscode.ExtensionContext): void {
151+
const command = vscode.commands.registerCommand(
152+
"string-manipulation.showTransformationsWithPreview",
153+
() => showTransformationQuickPick(context)
154+
);
155+
156+
context.subscriptions.push(command);
157+
}

src/extension.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
import * as vscode from "vscode";
22
import { StringManipulationSidebar } from "./sidebar";
33
import { activate as stringManipulationActivate } from "./commands/index";
4+
import { registerPreviewCommand } from "./commands/preview";
45

56
export function activate(context: vscode.ExtensionContext) {
67
stringManipulationActivate(context);
78

9+
// Register command to show transformations with previews
10+
registerPreviewCommand(context);
11+
812
const sidebarProvider = new StringManipulationSidebar(context);
913

1014
context.subscriptions.push(

0 commit comments

Comments
 (0)