Skip to content

Commit

Permalink
Fix for #4: [FR] Support move sync, bumped version to 0.1.2
Browse files Browse the repository at this point in the history
The edit history file was failing to be moved alongside the note when a note was
moved to a different folder.

This was due to code put in place to prevent history file renames/moves because,
when a folder is moved, Obsidian will move all the contents automatically, and
if the edit history file is moved explicitly before Obsidian moves it, then
Obsidian will throw a benign error when it tries to move the edit history file
and it doesn't find it.

The code was failing to allow the rename when a single note, but not the parent
folders, are moved across folders.

In summary the plugin should rename/move the edit history file when the note is
renamed or the direct parent folder changes, and let Obsidian move the edit
history file in all the other cases.

This fixes #4: [FR] Support move sync

Files:

README.md
- Minor clarification on history file format.

main.ts

- When there's a rename of a note, also move/rename the history file if either:
  - The note is changing name
  - The note is changing parent (but not any other ancestor)
- Added comments around
- Simplified link creation (no functional changes)

manifest.json
package.json
versions.json
- bumped to version 0.1.2

releases/0.1.2/main.js
releases/0.1.2/manifest.json
releases/0.1.2/styles.css
  - This release

Tests:
- Renamed note, verified edit history file is renamed by plugin
- Moved note to different folder, verified edit history file is moved by plugin
- Moved note to root folder, verified edit history file is moved by plugin
- Moved note from root folder, verified edit history file is moved by plugin
- Moved parent folder to different folder/root, verified edit history file is
  moved by Obsidian
- Moved grandparent to different folder/root, verified edit history file is
  moved by Obsidian
  • Loading branch information
antoniotejada committed Aug 11, 2023
1 parent 6d55e99 commit c799b60
Show file tree
Hide file tree
Showing 8 changed files with 5,064 additions and 33 deletions.
12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

This plugin saves each edit done to a note into a edit history file, the edits can later be diffed or copied.

