jrnl
A simple tool to maintain a journal/diary completely in CLI!
The github repository, which houses the source code for both the tool and this page.
Some roughly made documentation for the code. Not great/reliable. Mainly made for my own needs later on.
A sample video showing most of the functionalities of this tool with a dummy input
Template | Example
|
jrnl_folder | jrnl_folder
'- YYYY | '- 2025
| '- YYYY_MM.md | | '- 2025_01.md
| '- YYYY_MM.md | | '- 2025_02.md
'- YYYY | '- 2026
| '- YYYY_MM.md | | '- 2026_01.md
| '- YYYY_MM.md | | '- 2026_02.md
jrnl
with no flags opens the current day's entry in your text editor.
Automatically fills in the date - weekday and time is configurable.
Template | Example
|
### WEEKDAY (HH:MM:SS) | ### FRI (13:05:28)
# YYYY-MM-DD | # 2025-03-28
- [tag] entry | - [milestone] [game] Played and won 200th game of chess.
- entry | - Cleaned up room.
- [tag1] [tag2] entry | - [fees] Paid electricity bill.
╭───────────────┬──────────────────────────────────────────╮
│ Date of Entry ┆ Record │
╞═══════════════╪══════════════════════════════════════════╡
│ 2025-03-31 ┆ [tag_1] Stuff │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ 2025-03-29 ┆ [tag_1] Some more │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
│ 2025-03-28 ┆ [tag_1] Other things │
╰───────────────┴──────────────────────────────────────────╯
March 2025
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
(Note: Here, the colors cannot be shown, so you'll have to trust this.)
food
is pre-defined. Input your daily food intake as:
- [food] Breakfast | Lunch | Dinner | Other
- [food] some breakfast item | A lunch item - course 1 A lunch item - course 2 A lunch item - course 3 | A filling dinner. A tasty dinner. | Snack - Chips Fruit - Mango
When fetching the tag through `--tag food`, you get a nice ascii table(along with a calendar - not shown here):
╭───────────────┬─────────────────────┬─────────────────────────┬───────────────────┬────────────────╮
│ Date of Entry ┆ Breakfast ┆ Lunch ┆ Dinner ┆ Other │
╞═══════════════╪═════════════════════╪═════════════════════════╪═══════════════════╪════════════════╡
│ 2025-03-27 ┆ some breakfast item ┆ A lunch item - course 1 ┆ A filling dinner. ┆ Snack - Chips │
│ ┆ ┆ A lunch item - course 2 ┆ A tasty dinner. ┆ Fruit - Mango │
│ ┆ ┆ A lunch item - course 3 ┆ ┆ │
╰───────────────┴─────────────────────┴─────────────────────────┴───────────────────┴────────────────╯
--entry YYYY-MM-DD
(-e YYYY-MM-DD
), or if you just pass an empty flag(-e
), an interactive calendar will prompt for the
date(Using [inquire](https://github.com/mikaelmello/inquire)). The calendar will also open if there is any
problem with reading the date.--year YYYY
(-y YYYY
) or --month MM
(-m MM
). If only provided with a year, and no month, all files
of that year will be searched through and printed chronologically.(The pager comes in use here)This is a quite detailed explanation of what I made this tool for and how to use it to get the most out of it
Once installed, run jrnl -V
. You should get the version printed out.
The next step is to add the configuration file. Copy the config.toml
file into ~/.config/jrnl/config.toml
, and read it. It contains all the currently possible configuration options. All their details are given in comments. Make suitable changes.
Then run jrnl -h
. If no errors appear, great! You are set to go. If some error appears(most likely configuration errors), then read the error message and make appropriate corrections.
jrnl
doesn't make any folder for you. This is to avoid accidental creations of a lot of directories.
Hence, you will have to create the folders yourself. The files, however, are generated by the code.
Say your default_path
is set to ~
. Go to this directory(~
), and make a
folder named jrnl_folder
. All of your main journal or diary entries will live here. Go into this
folder(you should now be at ~/jrnl_folder
). Make a folder whose name is the current year as YYYY
, for instance, at the moment of writing this, it is April 2025, so the folder name would be 2025
. Now go back
to ~
, and run jrnl
. A new file ~/jrnl_folder/2025/2025_04.md
will have been created, and that file will be opened in your specified editor, with the date(and weekday and
time if configured). You can now directly enter your entry.
Each entry is preferably supposed to be in this format:
- [tag1] [tag2] [tag3] Your entry here.
Some points to note from this:
-
, which indicates(in markdown) that it is an unordered list.food
You can create any name for the tags, except for food
, because it has pre-defined behaviour.
The `food` tag is to be entered as follows:
- [food] Breakfast | Lunch | Dinner | Other
// Example
- [food] some breakfast item | A lunch item | A filling dinner. A tasty dinner. | Snacks
This is so that, later, when you use the --tag
flag to fetch all instances of that tag, if you use food
, you'll
get a nice table as can be seen here.
Make a file called events.md
in your jrnl_folder
. Here, you can store all your events
in a specific format, and when you run --gen-report
, it shows you the upcoming events, and the
recently completed ones, with highlighting.
The format to be followed is:
- [MM-DD] Information about the event
// Example
- [04-25] Person A's birthday.
Any lines not starting with -
will be ignored, so this can be used to add comments if required.
If any error occurs in parsing the date, an Error with the line number will be shown so you can correct it.
You can also open the events file from anywhere using jrnl --open e
. Here, e
is hardcoded
to mean the events.md
file. This means you cannot create a file named e
, but can create
a file named e.txt
. This is simply for ease of input.
jrnl YYYY-MM-DD #OR
jrnl #Opens today's entry
By default, if you just run jrnl
, then the current date(today's date) will be considered. If you want
the interactive calendar to show, then you can use jrnl c
This will open an interactive
calendar, from which you can select the date.
--entry
or -e
This flag is used to fetch any given day's entry if it exists. General usage:
jrnl --entry YYYY-MM-DD
where YYYY-MM-DD
is the date of the entry which you are trying to fetch.
YYYY-MM-DD
) everytime, if you just pass an empty flag,
i.e. jrnl --entry
you will get an interactive calendar from which you can select the date required.
--tag
or -t
jrnl --tag "tag_name" --year YYYY --month MM # OR
jrnl -t "tag_name" -y YYYY -m MM
Here, "tag_name" is the name of the tag you are searching for. If it doesn't exist, you will get a message
saying so. You can also provide the year/month to specify which date range to search from.
By default, the current month's file is considered. If you pass only --year
or -y
flag, you
will get all the results from the provided year. If you just pass the flag with no YYYY
, then the current
year's files will be searched.
jrnl -t tag_1 -m 3 # The current year is 2025, and current month is April
This will result(provided the entries exist) in this.
--search
or -s
--approx
or -a
flag along with this, to search for similar words.
General usage:
jrnl --search "word" --year YYYY --month MM --approx *sensitivity*
Here, the "word" can be any string to be searched for. The provision of year and month works the same as it did for
the tags.
You can provide the --approx
or -a
flag, which also searches for words similar to the one
provided. You can pass a number which denotes the sensitivity of the search. 1
corresponds to allowing 1
character difference, 2
allows two characters differnce, and so on. If you pass just the flag
-a
, the default sensitivity which you have provided in the config.toml
file will be used.
--gen-report
STDOUT
). General
usage: jrnl --gen-report --year YYYY --month MM
By default(i.e. if you provide no -y
or -m
flags), the current month's file is considered.
It will print out(in a nice format), the number of entries in the provided month, and a table of n of the most
used tags and their frequencies, along with a calendar(or a couple of them) representing which all days you wrote the
entries. Here, n is the corresponding number provided in the config.toml
file.
If a year is passed, without any month, then the report is generated for the provided year(if not provided, then
it defaults to the current year).
This also prints the upcoming and recently completed events. (Refer this)
--open-config
~/.config/jrnl/config.toml
in your
provided text editor.
--path
or -p
jrnl
s. If you run jrnl
from any directory,
the default jrnl_folder
will be opened(which is configured). To use another jrnl_folder
(as is
done in the video demo), you can use this flag. General usage:
jrnl --path "path" *any other flags here*
Here, if you provide the "path", it will use that. If you don't, it will search for jrnl_folder
in
the current directory.
--print-config
CONFIGURATION
╭──────────────────────────────┬─────────╮
│ Quantities ┆ Value │
╞══════════════════════════════╪═════════╡
│ Add Weekday ┆ true │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
│ Add Food Column ┆ true │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
│ Add timestamp ┆ true │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
│ Default Editor ┆ hx │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
│ Default Pager ┆ bat │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
│ Max rows to display for tags ┆ 5 │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
│ When to use pager ┆ default │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
│ Default path ┆ ~ │
├╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┼╌╌╌╌╌╌╌╌╌┤
│ Approximation sensitivity ┆ 1 │
╰──────────────────────────────┴─────────╯
--open
jrnl_folder
.
This is so that you can add some notes or whatever. Usage:
jrnl --open "filename"
# Example
jrnl --open events.md
To use the events functionality, refer this.
chrono
: For date and time purposes.clap
: For CLI arguments.colored
: For colored messages.inquire
: To interactively get the date(of entry to be fetched) from the user.pager
: To page long outputs.comfy-table
: To print tables.toml
: To parse the configuration file.serde
: For use in toml
and clap
.term_size
: To get the terminal width, to be able to wrap tables and calendars accordingly.stringmetrics
: For approximate word searching.shellexpand
: To expand the ~
(tilde) in paths.parse_datetime
: To convert human-readable time to exact dates.Last Edited: