Giter Site home page Giter Site logo

org-roam-timestamps's Introduction

https://melpa.org/packages/org-roam-timestamps-badge.svg

org-roam-timestamps

./pic.png

Small package to keep track of the modification and creation time of individual nodes.

I created this to use mtime data in org-roam-ui, and it is highly recommended you use this package if you are using org-roam-ui to get the most out of that.

Offers two pieces of functionality:

  1. Add creation and modification properties to all nodes.
  2. Keep the mtime property of a node updated.

How to use

Most basic use case:

  1. Run `org-roam-timestamps-all`. This will add ctime and mtime properties to all the property drawers of your notes. This might take a while. It will make backups of your notes and org-roam-db in case anything goes wrong, but back them up yourself as well!
  2. Keep `org-roam-timestamps-mode` running while you do your org-roam-business.

Installation

org-roam-timestamps is on MELPA!

Doom emacs

;;packages.el
(package! org-roam-timestamps)
(use-package! org-roam-timestamps
  :after org-roam
  :config (org-roam-timestamps-mode))

package.el

M-x package-install org-roam-timestamps

Customizations

Org-roam-timestamps exposes three variables for customization

Parent file

(setq org-roam-timestamps-parent-file t)

This will also update the parent file when you update a subnote.

Remember timestamps

(setq org-roam-timestamps-remember-timestamps t)

This will remember previous mtimes and add the new timestamp to the front of the list rather than replace the old one. This will allow us to create git-like time-tracker-views in org-roam-ui, showing you when you modified which files.

It will however clog up your properties drawer a lot more and of course increase file size. If you previously had this turned on but want to remove it for all files, run org-roam-timestamps-clean-mtimes.

Min gap

(setq org-roam-timestamps-minimum-gap 3600)

Minimum time in seconds between two timestamps. Defaults to an hour. Only does something if org-roam-timestamps-remember-timestamps is t

Caveats

This package is not working flawlessly yet.

Saving

Since org-roam does not really store any data about the contents of the current node, I can’t really check whether the current node has been changed at all. There are four ways to possibly get around this:

Save copy of previous node

This would be the most accurate way to check whether the current node has been modified, by doing an actual comparison with the previous state. This would end up doubling the whole node though, which sucks.

Git

Next best option would be to compare the current state to the latest git state. This is kind of annoying though, and would rely on you keeping an accurate git repo of your notes. Since I personally am not that accurate with it, and I want this package to be useable without git (as org-roam(-ui) is), this is not an option.

Size comparison

Basic idea: store the previous size of the node in bytes in the property drawer.

Advantages:

  • Somewhat accurate

Disadvantages:

  • Slower than the next option, as you need to check all nodes in the buffer.
  • Can’t account for small updates (such as checking a list)
  • Yet more properties
  • Harder

Just update the current node

This is what we use atm. We just update the node the cursor is on when you save. This is not the best way to do this by a long shot, but it’s fast and easy.

I might update this in the future (and of course contributions are very welcome).

Smaller problems

The smaller problems are

  • [ ] Flickering when org-roam-buffer is open
  • [ ] Slowish

org-roam-timestamps's People

Contributors

stites avatar tefkah avatar trevoke avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

org-roam-timestamps's Issues

Human readable time format related to posix

Currently I add the creation time of an org-file via date: %U.

I would like to have your modification time also as %U or another one of the datetime format string options (e.g. %Y-%m-%d %H:%M:%S).

Would be great to have a solution for that.

Provide option to detect modification based on hash, rather than on save location

It would be nice if only the nodes that have been modified would get saved, rather than relying on the location of saving.

One way to do this would be to calculate the hash of the node-tree and compare that to a previous value.

