diff --git a/icons/awesome-template.svg b/icons/awesome-template.svg
new file mode 100644
index 0000000..6184e34
--- /dev/null
+++ b/icons/awesome-template.svg
@@ -0,0 +1,7 @@
+
+
diff --git a/package-lock.json b/package-lock.json
index 9de19bb..306fcf6 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -506,8 +506,7 @@
"@types/node": {
"version": "10.14.18",
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.18.tgz",
- "integrity": "sha512-ryO3Q3++yZC/+b8j8BdKd/dn9JlzlHBPdm80656xwYUdmPkpTGTjkAdt6BByiNupGPE8w0FhBgvYy/fX9hRNGQ==",
- "dev": true
+ "integrity": "sha512-ryO3Q3++yZC/+b8j8BdKd/dn9JlzlHBPdm80656xwYUdmPkpTGTjkAdt6BByiNupGPE8w0FhBgvYy/fX9hRNGQ=="
},
"@types/stack-utils": {
"version": "1.0.1",
@@ -515,6 +514,14 @@
"integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==",
"dev": true
},
+ "@types/uuid": {
+ "version": "3.4.5",
+ "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-3.4.5.tgz",
+ "integrity": "sha512-MNL15wC3EKyw1VLF+RoVO4hJJdk9t/Hlv3rt1OL65Qvuadm4BYo6g9ZJQqoq7X8NBFSsQXgAujWciovh2lpVjA==",
+ "requires": {
+ "@types/node": "*"
+ }
+ },
"@types/vscode": {
"version": "1.38.0",
"resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.38.0.tgz",
diff --git a/package.json b/package.json
index c6babcc..0ea55c1 100644
--- a/package.json
+++ b/package.json
@@ -34,7 +34,26 @@
},
"main": "./out/extension.js",
"contributes": {
- "commands": [],
+ "commands": [
+ {
+ "command": "extension.saveAsTemplate",
+ "title": "Save file as awesome template",
+ "category": "FILE",
+ "icon": {
+ "dark": "icons/awesome-template.svg",
+ "light": "icons/awesome-template.svg"
+ }
+ }
+ ],
+ "menus": {
+ "editor/title": [
+ {
+ "command": "extension.saveAsTemplate",
+ "group": "navigation@1",
+ "when": "resourceScheme == file"
+ }
+ ]
+ },
"configuration": {
"title": "Awesome Tree",
"properties": {
@@ -80,6 +99,7 @@
"vscode-test": "^1.2.0"
},
"dependencies": {
+ "@types/uuid": "^3.4.5",
"lodash": "^4.17.15"
}
}
diff --git a/src/__mocks__/vscode.ts b/src/__mocks__/vscode.ts
index 87dd7f5..305bee6 100644
--- a/src/__mocks__/vscode.ts
+++ b/src/__mocks__/vscode.ts
@@ -15,3 +15,7 @@ export const window = {
createOutputChannel: jest.fn(() => outputChanelMock),
showInformationMessage: jest.fn(),
} as {[key in keyof typeof vscode.window]: jest.Mock};
+
+export const commands = {
+ registerCommand: jest.fn(),
+} as {[key in keyof typeof vscode.commands]: jest.Mock};
diff --git a/src/commands/saveAsTemplate.ts b/src/commands/saveAsTemplate.ts
new file mode 100644
index 0000000..c007742
--- /dev/null
+++ b/src/commands/saveAsTemplate.ts
@@ -0,0 +1,66 @@
+import * as fs from 'fs';
+import * as vscode from 'vscode';
+import * as path from 'path';
+import * as uuid from 'uuid/v4';
+import { getRelativePath } from '../fileSystem/getRelativePath';
+import { getInfoAboutPath } from '../fileInfo/getInfoAboutPath';
+import { createVariableTemplate } from '../variableTemplate/createVariableTemplate';
+import { createDocument } from '../fileSystem/createDocument';
+import { addExtensionToRecommendations } from '../fileSystem/addExtensionToRecommendations';
+
+const DIRECTORY_FOR_TEMPLATES = 'awesome-tree-templates';
+
+function findWorkspacePath(searchFsPath:string): string | undefined {
+ const { workspaceFolders } = vscode.workspace;
+ if(!workspaceFolders){
+ return;
+ }
+ for (let i = 0; i < workspaceFolders.length; i++) {
+ const {fsPath} = workspaceFolders[i].uri;
+ if(searchFsPath.indexOf(fsPath) === 0){
+ return fsPath;
+ }
+ }
+}
+
+export function saveAsTemplate(file: vscode.Uri) {
+ const workspacePath = findWorkspacePath(file.fsPath);
+ if (workspacePath === undefined) {
+ vscode.window.showWarningMessage(`Can't find workspace directory for file: '${file.fsPath}'`);
+ return;
+ }
+
+ const relativePath = getRelativePath(file.fsPath);
+ const templateId = uuid();
+ const templatePath = path.join(workspacePath, DIRECTORY_FOR_TEMPLATES, 'templates', `template-${templateId}.json` );
+ const templateDatabasePath = path.join(workspacePath, DIRECTORY_FOR_TEMPLATES, 'database-awesome.json' );
+ const infoAboutNewFile = getInfoAboutPath(relativePath);
+ const lines = fs.readFileSync(file.fsPath).toString().split('\n');
+ const templateLines = lines.map(line => createVariableTemplate(line, [infoAboutNewFile]));
+
+ const template = {
+ baseFilePath: relativePath,
+ pathsTemplate: [
+ createVariableTemplate(relativePath, [infoAboutNewFile])
+ ],
+ templateId
+ };
+
+ let currentSavedTemplates: Array;
+
+ try {
+ currentSavedTemplates = JSON.parse(fs.readFileSync(templateDatabasePath).toString());
+ } catch (error) {
+ currentSavedTemplates = [];
+ }
+
+ currentSavedTemplates.push(template);
+
+ Promise.all([
+ createDocument(templatePath, JSON.stringify(templateLines, null, 4)),
+ createDocument(templateDatabasePath, JSON.stringify(currentSavedTemplates, null, 4))
+ ]).then(() => {
+ vscode.window.showInformationMessage('Saved success!');
+ addExtensionToRecommendations(workspacePath);
+ });
+}
diff --git a/src/extension.ts b/src/extension.ts
index 73a7b44..a177f69 100644
--- a/src/extension.ts
+++ b/src/extension.ts
@@ -10,12 +10,15 @@ import { getRelativePath } from './fileSystem/getRelativePath';
import { getSiblingInfo, DirectoriesInfo } from './fileInfo/getSiblingInfo';
import { getPathTemplates } from './fileSystem/getPathTemplates';
import { getFilesContentAsTemplate } from './fileSystem/getFilesContentAsTemplate';
+import { saveAsTemplate } from './commands/saveAsTemplate';
+import { createDocument } from './fileSystem/createDocument';
-export function activate() {
+export function activate(context: vscode.ExtensionContext) {
const settingProvider = vscode.workspace.getConfiguration('awesomeTree');
const fileSystemWatcher = vscode.workspace.createFileSystemWatcher('**/*',false, true, true);
const outputChannel = vscode.window.createOutputChannel('Awesome tree');
-
+
+ context.subscriptions.push(vscode.commands.registerCommand('extension.saveAsTemplate', saveAsTemplate));
outputChannel.appendLine('Listening for file changes started!');
fileSystemWatcher.onDidCreate(async(createdItemUri: vscode.Uri) => {
@@ -120,17 +123,6 @@ export function activate() {
}
});
- function createDocument(filePath: string, content: string): Promise {
- return new Promise((resolve, reject) => {
- ensureDirectoryExistence(filePath);
- fs.writeFile(filePath, content, {}, async (err) => {
- if(err){
- return reject(err);
- }
- vscode.workspace.openTextDocument(filePath).then(resolve);
- });
- });
- }
function createGithubIssue(error: Error) {
const MAX_CHARACTERS_IN_URI: number = 4000;
@@ -193,15 +185,6 @@ export function activate() {
}, [] as string[]);
}
- function ensureDirectoryExistence(filePath:string) {
- const dirname = path.dirname(filePath);
- if (fs.existsSync(dirname)) {
- return true;
- }
- ensureDirectoryExistence(dirname);
- fs.mkdirSync(dirname);
- }
-
function isDirectory(uri: vscode.Uri): boolean {
return fs.lstatSync(uri.fsPath).isDirectory();
}
diff --git a/src/extenstion.test.ts b/src/extenstion.test.ts
index 588601d..7ee265c 100644
--- a/src/extenstion.test.ts
+++ b/src/extenstion.test.ts
@@ -10,18 +10,24 @@ describe('extenstion', () => {
let mockWatcher: {
[key in keyof vscode.FileSystemWatcher]?: jest.Mock
};
+ let mockContext: vscode.ExtensionContext;
beforeEach(() => {
mockWatcher = {
onDidCreate: jest.fn()
};
+ mockContext = {
+ subscriptions: {
+ push: jest.fn()
+ }
+ } as any as vscode.ExtensionContext;
const createSystemWatcher = vscode.workspace.createFileSystemWatcher as jest.Mock;
createSystemWatcher.mockReturnValueOnce(mockWatcher);
});
it('should start listen for create file', () => {
expect(vscode.workspace.createFileSystemWatcher).not.toHaveBeenCalled();
- activate();
+ activate(mockContext);
expect(vscode.workspace.createFileSystemWatcher).toHaveBeenCalled();
expect(mockWatcher.onDidCreate).toHaveBeenCalled();
@@ -47,7 +53,7 @@ describe('extenstion', () => {
});
});
- activate();
+ activate(mockContext);
});
});
diff --git a/src/fileSystem/addExtensionToRecommendations.ts b/src/fileSystem/addExtensionToRecommendations.ts
new file mode 100644
index 0000000..ef54eab
--- /dev/null
+++ b/src/fileSystem/addExtensionToRecommendations.ts
@@ -0,0 +1,30 @@
+import * as fs from 'fs';
+import * as path from 'path';
+import * as process from 'child_process';
+
+export function addExtensionToRecommendations(workspaceDirectory: string){
+ try {
+ const extensionsPath = path.join(workspaceDirectory, '.vscode', 'extensions.json');
+ let fileData;
+ if (fs.existsSync(extensionsPath)) {
+ fileData = JSON.parse(fs.readFileSync(extensionsPath).toString());
+ if (!Array.isArray(fileData.recommendations)) {
+ fileData.recommendations = [];
+ }
+ if (fileData.recommendations.includes('bajdzis.awesome-tree')) {
+ return;
+ }
+ } else {
+ fileData = {
+ recommendations: []
+ };
+ }
+ fileData.recommendations.push('bajdzis.awesome-tree');
+
+ fs.writeFileSync(extensionsPath, JSON.stringify(fileData, null, 2));
+
+ process.spawn('git add ".vscode/extensions.json" -f');
+ } catch (error) {
+ console.log(error);
+ }
+}
diff --git a/src/fileSystem/createDocument.ts b/src/fileSystem/createDocument.ts
new file mode 100644
index 0000000..102304d
--- /dev/null
+++ b/src/fileSystem/createDocument.ts
@@ -0,0 +1,15 @@
+import * as fs from 'fs';
+import * as vscode from 'vscode';
+import { ensureDirectoryExistence } from './ensureDirectoryExistence';
+
+export function createDocument(filePath: string, content: string): Promise {
+ return new Promise((resolve, reject) => {
+ ensureDirectoryExistence(filePath);
+ fs.writeFile(filePath, content, {}, async (err) => {
+ if(err){
+ return reject(err);
+ }
+ vscode.workspace.openTextDocument(filePath).then(resolve);
+ });
+ });
+}
diff --git a/src/fileSystem/ensureDirectoryExistence.ts b/src/fileSystem/ensureDirectoryExistence.ts
new file mode 100644
index 0000000..c252050
--- /dev/null
+++ b/src/fileSystem/ensureDirectoryExistence.ts
@@ -0,0 +1,11 @@
+import * as fs from 'fs';
+import * as path from 'path';
+
+export function ensureDirectoryExistence(filePath:string) {
+ const dirname = path.dirname(filePath);
+ if (fs.existsSync(dirname)) {
+ return true;
+ }
+ ensureDirectoryExistence(dirname);
+ fs.mkdirSync(dirname);
+}