GithubHelp home page GithubHelp logo

samwho / hmm Goto Github PK

View Code? Open in Web Editor NEW
84.0 3.0 6.0 106 KB

A small command-line note taking app written in Rust. Notes are written in plain text and indexed by the time they were written.

License: MIT License

Rust 97.72% Shell 2.28%
note-taking journaling command-line rust

hmm's Introduction

Build status Crates.io

hmm is a small command-line note taking app written in Rust. Entries are written in plain text and indexed by the time they were written.

hmm is inspired by jrnl, except with a different use-case in mind. Where jrnl excels at a journaling use case, where users to can entries with arbitrary times and the file format is human-readable, hmm only allows you to add an entry at the current time and has a machine-readable format that's optimised for fast time-based querying.

Comparison to jrnl

Features jrnl has that hmm doesn't:

  • Encryption.
  • Ability to add entries at arbitrary points in time.
  • In-built notion of tags.
  • In-built notion of starring.
  • Ability to edit entries.
  • Ability to parse English dates/times, e.g. "yesterday" and "2 weeks ago."

Features hmm has that jrnl doesn't:

  • Unambigous date-format (RFC3339).
  • File-format optimised for searching by time.
  • Ability to format entries however you want.
  • No external dependencies.
  • Lots of flexibility.

If you need to add entries at times in the past, or you need encryption, or you need your file format to be purely plain text, or you need to edit entries after they're written, hmm isn't for you. Other than that, I believe hmm can be made to work exactly how you want it to.

Installation

No support for Homebrew yet, so Mac users will need to go down the cargo route, but I plan to get it in to the Homebrew repos soon.

Arch Linux (AUR)

hmm is in the AUR, and can be installed with an AUR helper such as yay:

yay -S hmm-bin

Using cargo

Install Rust, then run:

cargo install hmmcli

Now the hmm and hmmq binaries should be available in your terminal.

From source

Install Rust, install git then run:

git clone https://github.com/samwho/hmm
cd hmm
cargo install

Usage

hmm is split in to three binaries: hmm, hmmq and hmmp.

  • hmm is for writing new entries via the CLI.
  • hmmq is for querying entries by time and content.
  • hmmp is for printing entries if you want to use tools other than hmmq to query them.

hmm

Writing an entry from the CLI

hmm hello world

This will write an entry to the default .hmm file location, which is in your home directory.

Writing an entry to a different .hmm file

Your .hmm file can be located wherever you want, and named whatever you want.

hmm --path ~/.notes hello world

Writing long-form entries in your EDITOR

hmm

Invoked with no arguments, or just a --path argument, hmm will open your default EDITOR to compose an entry. Saving and quitting that editor will then write the note to your .hmm file. If you don't have an EDITOR configured, you can also pass one as a flag:

hmm --editor vim

The editor variable can be arbitrarily complex, the only thing to keep in mind is that hmm will call it with a temporary file as the last argument. It will read the contents of that temporary file after your editor command exits successfully. If your editor does not exit successfully, nothing is written to your .hmm file.

hmmq

Listing your entries

hmmq

By default, this lists all of your entries in a default format in ascending chronological order. This may not be desired, so there are a bunch of flags to narrow down what is shown.

Show the most recent 10 entries

hmmq --last 10

Show the frst 10 entries

hmmq --first 10

Show entries on a specific day

hmmq --start 2020-01-01 --end 2020-01-02

The --start flag is inclusive and the --end flag is exclusive, so the above command will show all entries that were created on the 1st of January 2020.

Dates follow the RFC3339/ISO8601 format, allowing you to omit parts you don't need. All dates are in your local timezone.

Show entries on a given year

hmmq --start 2019 --end 2020

This will show all of your entries from 2019.

Count entries in a given year

hmmq --start 2019 --end 2020 --count

This will show you how many entries you made in 2019.

Show all entries from a given date

hmmq --start 2020-02-20

This will print all of your entries from the 20th of February 2020.

Show a random entry

hmmq --random

Prints out a random entry. The randomness comes from selecting a random byte in your .hmm file, and as such longer entries are more likely to be picked. This is a trade-off. Picking entries in a truly random fashion would require reading the entire file, which is against the philosophy of hmmq.

Formatting entries

hmmq makes use of the Handlebars templating format to determine how entries are printed to the terminal. Here's an example of a really simple template:

hmmq --format "{{ datetime }}: {{ message }}"

It's not much to look at, but it shows how the templates look and all of the variables you have access to inside a template.

hmmq offers some helper functions to make your templates look nicer. Here's the default output format specified explicitly:

hmmq --format $'╭ {{ color "blue" (strftime "%Y-%m-%d %H:%M" datetime) }}\n{{ indent (markdown message) }}╰─────────────────"

The keen reader will notice the $ before the format argument. This is a bash quirk. Without it, the \n inside the format argument will print literally instead of being interpreted as a newline.

hmmp

If you want to use other tools to filter through your .hmm file, that's completely file and even encouraged. The hmmp tool exists to let you pipe filtered .hmm file contents and have it formatted how you want it.

The following two commands are equivalent:

tail -n 10 ~/.hmm | hmmp
hmmq --last 10

As are the following two:

tail -n 10 ~/.hmm | hmmp --format "{{ message }}"
hmmq --last 10 --format "{{ message }}"

