obsidian-linter icon indicating copy to clipboard operation
obsidian-linter copied to clipboard

FR: Fix the `ctime` of .md files based on "Date Created" frontmatter.

Open sampajano opened this issue 3 years ago • 17 comments
trafficstars

Is Your Feature Request Related to a Problem? Please Describe.

Yes it is!!

One of the main pain point when migrating from Evernote to Obsidian is that the note's ctime can often get lost/modified during syncing -- either due to restrictions of sync services like Git (e.g. when i setup a new computer from a obsidian Git repo), or due to OS restrictions (Obsidian Sync cannot preserve file's ctime on Linux),

To the point that, i cannot reliably view the notes sorted by their "create time" in the Obsidian's Files Explorer.

Describe the Solution You'd Like

Since Linter already supports the feature to maintain a create timestamp in frontmatter, I wonder if it'd be possible to add a new option use create date YAML to set the ctime of the file, when they do not match.

Potential name for the new option: Sync "Date Created" to the file `ctime` (when mismatched)

Roughly logic (when the new option is turned on):

  1. if "Date Created" YAML does NOT exist -> fill it in just like today
  2. if "Date Created" DOES exist, and when it's the SAME as the ctime of the file -> do nothing
  3. if "Date Created" DOES exist, and is DIFFERENT than the ctime of the file -> Update the file's ctime using the "Date Created" value

Describe Alternatives You've Considered

  1. Currently, i rely on Dataview to generate a view using the "Date Created" frontmatter value. It works, but is somewhat awkward and requires keeping a separate note per folder that i'm interested in.

    It would be MUCH nicer if the sort order by "create time" in File Explorer can be reliably used :)

  2. Alternatively, i could do the above using a custom script, but it would be much nicer if this is built-in into Linter (for batch-fixing all my notes) :)


Thanks SO much for your considerations! :)

(credit to @Antisimplistic on Discord for the brilliant idea!! 😃)

sampajano avatar Sep 03 '22 00:09 sampajano

I can check and see if ctime is mutable, but I am pretty sure that it cannot be user specified due to how OSs work. I could be wrong though.

pjkaufman avatar Sep 03 '22 00:09 pjkaufman

This looks to be something that can only be done on Windows. I am waiting for confirmation that you can actually update the value rather than just being able to create a note that has an older ctime than the current date.

Do you intend to use such a functionality on Windows only?

pjkaufman avatar Sep 03 '22 01:09 pjkaufman

It looks to me from your above statement that you would like to use Linux for this since you mention it relating to Obsidian Sync, though it could be just coincidental.

pjkaufman avatar Sep 03 '22 01:09 pjkaufman

This looks to be something that can only be done on Windows. I am waiting for confirmation that you can actually update the value rather than just being able to create a note that has an older ctime than the current date.

Do you intend to use such a functionality on Windows only?

Hi! I've been fixing this on MacOS too so it should definitely be possible there as well 😃

setfile -d "06/01/2022 00:00:00" "filename"

It looks to me from your above statement that you would like to use Linux for this since you mention it relating to Obsidian Sync, though it could be just coincidental.

I primarily use Mac so it is where i'm most interested 😃

sampajano avatar Sep 03 '22 01:09 sampajano

Gotcha. It seems there is potentially a hidden adapter somewhere in the Obsidian logic. I am not sure where that would be and its stability may be questionable since it is not publicly exposed for devs to openly use.

It looks like the above is a system command that is being run. That might be something more suited to a Templater custom script since it can run system commands.

But it does seem like it might be feasible to do via Obsidian.

pjkaufman avatar Sep 03 '22 01:09 pjkaufman

Gotcha. It seems there is potentially a hidden adapter somewhere in the Obsidian logic. I am not sure where that would be and its stability may be questionable since it is not publicly exposed for devs to openly use.

ahh i see.. afaiu Obsidian Sync will try to preserve ctime during new notes sync as well, but there maybe no API for this.

It looks like the above is a system command that is being run. That might be something more suited to a Templater custom script since it can run system commands.

But it does seem like it might be feasible to do via Obsidian.

ahh i see.. Do you mean Linter won't be able to run system commands (whereas Templater custom scripts can)? I'm not at all familiar with the access restrictions of plugins so i'll defer to your expertise.. 😃

sampajano avatar Sep 03 '22 01:09 sampajano

The linter could be setup to run system commands. But Templater has that already setup that they can be triggered from templates (this may not be what you want since it seems you want to run this against files that already exist, though templates can do that as well). However this may be something that could be useful as its own plugin since it tackles something that users sync between devices may need.

As for updating the ctime via Obsidian, that is entirely at the mercy of the Obsidian devs as that is who would have to be relied on to make sure that the API to use is stable and something that works across OSs.

pjkaufman avatar Sep 03 '22 01:09 pjkaufman

The linter could be setup to run system commands. But Templater has that already setup that they can be triggered from templates (this may not be what you want since it seems you want to run this against files that already exist, though templates can do that as well).

Ah right.. I'm sure Templater or even a custom NodeJs script can be made to work. Although, i was thinking that since Linter has the ability to "Lint all files in the vault", this would be a great place where it can fix ALL files at once (and potentially every once a while).

