diff --git a/CHANGELOG.md b/CHANGELOG.md index b7a38790..797f7533 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,20 @@ # Change Log +## [5.7.0] - 2021-12-07 - [Release Notes](https://beta.frontmatter.codes/updates/v5.7.0) + +### 🎨 Enhancements + +- [#188](https://github.com/estruyf/vscode-front-matter/issues/188): Support for `.markdown` files added to the dashboard +- [#190](https://github.com/estruyf/vscode-front-matter/issues/190): Diagnostic output for the extension +- [#194](https://github.com/estruyf/vscode-front-matter/issues/194): WYSIWYG controls added for markdown files + configuration to enable/disable the functionality + +### 🐞 Fixes + +- [#191](https://github.com/estruyf/vscode-front-matter/issues/191): Fix beta settings page +- [#200](https://github.com/estruyf/vscode-front-matter/issues/200): Fix last modified date sorting for media files +- [#201](https://github.com/estruyf/vscode-front-matter/issues/201): Fix overflow issue with the media filename +- [#202](https://github.com/estruyf/vscode-front-matter/issues/202): Fix checkbox label color for light themes + ## [5.6.0] - 2021-11-23 ### 🎨 Enhancements diff --git a/README.beta.md b/README.beta.md index 96c7932e..e5649abd 100644 --- a/README.beta.md +++ b/README.beta.md @@ -111,7 +111,10 @@ If you have the courage to test out the beta features, we made available a beta
- + + + + diff --git a/README.md b/README.md index 0bbbf7d7..28be793d 100644 --- a/README.md +++ b/README.md @@ -109,7 +109,10 @@ If you have the courage to test out the beta features, we made available a beta
-
+
+
+
+
diff --git a/assets/icons/blockquote-dark.svg b/assets/icons/blockquote-dark.svg
new file mode 100644
index 00000000..a9cebe94
--- /dev/null
+++ b/assets/icons/blockquote-dark.svg
@@ -0,0 +1,9 @@
+
\ No newline at end of file
diff --git a/assets/icons/blockquote-light.svg b/assets/icons/blockquote-light.svg
new file mode 100644
index 00000000..eb10a05b
--- /dev/null
+++ b/assets/icons/blockquote-light.svg
@@ -0,0 +1,9 @@
+
\ No newline at end of file
diff --git a/assets/icons/bold-dark.svg b/assets/icons/bold-dark.svg
new file mode 100644
index 00000000..6ba1d39f
--- /dev/null
+++ b/assets/icons/bold-dark.svg
@@ -0,0 +1,5 @@
+
\ No newline at end of file
diff --git a/assets/icons/bold-light.svg b/assets/icons/bold-light.svg
new file mode 100644
index 00000000..9c887220
--- /dev/null
+++ b/assets/icons/bold-light.svg
@@ -0,0 +1,5 @@
+
\ No newline at end of file
diff --git a/assets/icons/code-dark.svg b/assets/icons/code-dark.svg
new file mode 100644
index 00000000..a99e9aeb
--- /dev/null
+++ b/assets/icons/code-dark.svg
@@ -0,0 +1,6 @@
+
\ No newline at end of file
diff --git a/assets/icons/code-light.svg b/assets/icons/code-light.svg
new file mode 100644
index 00000000..1c0e436e
--- /dev/null
+++ b/assets/icons/code-light.svg
@@ -0,0 +1,6 @@
+
\ No newline at end of file
diff --git a/assets/icons/codeblock-dark.svg b/assets/icons/codeblock-dark.svg
new file mode 100644
index 00000000..8145c45f
--- /dev/null
+++ b/assets/icons/codeblock-dark.svg
@@ -0,0 +1,7 @@
+
\ No newline at end of file
diff --git a/assets/icons/codeblock-light.svg b/assets/icons/codeblock-light.svg
new file mode 100644
index 00000000..29714eb5
--- /dev/null
+++ b/assets/icons/codeblock-light.svg
@@ -0,0 +1,7 @@
+
\ No newline at end of file
diff --git a/assets/icons/heading-dark.svg b/assets/icons/heading-dark.svg
new file mode 100644
index 00000000..12e37896
--- /dev/null
+++ b/assets/icons/heading-dark.svg
@@ -0,0 +1,10 @@
+
\ No newline at end of file
diff --git a/assets/icons/heading-light.svg b/assets/icons/heading-light.svg
new file mode 100644
index 00000000..39010990
--- /dev/null
+++ b/assets/icons/heading-light.svg
@@ -0,0 +1,10 @@
+
\ No newline at end of file
diff --git a/assets/icons/italic-dark.svg b/assets/icons/italic-dark.svg
new file mode 100644
index 00000000..ac651c36
--- /dev/null
+++ b/assets/icons/italic-dark.svg
@@ -0,0 +1,6 @@
+
\ No newline at end of file
diff --git a/assets/icons/italic-light.svg b/assets/icons/italic-light.svg
new file mode 100644
index 00000000..427ab51d
--- /dev/null
+++ b/assets/icons/italic-light.svg
@@ -0,0 +1,6 @@
+
\ No newline at end of file
diff --git a/assets/icons/options-dark.svg b/assets/icons/options-dark.svg
new file mode 100644
index 00000000..0c0f9b9b
--- /dev/null
+++ b/assets/icons/options-dark.svg
@@ -0,0 +1,7 @@
+
\ No newline at end of file
diff --git a/assets/icons/options-light.svg b/assets/icons/options-light.svg
new file mode 100644
index 00000000..b5c10374
--- /dev/null
+++ b/assets/icons/options-light.svg
@@ -0,0 +1,7 @@
+
\ No newline at end of file
diff --git a/assets/icons/ordered-list-dark.svg b/assets/icons/ordered-list-dark.svg
new file mode 100644
index 00000000..1d351b8e
--- /dev/null
+++ b/assets/icons/ordered-list-dark.svg
@@ -0,0 +1,8 @@
+
\ No newline at end of file
diff --git a/assets/icons/ordered-list-light.svg b/assets/icons/ordered-list-light.svg
new file mode 100644
index 00000000..b238e15b
--- /dev/null
+++ b/assets/icons/ordered-list-light.svg
@@ -0,0 +1,8 @@
+
\ No newline at end of file
diff --git a/assets/icons/strikethrough-dark.svg b/assets/icons/strikethrough-dark.svg
new file mode 100644
index 00000000..a8a8a038
--- /dev/null
+++ b/assets/icons/strikethrough-dark.svg
@@ -0,0 +1,5 @@
+
\ No newline at end of file
diff --git a/assets/icons/strikethrough-light.svg b/assets/icons/strikethrough-light.svg
new file mode 100644
index 00000000..bd67607c
--- /dev/null
+++ b/assets/icons/strikethrough-light.svg
@@ -0,0 +1,5 @@
+
\ No newline at end of file
diff --git a/assets/icons/unordered-list-dark.svg b/assets/icons/unordered-list-dark.svg
new file mode 100644
index 00000000..9a66e6c9
--- /dev/null
+++ b/assets/icons/unordered-list-dark.svg
@@ -0,0 +1,9 @@
+
\ No newline at end of file
diff --git a/assets/icons/unordered-list-light.svg b/assets/icons/unordered-list-light.svg
new file mode 100644
index 00000000..29de1d80
--- /dev/null
+++ b/assets/icons/unordered-list-light.svg
@@ -0,0 +1,9 @@
+
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 0037f791..0c71e3db 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "vscode-front-matter-beta",
- "version": "5.6.0",
+ "version": "5.7.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 8e3831e4..faba76cf 100644
--- a/package.json
+++ b/package.json
@@ -3,7 +3,7 @@
"displayName": "Front Matter",
"description": "An essential Visual Studio Code extension when you want to manage the markdown pages of your static site like: Hugo, Jekyll, Hexo, NextJs, Gatsby, and many more...",
"icon": "assets/frontmatter-teal-128x128.png",
- "version": "5.6.0",
+ "version": "5.7.0",
"preview": false,
"publisher": "eliostruyf",
"galleryBanner": {
@@ -240,6 +240,12 @@
},
"scope": "Content"
},
+ "frontMatter.content.wysiwyg": {
+ "type": "boolean",
+ "default": true,
+ "markdownDescription": "Specifies if you want to enable/disable the What You See, Is What You Get (WYSIWYG) markdown controls. [Check in the docs](https://frontmatter.codes/docs/settings#frontMatter.content.wysiwyg)",
+ "scope": "Content"
+ },
"frontMatter.custom.scripts": {
"type": "array",
"default": [],
@@ -819,15 +825,170 @@
"command": "frontMatter.setLastModifiedDate",
"title": "Set lastmod date",
"category": "Front matter"
+ },
+ {
+ "command": "frontMatter.markup.bold",
+ "title": "Bold",
+ "category": "Front matter",
+ "icon": {
+ "light": "assets/icons/bold-light.svg",
+ "dark": "assets/icons/bold-dark.svg"
+ }
+ },
+ {
+ "command": "frontMatter.markup.italic",
+ "title": "Italic",
+ "category": "Front matter",
+ "icon": {
+ "light": "assets/icons/italic-light.svg",
+ "dark": "assets/icons/italic-dark.svg"
+ }
+ },
+ {
+ "command": "frontMatter.markup.strikethrough",
+ "title": "Strikethrough",
+ "category": "Front matter",
+ "icon": {
+ "light": "assets/icons/strikethrough-light.svg",
+ "dark": "assets/icons/strikethrough-dark.svg"
+ }
+ },
+ {
+ "command": "frontMatter.markup.code",
+ "title": "Code",
+ "category": "Front matter",
+ "icon": {
+ "light": "assets/icons/code-light.svg",
+ "dark": "assets/icons/code-dark.svg"
+ }
+ },
+ {
+ "command": "frontMatter.markup.codeblock",
+ "title": "Codeblock",
+ "category": "Front matter",
+ "icon": {
+ "light": "assets/icons/codeblock-light.svg",
+ "dark": "assets/icons/codeblock-dark.svg"
+ }
+ },
+ {
+ "command": "frontMatter.markup.blockquote",
+ "title": "Codeblock",
+ "category": "Front matter",
+ "icon": {
+ "light": "assets/icons/blockquote-light.svg",
+ "dark": "assets/icons/blockquote-dark.svg"
+ }
+ },
+ {
+ "command": "frontMatter.markup.heading",
+ "title": "Heading",
+ "category": "Front matter",
+ "icon": {
+ "light": "assets/icons/heading-light.svg",
+ "dark": "assets/icons/heading-dark.svg"
+ }
+ },
+ {
+ "command": "frontMatter.markup.unorderedlist",
+ "title": "Unordered list",
+ "category": "Front matter",
+ "icon": {
+ "light": "assets/icons/unordered-list-light.svg",
+ "dark": "assets/icons/unordered-list-dark.svg"
+ }
+ },
+ {
+ "command": "frontMatter.markup.orderedlist",
+ "title": "Ordered list",
+ "category": "Front matter",
+ "icon": {
+ "light": "assets/icons/ordered-list-light.svg",
+ "dark": "assets/icons/ordered-list-dark.svg"
+ }
+ },
+ {
+ "command": "frontMatter.markup.tasklist",
+ "title": "Task list",
+ "category": "Front matter"
+ },
+ {
+ "command": "frontMatter.markup.options",
+ "title": "Other markup options",
+ "category": "Front matter",
+ "icon": {
+ "light": "assets/icons/options-light.svg",
+ "dark": "assets/icons/options-dark.svg"
+ }
+ },
+ {
+ "command": "frontMatter.diagnostics",
+ "title": "Diagnostic logging",
+ "category": "Front matter"
}
],
"menus": {
"editor/title": [
+ {
+ "command": "frontMatter.markup.heading",
+ "group": "navigation@-132",
+ "when": "resourceLangId == markdown && frontMatter:markdown:wysiwyg"
+ },
+ {
+ "command": "frontMatter.markup.bold",
+ "group": "navigation@-131",
+ "when": "resourceLangId == markdown && frontMatter:markdown:wysiwyg"
+ },
+ {
+ "command": "frontMatter.markup.italic",
+ "group": "navigation@-130",
+ "when": "resourceLangId == markdown && frontMatter:markdown:wysiwyg"
+ },
+ {
+ "command": "frontMatter.markup.strikethrough",
+ "group": "navigation@-129",
+ "when": "resourceLangId == markdown && frontMatter:markdown:wysiwyg"
+ },
+ {
+ "command": "frontMatter.markup.blockquote",
+ "group": "navigation@-128",
+ "when": "resourceLangId == markdown && frontMatter:markdown:wysiwyg"
+ },
{
"command": "frontMatter.insertImage",
- "group": "navigation@-99",
+ "group": "navigation@-127",
"when": "resourceLangId == markdown"
},
+ {
+ "command": "frontMatter.markup.options",
+ "group": "navigation@-126",
+ "when": "resourceLangId == markdown && frontMatter:markdown:wysiwyg"
+ },
+ {
+ "command": "frontMatter.markup.orderedlist",
+ "group": "1_markup@1",
+ "when": "resourceLangId == markdown && frontMatter:markdown:wysiwyg"
+ },
+ {
+ "command": "frontMatter.markup.unorderedlist",
+ "group": "1_markup@2",
+ "when": "resourceLangId == markdown && frontMatter:markdown:wysiwyg"
+ },
+ {
+ "command": "frontMatter.markup.tasklist",
+ "group": "1_markup@3",
+ "when": "resourceLangId == markdown && frontMatter:markdown:wysiwyg"
+ },
+ {
+ "command": "frontMatter.markup.code",
+ "group": "1_markup@4",
+ "when": "resourceLangId == markdown && frontMatter:markdown:wysiwyg"
+ },
+ {
+ "command": "frontMatter.markup.codeblock",
+ "group": "1_markup@5",
+ "when": "resourceLangId == markdown && frontMatter:markdown:wysiwyg"
+ },
{
"command": "frontMatter.dashboard",
"group": "navigation@-98",
@@ -888,6 +1049,50 @@
{
"command": "frontMatter.dashboard.close",
"when": "false"
+ },
+ {
+ "command": "frontMatter.markup.bold",
+ "when": "false"
+ },
+ {
+ "command": "frontMatter.markup.italic",
+ "when": "false"
+ },
+ {
+ "command": "frontMatter.markup.strikethrough",
+ "when": "false"
+ },
+ {
+ "command": "frontMatter.markup.code",
+ "when": "false"
+ },
+ {
+ "command": "frontMatter.markup.codeblock",
+ "when": "false"
+ },
+ {
+ "command": "frontMatter.markup.blockquote",
+ "when": "false"
+ },
+ {
+ "command": "frontMatter.markup.heading",
+ "when": "false"
+ },
+ {
+ "command": "frontMatter.markup.unorderedlist",
+ "when": "false"
+ },
+ {
+ "command": "frontMatter.markup.orderedlist",
+ "when": "false"
+ },
+ {
+ "command": "frontMatter.markup.tasklist",
+ "when": "false"
+ },
+ {
+ "command": "frontMatter.markup.options",
+ "when": "false"
}
],
"view/title": [
@@ -968,4 +1173,4 @@
"webpack-cli": "3.3.12"
},
"dependencies": {}
-}
\ No newline at end of file
+}
diff --git a/src/commands/Article.ts b/src/commands/Article.ts
index b169b87d..86ce503c 100644
--- a/src/commands/Article.ts
+++ b/src/commands/Article.ts
@@ -203,7 +203,7 @@ export class Article {
const file = parseWinPath(editor.document.fileName);
- if (!file.endsWith(`.md`) && !file.endsWith(`.mdx`)) {
+ if (!file.endsWith(`.md`) && !file.endsWith(`.markdown`) && !file.endsWith(`.mdx`)) {
return;
}
diff --git a/src/commands/Dashboard.ts b/src/commands/Dashboard.ts
index a765d3d7..ffeacf11 100644
--- a/src/commands/Dashboard.ts
+++ b/src/commands/Dashboard.ts
@@ -434,7 +434,7 @@ export class Dashboard {
if (crntSort?.type === SortType.string) {
allMedia = allMedia.sort(Sorting.alphabetically("fsPath"));
} else if (crntSort?.type === SortType.date) {
- allMedia = allMedia.sort(Sorting.date("mtime"));
+ allMedia = allMedia.sort(Sorting.dateWithFallback("mtime", "fsPath"));
} else {
allMedia = allMedia.sort(Sorting.alphabetically("fsPath"));
}
@@ -548,7 +548,7 @@ export class Dashboard {
if (folderInfo) {
for (const folder of folderInfo) {
for (const file of folder.lastModified) {
- if (file.fileName.endsWith(`.md`) || file.fileName.endsWith(`.mdx`)) {
+ if (file.fileName.endsWith(`.md`) || file.fileName.endsWith(`.markdown`) || file.fileName.endsWith(`.mdx`)) {
try {
const article = ArticleHelper.getFrontMatterByPath(file.filePath);
diff --git a/src/commands/Diagnostics.ts b/src/commands/Diagnostics.ts
new file mode 100644
index 00000000..69093109
--- /dev/null
+++ b/src/commands/Diagnostics.ts
@@ -0,0 +1,63 @@
+import { Folders } from "./Folders";
+import { ViewColumn, workspace } from "vscode";
+import ContentProvider from "../providers/ContentProvider";
+import { join } from "path";
+import { ContentFolder } from "../models";
+
+
+export class Diagnostics {
+
+ public static async show() {
+ const folders = Folders.get();
+ const projectName = Folders.getProjectFolderName();
+ const wsFolder = Folders.getWorkspaceFolder();
+
+ const folderData = [];
+ for (const folder of folders) {
+ folderData.push(await Diagnostics.processFolder(folder, projectName));
+ }
+
+ const all = await Diagnostics.allProjectFiles();
+
+ const logging = `# Project name
+
+${projectName}
+
+# Folders
+
+${folders.map(f => `- ${f.title}: "${f.path}"`).join("\n")}
+
+# Workspace folder
+
+${wsFolder ? wsFolder.fsPath : "No workspace folder"}
+
+# Total files
+
+${all}
+
+# Folders to search files
+
+${folderData.join("\n")}
+ `;
+
+ ContentProvider.show(logging, `${projectName} diagnostics`, "markdown", ViewColumn.One);
+ }
+
+ private static async allProjectFiles() {
+ const allFiles = await workspace.findFiles(`**/*.*`);
+ return `Total files found: ${allFiles.length}`;
+ }
+
+ private static async processFolder(folder: ContentFolder, projectName: string) {
+ let projectStart = folder.path.split(projectName).pop();
+ projectStart = projectStart || "";
+ projectStart = projectStart?.replace(/\\/g, '/');
+ projectStart = projectStart?.startsWith('/') ? projectStart.substr(1) : projectStart;
+
+ const mdFiles = await workspace.findFiles(join(projectStart, folder.excludeSubdir ? '/' : '**/', '*.md'));
+ const mdxFiles = await workspace.findFiles(join(projectStart, folder.excludeSubdir ? '/' : '**/', '*.mdx'));
+ const markdownFiles = await workspace.findFiles(join(projectStart, folder.excludeSubdir ? '/' : '**/', '*.markdown'));
+
+ return `- Project start length: ${projectStart.length} | Search in: "${join(projectStart, folder.excludeSubdir ? '/' : '**/', '*.*')}" | mdFiles: ${mdFiles.length} | mdxFiles: ${mdxFiles.length} | markdownFiles: ${markdownFiles.length}`;
+ }
+}
\ No newline at end of file
diff --git a/src/commands/Folders.ts b/src/commands/Folders.ts
index 19653ab2..1b0c45ce 100644
--- a/src/commands/Folders.ts
+++ b/src/commands/Folders.ts
@@ -6,7 +6,7 @@ import { ContentFolder, FileInfo, FolderInfo } from "../models";
import uniqBy = require("lodash.uniqby");
import { Template } from "./Template";
import { Notifications } from "../helpers/Notifications";
-import { FilesHelper, Settings } from "../helpers";
+import { Settings } from "../helpers";
import { existsSync, mkdirSync } from 'fs';
import { format } from 'date-fns';
import { Dashboard } from './Dashboard';
@@ -207,12 +207,14 @@ export class Folders {
try {
const projectName = Folders.getProjectFolderName();
let projectStart = folder.path.split(projectName).pop();
+
if (projectStart) {
projectStart = projectStart.replace(/\\/g, '/');
projectStart = projectStart.startsWith('/') ? projectStart.substr(1) : projectStart;
const mdFiles = await workspace.findFiles(join(projectStart, folder.excludeSubdir ? '/' : '**/', '*.md'));
+ const markdownFiles = await workspace.findFiles(join(projectStart, folder.excludeSubdir ? '/' : '**/', '*.markdown'));
const mdxFiles = await workspace.findFiles(join(projectStart, folder.excludeSubdir ? '/' : '**/', '*.mdx'));
- let files = [...mdFiles, ...mdxFiles];
+ let files = [...mdFiles, ...markdownFiles, ...mdxFiles];
if (files) {
let fileStats: FileInfo[] = [];
diff --git a/src/commands/Wysiwyg.ts b/src/commands/Wysiwyg.ts
new file mode 100644
index 00000000..66367c37
--- /dev/null
+++ b/src/commands/Wysiwyg.ts
@@ -0,0 +1,230 @@
+import { commands, window, Selection, QuickPickItem } from "vscode";
+import { COMMAND_NAME, CONTEXT, SETTINGS_CONTENT_WYSIWYG } from "../constants";
+import { Settings } from "../helpers";
+
+enum MarkupType {
+ bold = 1,
+ italic,
+ strikethrough,
+ code,
+ codeblock,
+ blockquote,
+ heading,
+ unorderedList,
+ orderedList,
+ taskList
+}
+
+export class Wysiwyg {
+
+ /**
+ * Registers the markup commands for the WYSIWYG controls
+ * @param subscriptions
+ * @returns
+ */
+ public static async registerCommands(subscriptions: any) {
+
+ const wysiwygEnabled = Settings.get(SETTINGS_CONTENT_WYSIWYG);
+
+ if (!wysiwygEnabled) {
+ return;
+ }
+
+ await commands.executeCommand('setContext', CONTEXT.wysiwyg, true);
+
+ // Surrounding markup
+ subscriptions.push(commands.registerCommand(COMMAND_NAME.bold, () => this.addMarkup(MarkupType.bold)));
+ subscriptions.push(commands.registerCommand(COMMAND_NAME.italic, () => this.addMarkup(MarkupType.italic)));
+ subscriptions.push(commands.registerCommand(COMMAND_NAME.strikethrough, () => this.addMarkup(MarkupType.strikethrough)));
+ subscriptions.push(commands.registerCommand(COMMAND_NAME.code, () => this.addMarkup(MarkupType.code)));
+ subscriptions.push(commands.registerCommand(COMMAND_NAME.codeblock, () => this.addMarkup(MarkupType.codeblock)));
+
+ // Prefix markup
+ subscriptions.push(commands.registerCommand(COMMAND_NAME.heading, () => this.addMarkup(MarkupType.heading)));
+ subscriptions.push(commands.registerCommand(COMMAND_NAME.blockquote, () => this.addMarkup(MarkupType.blockquote)));
+ subscriptions.push(commands.registerCommand(COMMAND_NAME.unorderedlist, () => this.addMarkup(MarkupType.unorderedList)));
+ subscriptions.push(commands.registerCommand(COMMAND_NAME.orderedlist, () => this.addMarkup(MarkupType.orderedList)));
+ subscriptions.push(commands.registerCommand(COMMAND_NAME.taskList, () => this.addMarkup(MarkupType.taskList)));
+
+ // Options
+ subscriptions.push(commands.registerCommand(COMMAND_NAME.options, async () => {
+ const qpItems: QuickPickItem[] = [
+ { label: "$(list-unordered) Unordered list", detail: "Add an unordered list", alwaysShow: true, },
+ { label: "$(list-ordered) Ordered list", detail: "Add an ordered list", alwaysShow: true },
+ { label: "$(tasklist) Task list", detail: "Add a task list", alwaysShow: true },
+ { label: "$(code) Code", detail: "Add inline code snippet", alwaysShow: true },
+ { label: "$(symbol-namespace) Code block", detail: "Add a code block", alwaysShow: true },
+ ]
+
+ const option = await window.showQuickPick([ ...qpItems ], {
+ placeHolder: "Which type of markup would you like to insert?",
+ canPickMany: false,
+ ignoreFocusOut: false,
+ });
+
+ if (option) {
+ if (option.label === qpItems[0].label) {
+ await this.addMarkup(MarkupType.unorderedList);
+ } else if (option.label === qpItems[1].label) {
+ await this.addMarkup(MarkupType.orderedList);
+ } else if (option.label === qpItems[2].label) {
+ await this.addMarkup(MarkupType.taskList);
+ } else if (option.label === qpItems[3].label) {
+ await this.addMarkup(MarkupType.code);
+ } else if (option.label === qpItems[4].label) {
+ await this.addMarkup(MarkupType.codeblock);
+ }
+ }
+ }));
+ }
+
+ /**
+ * Add the markup to the content
+ * @param type
+ * @returns
+ */
+ private static async addMarkup(type: MarkupType) {
+ const editor = window.activeTextEditor;
+ if (!editor) {
+ return;
+ }
+
+ const selection = editor.selection;
+ const hasTextSelection = !selection.isEmpty;
+
+ const markers = this.getMarkers(type);
+ if (!markers) {
+ return;
+ }
+
+ const crntSelection = selection.active;
+
+ if (hasTextSelection) {
+ // Replace the selection and surround with the markup
+ const selectionText = editor.document.getText(selection);
+ const txt = await this.insertText(markers, type, selectionText);
+
+ editor.edit(builder => {
+ builder.replace(selection, txt);
+ });
+ } else {
+ const txt = await this.insertText(markers, type);
+
+ // Insert the markers where cursor is located.
+ const markerLength = this.isMarkupWrapping(type) ? txt.length + 1 : markers.length;
+ let newPosition = crntSelection.with(crntSelection.line, crntSelection.character + markerLength);
+
+ await editor.edit(builder => {
+ builder.insert(newPosition, txt);
+ });
+
+ if (type === MarkupType.codeblock) {
+ newPosition = crntSelection.with(crntSelection.line + 1, 0);
+ }
+
+ editor.selection = new Selection(newPosition, newPosition);
+ }
+ }
+
+ /**
+ * Check if the text will be wrapped
+ * @param type
+ * @returns
+ */
+ private static isMarkupWrapping(type: MarkupType) {
+ return (
+ type === MarkupType.blockquote ||
+ type === MarkupType.heading ||
+ type === MarkupType.unorderedList ||
+ type === MarkupType.orderedList ||
+ type === MarkupType.taskList
+ );
+ }
+
+ /**
+ * Insert text at the current cursor position
+ */
+ private static async insertText(marker: string | undefined, type: MarkupType, text: string | null = null) {
+ const crntText = text || this.lineBreak(type);
+
+ if (this.isMarkupWrapping(type)) {
+ if (type === MarkupType.heading) {
+ const headingLvl = await window.showQuickPick([
+ "Heading 1",
+ "Heading 2",
+ "Heading 3",
+ "Heading 4",
+ "Heading 5",
+ "Heading 6"
+ ], {
+ canPickMany: false,
+ placeHolder: "Which heading level do you want to insert?",
+ ignoreFocusOut: false
+ });
+
+ if (headingLvl) {
+ const headingNr = parseInt(headingLvl.replace("Heading ", ""));
+ return `${Array(headingNr + 1).join(marker)} ${crntText}`;
+ }
+ }
+
+ if (type === MarkupType.unorderedList || type === MarkupType.taskList) {
+ const lines = crntText.split("\n").map(line => `${marker} ${line}`);
+ return lines.join("\n");
+ }
+
+ if (type === MarkupType.orderedList) {
+ const lines = crntText.split("\n").map((line, idx) => `${idx+1}. ${line}`);
+ return lines.join("\n");
+ }
+
+ return `${marker} ${crntText}`;
+ } else {
+ return `${marker}${crntText}${marker}`;
+ }
+ }
+
+ /**
+ * Check if linebreak needs to be added
+ * @param type
+ * @returns
+ */
+ private static lineBreak(type: MarkupType) {
+ if (type === MarkupType.codeblock) {
+ return `\n\n`;
+ }
+ return "";
+ }
+
+ /**
+ * Retrieve the type of markers
+ * @param type
+ * @returns
+ */
+ private static getMarkers(type: MarkupType) {
+ switch(type) {
+ case MarkupType.bold:
+ return `**`;
+ case MarkupType.italic:
+ return `*`;
+ case MarkupType.strikethrough:
+ return `~~`;
+ case MarkupType.code:
+ return "`";
+ case MarkupType.codeblock:
+ return "```";
+ case MarkupType.blockquote:
+ return ">";
+ case MarkupType.heading:
+ return "#";
+ case MarkupType.unorderedList:
+ return "-";
+ case MarkupType.orderedList:
+ return "1.";
+ case MarkupType.taskList:
+ return "- [ ]";
+ default:
+ return;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/constants/Extension.ts b/src/constants/Extension.ts
index 49ce954d..001311fa 100644
--- a/src/constants/Extension.ts
+++ b/src/constants/Extension.ts
@@ -32,4 +32,18 @@ export const COMMAND_NAME = {
promote: getCommandName("promoteSettings"),
insertImage: getCommandName("insertImage"),
createFolder: getCommandName("createFolder"),
+ diagnostics: getCommandName("diagnostics"),
+
+ // WYSIWYG
+ bold: getCommandName("markup.bold"),
+ italic: getCommandName("markup.italic"),
+ strikethrough: getCommandName("markup.strikethrough"),
+ code: getCommandName("markup.code"),
+ codeblock: getCommandName("markup.codeblock"),
+ heading: getCommandName("markup.heading"),
+ blockquote: getCommandName("markup.blockquote"),
+ unorderedlist: getCommandName("markup.unorderedlist"),
+ orderedlist: getCommandName("markup.orderedlist"),
+ taskList: getCommandName("markup.tasklist"),
+ options: getCommandName("markup.options"),
};
\ No newline at end of file
diff --git a/src/constants/context.ts b/src/constants/context.ts
index a8754720..376640ad 100644
--- a/src/constants/context.ts
+++ b/src/constants/context.ts
@@ -4,4 +4,5 @@ export const CONTEXT = {
canOpenDashboard: "frontMatterCanOpenDashboard",
isEnabled: "frontMatter:enabled",
isDashboardOpen: "frontMatter:dashboard:open",
+ wysiwyg: "frontMatter:markdown:wysiwyg",
};
\ No newline at end of file
diff --git a/src/constants/settings.ts b/src/constants/settings.ts
index 06eb3bb0..528f4d11 100644
--- a/src/constants/settings.ts
+++ b/src/constants/settings.ts
@@ -43,6 +43,7 @@ export const SETTINGS_CONTENT_STATIC_FOLDER = "content.publicFolder";
export const SETTINGS_CONTENT_FRONTMATTER_HIGHLIGHT = "content.fmHighlight";
export const SETTINGS_CONTENT_DRAFT_FIELD = "content.draftField";
export const SETTINGS_CONTENT_SORTING = "content.sorting";
+export const SETTINGS_CONTENT_WYSIWYG = "content.wysiwyg";
export const SETTINGS_CONTENT_SORTING_DEFAULT = "content.defaultSorting";
export const SETTINGS_MEDIA_SORTING_DEFAULT = "content.defaultSorting";
diff --git a/src/dashboardWebView/components/Media/Item.tsx b/src/dashboardWebView/components/Media/Item.tsx
index 8a30926b..e091ba47 100644
--- a/src/dashboardWebView/components/Media/Item.tsx
+++ b/src/dashboardWebView/components/Media/Item.tsx
@@ -15,7 +15,7 @@ import { MenuItem, MenuItems } from '../Menu';
import { Alert } from '../Modals/Alert';
import { Metadata } from '../Modals/Metadata';
import { MenuButton } from './MenuButton'
-
+
export interface IItemProps {
media: MediaInfo;
}
@@ -252,7 +252,7 @@ export const Item: React.FunctionComponent
+
{basename(parseWinPath(media.fsPath) || "")}