add settings management and UI integration

This commit is contained in:
2025-03-11 18:18:32 +00:00
parent c5e16a6ae9
commit 6bd50154f0
2 changed files with 162 additions and 34 deletions

View File

@@ -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": [

View File

@@ -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<FileTreeItem> {
private _onDidChangeTreeData: vscode.EventEmitter<FileTreeItem | undefined | null | void> = new vscode.EventEmitter<FileTreeItem | undefined | null | void>();
readonly onDidChangeTreeData: vscode.Event<FileTreeItem | undefined | null | void> = this._onDidChangeTreeData.event;
class PrompterTreeProvider implements vscode.TreeDataProvider<FileTreeItem | SettingTreeItem> {
private _onDidChangeTreeData: vscode.EventEmitter<FileTreeItem | SettingTreeItem | undefined | null | void> = new vscode.EventEmitter<FileTreeItem | SettingTreeItem | undefined | null | void>();
readonly onDidChangeTreeData: vscode.Event<FileTreeItem | SettingTreeItem | undefined | null | void> = this._onDidChangeTreeData.event;
private selectedFiles: Set<string> = 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<FileTreeItem[]> {
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<FileTreeItem> {
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<string> {
}
// Function to generate XML prompt
function generateXMLPrompt(files: Map<string, { content: string; tokens: number }>, xmlEdits: boolean): string {
function generateXMLPrompt(files: Map<string, { content: string; tokens: number }>, settings: PrompterSettings): string {
const xmlParts = ['<?xml version="1.0" encoding="UTF-8"?>', '<prompt>'];
// Add files section
@@ -148,12 +224,18 @@ function generateXMLPrompt(files: Map<string, { content: string; tokens: number
}
xmlParts.push(' </files>');
// Add XML edits flag if enabled
if (xmlEdits) {
xmlParts.push(' <options>');
// Add options based on settings
xmlParts.push(' <options>');
if (settings.xmlEditsEnabled) {
xmlParts.push(' <xml_edits>true</xml_edits>');
xmlParts.push(' </options>');
}
if (settings.includeLineNumbers) {
xmlParts.push(' <include_line_numbers>true</include_line_numbers>');
}
if (!settings.includeComments) {
xmlParts.push(' <exclude_comments>true</exclude_comments>');
}
xmlParts.push(' </options>');
xmlParts.push('</prompt>');
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
);
}