Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Copy & Project settings should be per project #287

Open
stephanj opened this issue Sep 10, 2024 · 1 comment
Open

Copy & Project settings should be per project #287

stephanj opened this issue Sep 10, 2024 · 1 comment
Labels
enhancement New feature or request

Comments

@stephanj
Copy link
Contributor

The current Scan & Copy is the same for all projects, this should however be per project.

image

@stephanj stephanj added the enhancement New feature or request label Sep 10, 2024
@stephanj
Copy link
Contributor Author

To refactor the Scan and Copy settings to be project-specific rather than global, we need to make several changes to the existing codebase. The main idea is to store these settings on a per-project basis rather than in the global application state. Here's a detailed approach to achieve this:

  1. Modify the DevoxxGenieStateService:

    Currently, the DevoxxGenieStateService is storing these settings globally. We need to change it to store project-specific settings.

@State(
    name = "com.devoxx.genie.ui.SettingsState",
    storages = @Storage("DevoxxGenieSettingsPlugin.xml")
)
public final class DevoxxGenieStateService implements PersistentStateComponent<DevoxxGenieStateService> {
    
    // ... existing fields ...

    // New field to store project-specific settings
    private Map<String, ProjectScanSettings> projectScanSettings = new HashMap<>();

    // ... existing methods ...

    public ProjectScanSettings getProjectScanSettings(Project project) {
        return projectScanSettings.computeIfAbsent(project.getLocationHash(), k -> new ProjectScanSettings());
    }

    public void setProjectScanSettings(Project project, ProjectScanSettings settings) {
        projectScanSettings.put(project.getLocationHash(), settings);
    }

    // Inner class to hold project-specific scan settings
    public static class ProjectScanSettings {
        private List<String> excludedDirectories = new ArrayList<>();
        private List<String> includedFileExtensions = new ArrayList<>();
        private boolean excludeJavaDoc = false;
        private boolean useGitIgnore = true;

        // Getters and setters for all fields
    }
}
  1. Create a new ProjectScanSettingsService:

    This service will handle project-specific settings.

@Service
public class ProjectScanSettingsService {
    private final Project project;
    private final DevoxxGenieStateService stateService;

    public ProjectScanSettingsService(Project project) {
        this.project = project;
        this.stateService = DevoxxGenieStateService.getInstance();
    }

    public List<String> getExcludedDirectories() {
        return stateService.getProjectScanSettings(project).getExcludedDirectories();
    }

    public void setExcludedDirectories(List<String> excludedDirectories) {
        DevoxxGenieStateService.ProjectScanSettings settings = stateService.getProjectScanSettings(project);
        settings.setExcludedDirectories(excludedDirectories);
        stateService.setProjectScanSettings(project, settings);
    }

    // Similar methods for other settings (includedFileExtensions, excludeJavaDoc, useGitIgnore)
}
  1. Modify the ProjectScannerService:

    Update the ProjectScannerService to use the new ProjectScanSettingsService.

public class ProjectScannerService {
    // ... existing fields ...

    public CompletableFuture<ScanContentResult> scanProject(Project project,
                                                            VirtualFile startDirectory,
                                                            int windowContextMaxTokens,
                                                            boolean isTokenCalculation) {
        // ... existing code ...

        ProjectScanSettingsService settingsService = project.getService(ProjectScanSettingsService.class);
        
        // Use project-specific settings
        List<String> excludedDirectories = settingsService.getExcludedDirectories();
        List<String> includedFileExtensions = settingsService.getIncludedFileExtensions();
        boolean excludeJavaDoc = settingsService.isExcludeJavaDoc();
        boolean useGitIgnore = settingsService.isUseGitIgnore();

        // ... rest of the method using these settings ...
    }

    // Update other methods to use ProjectScanSettingsService as well
}
  1. Update the UI components:

    Modify the CopyProjectSettingsComponent and CopyProjectSettingsConfigurable to work with project-specific settings.

public class CopyProjectSettingsComponent extends AbstractSettingsComponent {
    private final Project project;
    private final ProjectScanSettingsService settingsService;

    public CopyProjectSettingsComponent(Project project) {
        this.project = project;
        this.settingsService = project.getService(ProjectScanSettingsService.class);
        // Initialize UI components with project-specific settings
    }

    // ... modify other methods to use settingsService instead of global settings ...
}

public class CopyProjectSettingsConfigurable implements Configurable {
    private final Project project;
    private CopyProjectSettingsComponent copyProjectSettingsComponent;

    public CopyProjectSettingsConfigurable(Project project) {
        this.project = project;
    }

    @Override
    public JComponent createComponent() {
        copyProjectSettingsComponent = new CopyProjectSettingsComponent(project);
        return copyProjectSettingsComponent.createPanel();
    }

    @Override
    public boolean isModified() {
        ProjectScanSettingsService settings = project.getService(ProjectScanSettingsService.class);
        return !copyProjectSettingsComponent.getExcludedDirectories().equals(settings.getExcludedDirectories()) ||
               !copyProjectSettingsComponent.getIncludedFileExtensions().equals(settings.getIncludedFileExtensions()) ||
                copyProjectSettingsComponent.getExcludeJavadoc() != settings.isExcludeJavaDoc() ||
                copyProjectSettingsComponent.getUseGitIgnore() != settings.isUseGitIgnore();
    }

    @Override
    public void apply() {
        ProjectScanSettingsService settings = project.getService(ProjectScanSettingsService.class);
        settings.setExcludedDirectories(copyProjectSettingsComponent.getExcludedDirectories());
        settings.setIncludedFileExtensions(copyProjectSettingsComponent.getIncludedFileExtensions());
        settings.setExcludeJavaDoc(copyProjectSettingsComponent.getExcludeJavadoc());
        settings.setUseGitIgnore(copyProjectSettingsComponent.getUseGitIgnore());
    }

    // ... other methods ...
}
  1. Update plugin.xml:

    Register the new ProjectScanSettingsService in the plugin.xml file.

<idea-plugin>
    <!-- ... other configurations ... -->
    <projectService serviceImplementation="com.devoxx.genie.service.ProjectScanSettingsService"/>
</idea-plugin>
  1. Migration of existing settings:

    You may want to add a migration step to transfer existing global settings to project-specific settings when a project is opened for the first time after the update.

public class SettingsMigrationService {
    public static void migrateToProjectSettings(Project project) {
        DevoxxGenieStateService globalSettings = DevoxxGenieStateService.getInstance();
        ProjectScanSettingsService projectSettings = project.getService(ProjectScanSettingsService.class);

        // Only migrate if project settings are empty
        if (projectSettings.getExcludedDirectories().isEmpty()) {
            projectSettings.setExcludedDirectories(new ArrayList<>(globalSettings.getExcludedDirectories()));
            projectSettings.setIncludedFileExtensions(new ArrayList<>(globalSettings.getIncludedFileExtensions()));
            projectSettings.setExcludeJavaDoc(globalSettings.getExcludeJavaDoc());
            projectSettings.setUseGitIgnore(globalSettings.getUseGitIgnore());
        }
    }
}

Call this migration method when a project is opened, perhaps in a PostStartupActivity:

public class PostStartupActivity implements ProjectActivity {
    @Nullable
    @Override
    public Object execute(@NotNull Project project, @NotNull Continuation<? super Unit> continuation) {
        ChatMemoryService.getInstance().init(project);
        SettingsMigrationService.migrateToProjectSettings(project);
        return continuation;
    }
}

These changes will refactor the Scan and Copy settings to be project-specific. Each project will now have its own set of excluded directories, included file extensions, and other related settings. This approach ensures that different projects can have different scanning configurations, providing more flexibility to users working on multiple projects with varying requirements.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant