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/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.json b/package.json index d3320eb5..aee4d80d 100644 --- a/package.json +++ b/package.json @@ -827,7 +827,7 @@ "category": "Front matter" }, { - "command": "frontMatter.content.bold", + "command": "frontMatter.markup.bold", "title": "Bold", "category": "Front matter", "icon": { @@ -836,7 +836,7 @@ } }, { - "command": "frontMatter.content.italic", + "command": "frontMatter.markup.italic", "title": "Italic", "category": "Front matter", "icon": { @@ -845,7 +845,7 @@ } }, { - "command": "frontMatter.content.strikethrough", + "command": "frontMatter.markup.strikethrough", "title": "Strikethrough", "category": "Front matter", "icon": { @@ -854,7 +854,7 @@ } }, { - "command": "frontMatter.content.code", + "command": "frontMatter.markup.code", "title": "Code", "category": "Front matter", "icon": { @@ -863,7 +863,7 @@ } }, { - "command": "frontMatter.content.codeblock", + "command": "frontMatter.markup.codeblock", "title": "Codeblock", "category": "Front matter", "icon": { @@ -872,7 +872,7 @@ } }, { - "command": "frontMatter.content.blockquote", + "command": "frontMatter.markup.blockquote", "title": "Codeblock", "category": "Front matter", "icon": { @@ -881,7 +881,7 @@ } }, { - "command": "frontMatter.content.heading", + "command": "frontMatter.markup.heading", "title": "Codeblock", "category": "Front matter", "icon": { @@ -889,6 +889,33 @@ "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.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", @@ -898,42 +925,37 @@ "menus": { "editor/title": [ { - "command": "frontMatter.insertImage", - "group": "navigation@-99", - "when": "resourceLangId == markdown" - }, - { - "command": "frontMatter.content.heading", + "command": "frontMatter.markup.heading", "group": "navigation@-132", "when": "resourceLangId == markdown && frontMatter:markdown:wysiwyg" }, { - "command": "frontMatter.content.bold", + "command": "frontMatter.markup.bold", "group": "navigation@-131", "when": "resourceLangId == markdown && frontMatter:markdown:wysiwyg" }, { - "command": "frontMatter.content.italic", + "command": "frontMatter.markup.italic", "group": "navigation@-130", "when": "resourceLangId == markdown && frontMatter:markdown:wysiwyg" }, { - "command": "frontMatter.content.strikethrough", + "command": "frontMatter.markup.strikethrough", "group": "navigation@-129", "when": "resourceLangId == markdown && frontMatter:markdown:wysiwyg" }, { - "command": "frontMatter.content.blockquote", + "command": "frontMatter.markup.blockquote", "group": "navigation@-128", "when": "resourceLangId == markdown && frontMatter:markdown:wysiwyg" }, { - "command": "frontMatter.content.code", + "command": "frontMatter.insertImage", "group": "navigation@-127", - "when": "resourceLangId == markdown && frontMatter:markdown:wysiwyg" + "when": "resourceLangId == markdown" }, { - "command": "frontMatter.content.codeblock", + "command": "frontMatter.markup.options", "group": "navigation@-126", "when": "resourceLangId == markdown && frontMatter:markdown:wysiwyg" }, @@ -999,11 +1021,43 @@ "when": "false" }, { - "command": "frontMatter.content.bold", + "command": "frontMatter.markup.bold", "when": "false" }, { - "command": "frontMatter.content.italic", + "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.options", "when": "false" } ], diff --git a/src/commands/Wysiwyg.ts b/src/commands/Wysiwyg.ts index 60075599..8391b927 100644 --- a/src/commands/Wysiwyg.ts +++ b/src/commands/Wysiwyg.ts @@ -1,4 +1,4 @@ -import { commands, window, Selection } from "vscode"; +import { commands, window, Selection, QuickPickItem } from "vscode"; import { COMMAND_NAME, CONTEXT, SETTINGS_CONTENT_WYSIWYG } from "../constants"; import { Settings } from "../helpers"; @@ -9,7 +9,10 @@ enum MarkupType { code, codeblock, blockquote, - heading + heading, + unorderedList, + orderedList, + taskList } export class Wysiwyg { @@ -29,13 +32,49 @@ export class Wysiwyg { 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.blockquote))); + subscriptions.push(commands.registerCommand(COMMAND_NAME.orderedlist, () => this.addMarkup(MarkupType.blockquote))); + + // 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); + } + } + })); } /** @@ -92,7 +131,13 @@ export class Wysiwyg { * @returns */ private static isMarkupWrapping(type: MarkupType) { - return type === MarkupType.blockquote || type === MarkupType.heading; + return ( + type === MarkupType.blockquote || + type === MarkupType.heading || + type === MarkupType.unorderedList || + type === MarkupType.orderedList || + type === MarkupType.taskList + ); } /** @@ -110,7 +155,11 @@ export class Wysiwyg { "Heading 4", "Heading 5", "Heading 6" - ], { canPickMany: false, placeHolder: "Which heading level do you want to insert?", ignoreFocusOut: false }); + ], { + canPickMany: false, + placeHolder: "Which heading level do you want to insert?", + ignoreFocusOut: false + }); if (headingLvl) { const headingNr = parseInt(headingLvl.replace("Heading ", "")); @@ -118,6 +167,16 @@ export class Wysiwyg { } } + 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}`; @@ -157,6 +216,12 @@ export class Wysiwyg { return ">"; case MarkupType.heading: return "#"; + case MarkupType.unorderedList: + return "-"; + case MarkupType.orderedList: + return "1."; + case MarkupType.taskList: + return "- [ ]"; default: return; } diff --git a/src/constants/Extension.ts b/src/constants/Extension.ts index 7ea9f118..bb179c9d 100644 --- a/src/constants/Extension.ts +++ b/src/constants/Extension.ts @@ -35,11 +35,14 @@ export const COMMAND_NAME = { diagnostics: getCommandName("diagnostics"), // WYSIWYG - bold: getCommandName("content.bold"), - italic: getCommandName("content.italic"), - strikethrough: getCommandName("content.strikethrough"), - code: getCommandName("content.code"), - codeblock: getCommandName("content.codeblock"), - heading: getCommandName("content.heading"), - blockquote: getCommandName("content.blockquote"), + 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"), + options: getCommandName("markup.options"), }; \ No newline at end of file