From 6bd50154f0b40d73f1e3151f2a9f2e124606a69e Mon Sep 17 00:00:00 2001 From: abhishekbhakat Date: Tue, 11 Mar 2025 18:18:32 +0000 Subject: [PATCH] add settings management and UI integration --- package.json | 11 ++- src/extension.ts | 185 ++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 162 insertions(+), 34 deletions(-) diff --git a/package.json b/package.json index 6e74381..9df2150 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,11 @@ { "command": "prompter.generatePrompt", "title": "Copy" + }, + { + "command": "prompter.openSettings", + "title": "Settings", + "icon": "$(settings-gear)" } ], "viewsContainers": { @@ -44,7 +49,11 @@ "view/title": [ { "command": "prompter.generatePrompt", - "group": "navigation" + "group": "navigation@1" + }, + { + "command": "prompter.openSettings", + "group": "navigation@2" } ], "view/item/context": [ diff --git a/src/extension.ts b/src/extension.ts index 7319afe..8aa526f 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1,6 +1,7 @@ // The module 'vscode' contains the VS Code extensibility API import * as vscode from 'vscode'; import * as path from 'path'; +import * as fs from 'fs'; // Custom TreeItem for files and folders class FileTreeItem extends vscode.TreeItem { @@ -17,36 +18,82 @@ class FileTreeItem extends vscode.TreeItem { } } +// Settings interface +interface PrompterSettings { + xmlEditsEnabled: boolean; + includeLineNumbers: boolean; + includeComments: boolean; + tokenCalculationEnabled: boolean; +} + +// Custom TreeItem for settings +class SettingTreeItem extends vscode.TreeItem { + constructor( + public readonly label: string, + public readonly settingKey: keyof PrompterSettings, + public readonly checked: boolean + ) { + super(label, vscode.TreeItemCollapsibleState.None); + this.checkboxState = checked ? vscode.TreeItemCheckboxState.Checked : vscode.TreeItemCheckboxState.Unchecked; + this.contextValue = 'setting'; + } +} + // TreeView provider for the sidebar -class PrompterTreeProvider implements vscode.TreeDataProvider { - private _onDidChangeTreeData: vscode.EventEmitter = new vscode.EventEmitter(); - readonly onDidChangeTreeData: vscode.Event = this._onDidChangeTreeData.event; +class PrompterTreeProvider implements vscode.TreeDataProvider { + private _onDidChangeTreeData: vscode.EventEmitter = new vscode.EventEmitter(); + readonly onDidChangeTreeData: vscode.Event = this._onDidChangeTreeData.event; private selectedFiles: Set = new Set(); - private xmlEditsEnabled: boolean = false; + private settings: PrompterSettings = { + xmlEditsEnabled: false, + includeLineNumbers: false, + includeComments: true, + tokenCalculationEnabled: true + }; + private showingSettings: boolean = false; constructor(private workspaceRoot: string | undefined) {} - - getTreeItem(element: FileTreeItem): vscode.TreeItem { - const item = element; - if (this.selectedFiles.has(element.resourceUri.fsPath)) { - item.checkboxState = vscode.TreeItemCheckboxState.Checked; - item.label = path.basename(element.resourceUri.fsPath); - } else { - item.checkboxState = vscode.TreeItemCheckboxState.Unchecked; - item.label = path.basename(element.resourceUri.fsPath); - } - return item; + + // Toggle between file view and settings view + toggleSettingsView(): void { + this.showingSettings = !this.showingSettings; + this.refresh(); } - async getChildren(element?: FileTreeItem): Promise { + getTreeItem(element: FileTreeItem | SettingTreeItem): vscode.TreeItem { + // Return the element as is if it's a SettingTreeItem + if (element instanceof SettingTreeItem) { + return element; + } + + // Handle FileTreeItem + const fileItem = element as FileTreeItem; + if (fileItem.resourceUri && this.selectedFiles.has(fileItem.resourceUri.fsPath)) { + fileItem.checkboxState = vscode.TreeItemCheckboxState.Checked; + } else { + fileItem.checkboxState = vscode.TreeItemCheckboxState.Unchecked; + } + return fileItem; + } + + async getChildren(element?: FileTreeItem | SettingTreeItem): Promise<(FileTreeItem | SettingTreeItem)[]> { + // If we're showing settings, return settings items + if (this.showingSettings && !element) { + return this.getSettingsItems(); + } + + // Otherwise show files if (!this.workspaceRoot) { vscode.window.showInformationMessage('No workspace folder is opened'); return Promise.resolve([]); } if (element) { - const dirPath = element.resourceUri.fsPath; - return this.getFilesInDirectory(dirPath); + // Make sure we're dealing with a FileTreeItem that has a resourceUri + if (!(element instanceof SettingTreeItem) && element.resourceUri) { + return this.getFilesInDirectory(element.resourceUri.fsPath); + } + return Promise.resolve([]); } else { return this.getFilesInDirectory(this.workspaceRoot); } @@ -100,13 +147,42 @@ class PrompterTreeProvider implements vscode.TreeDataProvider { console.log('getSelectedFiles called, count:', this.selectedFiles.size); return this.selectedFiles; } + + // Get settings items for the tree view + private getSettingsItems(): SettingTreeItem[] { + return [ + new SettingTreeItem('XML Edits', 'xmlEditsEnabled', this.settings.xmlEditsEnabled), + new SettingTreeItem('Include Line Numbers', 'includeLineNumbers', this.settings.includeLineNumbers), + new SettingTreeItem('Include Comments', 'includeComments', this.settings.includeComments), + new SettingTreeItem('Token Calculation', 'tokenCalculationEnabled', this.settings.tokenCalculationEnabled) + ]; + } + + // Update a setting value + updateSetting(key: keyof PrompterSettings, value: boolean): void { + this.settings[key] = value; + this.refresh(); + } + + isShowingSettings(): boolean { + return this.showingSettings; + } toggleXmlEdits(): void { - this.xmlEditsEnabled = !this.xmlEditsEnabled; + this.settings.xmlEditsEnabled = !this.settings.xmlEditsEnabled; } isXmlEditsEnabled(): boolean { - return this.xmlEditsEnabled; + return this.settings.xmlEditsEnabled; + } + + getSettings(): PrompterSettings { + return this.settings; + } + + updateSettings(newSettings: PrompterSettings): void { + this.settings = { ...newSettings }; + this.refresh(); } refresh(): void { @@ -134,7 +210,7 @@ async function readFileContent(filePath: string): Promise { } // Function to generate XML prompt -function generateXMLPrompt(files: Map, xmlEdits: boolean): string { +function generateXMLPrompt(files: Map, settings: PrompterSettings): string { const xmlParts = ['', '']; // Add files section @@ -148,12 +224,18 @@ function generateXMLPrompt(files: Map'); - // Add XML edits flag if enabled - if (xmlEdits) { - xmlParts.push(' '); + // Add options based on settings + xmlParts.push(' '); + if (settings.xmlEditsEnabled) { xmlParts.push(' true'); - xmlParts.push(' '); } + if (settings.includeLineNumbers) { + xmlParts.push(' true'); + } + if (!settings.includeComments) { + xmlParts.push(' true'); + } + xmlParts.push(' '); xmlParts.push(''); return xmlParts.join('\n'); @@ -177,12 +259,26 @@ export function activate(context: vscode.ExtensionContext) { treeView.onDidChangeCheckboxState(e => { console.log('Checkbox state changed'); for (const [item, state] of e.items) { - const fileItem = item as FileTreeItem; - console.log(`Checkbox changed for ${fileItem.resourceUri.fsPath} to ${state}`); - if (state === vscode.TreeItemCheckboxState.Checked) { - prompterTreeProvider.addToSelection(fileItem); - } else { - prompterTreeProvider.removeFromSelection(fileItem); + if (item instanceof FileTreeItem) { + console.log(`Checkbox changed for ${item.resourceUri.fsPath} to ${state}`); + if (state === vscode.TreeItemCheckboxState.Checked) { + prompterTreeProvider.addToSelection(item); + } else { + prompterTreeProvider.removeFromSelection(item); + } + } else if (item instanceof SettingTreeItem) { + // Handle settings checkbox changes + console.log(`Setting changed: ${item.settingKey} to ${state === vscode.TreeItemCheckboxState.Checked}`); + prompterTreeProvider.updateSetting( + item.settingKey, + state === vscode.TreeItemCheckboxState.Checked + ); + + // Update XML edits button text if that setting changed + if (item.settingKey === 'xmlEditsEnabled') { + xmlEditsButton.text = prompterTreeProvider.isXmlEditsEnabled() ? + "$(check) XML Edits" : "$(diff-added) XML Edits"; + } } } }); @@ -213,6 +309,27 @@ export function activate(context: vscode.ExtensionContext) { xmlEditsButton.text = prompterTreeProvider.isXmlEditsEnabled() ? "$(check) XML Edits" : "$(diff-added) XML Edits"; }); + + // Create settings button + const settingsButton = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left); + settingsButton.text = "$(settings-gear)"; + settingsButton.tooltip = "Prompter Settings"; + settingsButton.command = 'prompter.openSettings'; + settingsButton.show(); + + // Settings panel state + let settingsPanel: vscode.WebviewPanel | undefined = undefined; + + // Register command to open settings + let openSettingsCommand = vscode.commands.registerCommand('prompter.openSettings', () => { + prompterTreeProvider.toggleSettingsView(); + + // Update the settings button icon based on current view + settingsButton.text = prompterTreeProvider.isShowingSettings() ? + "$(list-tree)" : "$(settings-gear)"; + settingsButton.tooltip = prompterTreeProvider.isShowingSettings() ? + "Show Files" : "Prompter Settings"; + }); // Register command to generate prompt from selected files let generatePromptCommand = vscode.commands.registerCommand('prompter.generatePrompt', async () => { @@ -245,7 +362,7 @@ export function activate(context: vscode.ExtensionContext) { ); // Generate XML prompt - const xmlPrompt = generateXMLPrompt(fileContents, prompterTreeProvider.isXmlEditsEnabled()); + const xmlPrompt = generateXMLPrompt(fileContents, prompterTreeProvider.getSettings()); // Copy to clipboard await vscode.env.clipboard.writeText(xmlPrompt); @@ -256,9 +373,11 @@ export function activate(context: vscode.ExtensionContext) { treeView, xmlEditsButton, copyButton, + settingsButton, toggleSelectionCommand, toggleXmlEditsCommand, - generatePromptCommand + generatePromptCommand, + openSettingsCommand ); }