The last 14 days were really exciting. We merged some awesome things and even more awesome things are in the pipeline, but lets focus on the past two weeks in this third update on imag, the personal information management suite for the terminal.
First of all, the big news: The hook system got merged.
Holy crap, this was a big one! 950 lines were added and 10 were deleted by this
merge, 14 files were changed. Well, I do not want to elaborate on the
architecture of the hook system now, this really belongs to the documentation.
What I want to do in the next 14 days is implementing a
library, which contains several builtin hooks for the store, such as:
- A rather simple “Debug”-Hook, which does nothing but printing debug information about the hook execution.
- A VCS hook which uses git to make the store version-controlled
- A crypto hook which encrypts and decrypts the store on the fly.
For the first iteration, the debug hook is enough. The other hooks are nice to have, though I would only create the stubs for them and then focus on even more important things: modules.
Where are my modules?
Well, I got some really interesting things merged in the last 14 days. Some libraries were merged which really make writing modules a joy. Here is the short list:
libimagentryfiltergot a version filter
libimagentryfiltergot some more rather basic filters added
libimagentryfiltergot the ability to filter by tag
libimaglinkinitial codebase was merged
libimagstoregot a function to retrieve all entries for one module
libimagtaggot exec functionality
But what does this mean in detail? Let me elaborate:
We have two new filter types in this library. First, the
version filter. It
enables to filter out entries by their version field from the header, so you
can, for example, select only entries which are in a certain range of versions,
if that matters to you when implementing a feature for a module. This filter
must prove its usability, of course.
The second filter is a tag filter, so you can select entries by tags. There’s no CLI functionality for this, yet. I really want to implement this as well.
Some more basic filter functionality was added. The very core of these changes is a filter which takes a predicate closure, all other basic filters (such as the header-field-is-equal-to-filter and so on) were reimplemented using this core filter type.
Yeah, we finally got this code merged! We have a library for linking entries now. I already elaborated this in the last part, so I won’t elaborate on it here
This is also really really nice. We have a
Store function to retrieve all
entries for one module now. And the best thing is: It is lazy, because it
returns an iterator! It uses the
glob crate internally, which returns an
Iterator itself and we wrap this iterator into a
libimagentryfilter you can simple call
filter() on this iterator to reduce
the disk IO. How awesome is that?
We have exec functionality. What does this mean? It means that you can pass the
commandline objects returned by the
clap functions for processing the passed
commandline flags and an entry and the
exec functionality of the
does what the CLI tells it to do: If the user specified that there should be the
tags “foo” and “bar” added but “baz” should be removed, this function does this
I really want all libraries to be like this, so a developer can compose new modules by simply reusing existing functionality like this.
The CLI gets rather verbose with this, but as Rust wants it: explicit is better than implicit, and we do it just like that.
And what about modules?
We got some interesting module code merged as well. I wrote about the libraries first because the libraries are the things where the big changes happen at this moment, later the module section will come first.
So what have we done?
imag-countergot an interactive mode
imag-countergot listing functionality
Interactive mode. That’s a really nice thing in my opinion: The counter binary
allows you to call interactive mode and provide a specification where you
specify which key is bound to which counter. Then, you can type
(optionally prefixed by
+) to increase the counters bound to
To decrease them you can prefix with
imag-link binary is a helper to link two entries. Not more and not less.
External linking is not supported yet, though.
This was nothing special. I merged a enhancement to make use of the
clap offeres. It prevents the user from specifying two (or more)
arguments which are mutually exclusive.
imag-tag binary is a frontend for the
libimagtag. It allows the user to
add and remove tags from entries.
imag-view binary helps you viewing entries.
Bugs everywhere? Bugs nowhere!
So far there haven’t been that many bugs! We only saw some minor bugs which resulted in rather simple errors. Nothing to serious, really.
What’s in the pipeline
There are some minor things which have to be done:
imag-tagbinary really should use the new exec functionality of the
libimagtagto add/remove tags from entries
libimagrtfunctionality to call the
$EDITORmust be merged. A friend of mine implemented this, thank you very much, Kai!
imag-viewbinary is implemented without library. A
libimagviewshall be created and used to reimplement
imag-view. Actually a friend of mine volunteered in doing this. Awesome!
And of course there have to be more modules. By now,
imag-counter is the only
real-world (and not core- or utility-module) which is available. I’m working on
imag-notes right now and I have some promising-looking code floating around
imag-task binary implemented using “taskwarrior”. I started to write a
library for writing taskwarrior hooks in Rust which I want to use to implement
imag-task. The taskwarrior hook library is not ready and not published, yet.
After these two, I will start working on
imag-calendar depending on what crates are available
Maildir stuff. If neither is available, I will do
imag-password using pass (after writing another
crate to interface with it, of course).
So, a lot of awesome things are planned. Stay tuned!