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
+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