diff --git a/CHANGELOG.md b/CHANGELOG.md
index b7a38790..38ade742 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,16 @@
# Change Log
+## [5.7.0] - 2021-12-xx
+
+### 🎨 Enhancements
+
+- [#188](https://github.com/estruyf/vscode-front-matter/issues/188): Support for `.markdown` files added to the dashboard
+- [#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
+
## [5.6.0] - 2021-11-23
### 🎨 Enhancements
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/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/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/package.json b/package.json
index 8e3831e4..24ad340b 100644
--- a/package.json
+++ b/package.json
@@ -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,6 +825,51 @@
"command": "frontMatter.setLastModifiedDate",
"title": "Set lastmod date",
"category": "Front matter"
+ },
+ {
+ "command": "frontMatter.content.bold",
+ "title": "Bold",
+ "category": "Front matter",
+ "icon": {
+ "light": "assets/icons/bold-light.svg",
+ "dark": "assets/icons/bold-dark.svg"
+ }
+ },
+ {
+ "command": "frontMatter.content.italic",
+ "title": "Italic",
+ "category": "Front matter",
+ "icon": {
+ "light": "assets/icons/italic-light.svg",
+ "dark": "assets/icons/italic-dark.svg"
+ }
+ },
+ {
+ "command": "frontMatter.content.strikethrough",
+ "title": "Strikethrough",
+ "category": "Front matter",
+ "icon": {
+ "light": "assets/icons/strikethrough-light.svg",
+ "dark": "assets/icons/strikethrough-dark.svg"
+ }
+ },
+ {
+ "command": "frontMatter.content.code",
+ "title": "Code",
+ "category": "Front matter",
+ "icon": {
+ "light": "assets/icons/code-light.svg",
+ "dark": "assets/icons/code-dark.svg"
+ }
+ },
+ {
+ "command": "frontMatter.content.codeblock",
+ "title": "Codeblock",
+ "category": "Front matter",
+ "icon": {
+ "light": "assets/icons/codeblock-light.svg",
+ "dark": "assets/icons/codeblock-dark.svg"
+ }
}
],
"menus": {
@@ -828,6 +879,31 @@
"group": "navigation@-99",
"when": "resourceLangId == markdown"
},
+ {
+ "command": "frontMatter.content.bold",
+ "group": "navigation@-130",
+ "when": "resourceLangId == markdown && frontMatter:markdown:wysiwyg"
+ },
+ {
+ "command": "frontMatter.content.italic",
+ "group": "navigation@-129",
+ "when": "resourceLangId == markdown && frontMatter:markdown:wysiwyg"
+ },
+ {
+ "command": "frontMatter.content.strikethrough",
+ "group": "navigation@-128",
+ "when": "resourceLangId == markdown && frontMatter:markdown:wysiwyg"
+ },
+ {
+ "command": "frontMatter.content.code",
+ "group": "navigation@-127",
+ "when": "resourceLangId == markdown && frontMatter:markdown:wysiwyg"
+ },
+ {
+ "command": "frontMatter.content.codeblock",
+ "group": "navigation@-126",
+ "when": "resourceLangId == markdown && frontMatter:markdown:wysiwyg"
+ },
{
"command": "frontMatter.dashboard",
"group": "navigation@-98",
@@ -888,6 +964,14 @@
{
"command": "frontMatter.dashboard.close",
"when": "false"
+ },
+ {
+ "command": "frontMatter.content.bold",
+ "when": "false"
+ },
+ {
+ "command": "frontMatter.content.italic",
+ "when": "false"
}
],
"view/title": [
diff --git a/src/commands/Wysiwyg.ts b/src/commands/Wysiwyg.ts
new file mode 100644
index 00000000..1e8e8dd9
--- /dev/null
+++ b/src/commands/Wysiwyg.ts
@@ -0,0 +1,114 @@
+import { commands, window, Selection } from "vscode";
+import { COMMAND_NAME, CONTEXT, SETTINGS_CONTENT_WYSIWYG } from "../constants";
+import { Settings } from "../helpers";
+
+enum MarkupType {
+ bold = 1,
+ italic,
+ strikethrough,
+ code,
+ codeblock
+}
+
+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);
+
+ 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)));
+ }
+
+ /**
+ * 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);
+
+ editor.edit(builder => {
+ builder.replace(selection, markers + selectionText + markers);
+ });
+ } else {
+ // Insert the markers where cursor is located.
+ let newPosition = crntSelection.with(crntSelection.line, crntSelection.character + markers.length);
+
+ await editor.edit(builder => {
+ builder.insert(newPosition, markers + this.lineBreak(type) + markers)
+ });
+
+ if (type === MarkupType.codeblock) {
+ newPosition = crntSelection.with(crntSelection.line + 1, 0);
+ }
+
+ editor.selection = new Selection(newPosition, newPosition);
+ }
+ }
+
+ /**
+ * 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 "```";
+ default:
+ return;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/constants/Extension.ts b/src/constants/Extension.ts
index 49ce954d..72528aeb 100644
--- a/src/constants/Extension.ts
+++ b/src/constants/Extension.ts
@@ -32,4 +32,11 @@ export const COMMAND_NAME = {
promote: getCommandName("promoteSettings"),
insertImage: getCommandName("insertImage"),
createFolder: getCommandName("createFolder"),
+
+ // WYSIWYG
+ bold: getCommandName("content.bold"),
+ italic: getCommandName("content.italic"),
+ strikethrough: getCommandName("content.strikethrough"),
+ code: getCommandName("content.code"),
+ codeblock: getCommandName("content.codeblock"),
};
\ 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/extension.ts b/src/extension.ts
index 3995918a..301be612 100644
--- a/src/extension.ts
+++ b/src/extension.ts
@@ -16,6 +16,7 @@ import { DashboardData } from './models/DashboardData';
import { Settings as SettingsHelper } from './helpers';
import { Content } from './commands/Content';
import ContentProvider from './providers/ContentProvider';
+import { Wysiwyg } from './commands/Wysiwyg';
let frontMatterStatusBar: vscode.StatusBarItem;
let statusDebouncer: { (fnc: any, time: number): void; };
@@ -183,6 +184,9 @@ export async function activate(context: vscode.ExtensionContext) {
// Create the editor experience for bulk scripts
subscriptions.push(vscode.workspace.registerTextDocumentContentProvider(ContentProvider.scheme, new ContentProvider()));
+ // What you see, is what you get
+ Wysiwyg.registerCommands(subscriptions);
+
// Subscribe all commands
subscriptions.push(
insertTags,