A minimalist command-line journaling system for tracking daily activities, metrics, and insights.
Chronicle is a lightweight tool that helps you systematically log and analyze your daily life using simple, human-readable text files. It emphasizes privacy by storing all data locally while maintaining flexibility in how you record and review your information.
- Chronicle uses a simple text format: you can use any text editor with
our
.chrfile format. - It is privacy-first: all data stored locally on your machine.
- You can track multiple metrics:
- daily activities and events,
- health and fitness metrics,
- tasks and goals,
- sleep patterns,
- custom metrics.
- Chronicle allows you to generate insights: analyze patterns and create summaries.
.chrfiles have a flexible syntax: intuitive format for quick entries.
Chronicle uses plain text files with the .chr extension. The syntax is
designed to be both human-readable and machine-parseable.
Each line in the file is a separate record, that can be an event (or a task), an object definition, a special command, or a comment.
Events are activities that have occurred, while tasks are planned future events.
-- Comments start with `--`.
-- Completed events.
podcast @inner_french e147 00:00/45:00
19:00/19:30 run 5.2km
-- Tasks (prefixed with [ ] or [x]).
[x] do the dishes
[ ] clean @bathroom
-- Future events (prefixed with >>>).
>>> 20:00/ concert @radioheadDefine reusable objects to simplify your entries:
podcast @innerfrench = Inner French Podcast .fr
book @dune = Dune by Frank HerbertDate entries help organize your journal chronologically:
2024-01-01 -- Sets the current date.
book @dune = Dune by Frank Herbert .en /fiction 896p
podcast @inner_french = Inner French Podcast .fr
2000-01-01
00:00/08:00 sleep
09:00/09:30 run 5.2km
read @dune 120/140p
podcast @inner_french e50 45:00
>>> 20:00/ concert Radiohead
[x] buy milk
[ ] pay for internet 15usd
Objects:
- Book Dune by Frank Herbert, 896 pages, in English, fiction.
- Podcast Inner French Podcast in French.
1 January 2000.
- Events:
- 00:00—08:00 Sleep.
- 09:00—09:30 Run 5.2 km.
- Read Dune from page 120 to 140.
- Listen to Inner French Podcast episode 50 for 45 minutes.
- Planned:
- 20:00 Concert Radiohead.
- Tasks:
- Buy milk.
- Pay for internet $15.
chronicle --input <files> view [--style <style>] [--colors light|dark|no] <subcommand>chronicle --input <files> view language \
[--form table|plot] \
[--file <output file>] \
[--period day|week|month|year] \
[--smooth <days>] \
[--interval <days>] \
[--plot-type fill|stack|bar|percent] \
[--margin <hours>] \
[--exclude-languages <lang> ...] \
[--services <service> ...] \
[--cumulative]chronicle --input <files> view travel [--svg-output <file>]chronicle --input <files> view books [--year <year>] [--title <title>] [--finished]chronicle --input <files> view podcasts [--title <title>]chronicle --input <files> view sportchronicle --input <files> view objects| Command | Description |
|---|---|
timeline |
Print the full timeline. |
summary |
Print a summary of all events. |
shows |
Show TV show progress. |
movies |
List watched movies. |
expired |
Show expired tasks. |
dishes |
Show dishes log. |
objects |
List all objects. |
graph |
Build an object graph. |
interpret |
Interactive mode: read commands from stdin. |
- Python 3.12+.
pip install .For the most detailed help, run:
chronicle --helpCommon usage:
chronicle \
--input <input Chronicle files> \
<import options> \
<command>Example:
chronicle \
--input timeline.chr \
--import-wikimedia User1@en.wikipedia.org User2@wikidata.org \
--import-memrise memrise.html \
view language --form table--import-memrise: exported Memrise.htmlfiles. File can be requested at Memrise settings by "Download Personal Data" button.--import-duome: exported Duome.txtfiles.--import-wikimedia: import contributions from Wikimedia projects. Argument format is<username>@<url>, e.g.User1@en.wikipedia.orgorUser2@wikidata.org.
Chronicle can generate a Vim syntax file for .chr files that highlights event
types, object definitions, timestamps, tags, languages, and other values.
Every time chronicle runs it writes a generated syntax file to
syntax/chronicle.vim in the repository and, if ~/.vim/syntax/ exists, also
to ~/.vim/syntax/chronicle.vim. The generated file is built from the static
header syntax/chronicle_header.vim with auto-generated rules for every known
event and object type appended.
-
Associate the
.chrextension with thechroniclefiletype. Add this line to your~/.vimrcor~/.config/nvim/init.vim:au BufRead,BufNewFile *.chr set filetype=chronicle
-
Copy the pre-generated syntax file into your Vim syntax directory:
cp syntax/chronicle.vim ~/.vim/syntax/chronicle.vimAfter that, re-running
chroniclewill keep~/.vim/syntax/chronicle.vimup to date automatically.
| Element | Examples |
|---|---|
| Event and object types | sleep, run, book, podcast |
| Timestamps and dates | 2024-01-01, 09:00/09:30 |
| Object references | @inner_french |
| Languages | .fr, .en |
| Tags | !work, !every_day |
| Subjects | /fiction, /language/de |
| Intervals and durations | 10:00/45:00, 1:52:00 |
| Season and episode numbers | s2, e15 |
| URLs | https://... |
| Comments | -- ... |
| Task markers | [ ], [x] |
Chronicle provides a Lua script (scripts/chronicle.lua) for Neovim to help
manage tasks directly within your .chr files. This script adds convenient
commands and key mappings for working with tasks in your journal.
-
:ChronicleStartor Space s- Changes the event start time to the current time.
-
:ChronicleDoneor Space d- Marks the current task as done (completes the task under the cursor).
- Changes the event end time to the current time.
- If the task is recurring (e.g., contains
!every_day), it will automatically schedule the next occurrence on the appropriate date.
-
:ChroniclePauseor Space p- Marks the current task as done and creates a new identical task.
These commands are available after sourcing the script in Neovim:
:source <path to Chronicle>/scripts/chronicle.lua- Place your cursor on a task line in a
.chrfile. - Press Space d to mark it as done, or Space s to start the task.
- If the task is recurring, the script will automatically insert the next occurrence on the correct date.