Last active
January 21, 2025 03:50
-
-
Save philoserf/f70c9629251a1425802675e12bd222b6 to your computer and use it in GitHub Desktop.
A rewrite of badrbouslikhin/obsidian-vault-changelog with suggested changes
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
var obsidian = require('obsidian'); | |
const DEFAULT_SETTINGS = { | |
autoUpdate: true, | |
changelogPath: "Changelog.md", | |
datetimeFormat: "YYYY-MM-DD[T]HHmm", | |
maxRecentFiles: 25, | |
}; | |
class ChangelogPlugin extends obsidian.Plugin { | |
settings = DEFAULT_SETTINGS; | |
async onload() { | |
await this.loadSettings(); | |
this.addSettingTab(new ChangelogSettingsTab(this.app, this)); | |
this.addCommand({ | |
id: "update-changelog", | |
name: "Update Changelog", | |
callback: () => this.updateChangelog(), | |
}); | |
this.onVaultChange = obsidian.debounce(this.onVaultChange.bind(this), 200); | |
this.enableAutoUpdate(); | |
} | |
enableAutoUpdate() { | |
if (this.settings.autoUpdate) { | |
this.registerEvent(this.app.vault.on("modify", this.onVaultChange)); | |
this.registerEvent(this.app.vault.on("delete", this.onVaultChange)); | |
this.registerEvent(this.app.vault.on("rename", this.onVaultChange)); | |
} | |
} | |
disableAutoUpdate() { | |
this.app.vault.off("modify", this.onVaultChange); | |
this.app.vault.off("delete", this.onVaultChange); | |
this.app.vault.off("rename", this.onVaultChange); | |
} | |
onVaultChange(file) { | |
if (file.path !== this.settings.changelogPath) { | |
this.updateChangelog(); | |
} | |
} | |
async updateChangelog() { | |
const changelog = await this.generateChangelog(); | |
await this.writeToFile(this.settings.changelogPath, changelog); | |
} | |
async generateChangelog() { | |
const recentFiles = this.getRecentlyEditedFiles(); | |
let changelogContent = ""; | |
recentFiles.forEach((file) => { | |
const formattedTime = obsidian.moment(file.stat.mtime).format(this.settings.datetimeFormat); | |
changelogContent += `- ${formattedTime} · [[${file.basename}]]\n`; | |
}); | |
return changelogContent; | |
} | |
getRecentlyEditedFiles() { | |
return this.app.vault | |
.getMarkdownFiles() | |
.filter((file) => file.path !== this.settings.changelogPath) | |
.sort((a, b) => b.stat.mtime - a.stat.mtime) | |
.slice(0, this.settings.maxRecentFiles); | |
} | |
async writeToFile(path, content) { | |
let file = this.app.vault.getAbstractFileByPath(path); | |
if (!file) { | |
file = await this.app.vault.create(path, path); | |
} | |
if (file instanceof obsidian.TFile) { | |
await this.app.vault.modify(file, content); | |
} | |
else { | |
new obsidian.Notice(`Could not update changelog at path: ${path}`); | |
} | |
} | |
async loadSettings() { | |
this.settings = { ...DEFAULT_SETTINGS, ...(await this.loadData()) }; | |
} | |
async saveSettings() { | |
await this.saveData(this.settings); | |
} | |
} | |
class ChangelogSettingsTab extends obsidian.PluginSettingTab { | |
plugin; | |
constructor(app, plugin) { | |
super(app, plugin); | |
this.plugin = plugin; | |
} | |
display() { | |
const { containerEl } = this; | |
const { settings } = this.plugin; | |
containerEl.empty(); | |
new obsidian.Setting(containerEl) | |
.setName("Auto Update") | |
.setDesc("Automatically update changelog on vault changes") | |
.addToggle((toggle) => toggle.setValue(settings.autoUpdate).onChange(async (value) => { | |
settings.autoUpdate = value; | |
await this.plugin.saveSettings(); | |
value | |
? this.plugin.enableAutoUpdate() | |
: this.plugin.disableAutoUpdate(); | |
})); | |
new obsidian.Setting(containerEl) | |
.setName("Changelog Path") | |
.setDesc("Relative path including filename and extension") | |
.addText((text) => text | |
.setPlaceholder("Folder/Changelog.md") | |
.setValue(settings.changelogPath) | |
.onChange(async (path) => { | |
settings.changelogPath = path; | |
await this.plugin.saveSettings(); | |
})); | |
new obsidian.Setting(containerEl) | |
.setName("Datetime Format") | |
.setDesc("Moment.js datetime format string") | |
.addText((text) => text | |
.setPlaceholder("YYYY-MM-DD[T]HHmm") | |
.setValue(settings.datetimeFormat) | |
.onChange(async (format) => { | |
settings.datetimeFormat = format; | |
await this.plugin.saveSettings(); | |
})); | |
new obsidian.Setting(containerEl) | |
.setName("Max Recent Files") | |
.setDesc("Maximum number of recently edited files to include") | |
.addText((text) => text | |
.setValue(settings.maxRecentFiles.toString()) | |
.onChange(async (value) => { | |
settings.maxRecentFiles = Number(value); | |
await this.plugin.saveSettings(); | |
})); | |
} | |
} | |
module.exports = ChangelogPlugin; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment