(That said, yes, it's a nice journaling system)
nix shell 'git+https://tangled.sh/@oppi.li/journal'
It's massive overkill for a shell alias, but for a more complex project it can be very nice.
When I first started reading I thought, why not use Vimwiki or org?
Iβve use vimwiki for years but I really like the approach taken here. Itβs simple and robust.
Making use of Vimβs built in abbreviations and syntax highlighting is a neat touch.
I've never found organizing notes purely by calendar dates to be ideal - I rarely think "didn't we discuss load testing with Bob sometime last October?" Instead, when I tag Bob and add a 'Load Testing' tag to my note, which automatically gets filed in Org-mode's date-tree outline, I can always find it - whether through Bob, 'Load Testing', or the date itself..
And because just like in the article - the notes are in plain text, it opens possibilities for easy syncing, version control & backup, and any other automations. Add to that a tons of other features like having executable source blocks where you can pipe data through, or pdf annotations, LaTeX embeddings, incredible LLM integration, spreadsheet-like calculations, publishing machinery, etc.. There's simply no better alternative - for me, if it ain't the pen&paper - it has to be in Org-mode. And I too, tried tons of different approaches before finding Org-mode.
If getting into Emacs and Org-mode feels too much for you right now, still, do yourself a favor, read this book - "How to take smart notes", ISBN-10: 1542866502.
$ ncal -w3
July 2025 August 2025 September 2025
Mo 7 14 21 28 4 11 18 25 1 8 15 22 29
Tu 1 8 15 22 29 5 12 19 26 2 9 16 23 30
We 2 9 16 23 30 6 13 20 27 3 10 17 24
Th 3 10 17 24 31 7 14 21 28 4 11 18 25
Fr 4 11 18 25 1 8 15 22 29 5 12 19 26
Sa 5 12 19 26 2 9 16 23 30 6 13 20 27
Su 6 13 20 27 3 10 17 24 31 7 14 21 28
27 28 29 30 31 31 32 33 34 35 36 37 38 39 40
I made a dedicated email account just for the journal. I personally chose gmail but if you distrust google you could use any other provider including self-hosted.
At the end of the day, or when I feel like it, I log in and email the account from itself with a message about whatever happened that day and whatever I'm thinking or feeling, and use the date for the subject line, like "August 12, 2025". I never, ever send emails to anything else from that account nor connect it to anything or use it for anything else. It is a total island.
The result is 17 years of easily-searchable journal, password-protected, backed-up, accessible from anywhere that has internet, can't be "lost" like a physical journal (yes I know I'm trusting google, but again, go self-host if you're worried about that), can't be "found" by someone looking through my things.
I can't even tell you how much value I've gotten out of it. You forget things you don't even know you forgot. So many little moments and days in life. You'll be shocked at the things you used to think and feel sometimes. You'll be shocked at whole magical days that you haven't thought of in years and years and likely would never have thought of again. It's a record of me changing over time and the phases I've gone through. I can't recommend it enough.
And it doesn't take much discipline, either. It's not something I "have" to do. I do it when I feel like it. There are years where I have only 25 entries, and others where I have 200. It depends how much I felt like writing. I find it spikes in years where I'm feeling very emotional, usually during bad times. But I've written down many great days too.
I guess this does ensure the key `journal` command works exactly the same because the dateutils binary will stay locked to the version in the `flake.lock`.
I would have assumed that nvim would also be locked because that's where I would expect more possible breaking changes with the existing special config.
With little tools/projects like these I could easily see months-years before it would get any active attention from me again (or simply I wouldn't be using it; so it doesn't matter).
w| Mo Tu We Th Fr Sa Su
31| 1 2 3
32| 4 5 6 7 8 9 10
Perhaps worth noting that ncal's -w is ISO-8601 compliantΒΉ, which may surprise some people around new year as week numbers can reset in December or January.[Said as someone who aliases cal to "ncal -wb" mostly just to get the correct first day of the week for their locale.]
Honest answer though, it's a deterministic way of building up a computer/environment. Think pip/uv/packages.lock but for everything.
You could then just open nvim in the `nix develop` environment (or even use something like direnv to activate it when you cd in) and have a minimal journaling environment
Then, while reading some productivity book, I stumbled on a trick: set the bar for success absurdly low. So low that even on my worst days I could still clear it.
Enter The One-Line Journal: the goal is to write just one single line each day. And, as it turns out, most days that first sentence is quickly followed by a few more β sometimes a lot more. Iβve been doing it almost every single day for 2.5 years now.
In the spirit of keeping the barrier low, I deliberately start with a blank slate each morning by creating a new file for that day. The fresh page lowers the threshold even further. Everything is done in Vim with this little alias:
oneline='printf "## $(date +"%Y") \n \n#" >> /path/to/folder/year/$( date +"%Y-%j-%b-%d" )_ol-jrnl.md && vim +$ /path/to/folder/year/$( date +"%Y-%j-%b-%d")_ol-jrnl.md'
Nothing fancy. Just works for me.
If I realize I forgot something from yesterday, I just add it the next day.
What kind of "tweaks" are you doing? You could use `nix-shell` to try out a new environment. If you like it the environment, you can make it declarative by creating a `shell.nix` file.
If you want to go further, you might make consider making a flake, but I would recommend reading https://nix.dev/concepts/flakes.html first.
With Nix, "dev environment" can be scoped to be specific to a project. Where on a typical system, you might install a compiler & libraries, with Nix you can describe the development environment in isolation. (Dev Containers uses containers to similar effect).
I'd rephrase your comment as: NixOS is anti-practical. Rather than just changing a config (& restarting a service), you have to change a NixOS config, rebuild that, & switch to the updated config. -- I'd say NixOS (and Nix) support the mindset of "put in all the effort up front now, in order to save effort later".
If someone's written a nix-shell or devenv file for a project, then no further effort is required to get a working dev environment setup. (Devenv is notable for nicer DX over docker-compose for things like "services.postgres.enable = true" to get a working DB).
Shell scripting by default has terrible isolation. But the way Nix puts shell scripts together, you can be confident that a script's own PATH only contains what it needs to, which is a nice guarantee to have.
I take it from your post that it is no more?
In my case I wanted to get back into working out more but the pandemic had completely messed up my existing workout routines, plus I travel a lot, so it's not easy to build new habits, either. So I decided I would just do one single exercise every day β doesn't matter when or what, as long as I do something.
I ended up doing the exercise usually right after getting up in the morning to build as strong a habit as possible. Also, I usually do 4 minutes instead of a fixed number of reps because 1) this way I can fully focus on perfecting the movement, 2) when it's early in the morning I often forget to count anyway, 3) this way I always know how long it's gonna take, so even on busy days I can make time.
Then once I had mastered that habit, I decided hey, why not try to do two exercises per day whenever possible? It's only 5 minutes more (including a 1 min break) but 100% more impact!
Now, recently, I've started doing 3-4 exercises because why not, it's only 5-10 minutes more for another 50-100% increase in gains! I think this β (up to) 20 min every morning β is probably my sweet spot. I get a decent workout, yet I can still squeeze it even into the busiest of days with relative ease, as long as I've made it a habit and don't waste time thinking about & hesitating to do it and instead just do it.
For journal entries I record voice notes. I can do it quicker, and I can do it while I'm e.g. driving or walking. I feel that I capture a bit more emotion with it too. I've been doing this for about 20 years, but only in the last year have I been writing a python application to organize and transcribe the notes.
Likewise I found getting myself to run a mile regularly was not happening. So I reduced it to running half a mile. That's pretty doable. That's 5 minutes of effort.
I do it with my coding projects. If I can't bring myself to really seriously spend hours progressing on my code, I'll do the absolute bare minimum just to move the needle forward a millimeter - write a boilerplate react component template that isn't much more than a div with the right class on it, or write the skeleton for an endpoint (like its function signature) but none of the actual logic, or simply write out a quick pseudocode of the steps for what i need to do the next time i work on it.
I do it with chores. Can't get myself to do laundry? Ok, instead just move the laundry to be sitting next to the basement door. Next time I go down for something else, I just take it with me and stick it in the machine since it was already right there. Same with dishes - don't want to do all of them - ok, just load the plates for now and leave the rest for later.
I do it with mail that requires a response, like bills. Don't want to go through all of them? Just do the one on top and do another tomorrow. (I don't get enough mail that it piles up faster than I can keep up with.)
I do it with guitar. Don't want to practice for half an hour? Okay, just do chord switching for 3 or 4 minutes.
When I describe it all this way, it makes me sound like someone who barely gets anything done, but the reality is I actually get A LOT done because of these tricks. Once I'm playing guitar for 3 minutes it usually becomes 30. Once I pseudocode a function I usually just write the whole thing. Once I put away the plates I usually just clear the whole sink. And if it gets put off for a day, that's fine. It's all about tricking myself into being disciplined.
- buy milk
- call doctor - shoulder
- call mechanic - head gasket
The terseness helps me review them quickly. And being able to review them quickly enables me to do them quickly.However, I only recommend it with the caveat that the practical benefits are not worth the time invested and it's only worth it as a fun hobby. I think an immutable desktop like Silverblue/Bazzite is really the sweet spot.
Nix (non-OS) as a way to define dev environments though? Incredible, would recommend it in a heartbeat. Opening a project and knowing you are going to have the exact versions of all dependencies you need is so refreshing, or seeing that a public git repo has a `flake.nix` and being able to `nix run <url>` and download/build the project in one command is truly magic.
- My basic nix-darwin and home-manager setup for my laptop
- Declarative tooling install for my clone of an open source Rust project
- LaTeX setup for my notes for a book club, including creating a nix package inside the flake to install the version of Garamond I wanted. Traditionally, installing LaTeX and non-free-fonts involves running a bunch of commands as root and praying. This is way better.
It took a lot of prodding and telling it things like "you'll know you did it right when `make all` works", but they all ended up working exactly how I wanted them to.
Besides, Nix is even better for such breakages. If GCC breaks you packages, the system does not build and never gets into broken state, all the while old system remains available and kicking.
Ξ» ls journal/
2022/ 2023/
Ξ» ls journal/2023/
01 02 03 04 05 06 07 08 09 10 11 12
Ξ» vim journal/2023/1
:read !cal -m
Ξ» cat journal/2023/01
January 2023
Mo Tu We Th Fr Sa Su
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
January 2023
Mo Tu We Th Fr Sa Su
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
week 1
done apply leaves
done dload boarding pass
moved reply to dan
week 2
todo reply to dan
todo pack bags
done travel insurance
todo weigh luggage
week 1
todo apply leaves
done dload boarding pass
todo reply to dan
event fr trip
note weight 68.6
:iabbrev todo Β·
:iabbrev done Γ
todo apply leaves
Β· apply leaves
-
for noteo
for event>
for moved.vip " line-wise select inner paragraph
:'<,'>sort " the markers '< and '> are automatically inserted,
" they mark the start and end of the selection
week 1
Β· apply leaves
Β· reply to dan
Γ dload boarding pass
:set formatprg=sort\ -V
:syntax match JournalAll /.*/ " captures the entire buffer
:syntax match JournalDone /^Γ.*/ " lines containing 'done' items: Γ
:syntax match JournalTodo /^Β·.*/ " lines containing 'todo' items: Β·
:syntax match JournalEvent /^o.*/ " lines containing 'event' items: o
:syntax match JournalNote /^- .*/ " lines containing 'note' items: -
:syntax match JournalMoved /^>.*/ " lines containing 'moved' items: >
:highlight JournalAll ctermfg=12 " bright black
:highlight JournalDone ctermfg=12 " bright black
:highlight JournalEvent ctermfg=6 " cyan
:highlight JournalMoved ctermfg=5 " magenta
:highlight JournalNote ctermfg=3 " yellow
week 1 --------------
Γ wake up on time
Γ water the plants
spend 7.5 7 10
---------------------
week 2 --------------
Β· make the bed
Β· go to bed
spend 30 2.75 6
---------------------
BEGIN {spend=0;}
/spend/ {for(i=1;i<=$NF;i++) spend+=$i;}
END { printf spend "eur"}
Ξ» awk -f spend.awk journal/2023/01
63.25eur
Ξ» vim -O journal/2023/0{1,2,3}
JANUARY ------------ β FEBRUARY ----------- β MARCH --------------
β β
Mo Tu We Th Fr Sa Su β Mo Tu We Th Fr Sa Su β Mo Tu We Th Fr Sa Su
1 β 1 2 3 4 5 β 1 2 3 4 5
2 3 4 5 6 7 8 β 6 7 8 9 10 11 12 β 6 7 8 9 10 11 12
9 10 11 12 13 14 15 β 13 14 15 16 17 18 19 β 13 14 15 16 17 18 19
16 17 18 19 20 21 22 β 20 21 22 23 24 25 26 β 20 21 22 23 24 25 26
23 24 25 26 27 28 29 β 27 28 β 27 28 29 30 31
30 31 β β
β β
β β
WEEK 1 ------------- β WEEK 1 ------------- β WEEK 1 -------------
β β
> latex setup β > forex β - weight: 64
Γ make the bed β Γ clean shoes β > close sg-pr
Γ 03: dentist β Γ buy clothes β Γ facewash
Γ integrate tsg β Γ draw β Γ groceries
β β
β β
WEEK 2 ------------- β WEEK 2 ------------- β WEEK 2 -------------
β β
Γ latex setup β - viral fever β > close sg-pr
Γ send invoice β Γ forex β Γ plan meet
Γ stack-graph pr β Γ activate sim β Γ sg storage
β Γ bitlbee β
Ξ» vim $(date +"%Y/%m")
Ξ» vim -O 2023/10 2023/11 2023/12 2024/01 2024/02
Ξ» dateseq 2012-02-01 2012-03-01
2012-02-01
2012-02-02
2012-02-03
...
2012-02-28
2012-02-29
2012-03-01
Ξ» vim -O $(
dateseq \
"$(date --date "2 months ago" +%Y/%m)" \
"$(date --date "2 months" +%Y/%m)" \
-i %Y/%m \
-f %Y/%m
)
Ξ» nix develop
Ξ» cd examples
Ξ» journal