Assistant checkpoint: Refactored prompterTreeProvider.ts into modular components

Assistant generated file changes:
- src/providers/prompterTreeProvider.ts: Refactor to a more modular structure
- src/providers/fileSelectionManager.ts: Create file selection manager class
- src/providers/settingsManager.ts: Create settings manager class

---

User prompt:

Can you help me make this file more modular?
@src/providers/prompterTreeProvider.ts

Replit-Commit-Author: Assistant
Replit-Commit-Session-Id: e2f69f78-99c3-447b-a97a-9a2c4347a1d6
This commit is contained in:
2025-03-12 08:01:18 +00:00
parent 2d28f71e9b
commit 926c88780b
3 changed files with 192 additions and 103 deletions

View File

@@ -0,0 +1,103 @@
import * as vscode from 'vscode';
import * as path from 'path';
/**
* Manages file selection state for the Prompter extension
*/
export class FileSelectionManager {
private selectedFiles: Set<string> = new Set();
constructor() {}
/**
* Add a file to the selection
*/
addFile(filePath: string): void {
this.selectedFiles.add(filePath);
console.log(`Added ${filePath} to selection`);
}
/**
* Add a directory and all its contents to the selection
*/
async addDirectory(dirPath: string): Promise<void> {
try {
// Add the directory itself
this.selectedFiles.add(dirPath);
console.log(`Added directory ${dirPath} to selection`);
// Read directory contents
const files = await vscode.workspace.fs.readDirectory(vscode.Uri.file(dirPath));
// Process each item
for (const [name, type] of files) {
const filePath = path.join(dirPath, name);
if (type === vscode.FileType.Directory) {
// Recursively process subdirectories
await this.addDirectory(filePath);
} else {
// Add files
this.selectedFiles.add(filePath);
console.log(`Added ${filePath} to selection (from directory)`);
}
}
} catch (error) {
console.error(`Error adding directory to selection: ${dirPath}`, error);
}
}
/**
* Remove a file from the selection
*/
removeFile(filePath: string): void {
this.selectedFiles.delete(filePath);
console.log(`Removed ${filePath} from selection`);
}
/**
* Remove a directory and all its contents from the selection
*/
async removeDirectory(dirPath: string): Promise<void> {
try {
// Remove the directory itself
this.selectedFiles.delete(dirPath);
console.log(`Removed directory ${dirPath} from selection`);
// Read directory contents
const files = await vscode.workspace.fs.readDirectory(vscode.Uri.file(dirPath));
// Process each item
for (const [name, type] of files) {
const filePath = path.join(dirPath, name);
if (type === vscode.FileType.Directory) {
// Recursively process subdirectories
await this.removeDirectory(filePath);
} else {
// Remove files
this.selectedFiles.delete(filePath);
console.log(`Removed ${filePath} from selection (from directory)`);
}
}
} catch (error) {
console.error(`Error removing directory from selection: ${dirPath}`, error);
}
}
/**
* Check if a file is selected
*/
isSelected(filePath: string): boolean {
return this.selectedFiles.has(filePath);
}
/**
* Get all selected files
*/
getSelectedFiles(): Set<string> {
console.log('getSelectedFiles called, count:', this.selectedFiles.size);
return this.selectedFiles;
}
}

View File

