My goal for this week was to get fancynote "good enough" to write my daily journal with it.
I've had the journal on and off since 2018, but really clicked in place this year. The value of it exists manifests in three different ways for me:
These all make it a pretty great starting point for a writing practice in fancynote. It doesn't depend on any fancy features and it's a pretty resilient habit I already have, making it even better.
By actually using this program for something I'll be able to discover what kinds of things it needs to support way more quickly than just theorizing about what I could do with it.
Pretty minimal eh? But, writing even this minimal UI has illuminated half a dozen different things I need to tackle ASAP that will make a big difference to my quality of life.
I had to debug a view today, which meant lots of making changes to the code, and then making one-character edits to a note to create a new event for a view to process. I could do this by versioning views and rebuilding every time the version increases, but this would get pretty frustrating in development. Instead perhaps I can implement a debug mode which triggers rebuilding a view every time the app starts, or add a function that I can call that does so.
As you can see in the screenshot, notes have names! This is something that would be table-stakes in pretty much any other environment, but because I'm trying to put all data in notes and extract it with a view, this is something I have to implement explicitly.
Luckily, doing so doesn't take too much code! The names view looks like this:
const NameView = {id: "names",update: (kv:KV<Data>) => async (event:Event)=>{let id = event.type === 'create' ? event.id : event.parentlet names = filter(parser(event.content), (item) => {if(item.type === 'atom') return falsereturn item.children[0].type === 'atom'&& item.children[0].value === '#'})if(names[0] && names[0].type === 'list') {kv.set(id, astToString(names[0].children.slice(1)))}},query: (kv:KV<Data>) => async (q: number) =>{return await kv.get(q)}}
I'm actually pretty happy with the API here. I use the parser I built for the fancynote syntax, and then filter out headers. And Then I can easily set and retrieve the values I want to! It's nice to see the views infrastructure pan out :D.
For example, "fetch all notes and then fetch their titles". This touches two different views (the all notes view and the names view I made today), but I only have reactive queries on a single view at a time. Right now I just do the all-notes query and then fetch the names of each note in a non reactive way. You can easily get around this with the component model with React, so it's not a pressing issue though!
One of the effects of making your own tooling is that you get emotionally attached to it. If I'm spending all this time thinking about it, and fixing the problems with it, I'm going to care about it! Using it or not using it has actual consequences. This is very different from trying out some productivity tool for a minute. Perhaps that's why #roamcult is so successful.
A post on Alexey Guzey's forum, "This productivity advice won’t help you but you should read it anyway" 1 touches on this idea. He spent months trying various productivity methods and arrived at very particular system of subtracting minutes of unproductive work from 30 minute chunks of time.
this system works absolute wonders. I also spent a lot of time making sure I actually care about this sheet and about focus minutes (which took a ton of effort) and the combination of really caring about them + usually being able to notice whenever I get distracted means I’m fully focused on work like 80% of dirty working time
My theory is making a tool yourself, and then making a process yourself, is a really good way to bootstrap really caring.
Both those things are really hard to do! At least both of those are really hard to do from scratch. The latter is a little easier as folks are always writing about their processes for you to get inspired by, but the former requires writing your own software, which is, um, non-trivial.
An interesting solution here is the new category of Roam inspired note-taking tools that exist as text-editor extensions, instead of standalone apps. Org-roam and Foam are the two big ones I know of. They're a curated collections of packages that approximate a specific notetaking experience on top of editors (VSCode and Emacs) that support a huge diversity of packages.
They're more starting points than experiences, and you can always tweak their settings or install other packages to make the tool and process your own.
Maybe one view on this is that most software is like a restaurant: you pay for the final end product. But Foam is more like a recipe than a final dish. A recipe tells you a good combination of ingredients, and you get to make the food yourself, substituting ingredients to your liking along the way. We all realize recipes are valuable. It’s easier to cook from a recipe than to make up a dish from scratch, even if you end up making tweaks.
Foam: Software as Curation by @geoffreylitt
I had a conversation with Celine a while ago about the sad lack of really good recipe management tools so maybe the recipe metaphor does not bode well here 😅.
Nevertheless package management is I think a really promising area for exploration here! I'm probably not going to get to implementing anything in this area til the core of fancynote is more stable but it's a really enticing problem. There's lots of ideas to steal from package management for developers (like type based searching with Hoogle for example), and lots of room for improvement by focusing on the end-user experience!
Because I'm planning to actually use fancynote this week I don't have too much of an agenda for what I'm going to be working on. The plan is to see what irks me the most and then dive into that. It's a different approach, but I'm excited to see how it goes. Nothing quite like frustration driven development.
I'll see you next week to relay my woes!
subscribe for updates