![image](https://github.com/antoniotejada/lessmostat/assets/6446344/5f19d87d-0f1c-48c8-bc55-45043b37a7e4)
![image](https://github.com/antoniotejada/obsidian-edit-history/assets/6446344/fa9456d5-0de0-4160-bd06-6a38494f7c57)

This is similar to the [File Recovery](https://help.obsidian.md/Plugins/File+recovery) core plugin with the following advantages:
- Can keep edit history of any type of file, selectable via settings
- Open edit history file format
- Opensource edit history file format
- History files are kept independently per vault and file
- History files can be externally accessed, examined, copied around, or deleted
- History files can be backed up by external means
Expand Down Expand Up @@ -58,6 +58,10 @@ Each entry in the file is named after the UTC epoch in seconds at which time the
- Edit diff prev/next navigation
- Restore a given edit
- Diff one edit against another arbitrary edit
- Choose edit date by timeline/slider
- Choose edit date by timeline/slider/calendar view
- Abstract out/refactor access to the edit history file
- Test on mobile
- Edit History File management:
- find orphaned files
- per file/vault statistics
- merge/remove edits
- ...
86 changes: 60 additions & 26 deletions main.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,16 @@
import { App, Modal, normalizePath, Plugin, PluginSettingTab, Setting, TFile, TAbstractFile, TFolder, ButtonComponent, DropdownComponent } from "obsidian";
import {
App,
Modal,
normalizePath,
Plugin,
PluginSettingTab,
Setting,
TFile,
TAbstractFile,
TFolder,
ButtonComponent,
DropdownComponent
} from "obsidian";
import { DiffMatchPatch } from "diff-match-patch-ts";
// @ts-ignore: Complains about default export this way, but since jszip 3.10 this
// is the recommended way
Expand Down Expand Up @@ -74,7 +86,12 @@ const EDIT_HISTORY_FILE_EXT = ".edtz";

// XXX Have a timeline view of changes (per day, hour, etc)

// XXX Allow management in the edit history modal, merging diffs, deleting, deleting all history
// XXX Allow management in the edit history modal, merging diffs, deleting, deleting all historyç

// XXX tgz reduces size by half, use native browser gzip plus tar? (at the
// expense of having to uncompress the whole file in memory, not clear jszip
// does that already anyway?)
// See https://stackoverflow.com/questions/65446607/how-do-i-extract-data-from-a-tar-gz-file-stored-in-the-cloud-from-a-browser


export default class EditHistory extends Plugin {
Expand Down Expand Up @@ -494,19 +511,27 @@ export default class EditHistory extends Plugin {
return;
}

// Don't move edit history files when the note is moved if notes and
// edit history files are in the same directory (ie empty
// editHistoryRootFolder). Otherwise, moving the edit history file
// would cause Obsidian to throw a benign error when it tries to
// move the edit history file and finds it's not there anymore.

// Since Obsidian will move the folder contents when a folder is
// moved, only move the history file when the note is renamed or
// moved to a different parent (or if history files are kept in
// their own directory)
// Otherwise, moving the edit history file would cause Obsidian to
// throw a benign error when it tries to move the edit history file
// and finds it's not there anymore.
const oldFiledirs = oldPath.split("/");
const oldFilename = oldFiledirs.pop();
const oldParentFolder = (oldFiledirs.length > 0) ? oldFiledirs.pop() : "";
const filedirs = file.path.split("/");
const filename = filedirs.pop();
const parentFolder = (filedirs.length > 0) ? filedirs.pop() : "";
if ((this.settings.editHistoryRootFolder == "") &&
(oldPath.split("/").pop() == file.name)) {
logDbg("Ignoring directory-only change rename");
((oldParentFolder == parentFolder) && (oldFilename == filename))) {
logDbg("Not moving edit history, expected to be moved later alongside parent folder");
return;
}

// Rename the edit history file if any

let zipFilepath = this.getEditHistoryFilepath(oldPath);
let zipFile = this.app.vault.getAbstractFileByPath(zipFilepath);
if (zipFile != null) {
Expand Down Expand Up @@ -661,7 +686,7 @@ class EditHistoryModal extends Modal {
}

let revStats = contentEl.createEl("p");
const control = contentEl.createDiv("setting-item-control")
const control = contentEl.createDiv("setting-item-control");
control.style.justifyContent = "flex-start";
const select = new DropdownComponent(control);
select.selectEl.focus();
Expand Down Expand Up @@ -798,9 +823,8 @@ class EditHistorySettingTab extends PluginSettingTab { plugin:

containerEl.empty();

let author = containerEl.createEl("small", { text: "Created by "});
let link = containerEl.createEl("a", { text: "Antonio Tejada", href:"https://github.com/antoniotejada/"});
author.appendChild(link);
containerEl.createEl("small", { text: "Created by "})
.appendChild(createEl("a", { text: "Antonio Tejada", href:"https://github.com/antoniotejada/"}));

// h2 is abnormally small in settings, start with h3 which has the right
// size (other plugins do the same)
Expand Down Expand Up @@ -930,9 +954,9 @@ class EditHistorySettingTab extends PluginSettingTab { plugin:
configuring the edit history folder in settings would cause a
rename on each keystroke. There doesn't seem to be a final
changed(), hide() is not called either
- it's not clear whether the folder should be deleted if empty
- it's not clear if it's safe to just copy all the files found with
whatever extension new Setting(containerEl) .setName('Edits
folder') .setDesc('Folder to store the edit history file. Empty to
Expand All @@ -941,20 +965,30 @@ class EditHistorySettingTab extends PluginSettingTab { plugin:
other than "."') .addText(text => text .setPlaceholder('Enter the
folder name')
.setValue(this.plugin.settings.editHistoryRootFolder)
.onChange(async (value) => { logInfo("onChange");
logInfo('Edits folder: ' + value); // Only allow top level
folders
.onChange(async (value) => { logInfo("onChange"); logInfo('Edits
folder: ' + value); // Only allow top level folders
this.plugin.settings.editHistoryRootFolder = value;
// XXX Can the folder just be renamed via the file explorer
interface? // XXX Check no dir component starts with "." // XXX
Delete edits? copy them to new folder? trash them? // XXX Ask the
user to delete folder? // XXX Ask for confirmation? // XXX Use
private apis to store in some hidden folder? await
this.plugin.saveSettings();
}));
XXX Can the folder just be renamed via the file explorer
interface?
XXX Check no dir component starts with "."
XXX Delete edits? copy them to new folder? trash them?
XXX Ask the user to delete folder?
XXX Ask for confirmation?
XXX Use private apis to store in some hidden folder?
XXX This could use the adapter apis instead of the vault apis //
be able to access the .obsidian dir? (or any other?)
XXX The directory doesn't need to be created on every keystroke,
it could have a create/commit button?
*/


Expand Down
2 changes: 1 addition & 1 deletion manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "edit-history",
"name": "Edit History",
"version": "0.1.1",
"version": "0.1.2",
"minAppVersion": "0.15.0",
"description": "Automatically saves the history of edits of a file when Obsidian saves the file, and allows viewing the differences between edits, copying text from a previous edit, or fully rolling back to a previous edit.",
"author": "Antonio Tejada",
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "edit-history",
"version": "0.1.1",
"version": "0.1.2",
"description": "Edit history plugin for Obsidian http://obsidian.md, automatically saves the history of edits of a file when Obsidian saves the file, and allows viewing the differences between edits, copying text from a previous edit, or fully rolling back to a previous edit.",
"main": "main.js",
"scripts": {
Expand Down
Loading

0 comments on commit c799b60

Please sign in to comment.