Benchmarking

There's a script in the repository root called bench.sh that shows the methodology behind the following table if you're interested.

Command Mean [ms] Min [ms] Max [ms] Relative
target/release/hmmq --path /tmp/out --random 13.5 ± 0.8 11.9 15.4 1.00
target/release/hmmq --path /tmp/out --last 10 15.0 ± 0.8 12.8 17.1 1.11 ± 0.09
target/release/hmmq --path /tmp/out --first 10 13.6 ± 1.0 9.0 16.2 1.01 ± 0.09
target/release/hmmq --path /tmp/out --start 2019 --first 10 16.8 ± 0.8 15.3 19.2 1.24 ± 0.09
target/release/hmmq --path /tmp/out --end 2019 --last 10 18.8 ± 0.9 16.4 21.4 1.40 ± 0.10
target/release/hmmq --path /tmp/out --start 2019-01 --end 2019-02 325.6 ± 11.9 309.9 379.9 24.11 ± 1.65
target/release/hmmq --path /tmp/out --start 2019 --end 2020 --count 346.6 ± 13.6 336.7 427.6 25.67 ± 1.79
target/release/hmmq --path /tmp/out --start 2019-01 --end 2019-06 --contains lorum 232.3 ± 5.2 226.4 262.7 17.21 ± 1.07
target/release/hmmq --path /tmp/out --start 2019 --end 2020 --regex "(lorum|ipsum)" 565.3 ± 13.3 548.1 622.1 41.87 ± 2.62

hmm's People

Contributors

digizeph avatar samwho avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

hmm's Issues

Default hmmq to printing out the last N entries

Not 100% sure how this will interact with --start and --end. It would have to behave differently with both.

  • --start 2012 -n 10 first 10 entries in 2012
  • --end 2012 -n 10 last 10 entries of 2011
  • -n 10 last 10 entries
  • --start 2010 --end 2012 -n 10 error?

Bug in `hmmq`: when you specify a `--start` flag and have 2 entries, one entry is missed.

❯ hmmq --start (date -I)
╭ 2021-04-01 12:14
│ Hello, world!
╰─────────────────

❯ hmmq
╭ 2021-04-01 12:14
╰─────────────────
╭ 2021-04-01 12:14
│ Hello, world!
╰─────────────────

❯ date -I
2021-04-01

❯ hmmq --start 2021-04-01
╭ 2021-04-01 12:14
│ Hello, world!
╰─────────────────

❯ hmm "test"

❯ hmmq --start 2021-04-01
╭ 2021-04-01 12:14
╰─────────────────
╭ 2021-04-01 12:14
│ Hello, world!
╰─────────────────
╭ 2021-04-01 12:17
│ test
╰─────────────────

Allow users to customise output.

Similar to git commits, where you have a bunch of formatting codes to choose from. I'd like that level of flexibility.

hmmq --format "{date}\n{wrapped_message}"

Maybe? Or...

hmmq --format "%t\n%w"

Not sure which is the best way to go. I think I'm preferring the first option.

Our use of the csv crate is very slow, consider moving off it.

Constructing a new csv::Reader every single record is very heavy, flamegraph attached.

It doesn't seem possible to use the csv library in a way that lets us have control over the IO seeks. Unless I'm missing something. I really just want a library that can take a CSV line and split it in to parts in a stands-compliant way.

flamegraph

Write a CONTRIBUTING.md file.

Ideally with some guidance on how the code is laid out. Might want to do some more code commenting while I'm at it.

Fix integration tests on Windows

Some of our integration tests fail on Windows because the error message from the OS is different when a file isn't found to the error on Linux.

Integration tests.

No idea how best to do this, but ideally something that runs the actual commands.

Add a --count flag to hmmq

Count the number of entries instead of printing them. I found myself wanting this so I could check if I've written any entries today and, if not, alert myself that I should.

Wrap file writes in a file lock

Given that hmm is intended to be used by one person at any one time, it’s unlikely that parallel writes would corrupt the file but I’d prefer to be on the safe side, especially since range searches depend on the file being lexicographically ordered to work properly.

It’s possible to lock access to a file such that only one process can access it at a time, and I reckon we should wrap writes in such a lock.

There appear to be some crates for this:

Handle seeking in to the middle of a UTF-8 character

See this issue for some background: mjc-gh/rev_lines#3.

At the moment it's possible for our line seeking code to find itself returning with the file cursor sat in the middle of a multibyte character that just happens to contain 0x0a as one of the bytes. Unlikely in English I think, but I've no idea about other languages.

`hmmp` crashes :(

Just installed via AUR, but hmmp does not work. It instantly crashes (and asks me nicely to submit a report, so here I am).

name = 'hmmcli'
operating_system = 'unix:Unknown'
crate_version = '0.5.2'
explanation = '''
Panic occurred in file 'src/entry.rs' at line 91
'''
cause = 'called `Option::unwrap()` on a `None` value'
method = 'Panic'
backtrace = '''

   0: 0x55c8c4c20513 - <unresolved>
   1: 0x55c8c4c31a49 - <unresolved>
   2: 0x7f9924008850 - <unresolved>
   3: 0x7f992400890a - __libc_start_main
   4: 0x55c8c4c2009e - <unresolved>
   5:        0x0 - <unresolved>'''

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.