Skip to content

Commit 3707630

Browse files
committed
notmuch: auto-locate the notmuch database
1. The notmuch database may not be the same as the maildir. 2. Notmuch has some pretty thorough logic for automatically locating the database (documented in notmuch(3)). This change: 1. Renames the `maildir` option to `database` to accurately reflect its purpose. 2. Makes the `database` option optional. 3. Adds a `profile` option so the user can specify the notmuch profile they want to use without hard-coding the path to the database.
1 parent fcce1f3 commit 3707630

File tree

2 files changed

+53
-17
lines changed

2 files changed

+53
-17
lines changed

NEWS.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
# i3status-rust 0.35.0 [unreleased]
22

3+
### Bug Fixes and Improvements
4+
5+
- The `notmuch` block can now automatically locate the notmuch database (the same way the `notmuch` command does) without being explicitly configured. Furthermore, the block has gained a `profile` option that can be used to specify a notmuch profile other than "default".
6+
37
### Breaking Changes
48

59
- The `interval` option has been removed from the `notmuch` block in favor of watching the notmuch database for changes.
10+
- The `maildir` option in the `notmuch` block has been renamed to `database` to better reflect its purpose, and has been made optional.
611

712
# i3status-rust 0.34.0
813

src/blocks/notmuch.rs

Lines changed: 48 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,6 @@
4343
//! # Icons Used
4444
//! - `mail`
4545
46-
use std::path::Path;
47-
4846
use inotify::{Inotify, WatchMask};
4947

5048
use super::prelude::*;
@@ -53,8 +51,15 @@ use super::prelude::*;
5351
#[serde(deny_unknown_fields, default)]
5452
pub struct Config {
5553
pub format: FormatConfig,
56-
#[default("~/.mail".into())]
57-
pub maildir: ShellString,
54+
/// Path to the notmuch database.
55+
///
56+
/// Defaults to the database used by the notmuch CLI tool.
57+
pub database: Option<ShellString>,
58+
/// Database profile. Cannot be specified at the same time as `database`.
59+
///
60+
/// Defaults to the profile used by the notmuch CLI tool.
61+
pub profile: Option<String>,
62+
/// The notmuch query to count.
5863
pub query: String,
5964
#[default(u32::MAX)]
6065
pub threshold_warning: u32,
@@ -69,17 +74,27 @@ pub struct Config {
6974
pub async fn run(config: &Config, api: &CommonApi) -> Result<()> {
7075
let format = config.format.with_default(" $icon $count ")?;
7176

72-
let db = config.maildir.expand()?;
77+
if config.database.is_some() && config.profile.is_some() {
78+
return Err(Error::new(
79+
"cannot specify both a notmuch database and a notmuch profile",
80+
));
81+
}
82+
83+
let profile = config.profile.as_deref();
84+
85+
let db_path = config.database.as_ref().map(|p| p.expand()).transpose()?;
86+
let db_path: Option<&str> = db_path.as_deref();
7387
let notify = Inotify::init().error("Failed to start inotify")?;
7488

75-
for lockpath in ["xapian/flintlock", ".notmuch/xapian/flintlock"] {
76-
let fname = Path::new(&*db).join(lockpath);
77-
if fname.exists() {
78-
notify
79-
.watches()
80-
.add(fname, WatchMask::CLOSE_WRITE)
81-
.error("failed to add inotify watch")?;
82-
}
89+
{
90+
let lock_path = open_database(db_path, profile)
91+
.error("failed to open the notmuch database")?
92+
.path()
93+
.join("xapian/flintlock");
94+
notify
95+
.watches()
96+
.add(lock_path, WatchMask::CLOSE_WRITE)
97+
.error("failed to watch the notmuch database lock")?;
8398
}
8499

85100
let mut updates = notify
@@ -88,7 +103,7 @@ pub async fn run(config: &Config, api: &CommonApi) -> Result<()> {
88103

89104
loop {
90105
// TODO: spawn_blocking?
91-
let count = run_query(&db, &config.query).error("Failed to get count")?;
106+
let count = run_query(db_path, profile, &config.query).error("Failed to get count")?;
92107

93108
let mut widget = Widget::new().with_format(format.clone());
94109

@@ -118,12 +133,28 @@ pub async fn run(config: &Config, api: &CommonApi) -> Result<()> {
118133
}
119134
}
120135

121-
fn run_query(db_path: &str, query_string: &str) -> std::result::Result<u32, notmuch::Error> {
136+
fn open_database(
137+
db_path: Option<&str>,
138+
profile: Option<&str>,
139+
) -> std::result::Result<notmuch::Database, notmuch::Error> {
140+
notmuch::Database::open_with_config(
141+
db_path,
142+
notmuch::DatabaseMode::ReadOnly,
143+
None::<&str>,
144+
profile,
145+
)
146+
}
147+
148+
fn run_query(
149+
db_path: Option<&str>,
150+
profile: Option<&str>,
151+
query_string: &str,
152+
) -> std::result::Result<u32, notmuch::Error> {
122153
let db = notmuch::Database::open_with_config(
123-
Some(db_path),
154+
db_path,
124155
notmuch::DatabaseMode::ReadOnly,
125156
None::<&str>,
126-
None,
157+
profile,
127158
)?;
128159
let query = db.create_query(query_string)?;
129160
query.count_messages()

0 commit comments

Comments
 (0)