Skip to content

Instantly share code, notes, and snippets.

@philoserf
Last active January 21, 2025 03:50
Show Gist options
  • Save philoserf/f70c9629251a1425802675e12bd222b6 to your computer and use it in GitHub Desktop.
Save philoserf/f70c9629251a1425802675e12bd222b6 to your computer and use it in GitHub Desktop.
A rewrite of badrbouslikhin/obsidian-vault-changelog with suggested changes
'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