Skip to content
Snippets Groups Projects
Commit 59a22afb authored by Csilla Farkas's avatar Csilla Farkas Committed by Adam Knapp
Browse files

Optimize file decoration when tpd is activated (issue #5)


Signed-off-by: default avatarCsilla Farkas <csilla.farkas@sigmatechnology.com>
parent 0d805ffc
No related branches found
No related tags found
1 merge request!27Optimize file decoration when tpd is activated (issue #5)
......@@ -167,12 +167,12 @@
{
"command": "tpdview.activateTpd",
"title": "Activate tpd",
"icon": "$(exclude)"
"icon": "$(circle-large-outline)"
},
{
"command": "tpdview.deactivateTpd",
"title": "Deactivate tpd",
"icon": "$(gear)"
"icon": "$(pass-filled)"
},
{
"command": "explorer.exclude",
......
......@@ -46,21 +46,12 @@ class ClientManager {
this._client.sendNotification(this._methods.exclude, { excludedStates });
}
public async readTpd(tpd: Uri) {
try {
// const response = await this._client.sendRequest(this._methods.openTpd, { tpdPath: tpd.toString()});
const response = {
success: true,
result: ["file:///c%3A/Users/cfa/Documents/Work/Titan/workspace/first.ttcn", "file:///c%3A/Users/cfa/Documents/Work/Titan/workspace/hello.ttcn"]
};
public async parseTpd(tpd: Uri) {
const response = await this._client.sendRequest(this._methods.openTpd, { tpdPath: tpd.fsPath}) as {success: boolean, result: string[]};
if(response.success && response.result.length) {
return response.result;
} catch(error: unknown) {
if(error instanceof ResponseError) {
await window.showErrorMessage(error.message);
}
}
await window.showErrorMessage(`Failed to parse tpd: ${tpd.fsPath}`);
}
}
......
......@@ -57,6 +57,8 @@ class TitanClientSocketListener {
const options = { cwd: settings.projectRootPath };
const { port } = socketListener.address() as net.AddressInfo;
const args: string[] = [
'-Xms4g',
'-Xmx8g',
'-jar',
TitanClientSocketListener._serverExecutableFilePath,
port.toString()
......
......@@ -23,7 +23,7 @@ import { clientManager } from './client/ClientManager';
import { mainExclusionManager } from './workspace/fileExclusion/MainExclusionManager';
export function activate(context: ExtensionContext): void {
export async function activate(context: ExtensionContext) {
const disposable = client.start();
context.subscriptions.push(disposable);
......@@ -48,7 +48,6 @@ export function activate(context: ExtensionContext): void {
client.onReady().then(() => {
clientManager.notifyServerIfExcludeStateChanged(mainExclusionManager.excludedStates);
console.log('Titan is now active!');
});
}
......
......@@ -12,6 +12,7 @@
import { Uri, workspace, FileType } from "vscode";
import * as path from 'path';
import * as fs from 'fs';
import { settings } from "../Settings";
......@@ -45,22 +46,56 @@ export class FileSystemManager {
return uri.with({ path: path.posix.dirname(uri.path) });
}
static getParentUrisOfUriInWorkspace(uri: Uri): string[] {
let inputPath = uri.path;
const parents: string[] = [];
while (inputPath !== settings.projectRootUri!.path) {
const parentDirPath = path.dirname(inputPath);
if(parentDirPath !== settings.projectRootUri!.path) {
parents.push(Uri.file(parentDirPath).fsPath);
static arePathsEqual(path1: string, path2: string): boolean {
const file1Stats = fs.statSync(path1);
const file2Stats = fs.statSync(path2);
if (file1Stats.ino && file2Stats.ino) {
return file1Stats.ino === file2Stats.ino;
} else {
return path.resolve(path1) === path.resolve(path2);
}
}
static getParentsOfUriInWorkspace(uri: Uri): string[] {
try {
let inputPath = uri.fsPath;
const parents: string[] = [];
while (!this.arePathsEqual(inputPath, settings.projectRootUri!.fsPath)) {
const parentDirPath = path.dirname(inputPath);
if(!this.arePathsEqual(parentDirPath, settings.projectRootUri!.fsPath)) {
parents.push(Uri.file(parentDirPath).fsPath);
}
inputPath = parentDirPath;
}
inputPath = parentDirPath;
}
return parents;
return parents;
} catch(e: unknown) {
console.log(e);
return [];
}
}
static async readWorkspace(): Promise<Uri[]> {
const workspaceContent = await this.readDir(settings.projectRootUri!);
return workspaceContent;
}
private static getDirectoryContents(dir: string): string[] {
let contents: string[] = [];
const files = fs.readdirSync(dir, { withFileTypes: true });
for (const file of files) {
const filePath = `${dir}/${file.name}`;
contents.push(filePath);
if (file.isDirectory()) {
contents = [...contents, ...FileSystemManager.getDirectoryContents(filePath)];
}
}
return contents;
}
static readWorkspace2(): Map<string, Uri> {
const workspaceContent = this.getDirectoryContents(settings.projectRootUri!.fsPath);
return new Map<string, Uri>(workspaceContent.map(content => [path.normalize(content.toLowerCase()), Uri.file(path.normalize(content))]));
}
}
\ No newline at end of file
......@@ -71,7 +71,7 @@ const workspaceEventHandlers = {
},
handleExcludedFromBuildChange: (event: ConfigurationChangeEvent) => {
if (event.affectsConfiguration(ConfigKey.excludeFromBuild || ConfigKey.activatedTpd)) {
if (event.affectsConfiguration(ConfigKey.excludeFromBuild)) {
mainExclusionManager.updateContext();
ExcludedFileDecorationProvider.decorate(mainExclusionManager.itemsToBeDecorated);
clientManager.notifyServerIfExcludeStateChanged(mainExclusionManager.excludedStates);
......
......@@ -10,11 +10,13 @@
* @author Csilla Farkas
*/
import { FileSystemWatcher, window, TreeItem, Uri, workspace, TreeDataProvider, EventEmitter, Event, Disposable } from "vscode";
import { FileSystemWatcher, window, TreeItem, Uri, workspace, TreeDataProvider, EventEmitter, Event, Disposable, commands } from "vscode";
import { ExcludedState, ViewNames } from "../../customTypes";
import { FileExclusionManager } from "./FileExclusionManager";
import { TpdFile } from "./TpdFile";
import { ExclusionByTpdConfigRepository } from "./ExclusionConfigRepository";
import { ExcludedFileDecorationProvider } from "./ExludedFileDecorationProvider";
import { clientManager } from "../../client/ClientManager";
export class ExclusionByTpdManager implements TreeDataProvider<TpdFile>, FileExclusionManager {
......@@ -36,6 +38,15 @@ export class ExclusionByTpdManager implements TreeDataProvider<TpdFile>, FileExc
return [...this.config.tpdFiles.content.map(tpd => tpd.resourceUri), ...this._itemsToBeDecorated];
}
public async init() {
const activatedTpd = this.config.activatedTpd.content;
if(activatedTpd) {
await this.config.activatedTpd.reset();
this.refresh();
ExcludedFileDecorationProvider.decorate([activatedTpd.resourceUri]);
}
}
public refresh() : void {
this._onDidChangeTreeData.fire();
}
......@@ -53,20 +64,56 @@ export class ExclusionByTpdManager implements TreeDataProvider<TpdFile>, FileExc
}
async exclude(item: TpdFile): Promise<void> {
// previous activated tpd:
const activatedTpd = this.config.activatedTpd.content;
// 1. save tpd path in settings
await this.config.activateTpd(item);
this.refresh();
ExcludedFileDecorationProvider.decorate([...this.config.tpdFiles.content.map(tpd => tpd.resourceUri)]);
// tpd view: refreshed, decorated, explorer: wasn't changed!
// 2. openTpd request --> 3. select excluded files
const filesToBeExcluded = await item.getFilesToBeExcluded();
if(filesToBeExcluded) {
await this.config.activateTpd(item);
this._itemsToBeDecorated.push(...filesToBeExcluded);
// 4. save excluded files
await this.config.updateExcludedItems(filesToBeExcluded);
let oldDecoratedItems: Uri[] = [];
if(this._itemsToBeDecorated.length) {
const filesToBeExcludedPaths = new Set(filesToBeExcluded.map(uri => uri.fsPath));
oldDecoratedItems = this._itemsToBeDecorated.filter(item => !filesToBeExcludedPaths.has(item.fsPath));
}
this._itemsToBeDecorated = filesToBeExcluded;
// 5. save excluded states
this.excludedStates = filesToBeExcluded.map(file => ({identifier: file.toString(), isExcluded: true} as ExcludedState));
await this.config.excludedItems.update(filesToBeExcluded);
// 6. decorate excluded files (only visible items in explorer will be decorated)
ExcludedFileDecorationProvider.decorate([...this.itemsToBeDecorated, ...oldDecoratedItems]);
// 7. notify server
clientManager.notifyServerIfExcludeStateChanged(this.excludedStates);
} else {
// Tpd parse failed
// restore the previous state
if(activatedTpd) {
await this.config.activateTpd(activatedTpd);
} else {
await this.config.activatedTpd.reset();
}
this.refresh();
ExcludedFileDecorationProvider.decorate([...this.config.tpdFiles.content.map(tpd => tpd.resourceUri)]);
}
};
async include(item: TpdFile): Promise<void> {
this.excludedStates = this.config.excludedItems.content.map(item => ({identifier: item.toString(), isExcluded: false} as ExcludedState));
this.excludedStates = this.config.excludedItems.map(item => ({identifier: item.toString(), isExcluded: false} as ExcludedState));
await this.config.deactivateTpd();
this.refresh();
ExcludedFileDecorationProvider.decorate([...this.config.tpdFiles.content.map(tpd => tpd.resourceUri)]);
clientManager.notifyServerIfExcludeStateChanged(this.excludedStates);
ExcludedFileDecorationProvider.decorate(this.itemsToBeDecorated);
this._itemsToBeDecorated = [];
};
async reset(): Promise<void> {
......@@ -74,7 +121,7 @@ export class ExclusionByTpdManager implements TreeDataProvider<TpdFile>, FileExc
this.disposable.dispose();
};
async open(item: Uri): Promise<void> {
async openTpdInEditor(item: Uri): Promise<void> {
const doc = await workspace.openTextDocument(item);
await window.showTextDocument(doc);
}
......
......@@ -10,43 +10,49 @@
* @author Csilla Farkas
*/
import { Uri } from "vscode";
import { Uri, commands } from "vscode";
import { TpdFile } from "./TpdFile";
import { activatedTpdConfig, excludedFilesConfig, tpdFilesConfig } from "./Config";
import { ContextKey } from '../../customTypes';
export class ExclusionConfigRepository {
excludedItems = excludedFilesConfig;
protected _excludedItems: Map<string, Uri>;
// TODO: handle changes of settings.json (eg. user remove something manually)
constructor() {
this._excludedItems = new Map<string, Uri>(excludedFilesConfig.content.map(uri => [uri.fsPath, uri]));
}
get excludedItems(): Uri[] {
return [...this._excludedItems.values()];
}
isExcludedItem(uri: Uri): boolean {
const excludedFiles = new Set(this.excludedItems.rawContent);
return excludedFiles.has(uri.fsPath);
return this._excludedItems.has(uri.fsPath);
}
async addExcludedItems(uris: Uri[]): Promise<void> {
const excludedFiles = new Map<string, Uri>(this.excludedItems.content.map(uri => [uri.fsPath, uri]));
const size = excludedFiles.size;
const size = this._excludedItems.size;
uris.forEach(uri => {
if(!excludedFiles.has(uri.fsPath)) {
excludedFiles.set(uri.fsPath, uri);
if(!this._excludedItems.has(uri.fsPath)) {
this._excludedItems.set(uri.fsPath, uri);
}
});
if(size < excludedFiles.size) {
await this.excludedItems.update([...excludedFiles.values()]);
if(size < this._excludedItems.size) {
await excludedFilesConfig.update([...this._excludedItems.values()]);
}
}
async removeExcludedItems(uris: Uri[]): Promise<void> {
const excludedFiles = new Map<string, Uri>(this.excludedItems.content.map(uri => [uri.fsPath, uri]));
const size = excludedFiles.size;
const size = this._excludedItems.size;
uris.forEach(uri => {
excludedFiles.delete(uri.fsPath);
this._excludedItems.delete(uri.fsPath);
});
if(size > excludedFiles.size) {
await this.excludedItems.update([...excludedFiles.values()]);
if(size > this._excludedItems.size) {
await excludedFilesConfig.update([...this._excludedItems.values()]);
}
}
}
......@@ -55,6 +61,10 @@ export class ExclusionByTpdConfigRepository extends ExclusionConfigRepository {
tpdFiles = tpdFilesConfig;
activatedTpd = activatedTpdConfig;
async updateExcludedItems(uris: Uri[]) {
this._excludedItems = new Map<string, Uri>(uris.map(uri => [uri.fsPath, uri]));
}
async addTpd(uri: Uri): Promise<void> {
const tpds = this.tpdFiles.content;
await this.tpdFiles.update([...tpds.map(tpd => tpd.resourceUri), uri]);
......@@ -70,8 +80,8 @@ export class ExclusionByTpdConfigRepository extends ExclusionConfigRepository {
}
async deactivateTpd(): Promise<void> {
this._excludedItems = new Map();
await this.activatedTpd.reset();
await this.excludedItems.reset();
}
}
\ No newline at end of file
......@@ -16,6 +16,7 @@ import { FileExclusionManager } from "./FileExclusionManager";
import { ExcludedState } from "../../customTypes";
import { ExclusionConfigRepository } from "./ExclusionConfigRepository";
import { FileSystemManager } from "../FileSystemManager";
import { excludedFilesConfig } from "./Config";
export class ExclusionInExplorerManager implements FileExclusionManager {
......@@ -28,7 +29,7 @@ export class ExclusionInExplorerManager implements FileExclusionManager {
constructor() {
this.watcher.onDidCreate(this._handleFileCreate);
this.watcher.onDidDelete(this._handleFileDelete);
this.excludedStates = this.config.excludedItems.content.map(item => ({identifier: item.toString(), isExcluded: true} as ExcludedState));
this.excludedStates = this.config.excludedItems.map(item => ({identifier: item.toString(), isExcluded: true} as ExcludedState));
}
public async init() {
......@@ -99,7 +100,7 @@ export class ExclusionInExplorerManager implements FileExclusionManager {
private _getAllUniqueParentDir(uris: Uri[]): Uri[] {
const uniqueParentDirs = new Set<string>;
uris.forEach(uri => {
const parentDirs = FileSystemManager.getParentUrisOfUriInWorkspace(uri);
const parentDirs = FileSystemManager.getParentsOfUriInWorkspace(uri);
parentDirs.forEach(parentPath => uniqueParentDirs.add(parentPath));
});
......@@ -164,6 +165,6 @@ export class ExclusionInExplorerManager implements FileExclusionManager {
};
async reset(): Promise<void> {
await this.config.excludedItems.reset();
await excludedFilesConfig.reset();
};
}
\ No newline at end of file
......@@ -9,7 +9,7 @@
* @author Csilla Farkas
*/
import { window, FileDecorationProvider, Disposable, Uri, CancellationToken, ProviderResult, FileDecoration, ThemeColor, EventEmitter } from 'vscode';
import { window, FileDecorationProvider, Disposable, Uri, CancellationToken, ProviderResult, FileDecoration, ThemeColor, EventEmitter, workspace } from 'vscode';
import { mainExclusionManager } from './MainExclusionManager';
export class ExcludedFileDecorationProvider implements FileDecorationProvider {
......@@ -33,8 +33,8 @@ export class ExcludedFileDecorationProvider implements FileDecorationProvider {
} else {
decoration = this._decorationForExcludedByFileExplorer;
}
if(mainExclusionManager.isExcludedItem(uri) || mainExclusionManager.isActivatedTpd(uri)) {
if( mainExclusionManager.isExcludedItem(uri) || mainExclusionManager.isActivatedTpd(uri)) {
return decoration;
}
}
......
......@@ -29,7 +29,7 @@ class MainExclusionManager {
constructor() {
this._exclusionManager = this._switchExclusionManager();
if(this._exclusionManager instanceof ExclusionInExplorerManager) {
if('init' in this._exclusionManager && typeof this._exclusionManager.init === 'function') {
this._exclusionManager.init();
}
this.updateContext();
......@@ -73,7 +73,7 @@ class MainExclusionManager {
public async updateContext() {
await commands.executeCommand('setContext', ContextKey.excludeByTpd, this.excludeByTpd.content);
await commands.executeCommand('setContext', ContextKey.excludedItems, this._exclusionManager.config.excludedItems.content.map(file => file.toString()));
await commands.executeCommand('setContext', ContextKey.excludedItems, this._exclusionManager.config.excludedItems.map(file => file.toString()));
}
public async exclude(selected: Uri[] | TpdFile) {
......@@ -109,7 +109,7 @@ class MainExclusionManager {
return;
}
await this._exclusionManager.open(file);
await this._exclusionManager.openTpdInEditor(file);
}
public async removeTpd(tpd: TpdFile) {
......
......@@ -41,11 +41,29 @@ export class TpdFile extends TreeItem {
}
public async getFilesToBeExcluded(): Promise<Uri[] | void> {
const fileList = await clientManager.readTpd(this.resourceUri);
const filesInWorkspace = await FileSystemManager.readWorkspace();
const filesToBeExcluded = filesInWorkspace.filter(file => !fileList?.includes(file.toString()));
const fileList = await clientManager.parseTpd(this.resourceUri);
if(fileList?.length) {
let parents = new Set<string>();
for(const file of fileList) {
const parentsOfFile = FileSystemManager.getParentsOfUriInWorkspace(Uri.file(file));
parents = new Set([...parents, ...parentsOfFile.map(item => item.toLowerCase())]);
}
return filesToBeExcluded;
const includedFiles = new Set([...fileList.map(file => file.toLowerCase()), ...parents]);
const filesInWorkspace = FileSystemManager.readWorkspace2();
const filesToBeExcluded: Uri[] = [];
for(const fileInWorkspace of filesInWorkspace.keys()) {
if(!includedFiles.has(fileInWorkspace)) {
const uri = filesInWorkspace.get(fileInWorkspace);
if(uri) {
filesToBeExcluded.push(uri);
}
}
}
return filesToBeExcluded;
}
}
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment