Setting up a sync client for org notes
I use Get Things Done (GTD) to organise my notes. It is a very popular method amongst Emacs users as it works well with Org captures. However, I used to run into a simple issue: synchronisation between my work machines. By combining a few small utilities, I implemented a Linux-minded sync client for my notes.
Getting things doen
I am not a good follower of productivity methods but I liked GTD for its simplicity. I am not following the whole thing but adding bits of it in my day-to-day work – in a similar way I learned Emacs. The core ideas of GTD are:
- When you think of something to do, determine how long it would take. If it takes less than 2 min., do it now. Otherwise make a task.
- Tasks are not just notes; they are actions. For example, don’t write down: “Look into different search methods;” but: “Compare methods x/y/z.” For large tasks, you will create projects.
- You then need to review your notes regularly and either update them, file them or trash them.
My setup
I organise my notes into four files:
inbox.org
where all my note taking goes by default.gtd.org
which contains my projects, the things I am currently doing.tickler.org
for organising time-definite things – usually meeting agendas.someday.org
which is the repository of the things I want to do but I am not working on right now.
What lead me to GTD is I can configure Emacs with Org capture templates to seamlessly take notes. Org captures are a key sequence which will open a frame in which you can write and will then be refiled to the appropriate file. You can call up a capture with C-c C-c
, which opens a menu in which your capture templates are listed. You can then save with C-c C-c
or abort with C-c C-k
.
Org templates define a structure for different note taking functions, I use three:
TODO: To keep track of tasks I want to action, I add a timestamp to remember how long ago I said I was going to do it.
("t" "Todo [inbox]" entry (file+headline "~/gtd/inbox.org" "Tasks") "* TODO %i%? %t")
Tickler: I add a deadline to the task and save it directly in the appropriate file.
("T" "Tickler" entry (file+headline "~/gtd/tickler.org" "Tickler") "* %i%? \nSCHEDULED: %^t\n")
Note: For things I just want to keep track of. (I may need a better system at some point.)
("n" "Note [inbox]" entry (file+headline "~/gtd/inbox.org" "Tasks") "* %i%?")
Sync client
The issue I have is I have two offices and sometime work from home. This means at least three computers, all with their own versions of my work.
I use Git extensively for versioning my code and writing papers. This already gets me into trouble as I regularly forget to push
. But, for code projects, I can always merge them back later.
My notes have slightly different requirements: I never work on two computers at once; revisions make little sense – and are messy; I want to keep the “stress-free” premise of GTD. Git was not cutting it in this case.
I came across this post a while back, and it looks like the solution to my problems. In it, the author implements a Dropbox-like sync client using Linux utilities:
entr
to watch a folder and run a command when it is modified.rclone
to sync files with the cloud.systemd
to run their combination as a daemon using async-client.service
file.
Why this post?
Well, the whole idea of the setup presented above is that it works for a single machine. I need to sync across multiple machines. I turn off or at least suspend my computer when I leave work, so that is a good hook. I need to add the following to the service file:
ExecStartPre
Before starting the daemon, I want to sync my local copy with the remote one, which is the up-to-date one.Type=simple
Because mysystemd
was complaining.Wants/After=network
This service needs the network to be active, and is started after the network connects.
Because I need two-way sync, I wrote a quick bash utility which runs the sync down on boot – so my files get synced with the remote. Then it runs the entr
and rclone
combo so my local changes are uploaded immediately.
Setting up a sync service
To set up the sync service, I will create two files:
- A bash script that runs the
entr/rclone
commands. - A
systemd
service file that will run at startup.
The first file is a simple utility to which I can pass arguments to decide which action to do. I have four:
test
to check what files will be synchronised.once
to upload my local directory to the cloud.start
to pull the cloud version onto my local machine.- Without arguments, this runs
entr
which will watch the files in my GTD directory.
The service file will simply run <sync scrip> start
at startup – more precisely after the network connects. Then it will run <sync script>
to watch the GTD directory. And that’s it.
Installing a sync’d GTD directory
I have created a blank project online, though it would be better to integrate the scripts to your existing workflow. You need to clone it into your home folder.
At this point, delete the .git
folder – unless you want to sync across git too. Make the bash script executable:
$ chmod +x org-gtd-sync.sh
Assuming you have created your org-drive
using rclone
, you will want to create your remote GTD directory:
$ ./org-gtd-sync.sh once
Finally, you need to activate the service:
$ cp org-gtd-sync.service ~/.config/systemd/user/
$ systemctl --user enable org-gtd-sync.service
$ systemctl --user start org-gtd-sync.service
Caveats
If you want to add files to the watched folder (happened to me with the .org_archive
), you need to upload them to the cloud folder. Otherwise, they will get deleted every time the service loads.
The test
parameter in the script is wonky. Realistically, I should build the sync function in a single place so test
would make actual sense.
If you only care about your active notes, you could filter only the org files:
19 find "$ORG_DIR" -name "*.org" | entr -r rclone sync "$ORG_DIR" "$REMOTE:$ORG_REMOTE_DIR"
I might actually do that now that I have a separate repo with the code.
Final words
I hope this benefits someone, flick me an email if something goes wrong – though you should check you distro’s docs first. I always find it a pleasant experience to create something out of “do-one-thing-well-tools.” I have been sticking with this setup for quite a while now, with some modicum of success.
$ wc -l gtd/*
225 gtd/gtd.org
957 gtd/gtd.org_archive
51 gtd/inbox.org
507 gtd/inbox.org_archive
16 gtd/org-gtd-sync.service
21 gtd/org-gtd-sync.sh
642 gtd/someday.org
285 gtd/someday.org_archive
7 gtd/tickler.org
241 gtd/tickler.org_archive
2954 total