#49 - Initialize new project

This commit is contained in:
Elio Struyf
2021-08-05 22:53:46 +02:00
parent 10268fc60f
commit 157228edb5
10 changed files with 201 additions and 49 deletions
+5 -4
View File
@@ -1,10 +1,11 @@
# Change Log
## [2.x.x] - 2020-08-xx
## [2.2.0] - 2020-08-xx
- [#47](https://github.com/estruyf/vscode-front-matter/issues/#47): Fix when table shows only value `0`
- [#48](https://github.com/estruyf/vscode-front-matter/issues/#48): Added new folder registration message + notification helper
- [#50](https://github.com/estruyf/vscode-front-matter/issues/#50): Fix in the table rendering of rows
- [#47](https://github.com/estruyf/vscode-front-matter/issues/47): Fix when table shows only value `0`
- [#48](https://github.com/estruyf/vscode-front-matter/issues/48): Added new folder registration message + notification helper
- [#49](https://github.com/estruyf/vscode-front-matter/issues/49): New initialize project command
- [#50](https://github.com/estruyf/vscode-front-matter/issues/50): Fix in the table rendering of rows
## [2.1.0] - 2020-08-04
+4
View File
@@ -133,6 +133,10 @@ When adding files in the folder, you'll be able to run the `Front Matter: New ar
## Available commands
**Front Matter: Initialize project**
This command will initialize the project with a template folder and an article template. It makes it easier to get you started with the extension and creating your content.
**Front Matter: Create content**
With this command, you can easily create content in your project within the registered folders and provided templates.
+38 -13
View File
@@ -56,6 +56,7 @@
"onCommand:frontMatter.registerFolder",
"onCommand:frontMatter.unregisterFolder",
"onCommand:frontMatter.createContent",
"onCommand:frontMatter.init",
"onView:frontMatter.explorer"
],
"main": "./dist/extension",
@@ -185,55 +186,73 @@
"commands": [
{
"command": "frontMatter.insertTags",
"title": "Front Matter: Insert tags"
"title": "Insert tags",
"category": "Front matter"
},
{
"command": "frontMatter.insertCategories",
"title": "Front Matter: Insert categories"
"title": "Insert categories",
"category": "Front matter"
},
{
"command": "frontMatter.createTag",
"title": "Front Matter: Create tag"
"title": "Create tag",
"category": "Front matter"
},
{
"command": "frontMatter.createCategory",
"title": "Front Matter: Create category"
"title": "Create category",
"category": "Front matter"
},
{
"command": "frontMatter.exportTaxonomy",
"title": "Front Matter: Export all tags & categories to your settings"
"title": "Export all tags & categories to your settings",
"category": "Front matter"
},
{
"command": "frontMatter.remap",
"title": "Front Matter: Remap or remove tag/category in all articles"
"title": "Remap or remove tag/category in all articles",
"category": "Front matter"
},
{
"command": "frontMatter.setDate",
"title": "Front Matter: Set current date"
"title": "Set current date",
"category": "Front matter"
},
{
"command": "frontMatter.setLastModifiedDate",
"title": "Front Matter: Set lastmod date"
"title": "Set lastmod date",
"category": "Front matter"
},
{
"command": "frontMatter.generateSlug",
"title": "Front Matter: Generate slug based on article title"
"title": "Generate slug based on article title",
"category": "Front matter"
},
{
"command": "frontMatter.createFromTemplate",
"title": "Front Matter: New article from template"
"title": "New article from template",
"category": "Front matter"
},
{
"command": "frontMatter.registerFolder",
"title": "Front Matter: Register folder"
"title": "Register folder",
"category": "Front matter"
},
{
"command": "frontMatter.unregisterFolder",
"title": "Front Matter: Unregister folder"
"title": "Unregister folder",
"category": "Front matter"
},
{
"command": "frontMatter.createContent",
"title": "Front Matter: Create content"
"title": "Create content",
"category": "Front matter"
},
{
"command": "frontMatter.init",
"title": "Initialize project",
"category": "Front matter"
}
],
"menus": {
@@ -253,6 +272,12 @@
"when": "explorerResourceIsFolder && resourcePath in frontMatter.registeredFolders",
"group": "Front Matter@3"
}
],
"commandPalette": [
{
"command": "frontMatter.init",
"when": "frontMatterCanInit"
}
]
},
"grammars": [
+2 -1
View File
@@ -5,6 +5,7 @@ import { ContentFolder } from "../models";
import uniqBy = require("lodash.uniqby");
import { Template } from "./Template";
import { Notifications } from "../helpers/Notifications";
import { CONTEXT } from "../constants/context";
export class Folders {
@@ -99,7 +100,7 @@ export class Folders {
for (const folder of folders) {
allFolders = [...allFolders, ...folder.paths]
}
commands.executeCommand('setContext', 'frontMatter.registeredFolders', allFolders);
commands.executeCommand('setContext', CONTEXT.registeredFolders, allFolders);
}
/**
+49
View File
@@ -0,0 +1,49 @@
import { workspace, Uri } from "vscode";
import { CONFIG_KEY, SETTING_TEMPLATES_FOLDER } from "../constants";
import { join } from "path";
import * as fs from "fs";
import { Notifications } from "../helpers/Notifications";
export class Project {
private static content = `---
title: "{{name}}"
slug: "/{{kebabCase name}}/"
description:
author:
date: 2019-08-22T15:20:28.000Z
lastmod: 2019-08-22T15:20:28.000Z
draft: true
tags: []
categories: []
---
`;
/**
* Initialize a new "Project" instance.
*/
public static async init() {
try {
const config = workspace.getConfiguration(CONFIG_KEY);
const folder = config.get<string>(SETTING_TEMPLATES_FOLDER);
const workspaceFolders = workspace.workspaceFolders;
if (!folder || !workspaceFolders || workspaceFolders.length === 0) {
return;
}
const workspaceFolder = workspaceFolders[0];
const templatePath = Uri.file(join(workspaceFolder.uri.fsPath, folder));
const article = Uri.file(join(templatePath.fsPath, "article.md"));
await workspace.fs.createDirectory(templatePath);
fs.writeFileSync(article.fsPath, Project.content, { encoding: "utf-8" });
Notifications.info("Project initialized successfully.");
} catch (err) {
Notifications.error(`Sorry, something went wrong - ${err?.message || err}`);
}
}
}
+27 -1
View File
@@ -1,15 +1,41 @@
import * as vscode from 'vscode';
import * as path from 'path';
import * as fs from 'fs';
import { CONFIG_KEY, EXTENSION_NAME, SETTING_TEMPLATES_FOLDER, SETTING_TEMPLATES_PREFIX } from '../constants';
import { CONFIG_KEY, SETTING_TEMPLATES_FOLDER, SETTING_TEMPLATES_PREFIX } from '../constants';
import { format } from 'date-fns';
import sanitize from '../helpers/Sanitize';
import { ArticleHelper } from '../helpers';
import { Article } from '.';
import { Notifications } from '../helpers/Notifications';
import { CONTEXT } from '../constants/context';
export class Template {
/**
* Check if the template folder is available
*/
public static async init() {
const config = vscode.workspace.getConfiguration(CONFIG_KEY);
const folder = config.get<string>(SETTING_TEMPLATES_FOLDER);
const workspaceFolders = vscode.workspace.workspaceFolders;
if (!folder || !workspaceFolders || workspaceFolders.length === 0) {
vscode.commands.executeCommand('setContext', CONTEXT.canInit, true);
return;
}
const workspaceFolder = workspaceFolders[0];
const templatePath = vscode.Uri.file(path.join(workspaceFolder.uri.fsPath, folder));
try {
await vscode.workspace.fs.stat(templatePath);
vscode.commands.executeCommand('setContext', CONTEXT.canInit, false);
} catch (e) {
vscode.commands.executeCommand('setContext', CONTEXT.canInit, true);
}
}
/**
* Create from a template
*/
+23
View File
@@ -0,0 +1,23 @@
const extensionName = "frontMatter";
export const getCommandName = (command: string) => {
return `${extensionName}.${command}`;
};
export const COMMAND_NAME = {
init: getCommandName("init"),
insertTags: getCommandName("insertTags"),
insertCategories: getCommandName("insertCategories"),
createTag: getCommandName("createTag"),
createCategory: getCommandName("createCategory"),
exportTaxonomy: getCommandName("exportTaxonomy"),
remap: getCommandName("remap"),
setDate: getCommandName("setDate"),
setLastModifiedDate: getCommandName("setLastModifiedDate"),
generateSlug: getCommandName("generateSlug"),
createFromTemplate: getCommandName("createFromTemplate"),
toggleDraft: getCommandName("toggleDraft"),
registerFolder: getCommandName("registerFolder"),
unregisterFolder: getCommandName("unregisterFolder"),
createContent: getCommandName("createContent")
};
+6
View File
@@ -0,0 +1,6 @@
export const CONTEXT = {
canInit: "frontMatterCanInit",
registeredFolders: 'frontMatter.registeredFolders'
};
+44 -29
View File
@@ -1,7 +1,9 @@
import * as vscode from 'vscode';
import { Article, Settings, StatusListener } from './commands';
import { Folders } from './commands/Folders';
import { Project } from './commands/Project';
import { Template } from './commands/Template';
import { COMMAND_NAME } from './constants/Extension';
import { TaxonomyType } from './models';
import { TagType } from './viewpanel/TagType';
import { ExplorerView } from './webview/ExplorerView';
@@ -20,68 +22,78 @@ export async function activate({ subscriptions, extensionUri }: vscode.Extension
}
});
let insertTags = vscode.commands.registerCommand('frontMatter.insertTags', async () => {
let insertTags = vscode.commands.registerCommand(COMMAND_NAME.insertTags, async () => {
await vscode.commands.executeCommand('workbench.view.extension.frontmatter-explorer');
await vscode.commands.executeCommand('workbench.action.focusSideBar');
explorerSidebar.triggerInputFocus(TagType.tags);
});
let insertCategories = vscode.commands.registerCommand('frontMatter.insertCategories', async () => {
let insertCategories = vscode.commands.registerCommand(COMMAND_NAME.insertCategories, async () => {
await vscode.commands.executeCommand('workbench.view.extension.frontmatter-explorer');
await vscode.commands.executeCommand('workbench.action.focusSideBar');
explorerSidebar.triggerInputFocus(TagType.categories);
});
let createTag = vscode.commands.registerCommand('frontMatter.createTag', () => {
let createTag = vscode.commands.registerCommand(COMMAND_NAME.createTag, () => {
Settings.create(TaxonomyType.Tag);
});
let createCategory = vscode.commands.registerCommand('frontMatter.createCategory', () => {
let createCategory = vscode.commands.registerCommand(COMMAND_NAME.createCategory, () => {
Settings.create(TaxonomyType.Category);
});
let exportTaxonomy = vscode.commands.registerCommand('frontMatter.exportTaxonomy', () => {
let exportTaxonomy = vscode.commands.registerCommand(COMMAND_NAME.exportTaxonomy, () => {
Settings.export();
});
let remap = vscode.commands.registerCommand('frontMatter.remap', () => {
let remap = vscode.commands.registerCommand(COMMAND_NAME.remap, () => {
Settings.remap();
});
let setDate = vscode.commands.registerCommand('frontMatter.setDate', () => {
let setDate = vscode.commands.registerCommand(COMMAND_NAME.setDate, () => {
Article.setDate();
});
let setLastModifiedDate = vscode.commands.registerCommand('frontMatter.setLastModifiedDate', () => {
let setLastModifiedDate = vscode.commands.registerCommand(COMMAND_NAME.setLastModifiedDate, () => {
Article.setLastModifiedDate();
});
let generateSlug = vscode.commands.registerCommand('frontMatter.generateSlug', () => {
let generateSlug = vscode.commands.registerCommand(COMMAND_NAME.generateSlug, () => {
Article.generateSlug();
});
let createFromTemplate = vscode.commands.registerCommand('frontMatter.createFromTemplate', (folder: vscode.Uri) => {
let createFromTemplate = vscode.commands.registerCommand(COMMAND_NAME.createFromTemplate, (folder: vscode.Uri) => {
const folderPath = Folders.getFolderPath(folder);
if (folderPath) {
Template.create(folderPath);
}
});
const toggleDraftCommand = 'frontMatter.toggleDraft';
const toggleDraftCommand = COMMAND_NAME.toggleDraft;
const toggleDraft = vscode.commands.registerCommand(toggleDraftCommand, async () => {
await Article.toggleDraft();
triggerShowDraftStatus();
});
// Register project folders
const registerFolder = vscode.commands.registerCommand(`frontMatter.registerFolder`, Folders.register);
const registerFolder = vscode.commands.registerCommand(COMMAND_NAME.registerFolder, Folders.register);
const unregisterFolder = vscode.commands.registerCommand(`frontMatter.unregisterFolder`, Folders.unregister);
const unregisterFolder = vscode.commands.registerCommand(COMMAND_NAME.unregisterFolder, Folders.unregister);
const createContent = vscode.commands.registerCommand(`frontMatter.createContent`, Folders.create);
const createContent = vscode.commands.registerCommand(COMMAND_NAME.createContent, Folders.create);
Folders.updateVsCodeCtx();
// Initialize command
Template.init();
const projectInit = vscode.commands.registerCommand(COMMAND_NAME.init, Project.init);
// Things to do when configuration changes
vscode.workspace.onDidChangeConfiguration(() => {
Template.init();
Folders.updateVsCodeCtx();
});
// Create the status bar
frontMatterStatusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 100);
frontMatterStatusBar.command = toggleDraftCommand;
@@ -94,21 +106,24 @@ export async function activate({ subscriptions, extensionUri }: vscode.Extension
triggerShowDraftStatus();
// Subscribe all commands
subscriptions.push(insertTags);
subscriptions.push(explorerView);
subscriptions.push(insertCategories);
subscriptions.push(createTag);
subscriptions.push(createCategory);
subscriptions.push(exportTaxonomy);
subscriptions.push(remap);
subscriptions.push(setDate);
subscriptions.push(setLastModifiedDate);
subscriptions.push(generateSlug);
subscriptions.push(createFromTemplate);
subscriptions.push(toggleDraft);
subscriptions.push(registerFolder);
subscriptions.push(unregisterFolder);
subscriptions.push(createContent);
subscriptions.push(
insertTags,
explorerView,
insertCategories,
createTag,
createCategory,
exportTaxonomy,
remap,
setDate,
setLastModifiedDate,
generateSlug,
createFromTemplate,
toggleDraft,
registerFolder,
unregisterFolder,
createContent,
projectInit
);
}
export function deactivate() {}
+3 -1
View File
@@ -394,7 +394,7 @@ export class ExplorerView implements WebviewViewProvider, Disposable {
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src ${webView.cspSource} 'self' 'unsafe-inline'; script-src 'nonce-${nonce}'; style-src ${webView.cspSource} 'self' 'unsafe-inline'; font-src ${webView.cspSource}">
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src ${webView.cspSource} https://api.visitorbadge.io 'self' 'unsafe-inline'; script-src 'nonce-${nonce}'; style-src ${webView.cspSource} 'self' 'unsafe-inline'; font-src ${webView.cspSource}">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="${styleResetUri}" rel="stylesheet">
<link href="${styleVSCodeUri}" rel="stylesheet">
@@ -405,6 +405,8 @@ export class ExplorerView implements WebviewViewProvider, Disposable {
<body>
<div id="app"></div>
<img style="display:none" src="https://api.visitorbadge.io/api/combined?user=estruyf&repo=frontmatter-usage&countColor=%23263759" alt="Daily usage" />
<script nonce="${nonce}" src="${scriptUri}"></script>
</body>
</html>