Overview
Overview
jrnl is a simple journal application for the command line.
You can use it to easily create, search, and view journal entries. Journals are
stored as human-readable plain text, and can also be encrypted using AES
encryption.
jrnl has most of the features you need, and few of the ones you don't.
Plain Text
jrnl stores each journal in plain text. You can store jrnl files anywhere,
including in shared folders to keep them synchronized between devices. Journal
files are compact (thousands of entries take up less than 1 MiB) and can be read
by almost any electronic device, now and for the foreseeable future.
Tags
To make it easier to find entries later, jrnl includes support for inline tags
(the default tag symbol is @). You can find and filter entries by using tags
along with other search criteria.
Support for Multiple Journals
jrnl includes support for the creation of multiple journals, each of whichcan be stored as a single file or as a set of files. Entries are automatically
timestamped in a human-readable format that makes it easy to view multiple
entries at a time.
jrnl can easily find the entries you want so that you canread them or edit them.
Support for External Editors
jrnl plays nicely with your favorite text editor. You may prefer to write
journal entries in an editor. Or you may want to make changes that require a
more comprehensive application. jrnl can filter specific entries and pass them
to the external editor of your choice.
Encryption
jrnl includes support for AESencryption. See the
encryption page for more information.
Import and Export
jrnl makes it easy to import entries from other sources. Existing entries can
be exported in a variety of formats.
Multi-Platform Support
jrnl is compatible with most operating systems. You can download it using one
of a variety of package managers, or you can build from source.
Open-Source
jrnl is written in Python and maintained by a
friendly community of open-source software
enthusiasts.
---
Advanced
Advanced Usage
Configuration File
jrnl has a wide variety of options that can be customized through the config file,
including templates, formats, multiple journals, and more. See
the configuration file reference for details
or read on for some common use cases.
Multiple journal files
You can configure jrnlto use with multiple journals (eg.private and work) by defining more journals in your config file,
for example:
`` You can also override the default options for each individual journal. You can override all options that are present at Consider the following example configuration You can override a configuration field for the current instance of You can specify multiple overrides as multiple calls to !!! note #### Examples: yamlstdin
journals:
default: ~/journal.txt
work: ~/work.txtThe default journal gets created the first time you start jrnlwork
Now you can access the journal by using jrnl work instead ofjrnl, eg.
jrnl work at 10am: Meeting with @Steve
jrnl work -n 3will both use ~/work.txt, while jrnl -n 3 will display the last~/journal.txt
three entries from (and so does jrnl default -n 3).jrnl.yaml
If your looks like this:
encrypt: false
journals:
default: ~/journal.txt
work:
journal: ~/work.txt
encrypt: true
food: ~/my_recipes.txtYour default and your food journals won't be encrypted, however yourwork journal will!jrnl.yaml
the top level of , just make sure that at the very leastjournal: ...
you specify a key that points to the journal file of
that journal.
editor: vi -c startinsert
journals:
default: ~/journal.txt
work:
journal: ~/work.txt
encrypt: true
display_format: json
editor: code -rw
food:
display_format: markdown
journal: ~/recipes.txt The work journal is encrypted, prints to json by default, and is edited using an existing window of VSCode. Similarly, the food journal prints to markdown by default, but uses all the other defaults.jrnlModifying Configurations from the Command line
using --config-override CONFIG_KEY CONFIG_VALUE where CONFIG_KEY is a valid configuration field, specified in dot notation and CONFIG_VALUE is the (valid) desired override value. The dot notation can be used to change config keys within other keys, such as colors.title for the title key within the colors key.--config-override.
These overrides allow you to modify any field of your jrnl configuration. We trust that you know what you are doing. Create an entry using the
prompt, for rapid logging
jrnl --config-override editor ""
Populate a project's log
jrnl --config-override journals.todo "$(git rev-parse --show-toplevel)/todo.txt" todo find my towel
Pass multiple overrides
jrnl --config-override display_format fancy --config-override linewrap 20 \
--config-override colors.title green
jrnlUsing an alternate config
You can specify an alternate configuration file for the current instance of
using--config-file CONFIG_FILE_PATHwhereCONFIG_FILE_PATHis a path to an alternatejrnlconfiguration file.#### Examples:
Use personalised configuration file for personal journal entries
jrnl --config-file ~/foo/jrnl/personal-config.yaml
Use alternate configuration file for work-related entries
jrnl --config-file ~/foo/jrnl/work-config.yaml
Use default configuration file (created on first run)
jrnl
---docs/*.mdContributing
Contributing to jrnl
We welcome contributions to jrnl, whether it's through reporting bugs, improving the documentation, testing releases, engaging in discussion on features and bugs, or writing code.
Table of Contents
* Code of Conduct
* Reporting Bugs
* Editing Documentation
* Testing
* Submitting feature requests and ideas
* Developing jrnlCode of Conduct
Before starting, please read the Code of Conduct.
Reporting Bugs
Please report bugs by opening a new issue and describing it as well as possible. Many bugs are specific to a particular operating system and Python version, so please include that information!
Editing Documentation
If you find a typo or a mistake in the docs, please fix it right away and send a pull request. If you're unsure what to change but still see a problem, you can open a new issue with the "Documentation change" type.
To edit the documentation, edit the
files on the main branch. You can see the result by runningpoe docs-runinside the project's root directory, then navigating your browser to localhost:8000.mainExternal editors and tips and tricks
If you'd like to share a jrnl command line trick that you find useful, you may find it worthwhile to add it to the "Tips and Tricks" section. For advice on how to integrate a particular external editor, you can add to the "External Editors" section.
Testing
Much of the work of maintaining jrnl involves testing rather than coding.
The nature of jrnl means we deal with extremely sensitive data, and can't risk data loss. While jrnl does have a comprehensive automated testing suite, user testing is crucial to mitigating this risk.
Prereleases
Prereleases are deployed through PyPi much like normal releases. You can use pipx to fetch them and test them. See the changelog for information on what has changed with each release.
Pull requests
If you are comfortable enough with git, feel free to fetch particular pull requests, test them yourself, and report back your findings. Bonus points if you can add a screencast of how the new feature works.
Confirm bug reports
There are always open bugs among our GitHub issues and many are specific to a particular OS, Python version, or jrnl version. A simple comment like "Confirmed on jrnl v2.2, MacOS 10.15, Python 3.8.1" would be extremely helpful in tracking down bugs.
Automate tests
See the develop section below for information on how to contribute new automated tests.
Submitting feature requests and ideas
If you have a feature request or idea for jrnl, please open a new issue and describe the goal of the feature, and any relevant use cases. We'll discuss the issue with you, and decide if it's a good fit for the project.
When discussing new features, please keep in mind our design goals. jrnl strives to
do one thing well. To us, that means:* being _nimble_
* having a simple interface
* avoiding duplicating functionalityDeveloping
Getting your environment set up
You will need to install poetry to develop jrnl. It will take care of all of the project's other dependencies.
Understanding the branches
jrnl uses two primary branches:
*
- for ongoing developmentrelease
*- for releasesmainIn general, pull requests should be made on the
branch.develop#### Updating an existing clone after the
→mainrenamedevelopIf you have a clone from before the default branch was renamed from
tomain, update it with:
git checkout develop
git branch -m develop main
git fetch origin
git remote prune origin
git branch -u origin/main main
git remote set-head origin -a
If you have other local branches based ondevelop, rebase them ontomain:
git rebase --onto main develop <your-branch>
pyproject.tomlCommon development commands
You can find an inventory of commands in the
. Users can run the commands by typingpoefollowed by the name of the command (Poe the Poet can be installed on its own, or as part ofpoetry install).poetry installA typical development workflow includes:
* Installing dependencies:
*poetry shell
* Activate virtual environment:
*jrnl
* Running the source in a virtual environment:
*(with or without arguments as necessary)poe test
* Running tests:
*poe format
* Formatting the code to standardize its style:
*testsUpdating automated tests
When resolving bugs or adding new functionality, please add tests to prevent that functionality from breaking in the future. If you notice any functionality that isn't covered in the tests, feel free to submit a test-only pull request as well.
For testing, jrnl uses pytest for unit tests, and pytest-bdd for integration testing. All tests are in the
folder.*.featureMany tests can be created by only editing
files with the same format as other tests. For more complicated functionality, you may need to implement steps intests/lib/which are then executed by your tests in thefeaturefiles.jrnlSubmitting pull requests
When you're ready, feel free to submit a pull request (PR). The jrnl maintainers generally review the pull requests every two weeks, but the continuous integration pipeline will run on automated tests on it within a matter of minutes and will report back any issues it has found with your code across a variety of environments.
The pull request template contains a checklist full of housekeeping items. Please fill them out as necessary when you submit.
If a pull request contains failing tests, it probably will not be reviewed, and it definitely will not be approved. However, if you need help resolving a failing test, please mention that in your PR.
Finding things to work on
You can search the jrnl GitHub issues by label for things to work on. Here are some labels worth searching:
* critical
* help wanted
* bug
* enhancementYou can also get a feel for the project's priorities by reviewing the milestones.
A note for new programmers and programmers new to python
Although jrnl has grown quite a bit since its inception, the overall complexity (for an end-user program) is fairly low, and we hope you'll find the code easy enough to understand.
If you have a question, please don't hesitate to ask! Python is known for its welcoming community and openness to novice programmers, so feel free to fork the code and play around with it! If you create something you want to share with us, please create a pull request. We never expect pull requests to be perfect, idiomatic, instantly mergeable code. We can work through it together!
---
Encryption
Encryption
A Note on Security
While
follows best practices, total security is never possible in thejrnl
real world. There are a number of ways that people can at least partially
compromise yourdata. See the Privacy and Security pageJRNLv3
for more information.There is one relevant security advisory for encryption-related security issues: GHSA-rhx6-37mm-5q9r.
Encryption Behavior Overview
- Encrypted journals are now written in the jrnl v3 format.
- jrnl v1 and v2 encrypted files are read-only formats. They can still be opened and decrypted, but new encrypted writes are always v3.jrnl v3 Encrypted File Format
jrnl v3 uses a random 16-byte salt per encrypted write, stored in a JSON
header after a magic prefix. This avoids the static-salt weakness from v2.File layout:
| Field | Size | Description |
| --- | --- | --- |
|| 6 bytes | Magic prefix |header_len
|| 2 bytes (uint16 BE) | Length of the header field, max 64KB |header_len
| header |bytes | Base64-encoded JSON, includessalt(base64url-encoded 16-byte salt) |
| Fernet token | Remaining bytes | Ciphertext |Additional header fields may be added in future without changing the format version.
!!! note
Journals encrypted with v3 before this format was base64-encoded store
raw JSON in the header field instead. These are still read correctly;
the base64-encoded format is written on the next save.Encrypting and Decrypting from the CLI
To encrypt a journal, run:
jrnl --encrypt [FILENAME]
You can then enter a new password, and the unencrypted file will replaced withjrnl
the new encrypted file.This command also works to change the password for a journal file that is
already encrypted.will prompt you for the current password and then new
password.Conversely, run this to decrypt a journal:
jrnl --decrypt [FILENAME]
replaces the encrypted journal file with a plain text file. You can also specifyjrnl --decrypt plain_text_copy.txt
a filename, e.g.,, to leave the originalencrypt
encrypted file untouched and create a new plain text file next to it.!!! note
Changingin your config file tojrnl
a different value will not encrypt or decrypt your
journal file. It merely says whether or not your journal
is encrypted. Hence manually changing
this option will most likely result in your journal file being
impossible to load. This is why the above commands are necessary.Storing Passwords in Your Keychain
Nobody can recover or reset your
password. If you lose it,jrnl
your data will be inaccessible forever.For this reason, when encrypting a journal,
asks whether you would likejrnl --encrypt
to store the password in your system's keychain. An added benefit is that you
will not need to enter the password when interacting with the journal file.If you don't initially store the password in your keychain but decide to do so
later---or if you want to store it in one computer's keychain but not in another
computer's---you can runon an encrypted journal and use thejrnl --decrypt
same password again. This will trigger the keychain storage prompt.Manual Decryption
The easiest way to decrypt your journal is with
, but you couldjrnl
also decrypt your journal manually if needed. To do this, you can use any
program that supports the AES algorithm (specifically AES-CBC), and you'll need
the following relevant information for decryption:- Key: The key used for encryption is the
SHA-256 hash of your password.
- Initialization vector (IV): The IV is stored in the first 16 bytes of
your encrypted journal file.
- The actual text of the journal (everything after the first 16 bytes in
the encrypted journal file) is encoded in
UTF-8 and padded according to
PKCS\#7 before being encrypted.If you'd like an example of what this might look like in script form, please
see below for some examples of Python scripts that you could use to manually
decrypt your journal.!!! note
These are only examples, and are only here to illustrate that your journal files
will still be recoverable even ifisn't around anymore. Please usejrnl --decrypt
if available.Example for jrnl v2 files:
#!/usr/bin/env python3
"""
Decrypt a jrnl v2 encrypted journal.
Note: the cryptography module must be installed (you can do this withpip3 install crytography
something like )
"""
import base64
import getpass
from pathlib import Path
from cryptography.fernet import Fernet
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
filepath = input("journal file path: ")
password = getpass.getpass("Password: ")
with open(Path(filepath), "rb") as f:
ciphertext = f.read()
password = password.encode("utf-8")
kdf = PBKDF2HMAC(
algorithm=hashes.SHA256(),
length=32,
salt=b"\xf2\xd5q\x0e\xc1\x8d.\xde\xdc\x8e6t\x89\x04\xce\xf8",
iterations=100_000,
backend=default_backend(),
)
key = base64.urlsafe_b64encode(kdf.derive(password))
print(Fernet(key).decrypt(ciphertext).decode("utf-8"))
Example for jrnl v1 files:#!/usr/bin/env python3
"""
Decrypt a jrnl v1 encrypted journal.
Note: the pycrypto module must be installed (you can do this with somethingpip3 install pycrypto
like )
"""
import argparse
import getpass
import hashlib
from Crypto.Cipher import AES
parser = argparse.ArgumentParser()
parser.add_argument("filepath", help="journal file to decrypt")
args = parser.parse_args()
pwd = getpass.getpass()
key = hashlib.sha256(pwd.encode("utf-8")).digest()
with open(args.filepath, "rb") as f:
ciphertext = f.read()
crypto = AES.new(key, AES.MODE_CBC, ciphertext[:16])
plain = crypto.decrypt(ciphertext[16:])
plain = plain.strip(plain[-1:])
plain = plain.decode("utf-8")
print(plain)
---editorExternal Editors
External editors
Configure your preferred external editor by updating theoptionPATH
in your configuration file. If your editor is not
in your operating system'senvironment variable, then you will have tojrnl
enter the full path of your editor.
Once it's configured, you can create an entry as a new document in your editor using the
command by itself:
jrnl
`
You can specify the time and title of the entry as usual on the first line of the document.
If you want, you can skip the editor by including a quick entry with the jrnl command:
` text
jrnl yesterday: All my troubles seemed so far away.
`
If you want to start the entry on the command line and continue writing in your chosen editor,
use the --edit flag. For example:
` text
jrnl yesterday: All my troubles seemed so far away. --edit
`
!!! note
To save and log any entry edits, save and close the file.
All editors must be blocking processes) to work with jrnl. Some editors, such as micro, are blocking by default, though others can be made to block with additional arguments, such as many of those documented below. If jrnl opens your editor but finishes running immediately, then your editor is not a blocking process, and you may be able to correct that with one of the suggestions below.
Please see this section about how
your editor might leak sensitive information and how to mitigate that risk.
Sublime Text
To use Sublime Text, install the command line
tools for Sublime Text and configure your jrnl.yaml like this:
`yaml
editor: "subl -w"
`
Note the -w flag to make sure jrnl waits for Sublime Text to close the
file before writing into the journal.
Visual Studio Code
Visual Studio Code also requires a flag
that tells the process to wait until the file is closed before exiting:
`yaml
editor: "code --wait"
`
On Windows, code is not added to the path by default, so you'll need to
enter the full path to your code.exe file, or add it to the PATH variable.
MacVim
Also similar to Sublime Text, MacVim must be started with a flag that tells
the the process to wait until the file is closed before passing control
back to journal. In the case of MacVim, this is -f:
`yaml
editor: "mvim -f"
`
Vim/Neovim
To use any of the Vim derivatives as editor in Linux, simply set the editor
to the executable:
`yaml
editor: "vim"
or
editor: "nvim"
`
iA Writer
On OS X, you can use the fabulous iA
Writer to write entries. Configure your
jrnl.yaml like this:
`yaml
editor: "open -b pro.writer.mac -Wn"
`
What does this do? open -b ... opens a file using the application
identified by the bundle identifier (a unique string for every app out
there). -Wn tells the application to wait until it's closed before
passing back control, and to use a new instance of the application.
If the pro.writer.mac bundle identifier is not found on your system,
you can find the right string to use by inspecting iA Writer's
Info.plist file in your shell:
`sh
grep -A 1 CFBundleIdentifier /Applications/iA\ Writer.app/Contents/Info.plist
`
Notepad++ on Windows
To set Notepad++ as your editor, edit
the jrnl config file (jrnl.yaml) like this:
`yaml
editor: "C:\\Program Files (x86)\\Notepad++\\notepad++.exe -multiInst -nosession"
`
The double backslashes are needed so jrnl can read the file path
correctly. The -multiInst -nosession options will cause jrnl to open
its own Notepad++ window.
emacs
To use emacs as your editor, edit the jrnl config file (jrnl.yaml) like this:
`yaml
editor: emacsclient -a "" -c
`
When you're done editing the message, save and C-x # to close the buffer and stop the emacsclient process.
gedit
To use gedit as your editor, edit the jrnl config
file (jrnl.yaml) like this:
`yaml
editor: "gedit -w"
`
The -w (--wait) flag tells gedit to wait until the file is closed before
passing control back to jrnl.
Other editors
If you're using another editor and would like to share, feel free to contribute documentation on it.---
Formats
Formats
jrnl supports a variety of alternate formats. These can be used to display your
journal in a different manner than the jrnl default, and can even be used to pipe data
from your journal for use in another program to create reports, or do whatever you want
with your jrnl data.Any of these formats can be used with a search (e.g.
jrnl -contains "lorem ipsum"--format json
) to display the results of that search in the given format, or can be
used alone (e.g. jrnl --format json) to display all entries from the selected journal.This page shows examples of all the built-in formats, but since
jrnl supports adding
more formats through plugins, you may have more available on your system. Please see
jrnl --help for a list of which formats are available on your system.Any of these formats can be used interchangeably, and are only grouped into "display",
"data", and "report" formats below for convenience.
Display Formats
These formats are mainly intended for displaying your journal in the terminal. Even so,
they can still be used in the same way as any other format (like written to a file, if
you choose).Pretty
` sh
jrnl --format pretty
or
jrnl -1 # any search
textThis is the default format in jrnl. If no --format is given, pretty will be used.It displays the timestamp of each entry formatted to by the user config followed by the
title on the same line. Then the body of the entry is shown below.
This format is configurable through these values from your config file (see
Advanced Usage for more details):
-
colors
- body
- date
- tags
- title
- indent_character
- linewrap
- timeformatExample output:
sh
2020-06-28 18:22 This is the first sample entry
| This is the sample body text of the first sample entry.2020-07-01 20:00 This is the second sample entry
| This is the sample body text of the second sample entry, but
| this one has a @tag.
2020-07-02 09:00 This is the third sample entry
| This is the sample body text of the third sample entry.
textShort
sh
jrnl --format short
or
jrnl --short
textThis will shorten entries to display only the date and title. It is essentially the
pretty format but without the body of each entry. This can be useful if you have long
journal entries and only want to see a list of entries that match your search.Example output:
sh
2020-06-28 18:22 This is the first sample entry
2020-07-01 20:00 This is the second sample entry
2020-07-02 09:00 This is the third sample entry
textFancy (or Boxed)
sh
jrnl --format fancy
or
jrnl --format boxed
textThis format outlines each entry with a border. This makes it much easier to tell where
each entry starts and ends. It's an example of how free-form the formats can be, and also
just looks kinda ~~fancy~~, if you're into that kind of thing.Example output:
sh
┎──────────────────────────────────────────────────────────────────────╮2020-06-28 18:22
┃ This is the first sample entry ╘═══════════════╕
┠╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
┃ This is the sample body text of the first sample entry. │
┖──────────────────────────────────────────────────────────────────────────────────────┘
┎──────────────────────────────────────────────────────────────────────╮2020-07-01 20:00
┃ This is the second sample entry ╘═══════════════╕
┠╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
┃ This is the sample body text of the second sample entry, but this one has a @tag. │
┖──────────────────────────────────────────────────────────────────────────────────────┘
┎──────────────────────────────────────────────────────────────────────╮2020-07-02 09:00
┃ This is the third sample entry ╘═══════════════╕
┠╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┤
┃ This is the sample body text of the third sample entry. │
┖──────────────────────────────────────────────────────────────────────────────────────┘
textData Formats
These formats are mainly intended for piping or exporting your journal to other
programs. Even so, they can still be used in the same way as any other format (like
written to a file, or displayed in your terminal, if you want).!!! note
You may see boxed messages like "2 entries found" when using these formats, but
those messages are written to
stderr instead of stdout, and won't be piped when
using the | operator.JSON
sh
jrnl --format json
textJSON is a very handy format used by many programs and has support in nearly every
programming language. There are many things you could do with JSON data. Maybe you could
use jq (project page) to filter through the fields in your journal.
Like this:
sh
$ j -3 --format json | jq '.entries[].date' jrnl-GFqVlfgP-py3.8
"2020-06-28"
"2020-07-01"
"2020-07-02"
textOr why not create a beautiful timeline of your journal?Example output:
json
{
"tags": {
"@tag": 1
},
"entries": [
{
"title": "This is the first sample entry",
"body": "This is the sample body text of the first sample entry.",
"date": "2020-06-28",
"time": "18:22",
"tags": [],
"starred": false
},
{
"title": "This is the second sample entry",
"body": "This is the sample body text of the second sample entry, but this one has a @tag.",
"date": "2020-07-01",
"time": "20:00",
"tags": [
"@tag"
],
"starred": false
},
{
"title": "This is the third sample entry",
"body": "This is the sample body text of the third sample entry.",
"date": "2020-07-02",
"time": "09:00",
"tags": [],
"starred": false
}
]
}
textMarkdown
sh
jrnl --format markdown
or
jrnl --format md
textMarkdown is a simple markup language that is human readable and can be used to be
rendered to other formats (html, pdf). jrnl's
README for example is
formatted in markdown, then Github adds some formatting to make it look nice.The markdown format groups entries by date (first by year, then by month), and adds
header markings as needed (e.g.
#, ##, etc). If you already have markdown header
markings in your journal, they will be incremented as necessary to make them fit under
these new headers (i.e. # will become ##).This format can be very useful, for example, to export a journal to a program that
converts markdown to html to make a website or a blog from your journal.
Example output:
markdown
2020
June
2020-06-28 18:22 This is the first sample entry
This is the sample body text of the first sample entry.
July
2020-07-01 20:00 This is the second sample entry
This is the sample body text of the second sample entry, but this one has a @tag.
2020-07-02 09:00 This is the third sample entry
This is the sample body text of the third sample entry.
textPlain Text
sh
jrnl --format text
or
jrnl --format txt
textThis outputs your journal in the same plain-text format that jrnl uses to store your
journal on disk. This format is particularly useful for importing and exporting journals
within jrnl.You can use it, for example, to move entries from one journal to another, or to create a
new journal with search results from another journal.
Example output:
sh
[2020-06-28 18:22] This is the first sample entry
This is the sample body text of the first sample entry.[2020-07-01 20:00] This is the second sample entry
This is the sample body text of the second sample entry, but this one has a @tag.
[2020-07-02 09:00] This is the third sample entry
This is the sample body text of the third sample entry.
textXML
sh
jrnl --format xml
textThis outputs your journal into XML format. XML is a commonly used data format and is
supported by many programs and programming languages.Example output:
xml
<?xml version="1.0" ?>
<journal>
<entries>
<entry date="2020-06-28T18:22:00" starred="">This is the first sample entry This is the sample body text of the first sample entry.</entry>
<entry date="2020-07-01T20:00:00" starred="">
<tag name="@tag"/>
This is the second sample entry This is the sample body text of the second sample entry, but this one has a @tag.
</entry>
<entry date="2020-07-02T09:00:00" starred="">*This is the third sample entry, and is starred This is the sample body text of the third sample entry.</entry>
</entries>
<tags>
<tag name="@tag">1</tag>
</tags>
</journal>
textYAML
sh
jrnl --format yaml --file 'my_directory/'
textThis outputs your journal into YAML format. YAML is a commonly used data format and is
supported by many programs and programming languages. Exporting to directories is the
only supported YAML export option and each entry will be written to a separate file.Example file:
yaml
title: This is the second sample entry
date: 2020-07-01 20:00
starred: False
tags: tagThis is the sample body text of the second sample entry, but this one has a @tag.
textReport formats
Since formats use your journal data and display it in different ways, they can also be
used to create reports.Tags
sh
jrnl --format tags
or
jrnl --tags
textThis format is a simple example of how formats can be used to create reports. It
displays each tag, and a count of how many entries in which tag appears in your journal
(or in the search results), sorted by most frequent.Example output:
sh
@one : 32
@two : 17
@three : 4
textOptions
Exporting with
--file Example:
jrnl --format json --file /some/path/to/a/file.txtBy default,
jrnl will output entries to your terminal. But if you provide --file
along with a filename, the same output that would have been to your terminal will be
written to the file instead. This is the same as piping the output to a file.So, in bash for example, the following two statements are equivalent:
sh
jrnl --format json --file myjournal.json
text
sh
jrnl --format json > myjournal.json
text#### Exporting to directoriesIf the
--file argument is a directory, jrnl will export each entry into an individual file:
sh
jrnl --format yaml --file my_entries/
textThe contents of my_entries/ will then look like this:
output
my_entries/
|- 2013_06_03_a-beautiful-day.yaml
|- 2013_06_07_dinner-with-gabriel.yaml
|- ...
text---Installation
Getting started
Installation
The easiest way to install
jrnl is using
pipx
with Python 3.11+:
sh
pipx install jrnl
text!!! tip
Do not use sudo while installing jrnl. This may lead to path issues.The first time you run
jrnl you will be asked where your journal file
should be created and whether you wish to encrypt it.Quickstart
To make a new entry, just type
text
jrnl yesterday: Called in sick. Used the time to clean, and spent 4h on writing my book.
textand hit return. yesterday: will be interpreted as a time stamp.
Everything until the first sentence mark (.?!:) will be interpreted as
the title, the rest as the body. In your journal file, the result will
look like this:
output
2012-03-29 09:00 Called in sick.
Used the time to clean the house and spent 4h on writing my book.
textIf you just call jrnl, you will be prompted to compose your entry -
but you can also configure jrnl to use your external editor.---
Journal Types
Journal Types
jrnl can store your journal in a few different ways:
- a single text file (encrypted or otherwise)
- a folder structure organized by date containing unencrypted text files
- the DayOne Classic format
There is no need to specify what type of journal you'd like to use. Instead,
jrnl will automatically detect the journal type based on whether you're
referencing a file or a folder in your config file,
and if it's a folder, whether or not DayOne Classic content exists in it.
Single File
The single file format is the most flexible, as it can be encrypted.
To use it, enter any path that is a file or does not already exist. You can
use any extension. jrnl will automatically create the file when you save
your first entry.
Folder
The folder journal format organizes your entries into subfolders for the year
and month and .txt files for each day. If there are multiple entries in a day,
they all appear in the same .txt file.
The directory tree structure is in this format: YYYY/MM/DD.txt. For instance, if
you have an entry on May 5th, 2021 in a folder journal at ~/folderjournal, it will
be located in: ~/folderjournal/2021/05/05.txt
!!! note
Creating a new folder journal can be done in two ways:
* Create a folder with the name of the journal before running jrnl. Otherwise, when you run jrnl for the first time, it will assume that you are creating a single file journal instead, and it will create a file at that path.
* Create a new journal in your config_file and end the path with a / (on a POSIX system like Linux or MacOSX) or a \ (on a Windows system). The folder will be created automatically if it doesn't exist.
!!! note
Folder journals can't be encrypted.
Day One Classic
jrnl supports the original data format used by DayOne. It's similar to the folder
journal format, except it's identified by either of these characteristics:
* the folder has a .dayone extension
* the folder has a subfolder named entries
This is not to be confused with the DayOne 2.0 format, which is very different.
!!! note
DayOne Classic journals can't be encrypted.
Changing your journal type
You can't simply modify a journal's configuration to change its type. Instead,
define a new journal as the type you'd like, and use
piping#Piping)
to export your old journal as txt to an import command on your new journal.
For instance, if you have a projects journal you would like to import into
a new journal, you would run the following after setting up the configuration
for your new journal:
jrnl projects --format txt | jrnl new --import
text---Privacy And Security
Privacy and Security
jrnl is designed with privacy and security in mind, but like any other
program there are some limitations to be aware of.Password strength
jrnl doesn't enforce password strength requirements. Short or commonly-used
passwords can be easily circumvented by someone with basic security skills
to access to your encrypted jrnl file.Plausible deniability
You may be able to hide the contents of your journal behind a layer of encryption,
but if someone has access to your configuration file, then they can figure out that
you have a journal, where that journal file is, and when you last edited it.
With a sufficient power imbalance, someone may be able to force you to unencrypt
it through non-technical means.
Spying
While
jrnl can protect against unauthorized access to your journal entries while
it isn't open, it cannot protect you against an unsafe computer/location.
For example:- Someone installs a keylogger, tracking what you type into your journal.
- Someone watches your screen while you write your entry.
- Someone installs a backdoor into
jrnl or poisons your journal into revealing your entries.Saved Passwords
When creating an encrypted journal, you'll be prompted as to whether or not you
want to "store the password in your keychain." This keychain is accessed using
the Python keyring library, which has different
behavior depending on your operating system.
In Windows, the keychain is the Windows Credential Manager (WCM), which can't be locked
and can be accessed by any other application running under your username. If this is
a concern for you, you may not want to store your password.
Shell history
Since you can enter entries from the command line, any tool that logs command
line actions is a potential security risk. See below for how to deal with this
problem in various shells.
bash
You can disable history logging for jrnl by adding this line into your
~/.bashrc file:
sh
HISTIGNORE="$HISTIGNORE:jrnl *"
textTo delete existing jrnl commands from bash history, simply delete them from
your bash history file. The default location of this file is ~/.bash_history,
but you can run echo "$HISTFILE" to find it if needed. Also, you can run
history -c to delete all commands from your history.zsh
You can disable history logging for jrnl by adding this to your
~/.zshrc
file:
sh
setopt HIST_IGNORE_SPACE
alias jrnl=" jrnl"
textTo delete existing jrnl commands from zsh history, simply remove them from
your zsh history file. The default location of this file is ~/.zsh_history,
but you can run echo "$HISTFILE" to find it if needed. Also, you can run
history -c to delete all commands from your history.fish
By default
fish will not log any command that starts with a space. If you
want to always run jrnl with a space before it, then you can add this to your
~/.config/fish/config.fish file:
sh
abbr --add jrnl " jrnl"
textTo delete existing jrnl commands from fish history, run history delete --prefix 'jrnl '.Windows Command Prompt
Windows doesn't log history to disk, but it does keep it in your command prompt
session. Close the command prompt or press
Alt+F7 to clear your history
after journaling.Files in transit from editor to jrnl
When creating or editing an entry,
jrnl uses a unencrypted temporary file on
disk in order to give your editor access to your journal. After you close your
editor, jrnl then deletes this temporary file.So, if you have saved a journal entry but haven't closed your editor yet, the
unencrypted temporary remains on your disk. If your computer were to shut off
during this time, or the
jrnl process were killed unexpectedly, then the
unencrypted temporary file will remain on your disk. You can mitigate this
issue by only saving with your editor right before closing it. You can also
manually delete these files from your temporary folder. By default, they
are named jrnl*.jrnl, but if you use a
template, they will have the same
extension as the template.Editor history
Some editors keep usage history stored on disk for future use. This can be a
security risk in the sense that sensitive information can leak via recent
search patterns or editor commands.
Visual Studio Code
Visual Studio Code stores the contents of saved files to allow you to restore or
review the contents later. You can disable this feature for all files by unchecking
the
workbench.localHistory.enabled setting in the
Settings editor.Alternatively, you can disable this feature for specific files by configuring a
pattern
in the
workbench.localHistory.exclude setting. To exclude unencrypted temporary files generated
by jrnl, you can set the /jrnl*.jrnl (unless you are using a
template) pattern for the workbench.localHistory.exclude setting
in the Settings editor.!!! note
On Windows, the history location is typically found at
%APPDATA%\Code\User\History.Visual Studio Code also creates a copy of all unsaved files that are open.
It stores these copies in a backup location that's automatically cleaned when
you save the file. However, if your computer shuts off before you save the file,
or the Visual Studio Code process stops unexpectedly, then an unencrypted
temporary file may remain on your disk. You can manually delete these files
from the backup location.
!!! note
On Windows, the backup location is typically found at
%APPDATA%\Code\Backups.Vim
Vim stores progress data in a so called Viminfo file located at
~/.viminfo
which contains all sorts of user data including command line history, search
string history, search/substitute patterns, contents of register etc. Also to
be able to recover opened files after an unexpected application close Vim uses
swap files.These options as well as other leaky features can be disabled by setting the
editor key in the Jrnl settings like this:
yaml
editor: "vim -c 'set viminfo= noswapfile noundofile nobackup nowritebackup noshelltemp history=0 nomodeline secure'"
textTo disable all plugins and custom configurations and start Vim with the default
configuration -u NONE can be passed on the command line as well. This will
ensure that any rogue plugins or other difficult to catch information leaks are
eliminated. The downside to this is that the editor experience will decrease
quite a bit.To instead let Vim automatically detect when a Jrnl file is being edited an
autocommand can be used. Place this in your
~/.vimrc:
vim
autocmd BufNewFile,BufReadPre *.jrnl setlocal viminfo= noswapfile noundofile nobackup nowritebackup noshelltemp history=0 nomodeline secure
text!!! note
If you're using a template, you will
have to use the template's file extension instead of .jrnl.See
:h <option> in Vim for more information about the options mentioned.Neovim
Neovim strives to be mostly compatible with Vim and has therefore similar
functionality as Vim. One difference in Neovim is that the Viminfo file is
instead called the ShaDa ("shared data") file which resides in
~/.local/state/nvim (~/.local/share/nvim pre Neovim v0.8.0). The ShaDa file
can be disabled in the same way as for Vim.
yaml
editor: "nvim -c 'set shada= noswapfile noundofile nobackup nowritebackup noshelltemp history=0 nomodeline secure'"
text-u NONE can be passed here as well to start a session with the default configs.As for Vim above we can create an autocommand in Vimscript:
vim
autocmd BufNewFile,BufReadPre *.jrnl setlocal shada= noswapfile noundofile nobackup nowritebackup noshelltemp history=0 nomodeline secure
textor the same but in Lua:
lua
vim.api.nvim_create_autocmd( {"BufNewFile","BufReadPre" }, {
group = vim.api.nvim_create_augroup("PrivateJrnl", {}),
pattern = "*.jrnl",
callback = function()
vim.o.shada = ""
vim.o.swapfile = false
vim.o.undofile = false
vim.o.backup = false
vim.o.writebackup = false
vim.o.shelltemp = false
vim.o.history = 0
vim.o.modeline = false
vim.o.secure = true
end,
})
text!!! note
If you're using a template, you will
have to use the template's file extension instead of .jrnl.Please see
:h <option> in Neovim for more information about the options mentioned.Notice any other risks?
Please let the maintainers know by filing an issue on GitHub.
---
Reference Command Line
Command Line Reference
Synopsis
usage: jrnl [--debug] [--help] [--version] [--list] [--encrypt] [--decrypt]
[--import] [-on DATE] [-today-in-history] [-month DATE]
[-day DATE] [-year DATE] [-from DATE] [-to DATE] [-contains TEXT]
[-and] [-starred] [-n [NUMBER]] [-not [TAG]] [--edit] [--delete]
[--format TYPE] [--tags] [--short]
[--config-override CONFIG_KEY CONFIG_VALUE]
[--config-file CONFIG_FILE_PATH]
[[...]]
`
Standalone Commands
These commands will exit after they complete. You may only run one at a time.
--help
Show a help message.
--version
Print version and license information.
--list
List the config file location, all configured journals, and their locations.
--encrypt
Encrypt a journal. See encryption for more information.
--decrypt
Decrypt a journal. See encryption for more information.
--import
Import entries from another journal. If any entries have the exact same content
and timestamp, they will be deduplicated.
Optional parameters:
`sh
--file FILENAME
`
Specify a file to import. If not provided, jrnl will use STDIN as the data source.
`sh
--format TYPE
`
Specify the format of the file that is being imported. Defaults to the same data
storage method that jrnl uses. See formats for more information.
Writing new entries
See Basic Usage.
Searching
To find entries from your journal, use any combination of the below filters.
Only entries that match all the filters will be displayed.
When specifying dates, you can use the same kinds of dates you use for new
entries, such as yesterday, today, Tuesday, or 2021-08-01.
| Search Argument | Description |
| --- | --- |
| -on DATE | Show entries on this date |
| -today-in-history | Show entries of today over the years |
| -month DATE | Show entries on this month of any year |
| -day DATE | Show entries on this day of any month |
| -year DATE | Show entries of a specific year |
| -from DATE | Show entries after, or on, this date |
| -to DATE | Show entries before, or on, this date (alias: -until) |
| -contains TEXT | Show entries containing specific text (put quotes around text with spaces) |
| -and | Show only entries that match all conditions, like saying "x AND y" (default: OR) |
| -starred | Show only starred entries (marked with *) |
| -tagged | Show only tagged entries (marked with the configured tagsymbols) |
| -n [NUMBER] | Show a maximum of NUMBER entries (note: '-n 3' and '-3' have the same effect) |
| -not [TAG] | Exclude entries with this tag |
| -not -starred | Exclude entries that are starred |
| -not -tagged | Exclude entries that are tagged |
Searching Options
These help you do various tasks with the selected entries from your search.
If used on their own (with no search), they will act on your entire journal.
--edit
Opens the selected entries in your configured editor. It will fail if the
editor key is not set in your config file.
Once you begin editing, you can add multiple entries and delete entries
by modifying the text in your editor. When your editor closes, jrnl reads
the temporary file you were editing and makes the changes to your journal.
--delete
Interactively deletes selected entries. You'll be asked to confirm deletion of
each entry.
--change-time DATE
Interactively changes the time of the selected entries to the date specified,
or to right now if no date is specified. You'll be asked to confirm each entry,
unless you are using this with --edit on a single entry.
--format TYPE
Display selected entries in an alternate format. See formats.
#### Optional parameters
`sh
--file FILENAME
`
Write output to file instead of STDOUT. In most shells, the
same effect can be achieved using >.
--tags
Alias for '--format tags'. Returns a list of all tags and the number of times
they occur within the searched entries. If there are no tags found, jrnl will output a message saying so.
--short
Only shows the date and titles of the searched entries.
Configuration arguments
--config-override CONFIG_KEY CONFIG_VALUE
Override configured key-value pair with CONFIG_KV_PAIR for this command invocation only. To access config keys that aren't at the top level, separate the keys with a dot, such as colors.title to access the title key within the colors key. Read advanced usage for examples.
--config-file CONFIG_FILE_PATH
Use the config file at CONFIG_FILE_PATH for this command invocation only.
Read advanced usage for examples.
Other Arguments
--debug
Prints information useful for troubleshooting while jrnl executes.
--diagnostic
Prints diagnostic information useful for reporting issues.---
Reference Config File
Configuration File Reference
jrnl stores its information in a YAML configuration file.
!!! note
Backup your journal and config file before editing. Changes to the config file
can have destructive effects on your journal!
Config location
You can find your configuration file location by running:
jrnl --list
By default, the configuration file is ~/.config/jrnl/jrnl.yaml.
If you have the XDG_CONFIG_HOME variable set, the configuration
file will be saved as $XDG_CONFIG_HOME/jrnl/jrnl.yaml.
!!! note
On Windows, the configuration file is typically found at
%USERPROFILE%\.config\jrnl\jrnl.yaml.
Config format
The configuration file is a YAML file and can be edited with
a text editor.
Config keys
journals
Describes each journal used by jrnl. Each indented key after this key is
the name of a journal.
If a journal key has a value, that value will be interpreted as the path
to the journal. Otherwise, the journal needs the additional indented key
journal to specify its path.
Example:
`yaml
journals:
default:
journal: /home/user/journals
`
All keys below can be specified for each journal at the same level as the
journal key. If a key conflicts with a top-level key, the journal-specific
key will be used instead.
editor
If set, executes this command to launch an external editor for
writing and editing your entries. The path to a temporary file
is passed after it, and jrnl processes the file once
the editor returns control to jrnl.
Some editors require special options to work properly, since they must be
blocking processes to work with jrnl. See External Editors
for details.
encrypt
If true, encrypts your journal using AES. Do not change this
value for journals that already have data in them.
template
The path to a text file to use as a template for new entries. Only works when you
have the editor field configured. If you use a template, the editor's
temporary files
will have the same extension as the template.
tagsymbols
Symbols to be interpreted as tags.
!!! note
Although it seems intuitive to use the #
character for tags, there's a drawback: on most shells, this is
interpreted as a meta-character starting a comment. This means that if
you type
> jrnl Implemented endless scrolling on the #frontend of our website.
your bash will chop off everything after the # before passing it to
jrnl. To avoid this, wrap your input into quotation marks like
this:
> jrnl "Implemented endless scrolling on the #frontend of our website."
Or use the built-in prompt or an external editor to compose your
entries.
default_hour and default_minute
Entries will be created at this time if you supply a date but no specific time (for example, last thursday).
timeformat
Defines how to format the timestamps as they are stored in your journal.
See the python docs for reference.
Do not change this for an existing journal, since that might lead
to data loss.
!!! note
jrnl doesn't support the %z or %Z time zone identifiers.
highlight
If true, tags will be highlighted in cyan.
linewrap
Controls the width of the output. Set to false if you don't want to
wrap long lines. Set to auto to let jrnl automatically determine
the terminal width.
colors
A dictionary that controls the colors used to display journal entries.
It has four subkeys, which are: body, date, tags, and title.
Current valid values are: BLACK, RED, GREEN, YELLOW, BLUE,
MAGENTA, CYAN, WHITE, and NONE.
colorama.Fore is used for colorization, and you can find the docs here.
To disable colored output, set the value to NONE.
display_format
Specifies formatter to use by default. See formats.
version
jrnl automatically updates this field to the version that it is running.
There is no need to change this field manually.---
Tips And Tricks
Tips and Tricks
This page contains tips and tricks for using
jrnl, often in conjunction
with other tools, including external editors.Co-occurrence of tags
If I want to find out how often I mentioned my flatmates Alberto and
Melo in the same entry, I run
shjrnl @alberto --tags | grep @melo
And will get something like
@melo: 9, meaning there are 9 entries
where both @alberto and @melo are tagged. How does this work? First,
jrnl @alberto will filter the journal to only entries containing the
tag @alberto, and then the --tags option will print out how often
each tag occurred in this filtered journal. Finally, we pipe this to
grep which will only display the line containing @melo.Combining filters
You can do things like
shjrnl @fixed -starred -n 10 -to "jan 2013" --short
To get a short summary of the 10 most recent, favourite entries before
January 1, 2013 that are tagged with
@fixed.Statistics
How much did I write last year?
shjrnl -from "jan 1 2013" -to "dec 31 2013" | wc -w
Will give you the number of words you wrote in 2013. How long is my
average entry?
shexpr $(jrnl --export text | wc -w) / $(jrnl --short | wc -l)
This will first get the total number of words in the journal and divide
it by the number of entries (this works because
jrnl --short will
print exactly one line per entry).Importing older files
If you want to import a file as an entry to
jrnl, you can just do jrnl < entry.ext. But what if you want the modification date of the file to
be the date of the entry in jrnl? Try thisshecho stat -f %Sm -t '%d %b %Y at %H:%M: ' entry.txt cat entry.txt | jrnl
The first part will format the modification date of
entry.txt, and
then combine it with the contents of the file before piping it to jrnl.
If you do that often, consider creating a function in your .bashrc or
.bash_profileshjrnlimport () {
echo stat -f %Sm -t '%d %b %Y at %H:%M: ' $1 cat $1 | jrnl
}
Using Templates
!!! note
Templates require an external editor be configured.
Templates are text files that are used for creating structured journals.
There are three ways you can use templates:
1. Use the
--template command line argument and the default $XDG_DATA_HOME/jrnl/templates directory $XDG_DATA_HOME/jrnl/templates is created by default to store your templates! Create a template (like default.md) in this directory and pass --template FILE_IN_DIR.shjrnl --template default.md
2. Use the
--template command line argument with a local / absolute path You can create a template file with any text. Here is an example:
sh/tmp/template.txt
My Personal Journal
Title:Body:
Then, pass the absolute or relative path to the template file as an argument, and your external
editor will open and have your template pre-populated.
shjrnl --template /tmp/template.md
3. Set a default template file in
jrnl.yaml If you want a template by default, change the value of
template in the config file
from false to the template file's path, wrapped in double quotes:sh...
template: "/path/to/template.txt"
...
!!! tip
To read your journal entry or to verify the entry saved, you can use this
command:
jrnl -n 1 (Check out Formats for more options).shjrnl -n 1
Prompts on shell reload
If you'd like to be prompted each time you refresh your shell, you can include
this in your
.bash_profile:shfunction log_question()
{
echo $1
read
jrnl today: ${1}. $REPLY
}
log_question 'What did I achieve today?'
log_question 'What did I make progress with?'
Whenever your shell is reloaded, you will be prompted to answer each of the
questions in the example above. Each answer will be logged as a separate
journal entry at the
default_hour and default_minute listed in your
jrnl.yaml config file.Display random entry
You can use this to select one title at random and then display the whole
entry. The invocation of
cut needs to match the format of the timestamp.
For timestamps that have a space between data and time components, select
fields 1 and 2 as shown. For timestamps that have no whitespace, select
only field 1.shjrnl -on "$(jrnl --short | shuf -n 1 | cut -d' ' -f1,2)"
Launch a terminal for rapid logging
You can use this to launch a terminal that is the jrnl stdin prompt so you can start typing away immediately.bashjrnl --config-override editor ""
Bind this to a keyboard shortcut.
Map
Super+Alt+J to launch the terminal with jrnl prompt- xbindkeys
In your
.xbindkeysrciniMod4+Mod1+j
alacritty -t floating-jrnl -e jrnl --config-override editor "",
- I3 WM Launch a floating terminal with the
jrnl promptinibindsym Mod4+Mod1+j exec --no-startup-id alacritty -t floating-jrnl -e jrnl --config-override editor ""
for_window[title="floating *"] floating enable
Visualize Formatted Markdown in the CLI
Out of the box,
jrnl can output journal entries in Markdown. To visualize it, you can pipe to mdless, which is a less)-like tool that allows you to visualize your Markdown text with formatting and syntax highlighting from the CLI. You can use this in any shell that supports piping.The simplest way to visualize your Markdown output with
mdless is as follows:
shjrnl --export md | mdless
This will render your Markdown output in the whole screen.
Fortunately,
mdless has an option that allows you to adjust the screen width by using the -w option as follows:shjrnl --export md | mdless -w 70
If you want Markdown to be your default display format, you can define this in your config file as follows:
yamldisplay_format: md
or
display_format: markdown
For more information on how
jrnl outputs your entries in Markdown, please visit the Formats section.
Jump to end of buffer (with vi)
To cause vi to jump to the end of the last line of the entry you edit, in your config file set:
yamleditor: vi + -c "call cursor('.',strwidth(getline('.')))"
---
Usage
Basic Usage #
jrnl has two modes: composing and viewing. Whenever you don't enter
any arguments that start with a dash (-) or double-dash (--), you're in
composing mode, meaning that you can write your entry on the command line.We intentionally break a convention on command line arguments: all arguments
starting with a _single dash_ (
-) will _filter_ your journal before viewing
it. Filter arguments can be combined arbitrarily. Arguments with a _double dash_
(--) will _control_ how your journal is displayed or exported. Control
arguments are mutually exclusive (i.e., you can only specify one way to display
or export your journal at a time).For a list of commands, enter
jrnl --help.Composing Entries ##
Composing mode is entered by either starting
jrnl without any arguments --
which will launch an external editor -- or by just writing an entry on the
command line:textjrnl today at 3am: I just met Steve Buscemi in a bar! What a nice guy.
!!! note
Most shells contain a certain number of reserved characters, such as
# and
*. These characters, as well as unbalanced single or double quotation
marks, parentheses, and others, likely will cause problems. Although
reserved characters can be escaped using \, this is not ideal for
long-form writing. The solution: first enter jrnl and hit return. You
can then enter the text of your journal entry. Alternatively, you can use
an external editor.You can also import an entry directly from a file:
shjrnl < my_entry.txt
Specifying Date and Time ###
If you don't specify a date and time (e.g.,
jrnl finished writing letter to brother), jrnl will create an entry using the current date and time. For retrospective entries, you can use a timestamp to tell jrnl where to put the entry. Timestamps can be entered using a variety of formats. Here are some that work:- at 6am
- yesterday
- last monday
- sunday at noon
- 2 march 2012
- 7 apr
- 5/20/1998 at 23:42
- 2020-05-22T15:55-04:00
If you don't use a timestamp,
jrnl will create an entry using the current
time. If you use a date only (no time), jrnl will use the default time
specified in your configuration file.
Behind the scenes, jrnl reorganizes entries in chronological order.Using Tags ###
jrnl supports tags. The default tag symbol is @ (largely because # is a
reserved character). You can specify your own tag symbol in the
configuration file. To use tags, preface the
desired tag with the symbol:shjrnl Had a wonderful day at the @beach with @Tom and @Anna.
Although you can use capitals while tagging an entry, searches by tag are
case-insensitive.
There is no limit to how many tags you can use in an entry.
#### Similar Tag Warning ####
When you write an entry,
jrnl checks whether any of its tags closely resemble
tags you've used before. If so, it prints a warning:textThe tag '@works' is similar to: @workWas this intentional? If not, re-open the entry with 'jrnl --edit' to fix it.
This is just a warning —
jrnl will not ask for confirmation or block the
entry from being saved. This is intentional: some similar-looking tags are
perfectly meaningful to keep separate. For example:-
@health and @wealth — related topics, but distinct goals
- @friend and @fiend — very different meanings
- @hiking and @biking — different activities worth tracking separately
- @learn and @lean — different intentions entirelyIf the warning appears and you did make a typo, run
jrnl --edit to fix it.Starring Entries ###
To mark an entry as a favorite, simply "star" it using an asterisk (
*):shjrnl last sunday *: Best day of my life.
If you don't want to add a date (i.e., you want the date to be entered as
_now_), the following options are equivalent:
-
jrnl *: Best day of my life.
- jrnl *Best day of my life.
- jrnl Best day of my life.*!!! note
Make sure that the asterisk (
*) is not surrounded by whitespaces.
jrnl Best day of my life! will not work because the character has a
special meaning in most shells.Viewing and Searching Entries ##
jrnl can display entries in a variety of ways.To view all entries, enter:
shjrnl -to today
jrnl provides several filtering commands, prefaced by a single dash (-), that
allow you to find a more specific range of entries. For example,shjrnl -n 10
lists the ten most recent entries.
jrnl -10 is even more concise and works the
same way. If you want to see all of the entries you wrote from the beginning of
last year until the end of this past March, you would entershjrnl -from "last year" -to march
Filter criteria that use more than one word require surrounding quotes (
"").To see entries on a particular date, use
-on:
shjrnl -on yesterday
Text Search ###
The
-contains command displays all entries containing the text you enter after it.
This may be helpful when you're searching for entries and you can't remember if you
tagged any words when you wrote them.You may realize that you use a word a lot and want to turn it into a tag in all
of your previous entries.
shjrnl -contains "dogs" --edit
opens your external editor so that you can add a tag symbol (
@ by default) to
all instances of the word "dogs."Filtering by Tag ###
You can filter your journal entries by tag. For example,
shjrnl @pinkie @WorldDomination
displays all entries in which either
@pinkie or @WorldDomination
occurred. Tag filters can be combined with other filters:shjrnl -n 5 @pinkie -and @WorldDomination
displays the last five entries containing _both_
@pinkie _and_
@worldDomination. You can change which symbols you'd like to use for tagging
in the configuration file.!!! note
Entering
jrnl @pinkie @WorldDomination will display entries in which both
tags are present because, although no command line arguments are given, all
of the input strings look like tags. jrnl will assume you want to filter
by tag, rather than create a new entry that consists only of tags.To view a list of all tags in the journal, enter:
shjrnl --tags
Viewing Starred Entries ###
To display only your favorite (starred) entries, enter
shjrnl -starred
Editing Entries ##
You can edit entries after writing them. This is particularly useful when your
journal file is encrypted. To use this feature, you need to have an external
editor configured in your configuration file. You
can also edit only the entries that match specific search criteria. For example,
shjrnl -to 1950 @texas -and @history --edit
opens your external editor displaying all entries tagged with
@texas and
@history that were written before 1950. After making changes, save and close
the file, and only those entries will be modified (and encrypted, if
applicable).If you are using multiple journals, it's easy to edit specific entries from
specific journals. Simply prefix the filter string with the name of the journal.
For example,
shjrnl work -n 1 --edit
opens the most recent entry in the 'work' journal in your external editor.
Deleting Entries ##
The
--delete command opens an interactive interface for deleting entries. The
date and title of each entry in the journal are presented one at a time, and you
can choose whether to keep or delete each entry.If no filters are specified,
jrnl will ask you to keep or delete each entry in
the entire journal, one by one. If there are a lot of entries in the journal, it
may be more efficient to filter entries before passing the --delete command.Here's an example. Say you have a journal into which you've imported the last 12
years of blog posts. You use the
@book tag a lot, and for some reason you want
to delete some, but not all, of the entries in which you used that tag, but only
the ones you wrote at some point in 2004 or earlier. You're not sure which
entries you want to keep, and you want to look through them before deciding.
This is what you might enter:shjrnl -to 2004 @book --delete
jrnl will show you only the relevant entries, and you can choose the ones you
want to delete.You may want to delete _all_ of the entries containing
@book that you wrote in
2004 or earlier. If there are dozens or hundreds, the easiest way would be to
use an external editor. Open an editor with the entries you want to delete...shjrnl -to 2004 @book --edit
...select everything, delete it, save and close, and all of those entries are
removed from the journal.
Listing Journals ##
To list all of your journals:
shjrnl --list
The journals displayed correspond to those specified in the
jrnl
configuration file.---
CHANGELOG
Changelog
Unreleased
Packaging:
- Update dependency ruff to v0.16.2 \#2109 ([renovate[bot]](https://github.com/apps/renovate))
v4.6 (2026-08-07)
Implemented enhancements:
- Feature Request: VJOURNAL Backend \#2083
- Feature Request: Add a config option to output any new entries to the terminal after submission. \#1871
Fixed bugs:
- Icelandic letters in UTF-8 not working. \#2113
-
--config-file broken on latest build \#2099
- Bug Report \#2082
- KeyError: date \#2077
- 6 Tests failed because 'v' is missing in front of '4.3.0' \#2065
- Version tests failing on 4.3-beta release due to beta/b0 tags \#2060
- jrnl crashes when colors.tags is not configured \#2021
- Bug: Using time format "%H:%m" overwrites old entries on a day \#2006Packaging:
- Drop Python 3.10 support \#2055
- Update dependency cryptography to v50 \#2114 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency tox to v4.58.0 \#2108 ([renovate[bot]](https://github.com/apps/renovate))
- Update actions/setup-python action to v7 \#2102 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency ruff to v0.15.22 \#2098 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency rich to v15 \#2094 ([renovate[bot]](https://github.com/apps/renovate))
- Update actions/checkout action to v7 - autoclosed \#2093 ([renovate[bot]](https://github.com/apps/renovate))
- Update actions/cache action to v6 \#2092 ([renovate[bot]](https://github.com/apps/renovate))
- Update heinrichreimer/action-github-changelog-generator action to v2.4 \#2078 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency tox to v4.57.0 \#2017 ([renovate[bot]](https://github.com/apps/renovate))
Merged pull requests:
- Enable automerge for Renovate PRs \#2116 (alichtman)
- Derive folder-journal entry dates from the folder path \#2115 (youdie006)
- docs: add gedit to external editors \#2107 (natejswenson)
- fix: guarantee editor tempfile cleanup and add debug logging \#2106 (alichtman)
- fix: don't crash on invalid UTF-8 from stdin when writing an entry \#2104 (alichtman)
- fix: don't overwrite the default config when using --config-file \#2101 (alichtman)
- fix: write journal files atomically to avoid corruption on crash \#2096 (alichtman)
- fix: emit error when running --decrypt on an unencrypted journal \#2095 (alichtman)
- chore: upgrade all deps \#2091 (alichtman)
- fix: don't crash on missing or invalid color config values \#2089 (alichtman)
- Drop Python 3.10 support \#2088 (alichtman)
- docs: add CLAUDE.md \#2086 (alichtman)
- fix: prevent ValueError when upgrading with no journals configured \#2080 (miloquinn)
- Feature: warning for similar tags \#2064 (hanbeex)
- Minor fixes to docstrings of functions \#1868 (MuditJ)
v4.3 (2026-02-24)
Build:
- Modernize pyproject \#2046 (micahellison)
- Remove release step to publish to Homebrew \#1994 (micahellison)
Documentation:
- Doc missing: Setting location of journal \#2019
- \[Documentation change\] Update command line reference \#2032 (katielin019)
- Add example of how to configure location of a journal \#2020 (matthiasbeyer)
Packaging:
- Update actions/checkout action to v6 \#2053 ([renovate[bot]](https://github.com/apps/renovate))
- Update actions/cache action to v5 \#2052 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency rich to \>=14.3.2,\<14.4.0 \#2051 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency python to 3.14 \#2050 ([renovate[bot]](https://github.com/apps/renovate))
- Update actions/setup-python action to v6 \#2031 ([renovate[bot]](https://github.com/apps/renovate))
- Add support for Python 3.14 \#2015 (micahellison)
- Update dependency pa11y-ci to v4 \#2014 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency rich to \>=14.1.0, \<14.2.0 \#2013 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency requests to v2.32.4 \#2010 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency pytest to v8.4.1 \#2009 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency pytest-xdist to v3.8.0 \#2005 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency ruamel.yaml to v0.18.14 \#2004 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency cryptography to v45 \#2001 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency tox to v4.28.3 \#2000 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency poethepoet to v0.36.0 \#1993 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency ruff to v0.12.5 \#1991 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency rich to v14 \#1989 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency python to 3.13 \#1988 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency tox to v4.25.0 \#1986 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency tzlocal to v5.3.1 \#1984 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency jinja2 to v3.1.6 \#1983 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency poethepoet to v0.33.1 \#1982 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency pytest to v8.3.5 \#1981 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency cryptography to v44.0.2 \#1980 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency ruff to v0.11.3 \#1978 ([renovate[bot]](https://github.com/apps/renovate))
v4.2.1 (2025-02-25)
Documentation:
- Typing animation in landing page is broken \#1969
Packaging:
- Update dependency pytest to \>=8.1.1 \#1974 (wren)
- Update dependency black to v25 \#1973 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency tzlocal to v5.3 \#1972 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency ruamel.yaml to v0.18.10 \#1967 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency jinja2 to v3.1.5 \#1966 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency cryptography to v44 \#1962 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency pytest-bdd to v8.1.0 \#1952 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency poethepoet to v0.32.2 \#1951 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency keyring to v25.6.0 \#1948 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency ruff to v0.9.7 \#1947 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency rich to v13.9.4 \#1946 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency tox to v4.24.1 \#1945 ([renovate[bot]](https://github.com/apps/renovate))
v4.2 (2024-11-17)
Implemented enhancements:
- Add Python 3.13 support \#1893
- Add calendar heatmap display format \#1759 (alichtman)
Fixed bugs:
- -contains doesn't accept multiple search terms, doesn't work with -and \#1877
- Tests failing on develop branch starting with pytest-bdd 7.1.2 \#1875
- Ignore color when used in a pipeline \#1839
- Fix -contains to allow multiple terms with "OR" logic unless -and is added \#1890 (eigenric)
Documentation:
- Recommend pipx as default installation method \#1888
- Remove documentation recommendation to install pipx through brew or pip \#1886
- Document security risks of using a computer that someone else has admin access to \#1793
- Recommend pipx as easiest installation method for all OSes and remove warning about apt \#1889 (micahellison)
- Docs accessibility checker failure - contrast ratio \#1934
- Docs accessibility test runner failing \#1932
Packaging:
- Update actions/cache action to v4 \#1847 ([renovate[bot]](https://github.com/apps/renovate))
- Update actions/setup-python action to v5 \#1848 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency black to v24.8.0 \#1923 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency cryptography to v43.0.3 \#1942 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency jinja2 to v3.1.4 \#1892 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency keyring to v25.4.1 \#1924 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency mkdocs to v1.6.1 \#1895 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency pa11y-ci to v3.1.0 \#1831 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency parse-type to v0.6.4 \#1936 ([renovate[bot]](https://github.com/apps/renovate))
- Update peter-evans/create-pull-request action to v7 \#1929 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency poethepoet to v0.29.0 \#1925 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency pytest to v7.4.4 \#1845 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency pytest-bdd to v7.3.0 \#1896 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency pytest-xdist to v3.6.1 \#1897 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency python-dateutil to v2.9.0 \#1898 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency requests to v2.32.3 \#1899 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency rich to v13.9.2 \#1937 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency ruamel.yaml to v0.18.6 \#1855 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency ruff to v0.7.0 \#1938 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency tox to v4.23.0 \#1935 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency typed.js to v2.1.0 \#1861 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency xmltodict to v0.14.2 \#1940 ([renovate[bot]](https://github.com/apps/renovate))
- Update nick-invision/retry action to v3 \#1851 ([renovate[bot]](https://github.com/apps/renovate))
- Update peter-evans/create-pull-request action to v6 \#1852 ([renovate[bot]](https://github.com/apps/renovate))
v4.1 (2023-11-04)
Build:
- Add Python 3.12 support \#1761 (micahellison)
- Set new required build fields in the ReadTheDocs config file \#1803 (micahellison)
- Replace flake8 and isort with ruff linter and add
black --check to linting step \#1763 (micahellison)Documentation:
- Add note about messages going to
stderr and the implication for piping \#1768 (micahellison)Packaging:
- Drop/replace ansiwrap dependency \#1191
- Use rich instead of ansiwrap to wrap text \#1693 (micahellison)
- Update actions/checkout action to v4 \#1788 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency black to v23.10.1 \#1811 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency cryptography to v41.0.5 \#1815 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency keyring to v24.2.0 \#1760 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency mkdocs to v1.5.3 \#1795 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency parse-type to v0.6.2 \#1762 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency poethepoet to v0.24.1 \#1806 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency pytest to v7.4.3 \#1816 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency pytest-bdd to v7 \#1807 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency rich to v13.6.0 \#1794 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency ruamel.yaml to v0.18.3 \#1813 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency ruff to v0.1.3 \#1810 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency tox to v4.11.3 \#1782 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency tzlocal to v5.2 \#1814 ([renovate[bot]](https://github.com/apps/renovate))
Special thanks:
- jrnl uses UTC instead of local time for entries in WSL/Ubuntu \#1607 investigated and reported upstream by giuseppedandrea
v4.0.1 (2023-06-20)
Fixed bugs:
- jrnl crashes when running
jrnl --list --format json and jrnl --list --format yaml \#1737
- Refactor --template code \#1711 (micahellison)Build:
- Fix linting issue in CI pipeline \#1743 (wren)
Packaging:
- Update dependency ruamel.yaml to v0.17.28 \#1749 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency requests to v2.31.0 \#1748 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency ruamel.yaml to v0.17.26 \#1746 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency tzlocal to v5 \#1741 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency pytest-xdist to v3.3.1 \#1740 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency poethepoet to v0.20.0 \#1735 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency mkdocs to v1.4.3 \#1733 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency rich to v13.3.5 \#1729 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency requests to v2.30.0 \#1728 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency tox to v4.5.1 \#1727 ([renovate[bot]](https://github.com/apps/renovate))
- Update peter-evans/create-pull-request action to v5 \#1719 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency flake8-simplify to v0.20.0 \#1716 ([renovate[bot]](https://github.com/apps/renovate))
v4.0 (2023-05-20)
🚨 BREAKING CHANGES 🚨
Deprecated:
- Drop Python 3.9 and use Python 3.11 official release \#1611 (micahellison)
Implemented enhancements:
- Add message with config location and docs location when installation is complete \#1695 (micahellison)
- Prompt to include colors in config when first running jrnl \#1687 (micahellison)
- Add ability to use template with
--template \#1667 (alichtman)
- Search for entries with no tags or stars with -not -starred and -not -tagged \#1663 (cjcon90)
- Refactor flow for easier access to some files \(avoid things like jrnl.Journal.Journal and jrnl.jrnl co-existing\) \#1662 (wren)
- Add more type hints \#1642 (outa)
- Add rich handler to debug logging \#1627 (wren)
- Rework Encryption to enable future support of other encryption methods \#1602 (wren)Fixed bugs:
- Only read text files that look like entries when opening folder journal \#1697 (micahellison)
- Save empty journal on install instead of just creating a zero-length file \#1690 (micahellison)
- Allow combinations of
--change-time, --delete, and --edit while correctly counting the number of entries affected \#1669 (wren)
- Don't save templated journal entries if the received raw text is the same as the template itself \#1653 (Briscoooe)
- Add tag to XML file when edited DayOne entry and is searchable afterward \#1648 (jonakeys)
- Update version key in config file after version changes \#1646 (jonakeys)Build:
- Update copyright notices for 2023 \#1660 (wren)
- Fix bug where changelog is always slightly out of date on release tags \#1631 (wren)
- Add
simplify plugin to linting checks \#1630 (wren)
- Add type hints \#1614 (outa)Documentation:
- Update contributing.md links in documentation \#1726 (ahosking)
- Fix various typos \#1718 (hezhizhen)
- Update documentation front page text \#1698 (micahellison)
- Support mkdocs 1.4.2 and fix its missing breadcrumb \#1691 (micahellison)
- Document temporary file extension behavior when using template \#1686 (micahellison)
- Document
-tagged, -not -tagged, and -not -starred \#1684 (micahellison)
- Update documentation about privacy and security in VSCode \#1680 (giuseppedandrea)
- Update documentation on temporary files naming \#1673 (giuseppedandrea)
- Update docs to include time and title in arguments with --edit \#1657 (pconrad-fb)
- Fix markup in "Advanced Usage" doc \#1655 (multani)
- Remove Windows 7 known issue since Windows 7 is no longer supported \#1636 (micahellison)Packaging:
- Lock ruamel.yaml version to v0.17.21 until bug is fixed \#1738 (wren)
- Update dependency black to v23.3.0 \#1715 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency cryptography to v40.0.2 \#1723 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency flake8-type-checking to v2.4.0 \#1714 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency flakeheaven to v3.3.0 \#1722 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency ipdb to v0.13.13 \#1703 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency poethepoet to v0.19.0 \#1709 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency pytest to v7.3.1 \#1720 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency pytest-xdist to v3.2.1 \#1705 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency rich to v13.3.4 \#1713 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency tox to v4.4.7 \#1707 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency tzlocal to v4.3 \#1708 ([renovate[bot]](https://github.com/apps/renovate))
v3.3 (2022-10-29)
Implemented enhancements:
- Change default config to use journal key \#1594 (micahellison)
- Add machine readable --list output \#1592 (apainintheneck)
Fixed bugs:
- Fix bug for new
--list --format options when no default journal is specified \#1621 (wren)
- Don't create empty file when attempting a YAML export to a non-existing folder \#1600 (outa)Build:
- Update
.gitignore \#1604 (wren)
- Fix Docs Accessibility Testing \#1588 (wren)
- Update to use renamed flag for brew bump-formula-pr \#1587 (wren)
- Update peter-evans/create-pull-request action to v4 \#1585 ([renovate[bot]](https://github.com/apps/renovate))
- Update actions/setup-python action to v4 \#1583 ([renovate[bot]](https://github.com/apps/renovate))
- Update actions/checkout action to v3 \#1582 ([renovate[bot]](https://github.com/apps/renovate))
- Update actions/cache action to v3 \#1581 ([renovate[bot]](https://github.com/apps/renovate))
- Replace Dependabot with Renovate \#1575 ([renovate[bot]](https://github.com/apps/renovate))Documentation:
- Add documentation about how the editor must be a blocking process \#1456
- Document that editors must be blocking processes \#1624 (micahellison)
- Remove wrong option in configuration file reference \#1618 (DSiekmeier)
- Update YAML export description in docs \#1591 (apainintheneck)
- Update dependency jinja2 to v3.1.2 \#1579 ([renovate[bot]](https://github.com/apps/renovate))
- Update dependency typed.js to v2.0.12 \#1578 ([renovate[bot]](https://github.com/apps/renovate))
- Add hint for how to get vi to go to end-of-file \#1563 (pjz)
Packaging:
- Pin dependencies \#1577 ([renovate[bot]](https://github.com/apps/renovate))
v3.2 (2022-09-03)
Implemented enhancements:
- Update issue & PR templates to use forms \#1559
- Suppress "Entry added" message if using default journal \#1561 (micahellison)
- Add message showing the number of search results \#1524 (apainintheneck)
Build:
- Quick fix follow up for actionlint \#1565 (wren)
Documentation:
- Remove note in contributing docs about gh-pages branch that we no longer use \#1566 (micahellison)
v3.1 (2022-08-21)
Implemented enhancements:
- Update tzlocal to v4.x and remove pytz dependency \#1528 (outa)
- Add linewrap option 'auto' \#1507 (jonakeys)
Fixed bugs:
- Update formatting function to better account for indentation \#1541 (wren)
- Export to file\(s\) when first line/title of an entry is very long \#1527 (jonakeys)
- Fixed index out of range error in fancy exporter \#1522 (apainintheneck)
Build:
- Add actionlint to testing pipelines \#1555 (wren)
- Fix docs pipeline, make docs tests easier to run locally and on different OSes \#1554 (wren)
Documentation:
- Reformat contributor appreciation on
--help screen \#1556 (xeruf)
- Clean up copyright notices and version screen \#1553 (wren)Packaging:
- Bump pyproject-flake8 from 0.0.1a4 to 0.0.1a5 \#1552 ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump keyring from 23.7.0 to 23.8.2 \#1551 ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump yq from 3.0.2 to 3.1.0 \#1546 ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump poethepoet from 0.15.0 to 0.16.0 \#1542 ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump keyring from 23.6.0 to 23.7.0 \#1539 ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump rich from 12.4.4 to 12.5.1 \#1538 ([dependabot[bot]](https://github.com/apps/dependabot))
v3.0 (2022-07-09)
🚨 BREAKING CHANGES 🚨
Deprecated:
- Drop support for Python 3.7 and 3.8 \#1412 (micahellison)
Implemented enhancements:
- Show name of journal when creating a password/encrypting \#1478 (jonakeys)
- Rework how all output and messaging works in jrnl \#1475 (wren)
- Implement --change-time flag \#1452 (richardjs)
- Reformat additional messages and finish centralizing exception handling \#1424 (wren)
- Reformat messages and add new centralized exception handling \#1417 (wren)
Fixed bugs:
- Display message when no edits take place \#1510 (apainintheneck)
- Fixed error related to display\_format in config file for some values \#1495 (apainintheneck)
- Create folder if config ends with \(back\)slash \#1492 (jonakeys)
-
-not search parameter no longer opens editor \#1490 (apainintheneck)
- Fix TypeError when using debug flag \#1484 (jonakeys)
- Prompt for password change when using 'jrnl --encrypt' on already encrypted journal \#1477 (jonakeys)
- Always expand all paths \(journals, templates, etc\) \#1468 (apainintheneck)
- The -not option with no arguments now outputs error instead of stack trace \#1466 (apainintheneck)
- Give a proper message when trying to use an empty config file \#1461 (jonakeys)
- Display "No entry to save, because no text was received" after empty entry on cmdline \#1459 (apainintheneck)
- Yaml export errors now don't show stack trace \#1449 (apainintheneck)Build:
- Pin
pytest-bdd to \<6.0 to temporarily avoid breaking changes \#1536 (wren)
- Reduce difference between local and CI environments \#1518 (wren)
- Add bdd tests for jrnl installation \#1513 (apainintheneck)
- Stop hardcoding bot info in changelog pipeline \#1506 (wren)
- Fix Poetry caching for accessibility tests \#1505 (wren)
- Implement Tox for testing \#1504 (wren)
- Replace make with python alternative \(poe\) \#1503 (wren)
- Update copyright year \#1502 (wren)
- Add Python 3.11 to PR tests \#1500 (micahellison)
- Pin jinja2 in docs requirements to keep readthedocs builds from failing \#1439 (micahellison)
- Tidy up git ignore \#1414 (nelnog)Documentation:
- Document --change-time in web-based docs' command line reference \#1471 (micahellison)
Packaging:
- Bump cryptography from 37.0.2 to 37.0.3 \#1516 ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump poethepoet from 0.13.1 to 0.14.0 \#1514 ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump keyring from 23.5.1 to 23.6.0 \#1499 ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump pyxdg from 0.27 to 0.28 \#1497 ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump keyring from 23.5.0 to 23.5.1 \#1487 ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump cryptography from 37.0.1 to 37.0.2 \#1467 ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump cryptography from 36.0.2 to 37.0.1 \#1462 ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump pytest from 7.1.1 to 7.1.2 \#1458 ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump pyproject-flake8 from 0.0.1a3 to 0.0.1a4 \#1447 ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump black from 22.1.0 to 22.3.0 \#1442 ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump mkdocs from 1.2.3 to 1.3.0 \#1441 ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump pyproject-flake8 from 0.0.1a2 to 0.0.1a3 \#1440 ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump pytz from 2021.3 to 2022.1 \#1438 ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump pytest from 7.0.1 to 7.1.1 \#1430 ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump cryptography from 36.0.1 to 36.0.2 \#1427 ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump yq from 2.13.0 to 2.14.0 \#1418 ([dependabot[bot]](https://github.com/apps/dependabot))
- Replace PyYAML with ruamel.yaml \#1416 (micahellison)
- Bump pytest from 6.2.5 to 7.0.0 \#1407 ([dependabot[bot]](https://github.com/apps/dependabot))
v2.8.4 (2022-02-12)
Implemented enhancements:
- Add hash as a default tag symbol for new jrnl config file \#1398 (micahellison)
- Add --config-file argument to use alternate config file at runtime \#1290 (samuelgregorovic)
Fixed bugs:
- Certs broken on website \#1408
- Add added option to \_print\_edited\_summary \#1366 (piero-vic)
Build:
- Improve handling of mocking logic in pytest \#1382 (wren)
- Use full Python version for GitHub Actions cache key \#1373 (micahellison)
- Use Python 3.10 stable in CI \#1362 (micahellison)
- Switch from poetry to poetry-core \#1359 (fabaff)
- Add more steps to
pytest, fully remove behave \#1347 (wren)Documentation:
- Fix styling on documentation sidebar \#1395 (wren)
- Added Recipe for visualizing Markdown in the CLI \#1354 (viegasfh)
- Fix recipe 'Launch a terminal for rapid logging' \#1351 (zapateo)
- Fix readme splash and add changelog link to readme \#1339 (micahellison)
- Add reference documentation to docs site and separate out "Tips and Tricks" and "External Editors" from "Recipes" \#1332 (micahellison)
- Document journal types \#1331 (micahellison)
Packaging:
- Bump asteval from 0.9.25 to 0.9.26 \#1400 ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump black from 21.7b0 to 22.1.0 \#1404 ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump cryptography from 3.4.8 to 36.0.1 \#1389 ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump ipython from 7.28.0 to 7.31.1 \#1401 ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump keyring from 23.1.0 to 23.5.0 \#1392 ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump mkdocs from 1.2.2 to 1.2.3 \#1355 ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump pytest from 6.2.4 to 6.2.5 \#1334 ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump pytest-bdd from 4.1.0 to 5.0.0 \#1368 ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump pytz from 2021.1 to 2021.3 \#1348 ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump yq from 2.12.2 to 2.13.0 \#1385 ([dependabot[bot]](https://github.com/apps/dependabot))
v2.8.3 (2021-09-06)
Fixed bugs:
- Fix deletion of entries on folder journal through
--delete flag \#1328 (micahellison)
- Warn when DayOne/directory journals have encrypt: true in config \#1325 (micahellison)
- Fix failure to import into directory journal \#1314 (micahellison)
- Allow emoji in config file in Windows by always opening it as unicode \#1313 (micahellison)Build:
- Set bash as default shell \#1324 (micahellison)
Packaging:
- Bump cryptography from 3.4.7 to 3.4.8 \#1329 ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump keyring from 23.0.1 to 23.1.0 \#1318 ([dependabot[bot]](https://github.com/apps/dependabot))
v2.8.2 (2021-07-31)
Build:
- Add CI tests for latest dev Python build \#1273
- Fix lock file from stable Poetry version \#1298 (wren)
- Change all YAML FullLoader calls to SafeLoader \#1285 (micahellison)
- Remove useless shebangs and executable permissions \#1283 (musicinmybrain)
- Add Python 3.10 support \#1271 (micahellison)
- Ensure that line endings in all py files are Linux style instead of Windows \#1250 (micahellison)
- Remove
--version from brew release workflow \#1233 (wren)
- Move test suite to Pytest \(replace Behave\) \#1193 (wren)Documentation:
- Add documentation about saved passwords in Windows \#1301 (micahellison)
- Add security.md \#1299 (micahellison)
Packaging:
- Bump mkdocs from 1.2.1 to 1.2.2 \#1307 ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump python-dateutil from 2.8.1 to 2.8.2 \#1302 ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump black from 21.5b1 to 21.5b2 \#1254 ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump black from 21.5b0 to 21.5b1 \#1244 ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump black from 20.8b1 to 21.5b0 \#1241 ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump pytest from 6.2.3 to 6.2.4 \#1240 ([dependabot[bot]](https://github.com/apps/dependabot))
v2.8.1 (2021-04-24)
Fixed bugs:
- More graceful handling of low linewrap values \#1219 (sriniv27)
Documentation:
- Update absolute URLs to preview images in metatags \#1229 (maebert)
- Docs: Add emacs as external editor to recipes \#1220 (mandarvaze)
Packaging:
- Bump pytest from 6.2.2 to 6.2.3 \#1228 ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump cryptography from 3.4.6 to 3.4.7 \#1223 ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump keyring from 23.0.0 to 23.0.1 \#1222 ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump pyflakes from 2.3.0 to 2.3.1 \#1221 ([dependabot[bot]](https://github.com/apps/dependabot))
v2.8 (2021-03-27)
Implemented enhancements:
- Add
--config-override feature \#1169 (sriniv27)Fixed bugs:
- Fix bug that prevented --format pretty and --format short from working \#1177 (sriniv27)
Build:
- Fix broken brew release process \#1211 (micahellison)
Packaging:
- Bump pyflakes from 2.2.0 to 2.3.0 \#1215 ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump keyring from 22.3.0 to 23.0.0 \#1213 ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump keyring from 22.0.1 to 22.3.0 \#1210 ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump asteval from 0.9.22 to 0.9.23 \#1209 ([dependabot[bot]](https://github.com/apps/dependabot))
v2.7.1 (2021-02-27)
Full ChangelogFixed bugs:
- Make journal selection behavior more consistent when there's a colon with no date \#1164 (wren)
Documentation:
- Update documentation about journal-level config values \#1196
- update per-journal config documentation \#1199 (sriniv27)
Packaging:
- Bump cryptography from 3.4.4 to 3.4.6 \#1195 ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump asteval from 0.9.21 to 0.9.22 \#1189 ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump cryptography from 3.3.1 to 3.4.4 \#1188 ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump yq from 2.11.1 to 2.12.0 \#1186 ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump pytz from 2020.5 to 2021.1 \#1174 ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump keyring from 21.8.0 to 22.0.1 \#1168 ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump pytest from 6.2.1 to 6.2.2 \#1167 ([dependabot[bot]](https://github.com/apps/dependabot))
v2.7 (2021-01-23)
Implemented enhancements:
- Add new date format \(
--format date\) for heatmapping \#1146 (KarimPwnz)
- Add new -today-in-history, -month, -day, and -year search filters \#1145 (KarimPwnz)
- Allow custom extensions when editing \(for easier syntax highlighting\) \#1139 (KarimPwnz)Fixed bugs:
- Editor can't be launched on Windows when using full path to editor executable \#1096
- Fix OS compatibility issues for editors with spaces, slashes, and quotes \#1153 (micahellison)
- Add delimiters in YAML format \#1150 (Seopril)
- Fix keyring error handling \#1138 (KarimPwnz)
- Notify user when config directory can't be created because there is already a file with the same name \#1134 (micahellison)
Build:
- Fix homebrew release, add options for release pipeline \#1154 (wren)
- Fix changelog generator \#1127 (wren)
Documentation:
- add instructions to add VSCode as an external editor for Windows \#1155
- Clarify editor documentation for PATH variable and VS Code \#1160 (micahellison)
- Emphasize installing dependencies before testing \#1148 (gumatias)
- Clarify installation documentation \(\#1097\) \#1137 (Seopril)
- Fix broken search bar in docs site \#1135 (wren)
- Fix search on docs site \#1133 (wren)
- Add packaging label to changelog generator config \#1132 (wren)
- Fix failing contrast test in accessibility tools on docs site \#1126 (wren)
Packaging:
- Bump pyyaml from 5.3.1 to 5.4.1 \#1158 ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump keyring from 21.7.0 to 21.8.0 \#1136 ([dependabot[bot]](https://github.com/apps/dependabot))
- Bump pytz from 2020.4 to 2020.5 \#1130 ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview))
- Bump pytest from 6.2.0 to 6.2.1 \#1129 ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview))
- Bump keyring from 21.5.0 to 21.7.0 \#1128 ([dependabot-preview[bot]](https://github.com/apps/dependabot-preview))
v2.6 (2020-12-20)
Implemented enhancements:
- Add ability to put --edit partly through a cli entry to move it to the editor \#1091 (wren)
- Allow --edit flag partway through an entry \#906
Fixed bugs:
- Check for readline module instead of Windows when initializing autocomplete in install \#1104 (micahellison)
- Directory export crashes in Windows with certain characters - UnicodeEncodeError: 'locale' codec can't encode character \#1089
- Fix Unicode encoding failure in directory export when creating filenames from journal titles with certain characters \#1090 (micahellison)
- Typo fix in output.py: "us" -\> "use" \#1117 (signal-9)
Build:
- Add a release workflow for PyPI in CI \(Github Actions\) \#1095 (wren)
- Add automatic deployment for homebrew releases \(and prereleases\) \#1111 (wren)
- Add changelog generation workflow to github actions \#1086 (wren)
- Add fix for changelog conditional always returning false \#1101 (wren)
- Change approach for docs workflow to use pa11y-ci \#1116 (wren)
- Changelog fixes \#1088 (wren)
- Fix trigger for changelog \#1114 (wren)
- Make changelog auto exclude stale and wontfix issues \#1081 (wren)
- Migrate to Github Actions from Travis CI \#1060
- More changelog fixes \#1092 (wren)
- Standardize version regex in release pipeline \#1124 (wren)
- Udpate build badge in readme to point at github instead of travis \#1094 (wren)
- Update all dependencies and lock file \#1110 (wren)
- get rid of travis and circle configs \(in favor of github actions\) \#1082 (wren)
Documentation:
- Add visual header to readme \#1085 (wren)
- Comply with GPL by acknowledging all authors and including license info in each source file \#1121 (micahellison)
- Fix lone closing parenthesis \#1118 (maebert)
- Make docs site \(jrnl.sh\) fully meet Web Content Accessibility Guidelines \(WCAG\) 2.1 \#1105 (wren)
- Small accessibility fixes for docs site \#1122 (wren)
v2.5 (2020-11-07)
Implemented enhancements:
- 🚨 Deprecate Python 3.6 🚨 \#992
- Add support for Python 3.9 \#1017
- Implement arg parsing library \#866
- Rename
--export to --format and --export -o to --format --file \#814
- Pull functionality out of util.py \#737
- Support -not for individual @tag in the command line \#374
- Add punctuation more commonly used in Asian languages \(ellipsis\) to sentence parsing \#1044 (felixonmars)
- Clean up help screen, get rid of util.py \#1027 (wren)Fixed bugs:
- Extra error when writing empty entry \#1048
- 'Edit on Github' Button in Documentation not working \#1039
- Decrypt jrnl file in dropbox on another machine fails \#1019
- Listing jrnl entries by tag for non default journal seem to not work as expected. \#875
- -and parameter seems to only work for the default journal \#520
- Disable logging by default \#1053 (wren)
- Partial refactor of cli.py \(mainly help screen and arg parsing\) \#991 (wren)
Build:
- Add accessibility testing for docs site \(https://jrnl.sh) \#1067 (wren)
- Add circle ci config file for linux tests \#1063 (wren)
- Lots of test refactoring \#1042 (wren)
- Add support for Python 3.9 build testing \#1018 (micahellison)
- Resolve Travis/Windows/pip issues with upgrade to cryptography 3.0 \#1016 (micahellison)
Updated documentation:
- Clarify usage output between export and reading sections \#344
- Fix "Edit on GitHub" button on docs site \#1043 (matildepark)
- Correct typos in CONTRIBUTING.md \#1040 (felixonmars)
- Change styling of terminal on docs site, small copy changes \#1038 (wren)
- Documentation updates \#1032 (micahellison)
- Updated advanced.md in docs to reflect all four subkeys under colors … \#1023 (DacodaNelson)
- Update github issue templates to use new diagnostic command \#1022 (wren)
v2.4.5 (2020-07-31)
Fixed bugs:
- Add missing dependency \(packaging\) \#1011 (wren)
v2.4.4 (2020-07-25)
Implemented enhancements:
- Add --diagnostic argument \#984 (micahellison)
- Add tags to json and xml exporters \#975 (eshrh)
- Add extended metadata support for DayOne Classic \#928 (MinchinWeb)
Fixed bugs:
- Allow editing of DayOne entries \#1001 (minchinweb, micahellison, wren)
- Create journal with absolute path when no path is specified \#972 (eshrh)
Build:
- Add unit testing via pytest \#987 (micahellison)
- Rename master branch to release \#985 (wren)
Updated documentation:
- Fix readme link to submit an issue \#1002 (wren)
- Extensive modifications to overview.md \#957 (guydebros)
v2.4.3 (2020-06-13)
Implemented enhancements:
- Speed up jrnl by 10%, improve slow imports \#959 (wotgl)
Fixed bugs:
- Fix set\_keychain errors \#964 (eshrh)
- Fix title splitting logic to account for both newlines and periods \#958 (eshrh)
- Fix editor config when an argument with a space is used \#953 (wren)
- Ask for password before adding entry instead of after \#951 (ollybritton)
- Fix duplicate text in multiple tag search \#948 (micahellison)
Build:
- Fix for hanging Windows tests on Travis \#969 (wren)
- Ensure test data is always checked out with LF line endings \#965 (micahellison)
- Clean up templates and issues \#954 (wren)
- Update lockbot comment to encourage linking to issue \#941 (MinchinWeb)
Updated documentation:
- Cleaned up usage.md for clarity, formatting, and grammar. \#956 (guydebros)
v2.4.2 (2020-05-09)
Fixed bugs:
- Prevent filtered delete from deleting journal \#935 (micahellison)
Build:
- Make sure testing cleans up after itself \#940 (wren)
- Allow most recent pytz version and update dependencies \#937 (micahellison)
- Use gitlab to trigger releases in pipeline \#947 (wren)
Updated documentation:
- Change jrnl.sh GitHub new issue link to issue template chooser \#936 (micahellison)
- Improve privacy, security, and encryption documentation \#896 \#925 (micahellison)
v2.4.1 (2020-05-02)
Fixed bugs:
- Disable --delete due to critical bug \#934 (wren)
v2.4 (2020-04-25)
Implemented enhancements:
- Update keyring version from "^19.0" to "\>19.0, \<22.0" \#914 (micahellison)
- Allow tzlocal version \>1.5 \<3.0 instead of \>1.5 \<2.0 \#900 (micahellison)
- Interactive delete \#650 (alichtman)
- Upgrade license to GPLv3 \#918 (wren, micahellison)
Fixed bugs:
- Fix Python 3.9 incompatibility by updating plistlib \#909 (MinchinWeb)
- Ensure exported entries end in a newline for Markdown and YAML exporters \#908 (MinchinWeb)
- Fix typo in YAML exporter \("stared" -\> "starred"\) \#907 (MinchinWeb)
- Fix for upgrade with missing journal \#796 (dbxnr)
Build:
- Update Python versions in pipeline \#910 (MinchinWeb)
- Update Poetry requirements for testing latest Python version \#898 (wren)
- Update makefile to match pipeline better \#919 (wren)
Updated documentation:
- Update the code of conduct \#913 (wren)
- Update twitter buttons, contribution in footer \#905 (wren)
- Change install doc guideline from pip to pipx \#904 (micahellison)
- Update twitter buttons, contribution in footer \#905 (wren)
- Clean up readme file \#924 (wren)
- Clarify that editing config isn't always destructive \#923 (Epskampie)
v2.3 (2020-03-21)
Implemented enhancements:
- Update YAML exporter to handle Dayone format \#773 (MinchinWeb)
- Pretty print journal entries (add color) \#692 (alichtman)
- Allow journals to be saved into multiple files in a directory structure \#485 (notbalanced)
Fixed bugs:
- Listing all entries in DayOne Classic journal throws IndexError \#786 (MinchinWeb)
- Add UTC support for failing DayOne tests \#785 (MinchinWeb)
Build:
- Stop multiple changelog generators from crashing into each other \#845 (wren)
- Don't re-run tests on deployment \#839 (wren)
- Put back build lines in Poetry config \#838 (wren)
- Restore emoji test \#837 (micahellison)
- Fix crashing unicode Travis tests on Windows and fail build if Windows tests fail \#836 (micahellison)
- Remove poetry from build system in pyproject config to fix
brew install \#830 (wren)
- Fix all skipped tests on Travis Windows builds by preserving newlines \#823 (micahellison)Updated documentation:
- Update url for "beautiful timeline" in export.md \#879 (NGenetzky)
- Docs: Fix broken links in recipes.md \#854 (lrvl)
- Fix configuration slashes and indentation in advanced usage documentation \#852 (aallbrig)
- Fix fish history instructions. \#846 (aureooms)
- Update site description \#841 (wren)
- Get rid of dumb sex joke \#840 (wren)
- Updating/clarifying template explanation \#829 (heymajor)
v2.2 (2020-02-01)
Implemented enhancements:
- Full text search \(case insensitive\) with "-contains" \#740 (empireshades)
- Reduce startup time by 55% \#719 (maebert)
- Refactor password logic to prevent accidental password leakage \#708 (pspeter)
- Password confirmation \#706 (pspeter)
Fixed bugs:
- Close temp file before passing it to editor to prevent file locking issues in Windows \#792 (micahellison)
- Fix crash while encrypting a journal on first run without saving password \#789 (dbxnr)
Build:
- Fix issue where jrnl would always out 'source' for version, fix Poetry config to build and publish properly \#820 (wren)
- Unpin poetry \#808 (wren)
- Fix all skipped tests on Travis Windows builds by preserving newlines \#823 (micahellison)
- Change PyPI auth method in build pipeline \#807 (wren)
- Automagically update the changelog you see before your very eyes! \#806 (wren)
- Update Black version and lock file to fix builds on develop branch \#784 (wren)
- Run black formatter on codebase for standardization \#778 (wren)
- Skip Broken Windows Tests \#772 (wren)
- Black Formatter \#769 (MinchinWeb)
- Update lock file and testing suite for Python 3.8 \#765 (wren)
- Fix CI config to only deploy once \#761 (wren)
- More Travis-CI Testing \#759 (MinchinWeb)
Updated documentation:
- Explain how fish can be configured to exclude jrnl commands from history by default \#809 (aureooms)
- Remove merge marker in recipes.md \#782 (markphelps)
- Fix merge conflict left-over \#767 (thejspr)
- Display header in docs on mobile devices \#763 (maebert)
v2.1.1 (2019-11-26)
Implemented enhancements:
- Support Python 3.6+ \#710 (pspeter)
- Drop Python 2 support, add mocks in tests \#705 (pspeter)
Fixed bugs:
- Prevent readline usage on Windows, which was causing Active Python crashes on install \#751 (micahellison)
- Exit jrnl if no text entered into editor \#744 (alichtman)
- Fix crash when no keyring backend available \#699 (pspeter)
- Fix parsing Journals using a little-endian date format \#694 (pspeter)
Updated documentation:
- Update developer documentation \#752 (micahellison)
- Create templates for issues and pull requests \#679 (C0DK)
- Smaller doc fixes \#649 (maebert)
- Move to mkdocs \#611 (maebert)
v2.1.post2 (2019-11-11)
Fixed bugs:
- Expand paths that use ~ to full path \#704 (MinchinWeb)
Build:
- Separate local dev from pipeline releases \#684 (wren)
- Update version handling in source and travis deployments \#683 (wren)
- Use Poetry for dependency management and deployments \#612 (maebert)
Updated documentation:
- Fix typos, spelling \#734 (MinchinWeb)
v2.0.1 (2019-09-26)
Implemented enhancements:
- Switch to hashmark Markdown headers on export \(Mk II\) \#639 (MinchinWeb)
- Add '-not' flag for excluding tags from filter \#637 (jprof)
- Handle KeyboardInterrupt when installing journal \#550 (silenc3r)
Fixed bugs:
- Change pyYAML required version \#660 (etnnth)
Updated documentation:
- Fix references to Sphinx in CONTRIBUTING.md \#655 (maebert)
v2.0.0 (2019-08-24)
🚨 BREAKING CHANGES 🚨
Implemented enhancements:
- Change cryptographic backend from PyCrypto to cryptography.io
- Config now respects XDG conventions and may move accordingly
- Config name changed from
journals.jrnl_name.journal to journals.jrnl_name.pathFixed bugs:
- Confirm that each journal can be parsed during upgrade, and abort upgrade if not \#650 (micahellison)
- Escape dates in square brackets \#644 (wren)
- Create encrypted journal \#641 (gregorybodnar)
- Resolve issues around unreadable dates to allow markdown footnotes and prevent accidental deletion \#623 (micahellison)
- Update crypto module \#610 \#621 (wren)
- Fix issue \#584 YAMLLoadWarning \#585 (wren)
Deprecated:
- Deprecate Python 2 \#624 (micahellison)
- Config now saved as YAML (no more JSON)
Build:
- change pinned label to a super cool emoji ⭐️ \#646 (wren)
- Update Travis build badge and restore pypi badges \#603 (micahellison)
Updated documentation:
- Mention lack of Day One support and relevant history in readme \#608 (micahellison)
- Add a code of conduct file \(rather than adding to contributing\) \#604 (wren)
- Update docs to reflect merging jrnl-plus fork back upstream \#601 (micahellison)
- Add instructions for VS Code \#544 (emceeaich)
v1.9 (2014-07-21)
* __1.9.5__ Multi-word tags for DayOne Journals
* __1.9.4__ Fixed: Order of journal entries in file correct after --edit'ing
* __1.9.3__ Fixed: Tags at the beginning of lines
* __1.9.2__ Fixed: Tag search ignores email-addresses (thanks to @mjhoffman65)
* __1.9.1__ Fixed: Dates in the future can be parsed as well.
* __1.9.0__ Improved: Greatly improved date parsing. Also added an
-on option for filteringv1.8 (2014-05-22)
* __1.8.7__ Fixed: -from and -to filters are inclusive (thanks to @grplyler)
* __1.8.6__ Improved: Tags like @C++ and @OS/2 work, too (thanks to @chaitan94)
* __1.8.5__ Fixed: file names when exporting to individual files contain full year (thanks to @jdevera)
* __1.8.4__ Improved: using external editors (thanks to @chrissexton)
* __1.8.3__ Fixed: export to text files and improves help (thanks to @igniteflow and @mpe)
* __1.8.2__ Better integration with environment variables (thanks to @ajaam and @matze)
* __1.8.1__ Minor bug fixes
* __1.8.0__ Official support for python 3.4
v1.7 (2013-12-22)
* __1.7.22__ Fixed an issue with writing files when exporting entries containing non-ascii characters.
* __1.7.21__ jrnl now uses PKCS#7 padding.
* __1.7.20__ Minor fixes when parsing DayOne journals
* __1.7.19__ Creates full path to journal during installation if it doesn't exist yet
* __1.7.18__ Small update to parsing regex
* __1.7.17__ Fixes writing new lines between entries
* __1.7.16__ Even more unicode fixes!
* __1.7.15__ More unicode fixes
* __1.7.14__ Fix for trailing whitespaces (eg. when writing markdown code block)
* __1.7.13__ Fix for UTF-8 in DayOne journals
* __1.7.12__ Fixes a bug where filtering by tags didn't work for DayOne journals
* __1.7.11__
-ls will list all available journals (Thanks @jtan189)
* __1.7.10__ Supports -3 as a shortcut for -n 3 and updates to tzlocal 1.1
* __1.7.9__ Fix a logic bug so that jrnl -h and jrnl -v are possible even if jrnl not configured yet.
* __1.7.8__ Upgrade to parsedatetime 1.2
* __1.7.7__ Cleaned up imports, better unicode support
* __1.7.6__ Python 3 port for slugify
* __1.7.5__ Colorama is only needed on Windows. Smaller fixes
* __1.7.3__ Touches temporary files before opening them to allow more external editors.
* __1.7.2__ Dateutil added to requirements.
* __1.7.1__ Fixes issues with parsing time information in entries.
* __1.7.0__ Edit encrypted or DayOne journals with jrnl --edit.
v1.6 (2013-11-05)
* __1.6.6__ -v prints the current version, also better strings for windows users. Furthermore, jrnl/jrnl.py moved to jrnl/cli.py
* __1.6.5__ Allows composing multi-line entries on the command line or importing files
* __1.6.4__ Fixed a bug that caused creating encrypted journals to fail
* __1.6.3__ New, pretty, _useful_ documentation!
* __1.6.2__ Starring entries now works for plain-text journals too!
* __1.6.1__ Attempts to fix broken config files automatically
* __1.6.0__ Passwords are now saved in the key-chain. The
password field in .jrnl_config is soft-deprecated.v1.5 (2013-08-06)
* __1.5.7__ The
~ in journal config paths will now expand properly to e.g. /Users/maebert
* __1.5.6__ Fixed: Fixed a bug where on OS X, the timezone could only be accessed on administrator accounts.
* __1.5.5__ Fixed: Detects DayOne journals stored in ~/Library/Mobile Data as well.
* __1.5.4__ DayOne journals can now handle tags
* __1.5.3__ Fixed: DayOne integration with older DayOne Journals
* __1.5.2__ Soft-deprecated -to for filtering by time and introduces -until instead.
* __1.5.1__ Fixed: Fixed a bug introduced in 1.5.0 that caused the entire journal to be printed after composing an entry
* __1.5.0__ Exporting, encrypting and displaying tags now takes your filter options into account. So you could export everything before May 2012: jrnl -to 'may 2012' --export json. Or encrypt all entries tagged with @work into a new journal: jrnl @work --encrypt work_journal.txt. Or display all tags of posts where Bob is also tagged: jrnl @bob --tagsv1.4 (2013-07-22)
* __1.4.2__ Fixed: Tagging works again
* __1.4.0__ Unifies encryption between Python 2 and 3. If you have problems reading encrypted journals afterwards, first decrypt your journal with the __old__ jrnl version (install with
pip install jrnl==1.3.1, then jrnl --decrypt), upgrade jrnl (pip install jrnl --upgrade) and encrypt it again (jrnl --encrypt).v1.3 (2013-07-17)
* __1.3.2__ Everything that is not direct output of jrnl will be written stderr to improve integration
* __1.3.0__ Export to multiple files
* __1.3.0__ Feature to export to given output file
v1.2 (2013-07-15)
* __1.2.0__ Fixed: Timezone support for DayOne
v1.1 (2013-06-09)
* __1.1.1__ Fixed: Unicode and Python3 issues resolved.
* __1.1.0__
* JSON export exports tags as well.
* Nicer error message when there is a syntactical error in your config file.
* Unicode support
v1.0 (2013-03-04)
* __1.0.5__ Backwards compatibility with
parsedatetime 0.8.7
* __1.0.4__
* Python 2.6 compatibility
* Better utf-8 support
* Python 3 compatibility
* Respects the XDG_CONFIG_HOME environment variable for storing your configuration file (Thanks evaryont)* __1.0.3__
* Removed clint in favour of colorama
* Fixed: Fixed a bug where showing tags failed when no tags are defined.
* Fixed: Improvements to config parsing (Thanks alapolloni)
* Fixed: Fixes readline support on Windows
* Fixed: Smaller fixes and typos
* __1.0.1__ (March 12, 2013) Fixed: Requires parsedatetime 1.1.2 or newer
* __1.0.0__
* Integrates seamlessly with DayOne
* Each journal can have individual settings
* Fixed: A bug where jrnl would not go into compose mode
* Fixed: A bug where jrnl would not add entries without timestamp
* Fixed: Support for parsedatetime 1.x
v0.3 (2012-05-24)
* __0.3.2__ Converts
\n to new lines (if using directly on a command line, make sure to wrap your entry with quotes).
* __0.3.1__
* Supports deleting of last entry.
* Fixed: Fixes a bug where --encrypt or --decrypt without a target file would not work.
* Supports a config option for setting word wrap.
* Supports multiple journal files.
* __0.3.0__
* Fixed: Dates such as "May 3" will now be interpreted as being in the past if the current day is at least 28 days in the future
* Fixed: Bug where composed entry is lost when the journal file fails to load
* Changed directory structure and install scripts (removing the necessity to make an alias from jrnl to jrnl.py)v0.2 (2012-04-16)
* __0.2.4__
* Fixed: Parsing of new lines in journal files and entries
* Adds support for encrypting and decrypting into new files
* __0.2.3__
* Adds a
-short option that will only display the titles of entries (or, when filtering by tags, the context of the tag)
* Adds tag export
* Adds coloured highlight of tags (by default, highlights all tags - when filtering by tags, only highlights search tags)
* .jrnl_config will get automatically updated when updating jrnl to a new version
* __0.2.2__
* Adds --encrypt and --decrypt to encrypt / decrypt existing journal files
* Adds markdown export (kudos to dedan)
* __0.2.1__ Submitted to PyPi.
* __0.2.0__
* Encrypts using CBC
* Fixed: key has been renamed to password in config to avoid confusion. (The key use to encrypt and decrypt a journal is the SHA256-hash of the password.)v0.1 (2012-04-13)
* __0.1.1__
* Fixed: Removed unnecessary print commands
* Created the documentation
* __0.1.0__
* Supports encrypted journals using AES encryption
* Support external editors for composing entries
* __0.0.2__
* Filtering by tags and dates
* Fixed: Now using dedicated classes for Journals and entries
v0.0 (2012-03-29)
* __0.0.1__ Composing entries works. That's pretty much it.
\ This Changelog was automatically generated by github_changelog_generator*
---
CONTRIBUTING
Contributing
See "Contributing" in the
docs directory.---
README
<p align="center">
<a href="https://jrnl.sh">
<img align="center" src="https://raw.githubusercontent.com/jrnl-org/jrnl/main/docs_theme/assets/readme-header.png"/>
</a>
</p>
jrnl
[](https://github.com/jrnl-org/jrnl/actions?query=workflow%3ATesting)
[](https://pepy.tech/project/jrnl)
[](https://pypi.python.org/pypi/jrnl/)
[](https://formulae.brew.sh/formula/jrnl)
[](https://gitter.im/jrnl-org/jrnl)
[](https://github.com/jrnl-org/jrnl/blob/main/CHANGELOG.md)
====
_To get help, submit an issue on
GitHub._
jrnl is a simple journal application for the command line.You can use it to easily create, search, and view journal entries. Journals are
stored as human-readable plain text, and can also be encrypted using AES
encryption.
In a Nutshell
To make a new entry, just enter
` sh
jrnl yesterday: Called in sick. Used the time to clean the house and write my
book.
`yesterday: is interpreted by jrnl as a timestamp. Everything until the
first sentence ending (either ., ?, or !) is interpreted as the title, and
the rest as the body. In your journal file, the result will look like this: [2012-03-29 09:00] Called in sick.
Used the time to clean the house and write my book.
If you just call
jrnl, you will be prompted to compose your entry - but you
can also configure _jrnl_ to use your external editor.For more information, please read the
documentation.
Contributors
Maintainers
Our maintainers help keep the lights on for the project:
* Jonathan Wren (wren)
* Micah Ellison (micahellison)
* Aaron Lichtman (alichtman)
Please thank them if you like
jrnl!Code Contributors
This project is made with love by the many fabulous people who have contributed.
jrnl couldn't exist without each and every one of you!<a href="https://github.com/jrnl-org/jrnl/graphs/contributors"><img
src="https://opencollective.com/jrnl/contributors.svg?width=890&button=false"
/></a>
If you'd also like to help make
jrnl better, please see our contributing
documentation.Financial Backers
Another way show support is through direct financial contributions. These funds
go to covering our costs, and are a quick way to show your appreciation for
jrnl`.Become a financial contributor
and help us sustain our community.
<a href="https://opencollective.com/jrnl"><img
src="https://opencollective.com/jrnl/individuals.svg?width=890"></a>
---
SECURITY
Security
If you've discovered a potential security issue in jrnl, please contact the maintainers at [email protected].
You can also feel free to open an issue (but please don't disclose the vulnerability) in case the email goes to spam.
You can find known privacy and security issues in our documentation.
---
Mkdocs.Yml
site_name: jrnl
site_url: https://jrnl.sh
theme:
name: readthedocs
custom_dir: docs_theme
static_templates:
- index.html
watch:
- docs
- docs_theme
extra_css:
- https://fonts.googleapis.com/css?family=Open+Sans:300,600
- assets/colors.css
- assets/theme.css
- assets/highlight.css
markdown_extensions:
- admonition
repo_url: https://github.com/jrnl-org/jrnl/
edit_uri: edit/main/docs/
site_author: jrnl contributors
site_description: Collect your thoughts and notes without leaving the command line.
nav:
- Overview: overview.md
- 'User Guide':
- Quickstart: installation.md
- Basic Usage: usage.md
- Encryption: encryption.md
- Journal Types: journal-types.md
- Privacy and Security: privacy-and-security.md
- Formats: formats.md
- Advanced Usage: advanced.md
- 'External Editors': external-editors.md
- 'Tips and Tricks': tips-and-tricks.md
- 'Reference':
- Command Line: reference-command-line.md
- Configuration File: reference-config-file.md
- 'Contributing':
- Contributing to jrnl: contributing.md
---