jrnl/docs/recipes.md
Suhas 4f79803885
Allow runtime configuration overrides from the commandline (#1169)
Add --config-override feature

* add test and argument handler for runtime override of configurations.
* identify location to apply override in "main"
* update gitignore
* remove unneeded import
* add jrnl interface test for overriden configurations
* trivial whitespace change
* implement runtime override
* make format
* refactor override unittest
* clean up unused import
* start writing integration test
* add linewrap override scenario
* implement editor override step
* add dev dependencies on pytest -mock and -cov
* make format
* remove unused imports
* make format
* rename --override to --config-override
* move override implementation into own module
* begin TDD of dot notated overrides
* rewrite behavior scenario
* implement recursive config overrides
* clean up unittests
* iterate on behave step
* make format
* cleanup
* move override behave tests out of core
* refactor recursive code
* make format
* code cleanup
* remove unused import
* update test config
* rewrite test for better mock call expect
* make format
* binary search misbehaving windows test
* unittest multiple overrides
* uncomment dot notation unittest
* add multiple override scenario spec
* make format
* make format
* update unittests for new syntax
* update integ tests for new syntax
* update gitignore
* guard override application
* deserialize function as return type
* make format
* organize deserialization unittests
* better, more specific behave tests
* test different editor launch commands
* formatting
* handle datatypes in deserialization and update helptext
* stick to config convention in testbed
* update tests ith better verifications
* make format
* space
* review feedbac
* make format
* skip on win
* update deps
* update tests with better verifications
make format
space
review feedbac
* skip on win
* update deps
* refactor deserialization
organize test_parse_args
make format
* skip on win
* refactor deserialization
organize test_parse_args
make format
* update tests ith better verifications
* make format
* space
* make format
* document apply_overrides
* update gitignore
* document config-override enhancement
* Simplify config override syntax (#5)
* update tests and expected behavior
* clean up arg parsing tests
* update deserialization
* update deserialization
* config argparse action
* update override application logic
* update tests; delete unused imports
* override param must be list
* update docstring
* update test input to SUT
* update remaining override unittests
* make format
* forgot to update CLI syntax
* update documentation to sphinx style
* variable renames
* Lockfile merge (#7)
* Add brew and gitter badges to README
* Update changelog [ci skip]
* Make journal selection behavior more consistent when there's a colon with no date (#1164)
* Simplify config override syntax (#8)
* update tests and expected behavior
* clean up arg parsing tests
* update deserialization
* update deserialization
* config argparse action
* update override application logic
* update tests; delete unused imports
* override param must be list
* update docstring
* update test input to SUT
* update remaining override unittests
* make format
* forgot to update CLI syntax
* formatting
* Update pyproject.toml
* update lockfile to remove pytest-cov and pytest-mock deps
* update docs
* reuse existing mock; delete unneeded code
* move overrides earlier in the execution
use existing configs instead of custom
make format
clean up imports
* update for passworded access
context.parser -> parsed_args
* test that no editor is launched
* remove unnecessary mocks
* rename variable for intent
* reinstate getpass deletion
* update gitignore
* capture failure mode
* remove unneeded imports
* renamed variable
* delete redundant step
* comment on step
* clean up step behavior description
* [WIP] lock down journal access behavior
* skip -> wip
* correct command for overriding journal via dot keys
* update wip test for updating a "temp" journal and then reading baack its entries
* remove "mock" from poetry file
* make CI happy
* complex behavior sequence for default journal override
* separate out smaller pieces of logic
test that apply_overrides acts on base configuration and not the copy
* defer modification of loaded configuration to update_config
remove unused fixtures
delete complicated UT since behavior is covered in overrides.feature integ test
delete redundant UT
* Update .gitignore
* remove skip_win
* forward override unpacking to yaml library
* merge config override step with existing config_var step in core
delete config_override step
unify step description syntax
* delete unused and redundant code
* rebases are hard
* remove wip tag from test
* remove skipped tests for windows
* Address code review
yield -> return
remove needless copy
adjust spacing
re-inline args return
reset packaging info to e6c0a16342
revert package version for this PR
* consolidate imports
* Defer config_override unpacking to dict *after* base config is loaded
store cli overrides without unpacking just yet
move deserialize_config_args to config module
delete custom Action class for config operations
apply [k,v] -> {k, v} for each override
update test data
update import
* rename deserialize_config_args to better express intent
make format
2021-03-02 18:47:57 -08:00

7.2 KiB

FAQ

Recipes

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

jrnl @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

jrnl @fixed -starred -n 10 -to "jan 2013" --short

To get a short summary of the 10 most recent, favourited entries before January 1, 2013 that are tagged with @fixed.

Statistics

How much did I write last year?

jrnl -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?

expr $(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 this

echo `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_profile

jrnlimport () {
  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.

A template is a code snippet that makes it easier to use repeated text each time a new journal entry is started. There are two ways you can utilize templates in your entries.

1. Command line arguments

If you had a template.txt file with the following contents:

My Personal Journal
Title: 

Body:

The template.txt file could be used to create a new entry with these command line arguements:

jrnl < template.txt     # Imports template.txt as the most recent entry
jrnl -1 --edit          # Opens the most recent entry in the editor 

2. Include the template file in jrnl.yaml

A more efficient way to work with a template file is to declare the file in your config file by changing the template setting from false to the template file's path in double quotes:

...
template: "/path/to/template.txt"
...

Changes can be saved as you continue writing the journal entry and will be logged as a new entry in the journal you specified in the original argument.

!!! 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).

jrnl -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:

function 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.

jrnl -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.

jrnl now --config-override editor:""

Bind this to a keyboard shortcut.

Map Super+Alt+J to launch the terminal with jrnl prompt

  • xbindkeys In your .xbindkeysrc
Mod4+Mod1+j
 alacritty -t floating-jrnl -e jrnl now --config-override editor:"",
  • I3 WM Launch a floating terminal with the jrnl prompt
bindsym Mod4+Mod1+j exec --no-startup-id alacritty -t floating-jrnl -e jrnl --config-override editor:""
for_window[title="floating *"] floating enable

External editors

Configure your preferred external editor by updating the editor option in your jrnl.yaml file. (See advanced usage for details).

!!! note To save and log any entry edits, save and close the file.

If your editor is not in your operating system's PATH environment variable, then you will have to enter in the full path of your editor.

Sublime Text

To use Sublime Text, install the command line tools for Sublime Text and configure your jrnl.yaml like this:

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:

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:

editor: "mvim -f"

iA Writer

On OS X, you can use the fabulous iA Writer to write entries. Configure your jrnl.yaml like this:

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:

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:

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.