full PC config setup
shifting towards manual symlinks for more complex setup than laptop, allows for GUI settings changes to actually apply, and is much easier than nix-ifying every config
This commit is contained in:
149 files changed
+9539
-478
No files matched your search
@@ -0,0 +1,39 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.CHOICE_WORKSPACE_DESC = exports.CHOICE_WORKSPACE_LABEL = exports.CHOICE_GLOBAL_DESC = exports.CHOICE_GLOBAL_LABEL = exports.PROMPT_CONFIRM_OVERWRITE = exports.PROMPT_CONFIRM_DELETE = exports.PROMPT_SELECT_PATTERN = exports.PROMPT_SELECT_SCOPE = exports.PROMPT_PATTERN_NAME_PLACEHOLDER = exports.PROMPT_PATTERN_NAME = exports.INFO_PATTERN_DELETED = exports.INFO_PATTERN_SAVED = exports.INFO_PATTERN_LOADED = exports.INFO_NO_PATTERNS = exports.ERR_MANAGING_PATTERNS = exports.ERR_LOADING_PATTERN = exports.ERR_SAVING_PATTERN = exports.ERR_PATTERN_NAME_EMPTY = exports.ERR_NO_SEARCH_STATE = exports.UI_MANAGE_TITLE = exports.UI_SECTION_USER = exports.UI_SECTION_WORKSPACE = exports.UI_NO_PATTERNS_FOUND = exports.UI_NO_PATTERNS = exports.MSG_TYPE_SAVE = exports.MSG_TYPE_LOAD = exports.MSG_TYPE_DELETE = exports.MSG_TYPE_PATTERNS = exports.MSG_TYPE_READY = exports.COMMAND_MANAGE = exports.SCOPE_WORKSPACE = exports.SCOPE_GLOBAL = exports.CONFIG_KEY_WORKSPACE_PATTERNS = exports.CONFIG_KEY_USER_PATTERNS = exports.CONFIG_NAMESPACE = void 0;
|
||||
exports.CONFIG_NAMESPACE = 'patternStore';
|
||||
exports.CONFIG_KEY_USER_PATTERNS = 'savedPatterns';
|
||||
exports.CONFIG_KEY_WORKSPACE_PATTERNS = 'workspacePatterns';
|
||||
exports.SCOPE_GLOBAL = 'global';
|
||||
exports.SCOPE_WORKSPACE = 'workspace';
|
||||
exports.COMMAND_MANAGE = 'patternStore.manage';
|
||||
exports.MSG_TYPE_READY = 'ready';
|
||||
exports.MSG_TYPE_PATTERNS = 'patterns';
|
||||
exports.MSG_TYPE_DELETE = 'delete';
|
||||
exports.MSG_TYPE_LOAD = 'load';
|
||||
exports.MSG_TYPE_SAVE = 'save';
|
||||
exports.UI_NO_PATTERNS = 'No patterns yet';
|
||||
exports.UI_NO_PATTERNS_FOUND = 'No patterns found';
|
||||
exports.UI_SECTION_WORKSPACE = 'Workspace';
|
||||
exports.UI_SECTION_USER = 'User';
|
||||
exports.UI_MANAGE_TITLE = 'Manage Patterns';
|
||||
exports.ERR_NO_SEARCH_STATE = 'Could not read current search state';
|
||||
exports.ERR_PATTERN_NAME_EMPTY = 'Pattern name cannot be empty';
|
||||
exports.ERR_SAVING_PATTERN = 'Error saving pattern';
|
||||
exports.ERR_LOADING_PATTERN = 'Error loading pattern';
|
||||
exports.ERR_MANAGING_PATTERNS = 'Error managing patterns';
|
||||
exports.INFO_NO_PATTERNS = 'No saved patterns found. Use "PatternStore: Save Pattern" to create one.';
|
||||
exports.INFO_PATTERN_LOADED = 'Loaded pattern';
|
||||
exports.INFO_PATTERN_SAVED = 'Pattern saved';
|
||||
exports.INFO_PATTERN_DELETED = 'Pattern deleted';
|
||||
exports.PROMPT_PATTERN_NAME = 'Enter a name for this pattern';
|
||||
exports.PROMPT_PATTERN_NAME_PLACEHOLDER = 'e.g., "Replace quotes with angles"';
|
||||
exports.PROMPT_SELECT_SCOPE = 'Choose storage scope';
|
||||
exports.PROMPT_SELECT_PATTERN = 'Select a pattern to load';
|
||||
exports.PROMPT_CONFIRM_DELETE = 'Delete pattern';
|
||||
exports.PROMPT_CONFIRM_OVERWRITE = 'already exists. Overwrite?';
|
||||
exports.CHOICE_GLOBAL_LABEL = 'Global';
|
||||
exports.CHOICE_GLOBAL_DESC = 'Available in all workspaces';
|
||||
exports.CHOICE_WORKSPACE_LABEL = 'Workspace';
|
||||
exports.CHOICE_WORKSPACE_DESC = 'Only for this workspace';
|
||||
//# sourceMappingURL=constants.js.map
|
||||
@@ -0,0 +1,127 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.activate = activate;
|
||||
exports.deactivate = deactivate;
|
||||
const vscode = __importStar(require("vscode"));
|
||||
const storage = __importStar(require("./storage"));
|
||||
const searchCtx = __importStar(require("./searchCtx"));
|
||||
const WebviewManager_1 = require("./webview/WebviewManager");
|
||||
/**
|
||||
* Called when the extension is activated
|
||||
*/
|
||||
function activate(context) {
|
||||
console.log('PatternStore extension is now active!');
|
||||
// Register command: Manage Patterns
|
||||
const manageCommand = vscode.commands.registerCommand('patternStore.manage', async () => {
|
||||
await managePatternsCommand(context.extensionUri);
|
||||
});
|
||||
context.subscriptions.push(manageCommand);
|
||||
}
|
||||
/**
|
||||
* Called when the extension is deactivated
|
||||
*/
|
||||
function deactivate() {
|
||||
console.log('PatternStore extension is now deactivated');
|
||||
}
|
||||
/**
|
||||
* Command: Save the current search state as a pattern
|
||||
*/
|
||||
async function savePatternCommand() {
|
||||
try {
|
||||
vscode.window.showInformationMessage('PatternStore: Save Pattern command executed!');
|
||||
// Get current search state
|
||||
const searchState = await searchCtx.getCurrentSearchState();
|
||||
if (!searchState) {
|
||||
vscode.window.showErrorMessage('Could not read current search state');
|
||||
return;
|
||||
}
|
||||
// Prompt for pattern name
|
||||
const label = await vscode.window.showInputBox({
|
||||
prompt: 'Enter a name for this pattern',
|
||||
placeHolder: 'e.g., "Replace quotes with angles"',
|
||||
validateInput: (value) => {
|
||||
if (!value || value.trim().length === 0) {
|
||||
return 'Pattern name cannot be empty';
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
if (!label) {
|
||||
return; // User cancelled
|
||||
}
|
||||
// Ask for scope
|
||||
const scopeChoice = await vscode.window.showQuickPick([
|
||||
{ label: 'Global', description: 'Available in all workspaces', value: 'global' },
|
||||
{ label: 'Workspace', description: 'Only for this workspace', value: 'workspace' }
|
||||
], { placeHolder: 'Choose storage scope' });
|
||||
if (!scopeChoice) {
|
||||
return; // User cancelled
|
||||
}
|
||||
// Create pattern object
|
||||
const pattern = {
|
||||
id: 'new', // Temporary ID for new patterns
|
||||
label: label.trim(),
|
||||
find: searchState.find || '',
|
||||
replace: searchState.replace || '',
|
||||
flags: searchState.flags || {
|
||||
isRegex: false,
|
||||
isCaseSensitive: false,
|
||||
matchWholeWord: false,
|
||||
isMultiline: false
|
||||
},
|
||||
scope: scopeChoice.value
|
||||
};
|
||||
// Check if pattern exists (will check when we implement storage)
|
||||
const exists = storage.patternExists(pattern.label, pattern.scope);
|
||||
if (exists) {
|
||||
const overwrite = await vscode.window.showWarningMessage(`A pattern named "${pattern.label}" already exists. Overwrite?`, 'Yes', 'No');
|
||||
if (overwrite !== 'Yes') {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Save pattern
|
||||
await storage.savePattern(pattern);
|
||||
}
|
||||
catch (error) {
|
||||
vscode.window.showErrorMessage(`Error saving pattern: ${error}`);
|
||||
}
|
||||
}
|
||||
async function managePatternsCommand(extensionUri) {
|
||||
console.log('Manage Patterns command pressed - opening webview');
|
||||
// For now, just open global patterns. We'll add separate commands later
|
||||
WebviewManager_1.WebviewManager.show(extensionUri, 'global');
|
||||
}
|
||||
//# sourceMappingURL=extension.js.map
|
||||
@@ -0,0 +1,129 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getCurrentSearchState = getCurrentSearchState;
|
||||
exports.loadPatternIntoSearch = loadPatternIntoSearch;
|
||||
const vscode = __importStar(require("vscode"));
|
||||
/**
|
||||
* Get the current search state from the Search panel
|
||||
* Returns null if unable to get the state
|
||||
*
|
||||
* NOTE: VS Code doesn't expose search panel state via API.
|
||||
* This function tries to use editor selection as fallback.
|
||||
*/
|
||||
async function getCurrentSearchState() {
|
||||
// Try to get selected text from active editor
|
||||
const editor = vscode.window.activeTextEditor;
|
||||
const selection = editor?.document.getText(editor.selection);
|
||||
if (selection && selection.length > 0) {
|
||||
// Use selection as find text
|
||||
return {
|
||||
find: selection,
|
||||
replace: '',
|
||||
flags: {
|
||||
isRegex: false,
|
||||
isCaseSensitive: false,
|
||||
matchWholeWord: false,
|
||||
isMultiline: false
|
||||
}
|
||||
};
|
||||
}
|
||||
// No selection available - return null
|
||||
// User will need to enter manually
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* Resolve placeholders like ${prompt:varname} in multiple strings
|
||||
* Prompts once per unique placeholder name and reuses the value
|
||||
*/
|
||||
async function resolvePlaceholdersMultiple(texts) {
|
||||
const RE = /\$\{prompt:([^}]+)\}/g;
|
||||
// Collect all unique placeholder names across all texts
|
||||
const allNames = new Set();
|
||||
for (const text of texts) {
|
||||
Array.from(text.matchAll(RE), m => m[1]).forEach(name => allNames.add(name));
|
||||
}
|
||||
const vals = {};
|
||||
// Prompt once for each unique placeholder
|
||||
for (const name of allNames) {
|
||||
const value = await vscode.window.showInputBox({
|
||||
prompt: `Value for ${name}`,
|
||||
placeHolder: name
|
||||
});
|
||||
if (value === undefined) {
|
||||
return undefined; // User cancelled
|
||||
}
|
||||
vals[name] = value;
|
||||
}
|
||||
// Replace placeholders in all texts using the collected values
|
||||
return texts.map(text => text.replace(RE, (_, name) => vals[name] ?? ""));
|
||||
}
|
||||
/**
|
||||
* Resolve placeholders like ${prompt:varname} in a string (single text version)
|
||||
*/
|
||||
async function resolvePlaceholders(text) {
|
||||
const result = await resolvePlaceholdersMultiple([text]);
|
||||
return result ? result[0] : undefined;
|
||||
}
|
||||
async function loadPatternIntoSearch(pattern) {
|
||||
try {
|
||||
const hasReplace = pattern.replace && pattern.replace.trim().length > 0;
|
||||
const textsToResolve = hasReplace ? [pattern.find, pattern.replace] : [pattern.find];
|
||||
const resolved = await resolvePlaceholdersMultiple(textsToResolve);
|
||||
if (!resolved) {
|
||||
return; // User cancelled
|
||||
}
|
||||
const find = resolved[0];
|
||||
const replace = hasReplace ? resolved[1] : '';
|
||||
const commandArgs = {
|
||||
query: find,
|
||||
replace: replace,
|
||||
triggerSearch: false, // Don't auto-trigger search
|
||||
isRegex: pattern.flags.isRegex,
|
||||
isCaseSensitive: pattern.flags.isCaseSensitive,
|
||||
matchWholeWord: pattern.flags.matchWholeWord,
|
||||
preserveCase: false,
|
||||
filesToInclude: pattern.filesToInclude || '',
|
||||
filesToExclude: pattern.filesToExclude || ''
|
||||
};
|
||||
await vscode.commands.executeCommand("workbench.action.findInFiles", commandArgs);
|
||||
vscode.window.showInformationMessage(`✅ Loaded pattern: "${pattern.label}"`);
|
||||
}
|
||||
catch (error) {
|
||||
vscode.window.showErrorMessage(`Failed to load pattern: ${error}`);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=searchCtx.js.map
|
||||
@@ -0,0 +1,158 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getAllPatterns = getAllPatterns;
|
||||
exports.savePattern = savePattern;
|
||||
exports.deletePattern = deletePattern;
|
||||
exports.renamePattern = renamePattern;
|
||||
exports.patternExists = patternExists;
|
||||
const vscode = __importStar(require("vscode"));
|
||||
const C = __importStar(require("./constants"));
|
||||
/**
|
||||
* Get patterns from settings and add runtime IDs
|
||||
*/
|
||||
function getPatternsByScope(scope) {
|
||||
const config = vscode.workspace.getConfiguration(C.CONFIG_NAMESPACE);
|
||||
const configKey = scope === 'global' ? C.CONFIG_KEY_USER_PATTERNS : C.CONFIG_KEY_WORKSPACE_PATTERNS;
|
||||
let storedPatterns;
|
||||
if (scope === 'global') {
|
||||
storedPatterns = config.inspect(C.CONFIG_KEY_USER_PATTERNS)?.globalValue || [];
|
||||
}
|
||||
else {
|
||||
storedPatterns = config.inspect(C.CONFIG_KEY_WORKSPACE_PATTERNS)?.workspaceValue || [];
|
||||
}
|
||||
// Add runtime IDs and ensure scope is set
|
||||
return storedPatterns.map((p, index) => ({
|
||||
...p,
|
||||
id: `${scope}-${index}`, // Index-based runtime ID
|
||||
scope: scope
|
||||
}));
|
||||
}
|
||||
function getAllPatterns() {
|
||||
const workspace = getPatternsByScope('workspace');
|
||||
const global = getPatternsByScope('global');
|
||||
// Return all patterns - duplicates across scopes are allowed
|
||||
return [...workspace, ...global];
|
||||
}
|
||||
async function savePattern(pattern) {
|
||||
const config = vscode.workspace.getConfiguration(C.CONFIG_NAMESPACE);
|
||||
const configKey = pattern.scope === 'global' ? C.CONFIG_KEY_USER_PATTERNS : C.CONFIG_KEY_WORKSPACE_PATTERNS;
|
||||
const target = pattern.scope === 'global'
|
||||
? vscode.ConfigurationTarget.Global
|
||||
: vscode.ConfigurationTarget.Workspace;
|
||||
// Read fresh patterns with runtime IDs
|
||||
const patternsWithIds = getPatternsByScope(pattern.scope);
|
||||
// Find existing pattern by ID (runtime ID tells us the index it came from)
|
||||
const existingIndex = patternsWithIds.findIndex(p => p.id === pattern.id);
|
||||
const isUpdate = existingIndex !== -1;
|
||||
// Strip runtime ID before saving
|
||||
const { id, ...storedPattern } = pattern;
|
||||
// Create array of stored patterns (without IDs)
|
||||
let storedPatterns = patternsWithIds.map(p => {
|
||||
const { id, ...stored } = p;
|
||||
return stored;
|
||||
});
|
||||
if (isUpdate) {
|
||||
// Update existing pattern IN PLACE (maintains order)
|
||||
storedPatterns[existingIndex] = storedPattern;
|
||||
}
|
||||
else {
|
||||
// New pattern - add at beginning
|
||||
storedPatterns.unshift(storedPattern);
|
||||
}
|
||||
// Save to settings (without IDs)
|
||||
await config.update(configKey, storedPatterns, target);
|
||||
// Only show message if it's a new pattern (not an update)
|
||||
if (!isUpdate) {
|
||||
vscode.window.showInformationMessage(`✅ Pattern "${pattern.label}" saved to ${pattern.scope} settings`);
|
||||
}
|
||||
}
|
||||
async function deletePattern(id, scope) {
|
||||
const config = vscode.workspace.getConfiguration(C.CONFIG_NAMESPACE);
|
||||
const configKey = scope === 'global' ? C.CONFIG_KEY_USER_PATTERNS : C.CONFIG_KEY_WORKSPACE_PATTERNS;
|
||||
const target = scope === 'global'
|
||||
? vscode.ConfigurationTarget.Global
|
||||
: vscode.ConfigurationTarget.Workspace;
|
||||
// Read fresh patterns with runtime IDs
|
||||
const patternsWithIds = getPatternsByScope(scope);
|
||||
// Find pattern by runtime ID
|
||||
const patternToDelete = patternsWithIds.find(p => p.id === id);
|
||||
if (!patternToDelete) {
|
||||
vscode.window.showWarningMessage(`Pattern not found in ${scope} settings`);
|
||||
return;
|
||||
}
|
||||
// Filter out the pattern and strip IDs
|
||||
const storedPatterns = patternsWithIds
|
||||
.filter(p => p.id !== id)
|
||||
.map(p => {
|
||||
const { id, ...stored } = p;
|
||||
return stored;
|
||||
});
|
||||
// Save updated list (without IDs)
|
||||
await config.update(configKey, storedPatterns, target);
|
||||
vscode.window.showInformationMessage(`🗑️ Pattern "${patternToDelete.label}" deleted from ${scope} settings`);
|
||||
}
|
||||
async function renamePattern(id, newLabel, scope) {
|
||||
const config = vscode.workspace.getConfiguration(C.CONFIG_NAMESPACE);
|
||||
const configKey = scope === 'global' ? C.CONFIG_KEY_USER_PATTERNS : C.CONFIG_KEY_WORKSPACE_PATTERNS;
|
||||
const target = scope === 'global'
|
||||
? vscode.ConfigurationTarget.Global
|
||||
: vscode.ConfigurationTarget.Workspace;
|
||||
// Read fresh patterns with runtime IDs
|
||||
const patternsWithIds = getPatternsByScope(scope);
|
||||
// Find pattern by runtime ID
|
||||
const pattern = patternsWithIds.find(p => p.id === id);
|
||||
if (!pattern) {
|
||||
vscode.window.showWarningMessage(`Pattern not found in ${scope} settings`);
|
||||
return;
|
||||
}
|
||||
const oldLabel = pattern.label;
|
||||
// Update label and strip IDs for saving
|
||||
const storedPatterns = patternsWithIds.map(p => {
|
||||
const { id: _id, ...stored } = p;
|
||||
if (p.id === id) {
|
||||
return { ...stored, label: newLabel };
|
||||
}
|
||||
return stored;
|
||||
});
|
||||
// Save updated list (without IDs)
|
||||
await config.update(configKey, storedPatterns, target);
|
||||
vscode.window.showInformationMessage(`✏️ Pattern renamed from "${oldLabel}" to "${newLabel}" in ${scope} settings`);
|
||||
}
|
||||
function patternExists(label, scope) {
|
||||
const patterns = getPatternsByScope(scope);
|
||||
return patterns.some(p => p.label === label);
|
||||
}
|
||||
//# sourceMappingURL=storage.js.map
|
||||
@@ -0,0 +1,3 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
//# sourceMappingURL=types.js.map
|
||||
+266
@@ -0,0 +1,266 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.WebviewManager = void 0;
|
||||
const vscode = __importStar(require("vscode"));
|
||||
const path = __importStar(require("path"));
|
||||
const fs = __importStar(require("fs"));
|
||||
const storage = __importStar(require("../storage"));
|
||||
const searchCtx = __importStar(require("../searchCtx"));
|
||||
/**
|
||||
* Manages the webview panel for pattern management
|
||||
*/
|
||||
class WebviewManager {
|
||||
/**
|
||||
* Create or show the webview panel
|
||||
*/
|
||||
static show(extensionUri, scope) {
|
||||
const column = vscode.window.activeTextEditor
|
||||
? vscode.window.activeTextEditor.viewColumn
|
||||
: undefined;
|
||||
// If we already have a panel, show it
|
||||
if (WebviewManager.currentPanel) {
|
||||
WebviewManager.currentPanel.panel.reveal(column);
|
||||
return;
|
||||
}
|
||||
const panel = vscode.window.createWebviewPanel('patternStoreManage', 'PatternStore', column || vscode.ViewColumn.One, {
|
||||
enableScripts: true,
|
||||
retainContextWhenHidden: true,
|
||||
});
|
||||
WebviewManager.currentPanel = new WebviewManager(panel, extensionUri, scope);
|
||||
}
|
||||
constructor(panel, extensionUri, scope) {
|
||||
this.disposables = [];
|
||||
this.isInternalSave = false;
|
||||
this.panel = panel;
|
||||
this.extensionUri = extensionUri;
|
||||
this.scope = scope;
|
||||
// Set initial HTML content
|
||||
this.panel.webview.html = this.getHtmlContent();
|
||||
// Listen for when the panel is disposed
|
||||
this.panel.onDidDispose(() => this.dispose(), null, this.disposables);
|
||||
// Handle messages from the webview
|
||||
this.panel.webview.onDidReceiveMessage(message => {
|
||||
this.handleMessage(message);
|
||||
}, null, this.disposables);
|
||||
// Watch for external config changes
|
||||
vscode.workspace.onDidChangeConfiguration(e => {
|
||||
if (e.affectsConfiguration('patternStore')) {
|
||||
this.handleExternalConfigChange();
|
||||
}
|
||||
}, null, this.disposables);
|
||||
this.sendPatterns();
|
||||
}
|
||||
sendPatterns(selectId, selectScope, clearSelection) {
|
||||
const allPatterns = storage.getAllPatterns();
|
||||
const workspacePatterns = allPatterns.filter(p => p.scope === 'workspace');
|
||||
const userPatterns = allPatterns.filter(p => p.scope === 'global');
|
||||
const message = {
|
||||
type: 'patterns',
|
||||
workspace: workspacePatterns,
|
||||
user: userPatterns
|
||||
};
|
||||
if (selectId && selectScope) {
|
||||
message.selectPattern = {
|
||||
id: selectId,
|
||||
scope: selectScope
|
||||
};
|
||||
}
|
||||
if (clearSelection) {
|
||||
message.clearSelection = true;
|
||||
}
|
||||
this.panel.webview.postMessage(message);
|
||||
}
|
||||
/**
|
||||
* Handle external configuration changes (e.g., manual edits to settings.json)
|
||||
*/
|
||||
handleExternalConfigChange() {
|
||||
// Don't show notification if this was an internal save
|
||||
if (this.isInternalSave) {
|
||||
this.isInternalSave = false;
|
||||
return;
|
||||
}
|
||||
// Show warning to user for actual external changes
|
||||
vscode.window.showWarningMessage('Pattern settings changed externally. Webview reloaded.');
|
||||
// Force full reload - this clears any dirty state and rebuilds runtime IDs
|
||||
// Pass clearSelection flag to force the webview to clear the details view
|
||||
this.sendPatterns(undefined, undefined, true);
|
||||
}
|
||||
async handleMessage(message) {
|
||||
console.log('Received message from webview:', message);
|
||||
switch (message.type) {
|
||||
case 'ready':
|
||||
// Webview is ready, send patterns
|
||||
this.sendPatterns();
|
||||
break;
|
||||
case 'delete':
|
||||
await this.handleDelete(message.id, message.scope);
|
||||
break;
|
||||
case 'load':
|
||||
await this.handleLoad(message.id, message.scope, message.pattern);
|
||||
break;
|
||||
case 'create':
|
||||
await this.handleCreate(message.scope);
|
||||
break;
|
||||
case 'save':
|
||||
await this.handleSave(message.pattern);
|
||||
break;
|
||||
}
|
||||
}
|
||||
async handleCreate(scope) {
|
||||
// Generate unique label for new pattern
|
||||
const existingPatterns = storage.getAllPatterns().filter(p => p.scope === scope);
|
||||
const baseName = 'New Pattern';
|
||||
let label = baseName;
|
||||
let counter = 1;
|
||||
while (existingPatterns.some(p => p.label === label)) {
|
||||
counter++;
|
||||
label = `${baseName} ${counter}`;
|
||||
}
|
||||
const newPattern = {
|
||||
id: 'new', // Temporary ID for new patterns
|
||||
label: label,
|
||||
find: '',
|
||||
replace: '',
|
||||
flags: {
|
||||
isRegex: false,
|
||||
isCaseSensitive: false,
|
||||
matchWholeWord: false,
|
||||
isMultiline: false
|
||||
},
|
||||
scope: scope
|
||||
};
|
||||
// Mark as internal save to suppress external change notification
|
||||
this.isInternalSave = true;
|
||||
await storage.savePattern(newPattern);
|
||||
// New pattern will be at index 0 (savePattern uses unshift)
|
||||
this.sendPatterns(`${scope}-0`, scope);
|
||||
}
|
||||
async handleSave(patternData) {
|
||||
const { id, label, find, replace, flags, filesToInclude, filesToExclude, scope } = patternData;
|
||||
const pattern = {
|
||||
id: id, // Preserve existing ID
|
||||
label: label,
|
||||
find: find,
|
||||
replace: replace,
|
||||
flags: flags,
|
||||
filesToInclude: filesToInclude,
|
||||
filesToExclude: filesToExclude,
|
||||
scope: scope
|
||||
};
|
||||
// Mark as internal save to suppress external change notification
|
||||
this.isInternalSave = true;
|
||||
await storage.savePattern(pattern);
|
||||
this.sendPatterns(id, scope);
|
||||
}
|
||||
async handleDelete(id, scope) {
|
||||
// Find pattern to get label for confirmation
|
||||
const allPatterns = storage.getAllPatterns();
|
||||
const pattern = allPatterns.find(p => p.id === id && p.scope === scope);
|
||||
if (!pattern) {
|
||||
vscode.window.showErrorMessage(`Pattern not found`);
|
||||
return;
|
||||
}
|
||||
// Confirm deletion
|
||||
const confirm = await vscode.window.showWarningMessage(`Delete pattern "${pattern.label}"?`, { modal: true }, 'Delete');
|
||||
if (confirm === 'Delete') {
|
||||
// Mark as internal save to suppress external change notification
|
||||
this.isInternalSave = true;
|
||||
await storage.deletePattern(id, scope);
|
||||
// Refresh pattern list
|
||||
this.sendPatterns();
|
||||
}
|
||||
}
|
||||
async handleLoad(id, scope, providedPattern) {
|
||||
let pattern = providedPattern;
|
||||
// If no pattern was provided, look it up
|
||||
if (!pattern) {
|
||||
const allPatterns = storage.getAllPatterns();
|
||||
pattern = allPatterns.find(p => p.id === id && p.scope === scope);
|
||||
if (!pattern) {
|
||||
vscode.window.showErrorMessage(`Pattern "${id}" not found`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
await searchCtx.loadPatternIntoSearch(pattern);
|
||||
}
|
||||
getHtmlContent() {
|
||||
// Generate nonce for CSP
|
||||
const nonce = this.getNonce();
|
||||
// Get URIs for webview resources
|
||||
const cspSource = this.panel.webview.cspSource;
|
||||
// Load HTML, CSS, and JS from files
|
||||
const htmlPath = path.join(this.extensionUri.fsPath, 'src', 'webview', 'html', 'patternManager.html');
|
||||
const cssPath = path.join(this.extensionUri.fsPath, 'src', 'webview', 'css', 'patternManager.css');
|
||||
const jsPath = path.join(this.extensionUri.fsPath, 'src', 'webview', 'js', 'patternManager.js');
|
||||
let html = fs.readFileSync(htmlPath, 'utf8');
|
||||
const css = fs.readFileSync(cssPath, 'utf8');
|
||||
const js = fs.readFileSync(jsPath, 'utf8');
|
||||
// Build style tag with nonce
|
||||
const styleTag = `<style nonce="${nonce}">\n${css}\n </style>`;
|
||||
// Replace placeholders
|
||||
html = html.replace(/{{nonce}}/g, nonce);
|
||||
html = html.replace(/{{cspSource}}/g, cspSource);
|
||||
html = html.replace(/{{styleTag}}/g, styleTag);
|
||||
html = html.replace(/{{script}}/g, js);
|
||||
return html;
|
||||
}
|
||||
/**
|
||||
* Generate a nonce for CSP
|
||||
*/
|
||||
getNonce() {
|
||||
let text = '';
|
||||
const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
for (let i = 0; i < 32; i++) {
|
||||
text += possible.charAt(Math.floor(Math.random() * possible.length));
|
||||
}
|
||||
return text;
|
||||
}
|
||||
/**
|
||||
* Clean up resources
|
||||
*/
|
||||
dispose() {
|
||||
WebviewManager.currentPanel = undefined;
|
||||
this.panel.dispose();
|
||||
while (this.disposables.length) {
|
||||
const disposable = this.disposables.pop();
|
||||
if (disposable) {
|
||||
disposable.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.WebviewManager = WebviewManager;
|
||||
//# sourceMappingURL=WebviewManager.js.map
|
||||
Reference in new issue
Block a user