The main problem with this approach is that the hash would obviously change every save, because the hash of cannot include itself (I'm pretty sure).
So then I would need to compare hashes excluding the property drawer, which I don't really know how to do.

void function length=

org roam capture a new node , press C-c C-c to complete, the minibuffer echo (void function length=)

Debugger entered--Lisp error: (void-function length=)
  (length= el 1)
  (if (length= el 1) (progn (setq el (concat "0" el))))
  (let ((i --dotimes-counter--)) (setq el (number-to-string (nth i time))) (if (length= el 1) (progn (setq el (concat "0" el)))) (setq dec-time (concat el dec-time)))
  (while (< --dotimes-counter-- --dotimes-limit--) (let ((i --dotimes-counter--)) (setq el (number-to-string (nth i time))) (if (length= el 1) (progn (setq el (concat "0" el)))) (setq dec-time (concat el dec-time))) (setq --dotimes-counter-- (1+ --dotimes-counter--)))
  (let ((--dotimes-limit-- 6) (--dotimes-counter-- 0)) (while (< --dotimes-counter-- --dotimes-limit--) (let ((i --dotimes-counter--)) (setq el (number-to-string (nth i time))) (if (length= el 1) (progn (setq el (concat "0" el)))) (setq dec-time (concat el dec-time))) (setq --dotimes-counter-- (1+ --dotimes-counter--))))
  (let ((time (decode-time mtime)) dec-time el) (let ((--dotimes-limit-- 6) (--dotimes-counter-- 0)) (while (< --dotimes-counter-- --dotimes-limit--) (let ((i --dotimes-counter--)) (setq el (number-to-string (nth i time))) (if (length= el 1) (progn (setq el (concat "0" el)))) (setq dec-time (concat el dec-time))) (setq --dotimes-counter-- (1+ --dotimes-counter--)))) dec-time)
  org-roam-timestamps-decode((24949 60684 847116 567000))
  (org-roam-add-property (org-roam-timestamps-decode (progn (or (and (memq (type-of node) cl-struct-org-roam-node-tags) t) (signal 'wrong-type-argument (list 'org-roam-node node))) (aref node 4))) "mtime")
  (if mtime (progn (if (and org-roam-timestamps-timestamp-parent-file (not (eq (progn (or ... ...) (aref node 6)) 0))) (progn (let* (new-buf (auto-mode-alist nil) (buf (or ... ... ...)) res) (save-current-buffer (set-buffer buf) (if (equal major-mode ...) nil (progn ... ...)) (setq res (progn ...)) (if (and new-buf ...) nil (save-buffer))) (if (and new-buf (not nil)) (if (find-buffer-visiting file) (progn ...))) res))) (if org-roam-timestamps-remember-timestamps nil (org-roam-timestamps--remove-current-mtime node)) (org-roam-timestamps--add-mtime mtime)) (org-roam-add-property (org-roam-timestamps-decode (progn (or (and (memq (type-of node) cl-struct-org-roam-node-tags) t) (signal 'wrong-type-argument (list 'org-roam-node node))) (aref node 4))) "mtime"))
  (let* ((mod-time (and t (org-roam-timestamps--get-mtime node))) (mtime (and mod-time (car (split-string mod-time))))) (if mtime (progn (if (and org-roam-timestamps-timestamp-parent-file (not (eq (progn ... ...) 0))) (progn (let* (new-buf (auto-mode-alist nil) (buf ...) res) (save-current-buffer (set-buffer buf) (if ... nil ...) (setq res ...) (if ... nil ...)) (if (and new-buf ...) (if ... ...)) res))) (if org-roam-timestamps-remember-timestamps nil (org-roam-timestamps--remove-current-mtime node)) (org-roam-timestamps--add-mtime mtime)) (org-roam-add-property (org-roam-timestamps-decode (progn (or (and (memq ... cl-struct-org-roam-node-tags) t) (signal 'wrong-type-argument (list ... node))) (aref node 4))) "mtime")))
  (let* ((node (org-roam-populate (org-roam-node-create :id (org-roam-id-at-point)))) (file (progn (or (and (memq (type-of node) cl-struct-org-roam-node-tags) t) (signal 'wrong-type-argument (list 'org-roam-node node))) (aref node 1)))) (let* ((creation-time (and t (org-roam-timestamps--get-ctime node))) (ctime (and creation-time (car (split-string creation-time))))) (if ctime nil (let* ((level (and t (eq 0 ...))) (filename (and level (file-name-base file))) (index (and filename (string-match "^[0-9]\\{14\\}" filename))) (timestamp (and index (substring filename index ...)))) (if timestamp (org-roam-add-property timestamp "ctime") (org-roam-add-property (org-roam-timestamps-decode (progn ... ...)) "ctime"))))) (let* ((mod-time (and t (org-roam-timestamps--get-mtime node))) (mtime (and mod-time (car (split-string mod-time))))) (if mtime (progn (if (and org-roam-timestamps-timestamp-parent-file (not (eq ... 0))) (progn (let* (new-buf ... ... res) (save-current-buffer ... ... ... ...) (if ... ...) res))) (if org-roam-timestamps-remember-timestamps nil (org-roam-timestamps--remove-current-mtime node)) (org-roam-timestamps--add-mtime mtime)) (org-roam-add-property (org-roam-timestamps-decode (progn (or (and ... t) (signal ... ...)) (aref node 4))) "mtime"))))
  (progn (let* ((node (org-roam-populate (org-roam-node-create :id (org-roam-id-at-point)))) (file (progn (or (and (memq ... cl-struct-org-roam-node-tags) t) (signal 'wrong-type-argument (list ... node))) (aref node 1)))) (let* ((creation-time (and t (org-roam-timestamps--get-ctime node))) (ctime (and creation-time (car (split-string creation-time))))) (if ctime nil (let* ((level (and t ...)) (filename (and level ...)) (index (and filename ...)) (timestamp (and index ...))) (if timestamp (org-roam-add-property timestamp "ctime") (org-roam-add-property (org-roam-timestamps-decode ...) "ctime"))))) (let* ((mod-time (and t (org-roam-timestamps--get-mtime node))) (mtime (and mod-time (car (split-string mod-time))))) (if mtime (progn (if (and org-roam-timestamps-timestamp-parent-file (not ...)) (progn (let* ... ... ... res))) (if org-roam-timestamps-remember-timestamps nil (org-roam-timestamps--remove-current-mtime node)) (org-roam-timestamps--add-mtime mtime)) (org-roam-add-property (org-roam-timestamps-decode (progn (or ... ...) (aref node 4))) "mtime")))))
  (if (org-roam-buffer-p) (progn (let* ((node (org-roam-populate (org-roam-node-create :id (org-roam-id-at-point)))) (file (progn (or (and ... t) (signal ... ...)) (aref node 1)))) (let* ((creation-time (and t (org-roam-timestamps--get-ctime node))) (ctime (and creation-time (car ...)))) (if ctime nil (let* ((level ...) (filename ...) (index ...) (timestamp ...)) (if timestamp (org-roam-add-property timestamp "ctime") (org-roam-add-property ... "ctime"))))) (let* ((mod-time (and t (org-roam-timestamps--get-mtime node))) (mtime (and mod-time (car ...)))) (if mtime (progn (if (and org-roam-timestamps-timestamp-parent-file ...) (progn ...)) (if org-roam-timestamps-remember-timestamps nil (org-roam-timestamps--remove-current-mtime node)) (org-roam-timestamps--add-mtime mtime)) (org-roam-add-property (org-roam-timestamps-decode (progn ... ...)) "mtime"))))))
  org-roam-timestamps--on-save()
  run-hooks(after-save-hook)
  basic-save-buffer(nil)
  save-buffer()
  org-capture-finalize(nil)
  funcall-interactively(org-capture-finalize nil)
  call-interactively(org-capture-finalize nil nil)
  command-execute(org-capture-finalize)

Trouble with saving nodes created with capture templates.

Using the default org-roam-capture-templates and calling org-roam-node-find, an org capture buffer is opened, but is not yet saved to a file. On saving (save-buffer) or finishing the capture (C-c C-c), org-roam-timestamps--on-save is called but encounters problems.

I get "( wrong-type-argument number-or-marker-p nil)" as for #7, and this is in org-roam-timestamps--add-ctime.

The buffer registers as an org-roam buffer, but the org-roam-node-at-point returns a fairly empty struct with only :id and :point set. When org-roam-timestamps--add-ctime, we don’t have a level so the check (= 0 level) errors out.

Is this a problem with org-roam (should we have more info for the current node already?) or org-roam-timestamps assuming that this information should be available when it is not?

Support using the id as the ctime

I saw Nobiot doing this in some post on the discourse, and this sounds like a much better way to to accomplish the same thing as creating new properties.

Upsides:

  1. id is much more easily accessible than the properties using queries
  2. declutters the properties drawer from at least 3 to just 2 entries at minimum
  3. makes the id less ugly and more semantic

Downsides:

  1. Would need to edit all links in all files in order to make this work
  2. would need to put in some check which checks whether the id is some sort of date string to use as the ctime

I think this is worth it.

org-roam-timestamp-mode is modifying the file after save, leaving the buffer dirty

More or less what it says on the tin. I set up the module using this:

#+begin_src emacs-lisp :tangle packages.el
(package! org-roam-timestamps
  :recipe (:host github :repo "ThomasFKJorna/org-roam-timestamps"))
#+end_src

#+begin_src emacs-lisp
(use-package! org-roam-timestamps
  :after org-roam
  :config (org-roam-timestamps-mode))
#+end_src

Every time I write the buffer, it's immediately updated and marked dirty.

Sorting nodes according to mtime

What I'm trying to do is get a list of org-roam nodes sorted by their mtime attribute. With base org-roam I used (org-roam-node-read--completions nil #'org-roam-node-read-sort-by-file-mtime), but that only works on the file level. org-roam-timestamps keeps track of modification time with node granularity (even if it isn't perfect) so I thought I'd use that.

The above code snippet doesn't seem to use the data that org-roam-timestamps tracks. Is there a way of getting a list of org-roam-nodes that are sorted by modification time according to org-roam-timestamps?

Saving a capture buffer gives wrong behaviour, because the wrong node is found

Hi, after my report in #10 I’ve still not gotten org-roam-timestamp to always do the right thing when capturing.
As reported there, I often save the buffer before finalizing the capture (C-c C-c) and this is about what happens when invoking save-buffer in an org-roam capture buffer (although I don’t think I really get the right behaviour when doing org-capture-finalize either, will continue debugging that).

It seemed that org-roam-timestamps--on-save had trouble getting the right node. After doing some debugging with edebug (and lots of (message "pN %d" (point))) I realized that the problem is that when you do a save in an indirect buffer (which a capture buffer is) the buffer is switched to its base buffer (this happens in basic-save-buffer) and then the before-save-hooks (including org-roam-timestamps--on-save) but now (point) is wrong! This is because we are in the base buffer, which has a separate point, usually at some other node, so org-roam-timestamps--on-save gets it all wrong when invoking (org-roam-node-at-point) here.

The good thing is that I found what the problem was. The bad thing is that I don’t really have a good solution for this.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.