From 157228edb59244306687c5a2cd1b4fd3cafaf5b8 Mon Sep 17 00:00:00 2001 From: Elio Struyf Date: Thu, 5 Aug 2021 22:53:46 +0200 Subject: [PATCH] #49 - Initialize new project --- CHANGELOG.md | 9 +++-- README.md | 4 ++ package.json | 51 +++++++++++++++++++------- src/commands/Folders.ts | 3 +- src/commands/Project.ts | 49 +++++++++++++++++++++++++ src/commands/Template.ts | 28 +++++++++++++- src/constants/Extension.ts | 23 ++++++++++++ src/constants/context.ts | 6 +++ src/extension.ts | 73 ++++++++++++++++++++++--------------- src/webview/ExplorerView.ts | 4 +- 10 files changed, 201 insertions(+), 49 deletions(-) create mode 100644 src/commands/Project.ts create mode 100644 src/constants/Extension.ts create mode 100644 src/constants/context.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d02f615..48ac7842 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/README.md b/README.md index 7d78de3c..83ba8afd 100644 --- a/README.md +++ b/README.md @@ -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. diff --git a/package.json b/package.json index ceeb3e4d..018a269f 100644 --- a/package.json +++ b/package.json @@ -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": [ diff --git a/src/commands/Folders.ts b/src/commands/Folders.ts index 682cabde..346950dd 100644 --- a/src/commands/Folders.ts +++ b/src/commands/Folders.ts @@ -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); } /** diff --git a/src/commands/Project.ts b/src/commands/Project.ts new file mode 100644 index 00000000..e2c61f9b --- /dev/null +++ b/src/commands/Project.ts @@ -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(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}`); + } + } +} \ No newline at end of file diff --git a/src/commands/Template.ts b/src/commands/Template.ts index 9d0695b0..b00760f4 100644 --- a/src/commands/Template.ts +++ b/src/commands/Template.ts @@ -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(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 */ diff --git a/src/constants/Extension.ts b/src/constants/Extension.ts new file mode 100644 index 00000000..663fa3c6 --- /dev/null +++ b/src/constants/Extension.ts @@ -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") +}; \ No newline at end of file diff --git a/src/constants/context.ts b/src/constants/context.ts new file mode 100644 index 00000000..ed8fa529 --- /dev/null +++ b/src/constants/context.ts @@ -0,0 +1,6 @@ + + +export const CONTEXT = { + canInit: "frontMatterCanInit", + registeredFolders: 'frontMatter.registeredFolders' +}; \ No newline at end of file diff --git a/src/extension.ts b/src/extension.ts index eea5485c..bcc7083d 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -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() {} diff --git a/src/webview/ExplorerView.ts b/src/webview/ExplorerView.ts index 00fce51c..a424f473 100644 --- a/src/webview/ExplorerView.ts +++ b/src/webview/ExplorerView.ts @@ -394,7 +394,7 @@ export class ExplorerView implements WebviewViewProvider, Disposable { - + @@ -405,6 +405,8 @@ export class ExplorerView implements WebviewViewProvider, Disposable {
+ Daily usage +