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/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/package.json b/package.json index 77f174bf..d3320eb5 100644 --- a/package.json +++ b/package.json @@ -871,6 +871,24 @@ "dark": "assets/icons/codeblock-dark.svg" } }, + { + "command": "frontMatter.content.blockquote", + "title": "Codeblock", + "category": "Front matter", + "icon": { + "light": "assets/icons/blockquote-light.svg", + "dark": "assets/icons/blockquote-dark.svg" + } + }, + { + "command": "frontMatter.content.heading", + "title": "Codeblock", + "category": "Front matter", + "icon": { + "light": "assets/icons/heading-light.svg", + "dark": "assets/icons/heading-dark.svg" + } + }, { "command": "frontMatter.diagnostics", "title": "Diagnostic logging", @@ -884,18 +902,28 @@ "group": "navigation@-99", "when": "resourceLangId == markdown" }, + { + "command": "frontMatter.content.heading", + "group": "navigation@-132", + "when": "resourceLangId == markdown && frontMatter:markdown:wysiwyg" + }, { "command": "frontMatter.content.bold", - "group": "navigation@-130", + "group": "navigation@-131", "when": "resourceLangId == markdown && frontMatter:markdown:wysiwyg" }, { "command": "frontMatter.content.italic", - "group": "navigation@-129", + "group": "navigation@-130", "when": "resourceLangId == markdown && frontMatter:markdown:wysiwyg" }, { "command": "frontMatter.content.strikethrough", + "group": "navigation@-129", + "when": "resourceLangId == markdown && frontMatter:markdown:wysiwyg" + }, + { + "command": "frontMatter.content.blockquote", "group": "navigation@-128", "when": "resourceLangId == markdown && frontMatter:markdown:wysiwyg" }, diff --git a/src/commands/Wysiwyg.ts b/src/commands/Wysiwyg.ts index 1e8e8dd9..60075599 100644 --- a/src/commands/Wysiwyg.ts +++ b/src/commands/Wysiwyg.ts @@ -7,7 +7,9 @@ enum MarkupType { italic, strikethrough, code, - codeblock + codeblock, + blockquote, + heading } export class Wysiwyg { @@ -32,6 +34,8 @@ export class Wysiwyg { 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))); + subscriptions.push(commands.registerCommand(COMMAND_NAME.heading, () => this.addMarkup(MarkupType.heading))); + subscriptions.push(commands.registerCommand(COMMAND_NAME.blockquote, () => this.addMarkup(MarkupType.blockquote))); } /** @@ -58,16 +62,20 @@ export class Wysiwyg { 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, markers + selectionText + markers); + builder.replace(selection, txt); }); } else { + const txt = await this.insertText(markers, type); + // Insert the markers where cursor is located. - let newPosition = crntSelection.with(crntSelection.line, crntSelection.character + markers.length); + 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, markers + this.lineBreak(type) + markers) + builder.insert(newPosition, txt); }); if (type === MarkupType.codeblock) { @@ -78,6 +86,44 @@ export class Wysiwyg { } } + /** + * Check if the text will be wrapped + * @param type + * @returns + */ + private static isMarkupWrapping(type: MarkupType) { + return type === MarkupType.blockquote || type === MarkupType.heading; + } + + /** + * 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}`; + } + } + + return `${marker} ${crntText}`; + } else { + return `${marker}${crntText}${marker}`; + } + } + /** * Check if linebreak needs to be added * @param type @@ -107,6 +153,10 @@ export class Wysiwyg { return "`"; case MarkupType.codeblock: return "```"; + case MarkupType.blockquote: + return ">"; + case MarkupType.heading: + return "#"; default: return; } diff --git a/src/constants/Extension.ts b/src/constants/Extension.ts index 2cc73c55..7ea9f118 100644 --- a/src/constants/Extension.ts +++ b/src/constants/Extension.ts @@ -40,4 +40,6 @@ export const COMMAND_NAME = { strikethrough: getCommandName("content.strikethrough"), code: getCommandName("content.code"), codeblock: getCommandName("content.codeblock"), + heading: getCommandName("content.heading"), + blockquote: getCommandName("content.blockquote"), }; \ No newline at end of file