From 893bf3f73a92b0283810431968f2f831095b3ecd Mon Sep 17 00:00:00 2001 From: Elio Struyf Date: Wed, 28 Aug 2019 21:12:20 +0200 Subject: [PATCH] #2 - Added the ability to remove tags/categories --- README.md | 6 +-- package.json | 2 +- src/commands/Article.ts | 6 +-- src/commands/Settings.ts | 81 +++++++++++++++++++++-------------- src/constants/settings.ts | 2 + src/helpers/FilesHelper.ts | 7 +-- src/helpers/SettingsHelper.ts | 4 +- 7 files changed, 63 insertions(+), 45 deletions(-) diff --git a/README.md b/README.md index c448bf1d..a6b3f357 100644 --- a/README.md +++ b/README.md @@ -22,11 +22,11 @@ Inserts a selected into the front matter of your article/pos Export all the already used tags & categories in your articles/posts/... to your user settings -**Front Matter: Remap tag/category in all articles** +**Front Matter: Remap or remove tag/category in all articles** -This is commands helps you quickly update/remap a tag or category in all your markdown files. You'll be asked to select the taxonomy type (*tag* or *category*), the old taxonomy value and the new one. +This is commands helps you quickly update/remap or delete a tag or category in all your markdown files. You'll be asked to select the taxonomy type (*tag* or *category*), the old taxonomy value and the new one (leave the input field *blank* to remove the tag/category). -> **Info**: Once the remapping is completed, the taxonomy tags/categories will be updated in your user settings. +> **Info**: Once the remapping/deleting process is completed. The taxonomy tags/categories will be updated in your user settings. **Front Matter: Set current date** diff --git a/package.json b/package.json index 69b3b91e..1965c8cc 100644 --- a/package.json +++ b/package.json @@ -88,7 +88,7 @@ }, { "command": "frontMatter.remap", - "title": "Front Matter: Remap tag/category in all articles" + "title": "Front Matter: Remap or remove tag/category in all articles" }, { "command": "frontMatter.setDate", diff --git a/src/commands/Article.ts b/src/commands/Article.ts index da5be4ce..e8fdab7e 100644 --- a/src/commands/Article.ts +++ b/src/commands/Article.ts @@ -1,6 +1,6 @@ import * as vscode from 'vscode'; import { TaxonomyType } from "../models"; -import { CONFIG_KEY, ACTION_TAXONOMY_TAGS, ACTION_TAXONOMY_CATEGORIES, ACTION_DATE_FORMAT } from "../constants/settings"; +import { CONFIG_KEY, ACTION_TAXONOMY_TAGS, ACTION_TAXONOMY_CATEGORIES, ACTION_DATE_FORMAT, EXTENSION_NAME } from "../constants/settings"; import { format } from "date-fns"; import { ArticleHelper, SettingsHelper } from '../helpers'; @@ -51,7 +51,7 @@ export class Article { } if (options.length === 0) { - vscode.window.showInformationMessage(`No ${type === TaxonomyType.Tag ? "tags" : "categories"} configured.`); + vscode.window.showInformationMessage(`${EXTENSION_NAME}: No ${type === TaxonomyType.Tag ? "tags" : "categories"} configured.`); return; } @@ -92,7 +92,7 @@ export class Article { ArticleHelper.update(editor, article); } catch (e) { - vscode.window.showErrorMessage(`Front Matter: Something failed while parsing the date format. Check your "${CONFIG_KEY}${ACTION_DATE_FORMAT}" setting.`); + vscode.window.showErrorMessage(`${EXTENSION_NAME}: Something failed while parsing the date format. Check your "${CONFIG_KEY}${ACTION_DATE_FORMAT}" setting.`); console.log(e.message); } } diff --git a/src/commands/Settings.ts b/src/commands/Settings.ts index 59a16a8a..d034e054 100644 --- a/src/commands/Settings.ts +++ b/src/commands/Settings.ts @@ -2,7 +2,7 @@ import * as vscode from 'vscode'; import * as matter from 'gray-matter'; import * as fs from 'fs'; import { TaxonomyType } from "../models"; -import { CONFIG_KEY, ACTION_TAXONOMY_TAGS, ACTION_TAXONOMY_CATEGORIES } from '../constants'; +import { CONFIG_KEY, ACTION_TAXONOMY_TAGS, ACTION_TAXONOMY_CATEGORIES, EXTENSION_NAME } from '../constants'; import { ArticleHelper, SettingsHelper, FilesHelper } from '../helpers'; export class Settings { @@ -27,7 +27,7 @@ export class Settings { } if (options.find(o => o === newOption)) { - vscode.window.showInformationMessage(`The provided ${type === TaxonomyType.Tag ? "tag" : "category"} already exists.`); + vscode.window.showInformationMessage(`${EXTENSION_NAME}: The provided ${type === TaxonomyType.Tag ? "tag" : "category"} already exists.`); return; } @@ -79,7 +79,7 @@ export class Settings { vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, - title: `Front Matter: exporting tags and categories`, + title: `${EXTENSION_NAME}: exporting tags and categories`, cancellable: false }, async (progress) => { // Fetching all tags and categories from MD files @@ -136,7 +136,7 @@ export class Settings { await config.update(ACTION_TAXONOMY_CATEGORIES, crntCategories); // Done - vscode.window.showInformationMessage(`Front Matter: export completed. Tags: ${crntTags.length} - Categories: ${crntCategories.length}.`); + vscode.window.showInformationMessage(`${EXTENSION_NAME}: Export completed. Tags: ${crntTags.length} - Categories: ${crntCategories.length}.`); }); } @@ -159,10 +159,10 @@ export class Settings { } const type = taxType === "Tag" ? TaxonomyType.Tag : TaxonomyType.Category; - const options = SettingsHelper.getTaxonomy(type); + let options = SettingsHelper.getTaxonomy(type); if (!options || options.length === 0) { - vscode.window.showInformationMessage(`No ${type === TaxonomyType.Tag ? "tags" : "categories"} configured.`); + vscode.window.showInformationMessage(`${EXTENSION_NAME}: No ${type === TaxonomyType.Tag ? "tags" : "categories"} configured.`); return; } @@ -176,13 +176,15 @@ export class Settings { } const newOptionValue = await vscode.window.showInputBox({ - prompt: `Insert the value of the ${type === TaxonomyType.Tag ? "tag" : "category"} with which you want to remap "${selectedOption}".`, + prompt: `Specify the value of the ${type === TaxonomyType.Tag ? "tag" : "category"} with which you want to remap "${selectedOption}". Leave the input if you want to remove the ${type === TaxonomyType.Tag ? "tag" : "category"} from all articles.`, placeHolder: `Name of the ${type === TaxonomyType.Tag ? "tag" : "category"}` }); if (!newOptionValue) { - vscode.window.showInformationMessage(`You didn't provide a new value.`); - return; + const deleteAnswer = await vscode.window.showQuickPick(["yes", "no"], { canPickMany: false, placeHolder: `Delete ${selectedOption} ${type === TaxonomyType.Tag ? "tag" : "category"}?` }); + if (deleteAnswer === "no") { + return; + } } // Retrieve all the markdown files @@ -191,9 +193,13 @@ export class Settings { return; } + let progressText = `${EXTENSION_NAME}: Remapping "${selectedOption}" ${type === TaxonomyType.Tag ? "tag" : "category"} to "${newOptionValue}".`; + if (!newOptionValue) { + progressText = `${EXTENSION_NAME}: Deleting "${selectedOption}" ${type === TaxonomyType.Tag ? "tag" : "category"}.`; + } vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, - title: `Front Matter: remapping "${selectedOption}" ${type === TaxonomyType.Tag ? "tag" : "category"} to "${newOptionValue}".`, + title: progressText, cancellable: false }, async (progress) => { // Set the initial progress @@ -205,41 +211,50 @@ export class Settings { let i = 0; for (const file of allMdFiles) { progress.report({ increment: (++i/progressNr) }); - const mdFile = await vscode.workspace.openTextDocument(file); + const mdFile = fs.readFileSync(file.path, { encoding: "utf8" }); if (mdFile) { - const txtData = mdFile.getText(); - if (txtData) { - try { - const article = matter(txtData); - if (article && article.data) { - const { data } = article; - const options: string[] = data[matterProp]; - if (options && options.length > 0) { - const idx = options.findIndex(o => o === selectedOption); - if (idx !== -1) { - options[idx] = newOptionValue; - data[matterProp] = [...new Set(options)].sort(); - - // Update the file - fs.writeFileSync(mdFile.fileName, matter.stringify(article.content, article.data), { encoding: "utf8" }); + try { + const article = matter(mdFile); + if (article && article.data) { + const { data } = article; + let taxonomies: string[] = data[matterProp]; + if (taxonomies && taxonomies.length > 0) { + const idx = taxonomies.findIndex(o => o === selectedOption); + if (idx !== -1) { + if (newOptionValue) { + taxonomies[idx] = newOptionValue; + } else { + taxonomies = taxonomies.filter(o => o !== selectedOption); } + data[matterProp] = [...new Set(taxonomies)].sort(); + // Update the file + fs.writeFileSync(file.path, matter.stringify(article.content, article.data), { encoding: "utf8" }); } - } - } catch (e) { - // Continue with the next file - } + } + } + } catch (e) { + console.log(file.path); + // Continue with the next file } } } // Update the settings const idx = options.findIndex(o => o === selectedOption); - if (idx !== -1) { - options[idx] = newOptionValue; + if (newOptionValue) { + // Add or update the new option + if (idx !== -1) { + options[idx] = newOptionValue; + } else { + options.push(newOptionValue); + } } else { - options.push(newOptionValue); + // Remove the selected option + options = options.filter(o => o !== selectedOption); } await SettingsHelper.update(type, options); + + vscode.window.showInformationMessage(`${EXTENSION_NAME}: ${newOptionValue ? "Remapping" : "Deleation"} of the ${selectedOption} ${type === TaxonomyType.Tag ? "tag" : "category"} completed.`); }); } } \ No newline at end of file diff --git a/src/constants/settings.ts b/src/constants/settings.ts index 52c87915..4b49a18e 100644 --- a/src/constants/settings.ts +++ b/src/constants/settings.ts @@ -1,3 +1,5 @@ +export const EXTENSION_NAME = "Front Matter"; + export const CONFIG_KEY = "frontMatter"; export const ACTION_TAXONOMY_TAGS = "taxonomy.tags"; diff --git a/src/helpers/FilesHelper.ts b/src/helpers/FilesHelper.ts index 7cb44a3a..9e87aa97 100644 --- a/src/helpers/FilesHelper.ts +++ b/src/helpers/FilesHelper.ts @@ -1,4 +1,5 @@ import * as vscode from 'vscode'; +import { EXTENSION_NAME } from '../constants'; export class FilesHelper { @@ -6,10 +7,10 @@ export class FilesHelper { * Retrieve all markdown files from the current project */ public static async getMdFiles(): Promise { - const mdFiles = await vscode.workspace.findFiles('**/*.md', "**/node_modules/**"); - const markdownFiles = await vscode.workspace.findFiles('**/*.markdown', "**/node_modules/**"); + const mdFiles = await vscode.workspace.findFiles('**/*.md', "**/node_modules/**,**/archetypes/**"); + const markdownFiles = await vscode.workspace.findFiles('**/*.markdown', "**/node_modules/**,**/archetypes/**"); if (!mdFiles && !markdownFiles) { - vscode.window.showInformationMessage(`No MD files found.`); + vscode.window.showInformationMessage(`${EXTENSION_NAME}: No MD files found.`); return null; } diff --git a/src/helpers/SettingsHelper.ts b/src/helpers/SettingsHelper.ts index 1e7843d2..fbfa7c5d 100644 --- a/src/helpers/SettingsHelper.ts +++ b/src/helpers/SettingsHelper.ts @@ -9,7 +9,7 @@ export class SettingsHelper { * * @param type */ - public static getTaxonomy(type: TaxonomyType) { + public static getTaxonomy(type: TaxonomyType): string[] { const config = vscode.workspace.getConfiguration(CONFIG_KEY); // Add all the known options to the selection list const configSetting = type === TaxonomyType.Tag ? ACTION_TAXONOMY_TAGS : ACTION_TAXONOMY_CATEGORIES; @@ -17,7 +17,7 @@ export class SettingsHelper { if (crntOptions && crntOptions.length > 0) { return crntOptions; } - return null; + return []; } /**