From faa74132e56d6853be5f55fcc9df7a3e07ddeabc Mon Sep 17 00:00:00 2001 From: Austin Farmer <5827236+farmerau@users.noreply.github.com> Date: Thu, 6 Jan 2022 15:17:06 -0500 Subject: [PATCH] Adjust Automatic Date Updates to Run on Save Prefers `onWillSaveTextDocument` over `onDidChangeTextDocument` for the triggering event. --- src/commands/Article.ts | 67 +++++++++++++++++++++--------------- src/extension.ts | 7 ++-- src/helpers/ArticleHelper.ts | 32 +++++++++++++---- 3 files changed, 69 insertions(+), 37 deletions(-) diff --git a/src/commands/Article.ts b/src/commands/Article.ts index ccef34ae..5e4a228f 100644 --- a/src/commands/Article.ts +++ b/src/commands/Article.ts @@ -15,9 +15,6 @@ import { parseWinPath } from '../helpers/parseWinPath'; export class Article { - - private static prevContent = ""; - /** * Insert taxonomy * @@ -119,7 +116,37 @@ export class Article { return; } - const article = ArticleHelper.getFrontMatter(editor); + const updatedArticle = this.setLastModifiedDateInner(editor.document); + + if (typeof updatedArticle === "undefined") { + return; + } + + ArticleHelper.update( + editor, + updatedArticle as matter.GrayMatterFile + ); + } + + public static async setLastModifiedDateOnSave( + document: vscode.TextDocument + ): Promise { + const updatedArticle = this.setLastModifiedDateInner(document); + + if (typeof updatedArticle === "undefined") { + return []; + } + + const update = ArticleHelper.generateUpdate(document, updatedArticle); + + return [update]; + } + + private static setLastModifiedDateInner( + document: vscode.TextDocument + ): matter.GrayMatterFile | undefined { + const article = ArticleHelper.getFrontMatterFromDocument(document); + if (!article) { return; } @@ -128,8 +155,7 @@ export class Article { const dateField = Settings.get(SETTING_MODIFIED_FIELD) as string || DefaultFields.LastModified; try { cloneArticle.data[dateField] = Article.formatDate(new Date()); - - ArticleHelper.update(editor, cloneArticle); + return cloneArticle; } catch (e: any) { Notifications.error(`Something failed while parsing the date format. Check your "${CONFIG_KEY}${SETTING_DATE_FORMAT}" setting.`); } @@ -238,30 +264,17 @@ export class Article { /** * Article auto updater - * @param fileChanges + * @param event */ - public static async autoUpdate(fileChanges: vscode.TextDocumentChangeEvent) { - const txtChanges = fileChanges.contentChanges.map(c => c.text); - const editor = vscode.window.activeTextEditor; + public static async autoUpdate(event: vscode.TextDocumentWillSaveEvent) { + const document = event.document; + if (document && ArticleHelper.isMarkdownFile(document)) { + const autoUpdate = Settings.get(SETTING_AUTO_UPDATE_DATE); - if (txtChanges.length > 0 && editor && ArticleHelper.isMarkdownFile()) { - const autoUpdate = Settings.get(SETTING_AUTO_UPDATE_DATE); - - if (autoUpdate) { - const article = ArticleHelper.getFrontMatter(editor); - if (!article) { - return; - } - - if (article.content === Article.prevContent) { - return; - } - - Article.prevContent = article.content; - - Article.setLastModifiedDate(); + if (autoUpdate) { + event.waitUntil(Article.setLastModifiedDateOnSave(document)); } - } + } } /** diff --git a/src/extension.ts b/src/extension.ts index 3b9b3563..5b97b065 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -177,8 +177,7 @@ export async function activate(context: vscode.ExtensionContext) { triggerShowDraftStatus(); // Listener for file edit changes - editDebounce = debounceCallback(); - subscriptions.push(vscode.workspace.onDidChangeTextDocument(triggerFileChange)); + subscriptions.push(vscode.workspace.onWillSaveTextDocument(handleAutoDateUpdate)); // Listener for file saves subscriptions.push(vscode.workspace.onDidSaveTextDocument((doc: vscode.TextDocument) => { @@ -231,8 +230,8 @@ export async function activate(context: vscode.ExtensionContext) { export function deactivate() {} -const triggerFileChange = (e: vscode.TextDocumentChangeEvent) => { - editDebounce(() => Article.autoUpdate(e), 1000); +const handleAutoDateUpdate = (e: vscode.TextDocumentWillSaveEvent) => { + Article.autoUpdate(e); }; const triggerShowDraftStatus = () => { diff --git a/src/helpers/ArticleHelper.ts b/src/helpers/ArticleHelper.ts index 6d33ca3b..882f54f0 100644 --- a/src/helpers/ArticleHelper.ts +++ b/src/helpers/ArticleHelper.ts @@ -27,8 +27,17 @@ export class ArticleHelper { * @param editor */ public static getFrontMatter(editor: vscode.TextEditor) { - const fileContents = editor.document.getText(); - return ArticleHelper.parseFile(fileContents, editor.document.fileName); + return ArticleHelper.getFrontMatterFromDocument(editor.document); + } + + /** + * Get the contents of the specified document + * + * @param document The document to parse. + */ + public static getFrontMatterFromDocument(document: vscode.TextDocument) { + const fileContents = document.getText(); + return ArticleHelper.parseFile(fileContents, document.fileName); } /** @@ -47,6 +56,18 @@ export class ArticleHelper { * @param article */ public static async update(editor: vscode.TextEditor, article: matter.GrayMatterFile) { + const update = this.generateUpdate(editor.document, article); + + await editor.edit(builder => builder.replace(update.range, update.newText)); + } + + /** + * Generate the update to be applied to the article. + * @param article + */ + public static generateUpdate(document: vscode.TextDocument, article: matter.GrayMatterFile): vscode.TextEdit { + const nrOfLines = document.lineCount as number; + const range = new vscode.Range(new vscode.Position(0, 0), new vscode.Position(nrOfLines, 0)); const removeQuotes = Settings.get(SETTING_REMOVE_QUOTES) as string[]; const commaSeparated = Settings.get(SETTING_COMMA_SEPARATED_FIELDS); @@ -68,8 +89,7 @@ export class ArticleHelper { } } - const nrOfLines = editor.document.lineCount as number; - await editor.edit(builder => builder.replace(new vscode.Range(new vscode.Position(0, 0), new vscode.Position(nrOfLines, 0)), newMarkdown)); + return vscode.TextEdit.replace(range, newMarkdown); } /** @@ -109,12 +129,12 @@ export class ArticleHelper { /** * Checks if the current file is a markdown file */ - public static isMarkdownFile() { + public static isMarkdownFile(document: vscode.TextDocument | undefined | null = null) { const supportedLanguages = ["markdown", "mdx"]; const supportedFileExtensions = [".md", ".mdx"]; - const document = vscode.window.activeTextEditor?.document; const languageId = document?.languageId?.toLowerCase(); const isSupportedLanguage = languageId && supportedLanguages.includes(languageId); + document ??= vscode.window.activeTextEditor?.document; /** * It's possible that the file is a file type we support but the user hasn't installed