Skip to content

Commit 00d437a

Browse files
Attempting to preview transform before updating text.
1 parent 3810fdd commit 00d437a

File tree

2 files changed

+156
-1
lines changed

2 files changed

+156
-1
lines changed

package.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,16 @@
4545
"onCommand:string-manipulation.decrement",
4646
"onCommand:string-manipulation.duplicateAndIncrement",
4747
"onCommand:string-manipulation.duplicateAndDecrement",
48-
"onCommand:string-manipulation.sequence"
48+
"onCommand:string-manipulation.sequence",
49+
"onCommand:string-manipulation.quickPickTransform"
4950
],
5051
"contributes": {
5152
"commands": [
53+
{
54+
"title": "Quick Pick",
55+
"category": "String Manipulation",
56+
"command": "string-manipulation.quickPickTransform"
57+
},
5258
{
5359
"title": "Titleize",
5460
"category": "String Manipulation",

src/extension.ts

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,155 @@ export function activate(context: vscode.ExtensionContext) {
174174
)
175175
);
176176
});
177+
178+
// Register the new quick pick command with Temporary Preview using Overlays
179+
context.subscriptions.push(
180+
vscode.commands.registerCommand(
181+
"string-manipulation.quickPickTransform",
182+
async () => {
183+
const editor = vscode.window.activeTextEditor;
184+
if (!editor) {
185+
vscode.window.showInformationMessage(
186+
"No active editor found for transformation."
187+
);
188+
return;
189+
}
190+
191+
const selections = editor.selections;
192+
if (selections.length === 0) {
193+
vscode.window.showInformationMessage("No text selected.");
194+
return;
195+
}
196+
197+
// Store original text for all selections to allow reverting
198+
const originalTexts = selections.map((sel) =>
199+
editor.document.getText(sel)
200+
);
201+
202+
// Function to apply a transformation and generate preview texts
203+
const applyTransformation = async (commandName: string) => {
204+
let stringFunc: (str: string) => string;
205+
206+
if (functionNamesWithArgument.includes(commandName)) {
207+
const valueStr = await vscode.window.showInputBox({
208+
prompt: `Enter a number for "${commandName}"`,
209+
validateInput: (input) => {
210+
const num = Number(input);
211+
return isNaN(num) ? "Please enter a valid number." : null;
212+
},
213+
ignoreFocusOut: true,
214+
});
215+
if (valueStr === undefined) {
216+
return null; // User cancelled input
217+
}
218+
const value = Number(valueStr);
219+
stringFunc = (commandNameFunctionMap[commandName] as Function)(
220+
value
221+
);
222+
} else if (numberFunctionNames.includes(commandName)) {
223+
stringFunc = (str: string) =>
224+
(commandNameFunctionMap[commandName] as Function)(str, {});
225+
} else {
226+
stringFunc = commandNameFunctionMap[commandName] as StringFunction;
227+
}
228+
229+
const transformedTexts = originalTexts.map((text) =>
230+
stringFunc(text)
231+
);
232+
233+
return transformedTexts;
234+
};
235+
236+
// Prepare QuickPick items
237+
const quickPickItems: vscode.QuickPickItem[] = Object.keys(
238+
commandNameFunctionMap
239+
).map((cmd) => ({
240+
label: cmd,
241+
description: "Apply " + cmd + " transformation",
242+
}));
243+
244+
// Create the QuickPick
245+
const quickPick = vscode.window.createQuickPick();
246+
quickPick.items = quickPickItems;
247+
quickPick.placeholder = "Select a transformation to preview";
248+
249+
// Create a decoration type for previews
250+
const decorationType = vscode.window.createTextEditorDecorationType({
251+
// Customize the appearance of the preview overlay
252+
backgroundColor: "rgba(0, 255, 0, 0.3)", // Semi-transparent green background for preview
253+
border: "1px dashed rgba(0, 255, 0, 0.8)", // Dashed border to indicate preview
254+
isWholeLine: false,
255+
// Optionally, show the transformed text as an overlay
256+
after: {
257+
contentText: "",
258+
color: "rgba(0,0,0,0.8)",
259+
backgroundColor: "rgba(0,255,0,0.2)",
260+
},
261+
});
262+
263+
// Store current decorations to manage their lifecycle
264+
let currentDecorations: vscode.DecorationOptions[] = [];
265+
266+
// Function to update decorations based on transformed texts
267+
const updateDecorations = (transformedTexts: string[]) => {
268+
currentDecorations = selections.map((sel, idx) => {
269+
const transformed = transformedTexts[idx];
270+
return {
271+
range: sel,
272+
renderOptions: {
273+
after: {
274+
contentText: ` → ${transformed}`,
275+
color: "rgba(0, 0, 0, 0.6)",
276+
fontStyle: "italic",
277+
},
278+
},
279+
};
280+
});
281+
editor.setDecorations(decorationType, currentDecorations);
282+
};
283+
284+
// Function to clear decorations
285+
const clearDecorations = () => {
286+
editor.setDecorations(decorationType, []);
287+
currentDecorations = [];
288+
};
289+
290+
// Handle selection changes in QuickPick to update previews
291+
quickPick.onDidChangeSelection(async (selection) => {
292+
if (selection[0]) {
293+
const cmd = selection[0].label;
294+
const transformed = await applyTransformation(cmd);
295+
if (transformed) {
296+
updateDecorations(transformed);
297+
} else {
298+
clearDecorations();
299+
}
300+
}
301+
});
302+
303+
// Handle QuickPick closure to remove decorations
304+
quickPick.onDidHide(() => {
305+
clearDecorations();
306+
quickPick.dispose();
307+
decorationType.dispose();
308+
});
309+
310+
// Handle acceptance of a transformation
311+
quickPick.onDidAccept(async () => {
312+
const selected = quickPick.selectedItems[0];
313+
if (selected) {
314+
const cmd = selected.label;
315+
clearDecorations(); // Remove previews before applying changes
316+
await stringFunction(cmd, context);
317+
}
318+
quickPick.dispose();
319+
decorationType.dispose();
320+
});
321+
322+
quickPick.show();
323+
}
324+
)
325+
);
177326
}
178327

179328
export { commandNameFunctionMap };

0 commit comments

Comments
 (0)