However this may be something that could be useful as its own plugin since it tackles something that users sync between devices may need.

Yeah definitely possible.. Although i was thinking it might not be a super niche needs as Obsidian Git is fairly popular and one would definitely benefit if they ever setup a new Obsidian vault from Git repo (e.g. new computer, etc.).

As for updating the ctime via Obsidian, that is entirely at the mercy of the Obsidian devs as that is who would have to be relied on to make sure that the API to use is stable and something that works across OSs.

I'm not sure how likely it's going to be prioritized, but i can try file a FR on Obsidian forum. Would it help for you to consider adding this feature? 😃

sampajano avatar Sep 03 '22 03:09 sampajano

I am not sure an FR on an obsidian forum would help unless it was able to show that it is something that people are interested in as a whole.

pjkaufman avatar Sep 03 '22 09:09 pjkaufman

I am not sure an FR on an obsidian forum would help unless it was able to show that it is something that people are interested in as a whole.

Ahh ok makes sense.. Thanks for your considerations! 😃

Hope more people shows interests here :D

sampajano avatar Sep 03 '22 13:09 sampajano

I was thinkimg some more on this and I am not sure how maintainable that logic would be since it requires upsating file metadata. I am not saying it cannot be done, but testing and making sure it still works would require manual work since we would have to mock how obsidian works.

pjkaufman avatar Sep 03 '22 17:09 pjkaufman

@sampajano , it looks like this may be feasible through custom lint rules assuming that gets added (#358 ). Can the changes you are referring to be made via code and if so could they be added as an obsidian command through the quick add plugin?

I have not tried this out myself, but if the above changes can be made via code and quick add allows it, then it may work with the current suggested implementation of custom lint rules.

pjkaufman avatar Sep 04 '22 16:09 pjkaufman

It looks like the Linter itself will not be able to update ctime unless you find a way to modify it via JS and use QuickAdd to create it as a part of a command. There does not seem to be a good way to make this kind of update via the Obsidian API. I would be happy to try to help with that, but there will not be an addition of a rule specific to this functionality. Please let me know if you need any help with creating a command witb QuickAdd or in using that command with the new custom lint commands. I am adding support for lint all and lint all in folder for the Obsidian commands.

Here is the documentation I have come up with on how to create the QuickAdd command thus far: https://github.com/platers/obsidian-linter#custom-lint-commands

pjkaufman avatar Sep 07 '22 11:09 pjkaufman

@pjkaufman Thanks so much for the pointers and ideas! I'll test out the QuickAdd custom command and let you know if it works for my use case! Thanks again! 😃

sampajano avatar Sep 08 '22 05:09 sampajano

No problem. For now, you will only want to use the custom command for updating on save. But hopefully I will get something together soon for running it as a part of lint all in folder and lint all.

pjkaufman avatar Sep 08 '22 10:09 pjkaufman

I am going to close this unless there is a reason to keep it open. Feel free to let us know if there is anything that you think would be a good feature request for Lint users.

pjkaufman avatar Sep 17 '22 02:09 pjkaufman

Hi thanks for consideration and feel free to close! I'll try out the method you've recommended soon and post an update here.

In the meanwhile, if you can provide the function to run custom lint for all files it would be a nice addition for my use case too. thanks again! :)

sampajano avatar Sep 17 '22 15:09 sampajano

I will close this once I get done with adding the lint all functionality for the custom lint rules. Thus far, I have been really trying to fix bugs and work out custom ignore rules. Hopefully it won't be too much longer on this.

pjkaufman avatar Nov 07 '22 18:11 pjkaufman

Man. I am looking at this and it looks like I got distracted with a lot of other features and bug fixes between the time of this issue being created and when I finally got to biting the bullet for adding the logic even though it is not 100% where I would like it (that is a bad habit of mine). Hopefully you can tinker with this in the next release and see if it is what you are looking for. If not, hopefully you have a method for handling the creation time logic.

pjkaufman avatar Nov 12 '23 21:11 pjkaufman

@pjkaufman Hey no worries! Thanks so much for working on this! 😊

I've updated my linter plugin, but didn't exactly find the option to automatically update the file ctime yet.

Is it one of the following options? Or will it be added in the next release?

Screenshot 2023-11-13 at 9 22 38 PM

For my own solution, i've been using a simple node script (code), and it's been working well enough for me so far :)

sampajano avatar Nov 14 '23 05:11 sampajano

Hey @sampajano , the code has not been released for the changes, but the Linter itself cannot make the change (there is a lack of APIs to do so). However using QuickAdd or another action you may be able to run that node script as a command in Obsidian. If that is the case, then in the next release you should be able to use custom commands to handle the ctime logic.

pjkaufman avatar Nov 14 '23 10:11 pjkaufman

@pjkaufman Ah ok got it! Thanks so much for explaining! Appreciate the help! 😃

sampajano avatar Nov 14 '23 17:11 sampajano

No problem. Hopefully it can be added as a custom command to have that run on folder and vault lint.

pjkaufman avatar Nov 14 '23 18:11 pjkaufman