Navi is an application for defining desktop notifications in terms of a running notification system. That is, Navi does not implement desktop notifications from the ground up. Rather, given a running compatible notifications system, Navi provides a simple interface for defining notifications that hook into the running system.
There are built-in services for sending specific notifications, along with functionality to send custom notifications.
Navi is useful for when we have a running notification server and want to define custom notification events. For example, we may want a notification for cpu temperature. We can define a "service" that includes:
- The command to run.
- The command output that should trigger a notification.
- The notification to send.
# requires lm-sensors
[[custom]]
command = """
temp_res=$(sensors | grep "Core 0")
regex="Core 0:\\s*\\+([0-9]+)\\.[0-9]{0,2}°[C|F].*"
if [[ $temp_res =~ $regex ]]; then
temp="${BASH_REMATCH[1]}"
# not actually that hot...
if [[ $temp -gt 20 ]]; then
echo "true"
else
echo "false"
fi
else
echo "couldn't parse: ${temp_res}"
exit 1
fi
"""
[[custom.trigger-note]]
trigger = "true"
summary = "Temperature"
body = "We're hot!"
urgency = "critical"
timeout = 10
This allows us to define arbitrary notification services based on the current system. In other words, as long as we can query for a particular bit of information (e.g. bash code), then navi will take care of the rest: running this query every N seconds, sending notifications, caching previous values to avoid repeats, and error handling.
Navi currently supports:
-
DBus
If there is a DBus-compatible notification server running, navi can hook in directly. This has been tested with:
-
Libnotify
Navi can also use the
notify-send
tool directly. This is largely redundant sincenotify-send
itself requires a running DBus notification server, but this option is provided as an alternative. -
AppleScript
MacOS can use AppleScript.
Navi is configured via a toml file, by default located at <xdg-config>/navi/config.toml
. Full examples can be found in examples.
The releases page has binaries built for several platforms. If there are no binaries for your platform, it is possible to build navi yourself.
If you have never built a haskell program before, Cabal is probably the best choice.
The easiest way to install these is generally ghcup
.
The current "blessed" version is ghc-9.10.2
.
Once you have cabal
and ghc
, navi
can be built locally with cabal build
or installed globally (e.g. ~/.local/bin/navi
) with cabal install
.
Important
Navi requires git information to be available at build time, for the purposes of including some data in the binary (e.g. commit hash). Cabal's vanilla install method interfers with this, though we have a workaround that relies on passing the current directory as an environment variable:
$ export NAVI_HOME=$(pwd); cabal install exe:navi
Nix does not require such a workaround.
For further reproducibility, an optional freeze file can be used for the "blessed" compiler.
cabal build --project-file cabal.ghc<XYZ>.project
Building with nix
uses flakes. navi
can be built with nix build
, which will compile and run the tests.
Because Navi is a flake, it can be built as part of a nix expression. For instance, if you want to add Navi to NixOS
, your flake.nix
might look something like:
# flake.nix
{
inputs.navi.url = "github:tbidne/navi/main";
}
Then include this in the systemPackages
:
# wherever your global packages are defined
{
environment.systemPackages = [
navi.packages."${system}".default
];
}