add settings management and UI integration
This commit is contained in:
11
package.json
11
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": [
|
||||
|
||||
177
src/extension.ts
177
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<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);
|
||||
}
|
||||
@@ -101,12 +148,41 @@ class PrompterTreeProvider implements vscode.TreeDataProvider<FileTreeItem> {
|
||||
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) {
|
||||
// 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 (item instanceof FileTreeItem) {
|
||||
console.log(`Checkbox changed for ${item.resourceUri.fsPath} to ${state}`);
|
||||
if (state === vscode.TreeItemCheckboxState.Checked) {
|
||||
prompterTreeProvider.addToSelection(fileItem);
|
||||
prompterTreeProvider.addToSelection(item);
|
||||
} else {
|
||||
prompterTreeProvider.removeFromSelection(fileItem);
|
||||
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";
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -214,6 +310,27 @@ export function activate(context: vscode.ExtensionContext) {
|
||||
"$(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 () => {
|
||||
const selectedFiles = prompterTreeProvider.getSelectedFiles();
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user