@@ -2,6 +2,8 @@ import * as vscode from 'vscode';
import * as path from 'path'; import * as path from 'path';
import { FileTreeItem, SettingTreeItem } from '../models/treeItems'; import { FileTreeItem, SettingTreeItem } from '../models/treeItems';
import { PrompterSettings, DEFAULT_SETTINGS } from '../models/settings'; import { PrompterSettings, DEFAULT_SETTINGS } from '../models/settings';
import { FileSelectionManager } from './fileSelectionManager';
import { SettingsManager } from './settingsManager';
/** /**
* Tree provider for the Prompter extension * Tree provider for the Prompter extension
@@ -10,16 +12,19 @@ import { PrompterSettings, DEFAULT_SETTINGS } from '../models/settings';
export class PrompterTreeProvider implements vscode.TreeDataProvider<FileTreeItem | SettingTreeItem> { export class PrompterTreeProvider implements vscode.TreeDataProvider<FileTreeItem | SettingTreeItem> {
private _onDidChangeTreeData: vscode.EventEmitter<FileTreeItem | SettingTreeItem | undefined | null | void> = private _onDidChangeTreeData: vscode.EventEmitter<FileTreeItem | SettingTreeItem | undefined | null | void> =
new vscode.EventEmitter<FileTreeItem | SettingTreeItem | undefined | null | void>(); new vscode.EventEmitter<FileTreeItem | SettingTreeItem | undefined | null | void>();
readonly onDidChangeTreeData: vscode.Event<FileTreeItem | SettingTreeItem | undefined | null | void> = readonly onDidChangeTreeData: vscode.Event<FileTreeItem | SettingTreeItem | undefined | null | void> =
this._onDidChangeTreeData.event; this._onDidChangeTreeData.event;
private selectedFiles: Set<string> = new Set(); private fileSelectionManager: FileSelectionManager;
private settings: PrompterSettings = { ...DEFAULT_SETTINGS }; private settingsManager: SettingsManager;
private showingSettings: boolean = false; private showingSettings: boolean = false;
constructor(private workspaceRoot: string | undefined) {} constructor(private workspaceRoot: string | undefined) {
this.fileSelectionManager = new FileSelectionManager();
this.settingsManager = new SettingsManager();
}
// Toggle between file view and settings view // Toggle between file view and settings view
toggleSettingsView(): void { toggleSettingsView(): void {
this.showingSettings = !this.showingSettings; this.showingSettings = !this.showingSettings;
@@ -31,10 +36,10 @@ export class PrompterTreeProvider implements vscode.TreeDataProvider<FileTreeIte
if (element instanceof SettingTreeItem) { if (element instanceof SettingTreeItem) {
return element; return element;
} }
// Handle FileTreeItem // Handle FileTreeItem
const fileItem = element as FileTreeItem; const fileItem = element as FileTreeItem;
if (fileItem.resourceUri && this.selectedFiles.has(fileItem.resourceUri.fsPath)) { if (fileItem.resourceUri && this.fileSelectionManager.isSelected(fileItem.resourceUri.fsPath)) {
fileItem.checkboxState = vscode.TreeItemCheckboxState.Checked; fileItem.checkboxState = vscode.TreeItemCheckboxState.Checked;
} else { } else {
fileItem.checkboxState = vscode.TreeItemCheckboxState.Unchecked; fileItem.checkboxState = vscode.TreeItemCheckboxState.Unchecked;
@@ -47,7 +52,7 @@ export class PrompterTreeProvider implements vscode.TreeDataProvider<FileTreeIte
if (this.showingSettings && !element) { if (this.showingSettings && !element) {
return this.getSettingsItems(); return this.getSettingsItems();
} }
// Otherwise show files // Otherwise show files
if (!this.workspaceRoot) { if (!this.workspaceRoot) {
vscode.window.showInformationMessage('No workspace folder is opened'); vscode.window.showInformationMessage('No workspace folder is opened');
@@ -68,11 +73,11 @@ export class PrompterTreeProvider implements vscode.TreeDataProvider<FileTreeIte
private async getFilesInDirectory(dirPath: string): Promise<FileTreeItem[]> { private async getFilesInDirectory(dirPath: string): Promise<FileTreeItem[]> {
try { try {
const files = await vscode.workspace.fs.readDirectory(vscode.Uri.file(dirPath)); const files = await vscode.workspace.fs.readDirectory(vscode.Uri.file(dirPath));
return files.map(([name, type]) => { return files.map(([name, type]) => {
const filePath = path.join(dirPath, name); const filePath = path.join(dirPath, name);
const uri = vscode.Uri.file(filePath); const uri = vscode.Uri.file(filePath);
return new FileTreeItem( return new FileTreeItem(
uri, uri,
type === vscode.FileType.Directory type === vscode.FileType.Directory
@@ -94,100 +99,35 @@ export class PrompterTreeProvider implements vscode.TreeDataProvider<FileTreeIte
// Add a file to the selection // Add a file to the selection
addToSelection(item: FileTreeItem): void { addToSelection(item: FileTreeItem): void {
if (item.resourceUri) { if (item.resourceUri) {
const filePath = item.resourceUri.fsPath; if (this.isDirectory(item)) {
this.fileSelectionManager.addDirectory(item.resourceUri.fsPath);
// Check if it's a directory
if (item.collapsibleState === vscode.TreeItemCollapsibleState.Collapsed ||
item.collapsibleState === vscode.TreeItemCollapsibleState.Expanded) {
// It's a directory, recursively add all files
this.addDirectoryToSelection(filePath);
} else { } else {
// It's a file, just add it this.fileSelectionManager.addFile(item.resourceUri.fsPath);
this.selectedFiles.add(filePath);
console.log(`Added ${filePath} to selection`);
} }
} }
} }
// Recursively add all files in a directory to the selection
private async addDirectoryToSelection(dirPath: string): Promise<void> {
try {
// Add the directory itself
this.selectedFiles.add(dirPath);
console.log(`Added directory ${dirPath} to selection`);
// Read directory contents
const files = await vscode.workspace.fs.readDirectory(vscode.Uri.file(dirPath));
// Process each item
for (const [name, type] of files) {
const filePath = path.join(dirPath, name);
if (type === vscode.FileType.Directory) {
// Recursively process subdirectories
await this.addDirectoryToSelection(filePath);
} else {
// Add files
this.selectedFiles.add(filePath);
console.log(`Added ${filePath} to selection (from directory)`);
}
}
} catch (error) {
console.error(`Error adding directory to selection: ${dirPath}`, error);
}
}
// Remove a file from the selection // Remove a file from the selection
removeFromSelection(item: FileTreeItem): void { removeFromSelection(item: FileTreeItem): void {
if (item.resourceUri) { if (item.resourceUri) {
const filePath = item.resourceUri.fsPath; if (this.isDirectory(item)) {
this.fileSelectionManager.removeDirectory(item.resourceUri.fsPath);
// Check if it's a directory
if (item.collapsibleState === vscode.TreeItemCollapsibleState.Collapsed ||
item.collapsibleState === vscode.TreeItemCollapsibleState.Expanded) {
// It's a directory, recursively remove all files
this.removeDirectoryFromSelection(filePath);
} else { } else {
// It's a file, just remove it this.fileSelectionManager.removeFile(item.resourceUri.fsPath);
this.selectedFiles.delete(filePath);
console.log(`Removed ${filePath} from selection`);
} }
} }
} }
// Recursively remove all files in a directory from the selection private isDirectory(item: FileTreeItem): boolean {
private async removeDirectoryFromSelection(dirPath: string): Promise<void> { return item.collapsibleState === vscode.TreeItemCollapsibleState.Collapsed ||
try { item.collapsibleState === vscode.TreeItemCollapsibleState.Expanded;
// Remove the directory itself
this.selectedFiles.delete(dirPath);
console.log(`Removed directory ${dirPath} from selection`);
// Read directory contents
const files = await vscode.workspace.fs.readDirectory(vscode.Uri.file(dirPath));
// Process each item
for (const [name, type] of files) {
const filePath = path.join(dirPath, name);
if (type === vscode.FileType.Directory) {
// Recursively process subdirectories
await this.removeDirectoryFromSelection(filePath);
} else {
// Remove files
this.selectedFiles.delete(filePath);
console.log(`Removed ${filePath} from selection (from directory)`);
}
}
} catch (error) {
console.error(`Error removing directory from selection: ${dirPath}`, error);
}
} }
// Toggle a file's selection status // Toggle a file's selection status
toggleSelection(item: FileTreeItem): void { toggleSelection(item: FileTreeItem): void {
if (item.resourceUri) { if (item.resourceUri) {
const filePath = item.resourceUri.fsPath; const filePath = item.resourceUri.fsPath;
if (this.selectedFiles.has(filePath)) { if (this.fileSelectionManager.isSelected(filePath)) {
this.removeFromSelection(item); this.removeFromSelection(item);
} else { } else {
this.addToSelection(item); this.addToSelection(item);
@@ -198,25 +138,25 @@ export class PrompterTreeProvider implements vscode.TreeDataProvider<FileTreeIte
// Get the selected files // Get the selected files
getSelectedFiles(): Set<string> { getSelectedFiles(): Set<string> {
console.log('getSelectedFiles called, count:', this.selectedFiles.size); return this.fileSelectionManager.getSelectedFiles();
return this.selectedFiles;
} }
// Get settings items for the tree view // Get settings items for the tree view
private getSettingsItems(): SettingTreeItem[] { private getSettingsItems(): SettingTreeItem[] {
const settings = this.settingsManager.getSettings();
return [ return [
new SettingTreeItem('Include Formatting Instructions', 'includeFormattingInstructions', this.settings.includeFormattingInstructions), new SettingTreeItem('Include Formatting Instructions', 'includeFormattingInstructions', settings.includeFormattingInstructions),
new SettingTreeItem('Token Calculation', 'tokenCalculationEnabled', this.settings.tokenCalculationEnabled), new SettingTreeItem('Token Calculation', 'tokenCalculationEnabled', settings.tokenCalculationEnabled),
new SettingTreeItem('Include File Map', 'includeFileMap', this.settings.includeFileMap) new SettingTreeItem('Include File Map', 'includeFileMap', settings.includeFileMap)
]; ];
} }
// Update a setting value // Update a setting value
updateSetting(key: keyof PrompterSettings, value: boolean): void { updateSetting(key: keyof PrompterSettings, value: boolean): void {
this.settings[key] = value; this.settingsManager.updateSetting(key, value);
this.refresh(); this.refresh();
} }
// Check if showing settings view // Check if showing settings view
isShowingSettings(): boolean { isShowingSettings(): boolean {
return this.showingSettings; return this.showingSettings;
@@ -224,23 +164,23 @@ export class PrompterTreeProvider implements vscode.TreeDataProvider<FileTreeIte
// Toggle formatting instructions setting // Toggle formatting instructions setting
toggleXmlEdits(): void { toggleXmlEdits(): void {
this.settings.includeFormattingInstructions = !this.settings.includeFormattingInstructions; this.settingsManager.toggleFormattingInstructions();
this.refresh(); this.refresh();
} }
// Check if formatting instructions are enabled // Check if formatting instructions are enabled
isXmlEditsEnabled(): boolean { isXmlEditsEnabled(): boolean {
return this.settings.includeFormattingInstructions; return this.settingsManager.isFormattingInstructionsEnabled();
} }
// Get all settings // Get all settings
getSettings(): PrompterSettings { getSettings(): PrompterSettings {
return { ...this.settings }; return this.settingsManager.getSettings();
} }
// Update all settings at once // Update all settings at once
updateSettings(newSettings: PrompterSettings): void { updateSettings(newSettings: PrompterSettings): void {
this.settings = { ...newSettings }; this.settingsManager.updateAllSettings(newSettings);
this.refresh(); this.refresh();
} }
} }

View File

@@ -0,0 +1,46 @@
import { PrompterSettings, DEFAULT_SETTINGS } from '../models/settings';
/**
* Manages settings for the Prompter extension
*/
export class SettingsManager {
private settings: PrompterSettings = { ...DEFAULT_SETTINGS };
constructor() {}
/**
* Update a specific setting
*/
updateSetting(key: keyof PrompterSettings, value: boolean): void {
this.settings[key] = value;
}
/**
* Toggle formatting instructions setting
*/
toggleFormattingInstructions(): void {
this.settings.includeFormattingInstructions = !this.settings.includeFormattingInstructions;
}
/**
* Check if formatting instructions are enabled
*/
isFormattingInstructionsEnabled(): boolean {
return this.settings.includeFormattingInstructions;
}
/**
* Get all settings
*/
getSettings(): PrompterSettings {
return { ...this.settings };
}
/**
* Update all settings at once
*/
updateAllSettings(newSettings: PrompterSettings): void {
this.settings = { ...newSettings };
}
}