From 3a35eeb1d5dc5d6630c28f1d9c8eabb0c8aed594 Mon Sep 17 00:00:00 2001 From: Elio Struyf Date: Tue, 3 Aug 2021 11:04:43 +0200 Subject: [PATCH 1/5] enhancement preperations --- package.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/package.json b/package.json index 1206a29e..a38130b1 100644 --- a/package.json +++ b/package.json @@ -214,6 +214,14 @@ { "command": "frontMatter.createFromTemplate", "title": "Front Matter: New article from template" + }, + { + "command": "frontMatter.registerFolder", + "title": "Front Matter: Register folder" + }, + { + "command": "frontMatter.unregisterFolder", + "title": "Front Matter: Unregister folder" } ], "menus": { From a1ee808ed593f2c548e8d1c9ae3059633cefbd07 Mon Sep 17 00:00:00 2001 From: Elio Date: Tue, 3 Aug 2021 14:16:35 +0200 Subject: [PATCH 2/5] #44 - New article creation command --- package-lock.json | 20 ++++++ package.json | 27 +++++++- src/commands/Folders.ts | 134 ++++++++++++++++++++++++++++++++++++ src/constants/settings.ts | 4 +- src/extension.ts | 30 +++++--- src/models/ContentFolder.ts | 5 ++ src/models/index.ts | 2 + 7 files changed, 210 insertions(+), 12 deletions(-) create mode 100644 src/commands/Folders.ts create mode 100644 src/models/ContentFolder.ts diff --git a/package-lock.json b/package-lock.json index 99536e12..5d56b45e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -94,6 +94,21 @@ "integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==", "dev": true }, + "@types/lodash": { + "version": "4.14.172", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.172.tgz", + "integrity": "sha512-/BHF5HAx3em7/KkzVKm3LrsD6HZAXuXO1AJZQ3cRRBZj4oHZDviWPYu0aEplAqDFNHZPW6d3G7KN+ONcCCC7pw==", + "dev": true + }, + "@types/lodash.uniqby": { + "version": "4.7.6", + "resolved": "https://registry.npmjs.org/@types/lodash.uniqby/-/lodash.uniqby-4.7.6.tgz", + "integrity": "sha512-9wBhrm1y6asW50Joj6tsySCNUgzK2tCqL7vtKIej0E9RyeBFdcte7fxUosmFuMoOU0eHqOMK76kCCrK99jxHgg==", + "dev": true, + "requires": { + "@types/lodash": "*" + } + }, "@types/mdast": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.7.tgz", @@ -2759,6 +2774,11 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, + "lodash.uniqby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz", + "integrity": "sha1-2ZwHpmnp5tJOE2Lf4mbGdhavEwI=" + }, "loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", diff --git a/package.json b/package.json index a38130b1..dff23459 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,9 @@ "onCommand:frontMatter.setLastModifiedDate", "onCommand:frontMatter.generateSlug", "onCommand:frontMatter.createFromTemplate", + "onCommand:frontMatter.registerFolder", + "onCommand:frontMatter.unregisterFolder", + "onCommand:frontMatter.createContent", "onView:frontMatter.explorer" ], "main": "./dist/extension", @@ -171,6 +174,11 @@ "type": "array", "default": [], "markdownDescription": "Specify the path to a Node.js script to execute. The current file path will be provided as an argument." + }, + "frontMatter.content.folders": { + "type": "array", + "default": [], + "markdownDescription": "This array of folders defines where the extension can easily create new content by running the create article command." } } }, @@ -222,6 +230,10 @@ { "command": "frontMatter.unregisterFolder", "title": "Front Matter: Unregister folder" + }, + { + "command": "frontMatter.createContent", + "title": "Front Matter: Create content" } ], "menus": { @@ -230,6 +242,16 @@ "command": "frontMatter.createFromTemplate", "when": "explorerResourceIsFolder", "group": "Front Matter@1" + }, + { + "command": "frontMatter.registerFolder", + "when": "explorerResourceIsFolder", + "group": "Front Matter@2" + }, + { + "command": "frontMatter.unregisterFolder", + "when": "explorerResourceIsFolder && resourcePath in frontMatter.registeredFolders", + "group": "Front Matter@3" } ] }, @@ -255,6 +277,7 @@ "@iarna/toml": "2.2.3", "@types/glob": "7.1.3", "@types/js-yaml": "3.12.1", + "@types/lodash.uniqby": "4.7.6", "@types/mocha": "^5.2.6", "@types/node": "10.17.48", "@types/react": "17.0.0", @@ -277,5 +300,7 @@ "webpack": "4.44.2", "webpack-cli": "3.3.12" }, - "dependencies": {} + "dependencies": { + "lodash.uniqby": "4.7.0" + } } diff --git a/src/commands/Folders.ts b/src/commands/Folders.ts new file mode 100644 index 00000000..17351c3d --- /dev/null +++ b/src/commands/Folders.ts @@ -0,0 +1,134 @@ +import { commands, Uri, workspace, window } from "vscode"; +import { CONFIG_KEY, EXTENSION_NAME, SETTINGS_CONTENT_FOLDERS } from "../constants"; +import { basename } from "path"; +import { ContentFolder } from "../models"; +import uniqBy = require("lodash.uniqby"); +import { VscodeCollapsible } from "@bendera/vscode-webview-elements/dist/vscode-collapsible"; +import { Template } from "./Template"; + +export class Folders { + + public static async create() { + const folders = Folders.get(); + + if (!folders || folders.length === 0) { + window.showWarningMessage(`${EXTENSION_NAME}: There are no known content locations defined in this project.`); + return; + } + + const selectedFolder = await window.showQuickPick(folders.map(f => f.title), { + placeHolder: `Select where you want to create your content` + }); + + if (!selectedFolder) { + window.showWarningMessage(`${EXTENSION_NAME}: You didn't select a place where you wanted to create your content.`); + return; + } + + const location = folders.find(f => f.title === selectedFolder); + if (location) { + const folderPath = Folders.getFolderPath(Uri.file(location.fsPath)); + if (folderPath) { + Template.create(folderPath); + } + } + } + + /** + * Register the new folder path + * @param folder + */ + public static async register(folder: Uri) { + if (folder && folder.path) { + const wslPath = folder.path.replace(/\//g, '\\'); + + let folders = Folders.get(); + + const exists = folders.find(f => f.paths.includes(folder.path) || f.paths.includes(wslPath)); + + if (exists) { + return window.showInformationMessage(`Folder is already registered`); + } + + const folderName = await window.showInputBox({ + prompt: `Which name would you like to specify for this folder?`, + placeHolder: `Folder name`, + value: basename(folder.fsPath) + }); + + folders.push({ + title: folderName, + fsPath: folder.fsPath, + paths: [ + folder.path, + wslPath + ] + } as ContentFolder); + + folders = uniqBy(folders, f => f.fsPath); + await Folders.update(folders); + } + + Folders.updateVsCodeCtx(); + } + + /** + * Unregister a folder path + * @param folder + */ + public static async unregister(folder: Uri) { + if (folder && folder.path) { + let folders = Folders.get(); + folders = folders.filter(f => f.fsPath !== folder.fsPath); + await Folders.update(folders); + } + + Folders.updateVsCodeCtx(); + } + + /** + * Update the registered folders context + */ + public static updateVsCodeCtx() { + const folders = Folders.get(); + let allFolders: string[] = []; + for (const folder of folders) { + allFolders = [...allFolders, ...folder.paths] + } + commands.executeCommand('setContext', 'frontMatter.registeredFolders', allFolders); + } + + /** + * Retrieve the folder path + * @param folder + * @returns + */ + public static getFolderPath(folder: Uri) { + let folderPath = ""; + if (folder && folder.fsPath) { + folderPath = folder.fsPath; + } else if (workspace.workspaceFolders && workspace.workspaceFolders.length > 0) { + folderPath = workspace.workspaceFolders[0].uri.fsPath; + } + return folderPath; + } + + /** + * Get the folder settings + * @returns + */ + private static get() { + const config = workspace.getConfiguration(CONFIG_KEY); + const folders: ContentFolder[] = config.get(SETTINGS_CONTENT_FOLDERS) as ContentFolder[]; + return folders; + } + + /** + * Update the folder settings + * @param folders + */ + private static async update(folders: ContentFolder[]) { + const config = workspace.getConfiguration(CONFIG_KEY); + await config.update(SETTINGS_CONTENT_FOLDERS, folders); + } +} \ No newline at end of file diff --git a/src/constants/settings.ts b/src/constants/settings.ts index befd3921..03ca7684 100644 --- a/src/constants/settings.ts +++ b/src/constants/settings.ts @@ -26,4 +26,6 @@ export const SETTING_TEMPLATES_PREFIX = "templates.prefix"; export const SETTING_PANEL_FREEFORM = "panel.freeform"; -export const SETTING_CUSTOM_SCRIPTS = "custom.scripts"; \ No newline at end of file +export const SETTING_CUSTOM_SCRIPTS = "custom.scripts"; + +export const SETTINGS_CONTENT_FOLDERS = "content.folders"; \ No newline at end of file diff --git a/src/extension.ts b/src/extension.ts index 93ef664e..fe8c2b60 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1,5 +1,6 @@ import * as vscode from 'vscode'; import { Article, Settings, StatusListener } from './commands'; +import { Folders } from './commands/Folders'; import { Template } from './commands/Template'; import { TaxonomyType } from './models'; import { TagType } from './viewpanel/TagType'; @@ -9,7 +10,7 @@ let frontMatterStatusBar: vscode.StatusBarItem; let debouncer: { (fnc: any, time: number): void; }; let collection: vscode.DiagnosticCollection; -export function activate({ subscriptions, extensionUri }: vscode.ExtensionContext) { +export async function activate({ subscriptions, extensionUri }: vscode.ExtensionContext) { collection = vscode.languages.createDiagnosticCollection('frontMatter'); const explorerSidebar = ExplorerView.getInstance(extensionUri); @@ -59,14 +60,11 @@ export function activate({ subscriptions, extensionUri }: vscode.ExtensionContex Article.generateSlug(); }); - let createFromTemplate = vscode.commands.registerCommand('frontMatter.createFromTemplate', (e: vscode.Uri) => { - let folderPath = ""; - if (e && e.fsPath) { - folderPath = e.fsPath; - } else if (vscode.workspace.workspaceFolders && vscode.workspace.workspaceFolders.length > 0) { - folderPath = vscode.workspace.workspaceFolders[0].uri.fsPath; - } - Template.create(folderPath); + let createFromTemplate = vscode.commands.registerCommand('frontMatter.createFromTemplate', (folder: vscode.Uri) => { + const folderPath = Folders.getFolderPath(folder); + if (folderPath) { + Template.create(folderPath); + } }); const toggleDraftCommand = 'frontMatter.toggleDraft'; @@ -75,6 +73,15 @@ export function activate({ subscriptions, extensionUri }: vscode.ExtensionContex triggerShowDraftStatus(); }); + // Register project folders + const registerFolder = vscode.commands.registerCommand(`frontMatter.registerFolder`, Folders.register); + + const unregisterFolder = vscode.commands.registerCommand(`frontMatter.unregisterFolder`, Folders.unregister); + + const createContent = vscode.commands.registerCommand(`frontMatter.createContent`, Folders.create); + + Folders.updateVsCodeCtx(); + // Create the status bar frontMatterStatusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 100); frontMatterStatusBar.command = toggleDraftCommand; @@ -99,6 +106,9 @@ export function activate({ subscriptions, extensionUri }: vscode.ExtensionContex subscriptions.push(generateSlug); subscriptions.push(createFromTemplate); subscriptions.push(toggleDraft); + subscriptions.push(registerFolder); + subscriptions.push(unregisterFolder); + subscriptions.push(createContent); } export function deactivate() {} @@ -115,4 +125,4 @@ const debounceShowDraftTrigger = () => { clearTimeout(timeout); timeout = setTimeout(functionCall, time) as any; }; -}; +}; \ No newline at end of file diff --git a/src/models/ContentFolder.ts b/src/models/ContentFolder.ts new file mode 100644 index 00000000..806a8e59 --- /dev/null +++ b/src/models/ContentFolder.ts @@ -0,0 +1,5 @@ +export interface ContentFolder { + title: string; + fsPath: string; + paths: string[]; +} \ No newline at end of file diff --git a/src/models/index.ts b/src/models/index.ts index bbe2fda6..73ab3027 100644 --- a/src/models/index.ts +++ b/src/models/index.ts @@ -1 +1,3 @@ +export * from './ContentFolder'; +export * from './PanelSettings'; export * from './TaxonomyType'; From b8dc7990f7720f7bab5afbbb78929fdb842dd430 Mon Sep 17 00:00:00 2001 From: Elio Date: Wed, 4 Aug 2021 14:38:57 +0200 Subject: [PATCH 3/5] #45 - WSL support added --- CHANGELOG.md | 2 ++ src/commands/Folders.ts | 1 - src/extension.ts | 22 +++++++++++++++++----- src/webview/ExplorerView.ts | 8 +++++++- 4 files changed, 26 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b170a864..b93a2672 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## [2.1.0] - 2020-08-XX - Upcoming release +- [#44](https://github.com/estruyf/vscode-front-matter/issues/45): Added article creation command +- [#45](https://github.com/estruyf/vscode-front-matter/issues/45): WSL support added - [#46](https://github.com/estruyf/vscode-front-matter/issues/46): Make the tag pickers render in full width ## [2.0.1] - 2020-07-27 diff --git a/src/commands/Folders.ts b/src/commands/Folders.ts index 17351c3d..1f553c0a 100644 --- a/src/commands/Folders.ts +++ b/src/commands/Folders.ts @@ -3,7 +3,6 @@ import { CONFIG_KEY, EXTENSION_NAME, SETTINGS_CONTENT_FOLDERS } from "../constan import { basename } from "path"; import { ContentFolder } from "../models"; import uniqBy = require("lodash.uniqby"); -import { VscodeCollapsible } from "@bendera/vscode-webview-elements/dist/vscode-collapsible"; import { Template } from "./Template"; export class Folders { diff --git a/src/extension.ts b/src/extension.ts index fe8c2b60..70be28e9 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -73,14 +73,26 @@ export async function activate({ subscriptions, extensionUri }: vscode.Extension triggerShowDraftStatus(); }); - // Register project folders - const registerFolder = vscode.commands.registerCommand(`frontMatter.registerFolder`, Folders.register); + // Register project folders + const registerFolder = vscode.commands.registerCommand(`frontMatter.registerFolder`, Folders.register); - const unregisterFolder = vscode.commands.registerCommand(`frontMatter.unregisterFolder`, Folders.unregister); + const unregisterFolder = vscode.commands.registerCommand(`frontMatter.unregisterFolder`, Folders.unregister); - const createContent = vscode.commands.registerCommand(`frontMatter.createContent`, Folders.create); + const createContent = vscode.commands.registerCommand(`frontMatter.createContent`, Folders.create); - Folders.updateVsCodeCtx(); + try { + const allPaths = await vscode.commands.executeCommand("_workbench.getRecentlyOpened"); + + console.log(vscode.window.activeTextEditor?.document.uri) + console.log(vscode.Uri.parse(`vscode-remote:///home`)) + + console.log(`remoteName`, vscode.env.remoteName); + console.log(`appRoot`, vscode.env.appRoot); + } catch (e) { + console.log(e?.message || e) + } + + Folders.updateVsCodeCtx(); // Create the status bar frontMatterStatusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 100); diff --git a/src/webview/ExplorerView.ts b/src/webview/ExplorerView.ts index 9c7b8cc2..736c2147 100644 --- a/src/webview/ExplorerView.ts +++ b/src/webview/ExplorerView.ts @@ -111,7 +111,11 @@ export class ExplorerView implements WebviewViewProvider, Disposable { commands.executeCommand('workbench.action.openSettings', '@ext:eliostruyf.vscode-front-matter'); break; case CommandToCode.openFile: - commands.executeCommand('revealFileInOS'); + if (os.type() === "Linux" && vscodeEnv.remoteName?.toLowerCase() === "wsl") { + commands.executeCommand('remote-wsl.revealInExplorer'); + } else { + commands.executeCommand('revealFileInOS'); + } break; case CommandToCode.runCustomScript: this.runCustomScript(msg); @@ -124,6 +128,8 @@ export class ExplorerView implements WebviewViewProvider, Disposable { exec(`open ${wsPath}`); } else if (os.type() === "Windows_NT") { exec(`explorer ${wsPath}`); + } else if (os.type() === "Linux" && vscodeEnv.remoteName?.toLowerCase() === "wsl") { + exec('explorer.exe `wslpath -w "$PWD"`'); } else { exec(`xdg-open ${wsPath}`); } From df84c25e014283ba66e819402cde169b2d22df75 Mon Sep 17 00:00:00 2001 From: Elio Date: Wed, 4 Aug 2021 15:00:26 +0200 Subject: [PATCH 4/5] #44 - Windows path fix --- CHANGELOG.md | 2 +- src/commands/Folders.ts | 15 ++++++++------- src/extension.ts | 12 ------------ 3 files changed, 9 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b93a2672..f361d70d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Change Log -## [2.1.0] - 2020-08-XX - Upcoming release +## [2.1.0] - 2020-08-04 - [#44](https://github.com/estruyf/vscode-front-matter/issues/45): Added article creation command - [#45](https://github.com/estruyf/vscode-front-matter/issues/45): WSL support added diff --git a/src/commands/Folders.ts b/src/commands/Folders.ts index 1f553c0a..46f409c8 100644 --- a/src/commands/Folders.ts +++ b/src/commands/Folders.ts @@ -7,6 +7,10 @@ import { Template } from "./Template"; export class Folders { + /** + * Create content in a registered folder + * @returns + */ public static async create() { const folders = Folders.get(); @@ -38,12 +42,12 @@ export class Folders { * @param folder */ public static async register(folder: Uri) { - if (folder && folder.path) { - const wslPath = folder.path.replace(/\//g, '\\'); + if (folder && folder.fsPath) { + const wslPath = folder.fsPath.replace(/\//g, '\\'); let folders = Folders.get(); - const exists = folders.find(f => f.paths.includes(folder.path) || f.paths.includes(wslPath)); + const exists = folders.find(f => f.paths.includes(folder.fsPath) || f.paths.includes(wslPath)); if (exists) { return window.showInformationMessage(`Folder is already registered`); @@ -58,10 +62,7 @@ export class Folders { folders.push({ title: folderName, fsPath: folder.fsPath, - paths: [ - folder.path, - wslPath - ] + paths: folder.fsPath === wslPath ? [folder.fsPath] : [folder.fsPath, wslPath] } as ContentFolder); folders = uniqBy(folders, f => f.fsPath); diff --git a/src/extension.ts b/src/extension.ts index 70be28e9..eea5485c 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -80,18 +80,6 @@ export async function activate({ subscriptions, extensionUri }: vscode.Extension const createContent = vscode.commands.registerCommand(`frontMatter.createContent`, Folders.create); - try { - const allPaths = await vscode.commands.executeCommand("_workbench.getRecentlyOpened"); - - console.log(vscode.window.activeTextEditor?.document.uri) - console.log(vscode.Uri.parse(`vscode-remote:///home`)) - - console.log(`remoteName`, vscode.env.remoteName); - console.log(`appRoot`, vscode.env.appRoot); - } catch (e) { - console.log(e?.message || e) - } - Folders.updateVsCodeCtx(); // Create the status bar From 33dcfcb09a8363a2c473d9fb7f5abfc67adee4a3 Mon Sep 17 00:00:00 2001 From: Elio Date: Wed, 4 Aug 2021 15:02:10 +0200 Subject: [PATCH 5/5] 2.1.0 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5d56b45e..a15d6b46 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "vscode-front-matter", - "version": "2.0.1", + "version": "2.1.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index dff23459..67a68bf2 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "displayName": "Front Matter", "description": "Simplifies working with front matter of your articles. Useful extension when you are using a static site generator like: Hugo, Jekyll, Hexo, NextJs, Gatsby, and many more...", "icon": "assets/front-matter.png", - "version": "2.0.1", + "version": "2.1.0", "preview": false, "publisher": "eliostruyf", "galleryBanner": {