aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Jarry <robin@jarry.cc>2023-02-16 00:18:45 +0100
committerRobin Jarry <robin@jarry.cc>2023-10-31 19:00:50 +0100
commit202e8c9d06bab32217549f23125d6b274107afda (patch)
tree9a3735850946535f9c33730eaa156feda1ea1d78
parentae386daf5b121e233bd777432c2132caf9006506 (diff)
downloadaerc-202e8c9d06bab32217549f23125d6b274107afda.tar.gz
aerc-202e8c9d06bab32217549f23125d6b274107afda.zip
wip
Signed-off-by: Robin Jarry <robin@jarry.cc>
-rw-r--r--.gitignore1
-rw-r--r--Cargo.lock960
-rw-r--r--Cargo.toml34
-rw-r--r--src/app/mod.rs61
-rw-r--r--src/cmd/mod.rs4
-rw-r--r--src/config/accounts.rs17
-rw-r--r--src/config/columns.rs29
-rw-r--r--src/config/mod.rs31
-rw-r--r--src/config/style.rs5
-rw-r--r--src/config/templates.rs10
-rw-r--r--src/config/ui.rs99
-rw-r--r--src/main.rs142
-rw-r--r--src/worker/imap/mod.rs12
-rw-r--r--src/worker/maildir/mod.rs12
-rw-r--r--src/worker/mbox/mod.rs12
-rw-r--r--src/worker/mod.rs46
-rw-r--r--src/worker/notmuch/mod.rs12
17 files changed, 1487 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index 9d9a732e..480448e7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,6 +5,7 @@
/wrap
/colorize
/linters.so
+/target
*.log*
*.1
*.5
diff --git a/Cargo.lock b/Cargo.lock
new file mode 100644
index 00000000..7d5fbfe6
--- /dev/null
+++ b/Cargo.lock
@@ -0,0 +1,960 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "addr2line"
+version = "0.19.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97"
+dependencies = [
+ "gimli",
+]
+
+[[package]]
+name = "adler"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
+
+[[package]]
+name = "aerc"
+version = "0.20.0"
+dependencies = [
+ "anyhow",
+ "bitflags",
+ "clap",
+ "configparser",
+ "crossterm",
+ "derivative",
+ "futures",
+ "gtmpl",
+ "log",
+ "simple_logger",
+ "time",
+ "tokio",
+ "tui",
+]
+
+[[package]]
+name = "anyhow"
+version = "1.0.69"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "224afbd727c3d6e4b90103ece64b8d1b67fbb1973b1046c2281eed3f3803f800"
+dependencies = [
+ "backtrace",
+]
+
+[[package]]
+name = "atty"
+version = "0.2.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
+dependencies = [
+ "hermit-abi 0.1.19",
+ "libc",
+ "winapi",
+]
+
+[[package]]
+name = "autocfg"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
+
+[[package]]
+name = "backtrace"
+version = "0.3.67"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca"
+dependencies = [
+ "addr2line",
+ "cc",
+ "cfg-if",
+ "libc",
+ "miniz_oxide",
+ "object",
+ "rustc-demangle",
+]
+
+[[package]]
+name = "bitflags"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+
+[[package]]
+name = "bytes"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be"
+
+[[package]]
+name = "cassowary"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53"
+
+[[package]]
+name = "cc"
+version = "1.0.79"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "clap"
+version = "4.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f13b9c79b5d1dd500d20ef541215a6423c75829ef43117e1b4d17fd8af0b5d76"
+dependencies = [
+ "bitflags",
+ "clap_derive",
+ "clap_lex",
+ "is-terminal",
+ "once_cell",
+ "strsim",
+ "termcolor",
+]
+
+[[package]]
+name = "clap_derive"
+version = "4.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "684a277d672e91966334af371f1a7b5833f9aa00b07c84e92fbce95e00208ce8"
+dependencies = [
+ "heck",
+ "proc-macro-error",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "clap_lex"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "783fe232adfca04f90f56201b26d79682d4cd2625e0bc7290b95123afe558ade"
+dependencies = [
+ "os_str_bytes",
+]
+
+[[package]]
+name = "configparser"
+version = "3.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5458d9d1a587efaf5091602c59d299696a3877a439c8f6d461a2d3cce11df87a"
+dependencies = [
+ "indexmap",
+]
+
+[[package]]
+name = "crossterm"
+version = "0.25.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e64e6c0fbe2c17357405f7c758c1ef960fce08bdfb2c03d88d2a18d7e09c4b67"
+dependencies = [
+ "bitflags",
+ "crossterm_winapi",
+ "futures-core",
+ "libc",
+ "mio",
+ "parking_lot",
+ "signal-hook",
+ "signal-hook-mio",
+ "winapi",
+]
+
+[[package]]
+name = "crossterm_winapi"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2ae1b35a484aa10e07fe0638d02301c5ad24de82d310ccbd2f3693da5f09bf1c"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
+name = "derivative"
+version = "2.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "errno"
+version = "0.2.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1"
+dependencies = [
+ "errno-dragonfly",
+ "libc",
+ "winapi",
+]
+
+[[package]]
+name = "errno-dragonfly"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
+dependencies = [
+ "cc",
+ "libc",
+]
+
+[[package]]
+name = "futures"
+version = "0.3.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "13e2792b0ff0340399d58445b88fd9770e3489eff258a4cbc1523418f12abf84"
+dependencies = [
+ "futures-channel",
+ "futures-core",
+ "futures-executor",
+ "futures-io",
+ "futures-sink",
+ "futures-task",
+ "futures-util",
+]
+
+[[package]]
+name = "futures-channel"
+version = "0.3.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2e5317663a9089767a1ec00a487df42e0ca174b61b4483213ac24448e4664df5"
+dependencies = [
+ "futures-core",
+ "futures-sink",
+]
+
+[[package]]
+name = "futures-core"
+version = "0.3.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec90ff4d0fe1f57d600049061dc6bb68ed03c7d2fbd697274c41805dcb3f8608"
+
+[[package]]
+name = "futures-executor"
+version = "0.3.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e8de0a35a6ab97ec8869e32a2473f4b1324459e14c29275d14b10cb1fd19b50e"
+dependencies = [
+ "futures-core",
+ "futures-task",
+ "futures-util",
+]
+
+[[package]]
+name = "futures-io"
+version = "0.3.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bfb8371b6fb2aeb2d280374607aeabfc99d95c72edfe51692e42d3d7f0d08531"
+
+[[package]]
+name = "futures-macro"
+version = "0.3.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "95a73af87da33b5acf53acfebdc339fe592ecf5357ac7c0a7734ab9d8c876a70"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "futures-sink"
+version = "0.3.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f310820bb3e8cfd46c80db4d7fb8353e15dfff853a127158425f31e0be6c8364"
+
+[[package]]
+name = "futures-task"
+version = "0.3.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dcf79a1bf610b10f42aea489289c5a2c478a786509693b80cd39c44ccd936366"
+
+[[package]]
+name = "futures-util"
+version = "0.3.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c1d6de3acfef38d2be4b1f543f553131788603495be83da675e180c8d6b7bd1"
+dependencies = [
+ "futures-channel",
+ "futures-core",
+ "futures-io",
+ "futures-macro",
+ "futures-sink",
+ "futures-task",
+ "memchr",
+ "pin-project-lite",
+ "pin-utils",
+ "slab",
+]
+
+[[package]]
+name = "gimli"
+version = "0.27.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "221996f774192f0f718773def8201c4ae31f02616a54ccfc2d358bb0e5cefdec"
+
+[[package]]
+name = "gtmpl"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b924c0ea1149cd5cc9b208b33a4acb036ffb4b39c10048569de20616988a2b4"
+dependencies = [
+ "anyhow",
+ "gtmpl_value",
+ "lazy_static",
+ "percent-encoding",
+ "thiserror",
+]
+
+[[package]]
+name = "gtmpl_value"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d61bf6605eabca491ef6db6ed194e0aa82900ccc8bdea4c56ac277102152dd5"
+dependencies = [
+ "anyhow",
+ "thiserror",
+]
+
+[[package]]
+name = "hashbrown"
+version = "0.12.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
+
+[[package]]
+name = "heck"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
+
+[[package]]
+name = "hermit-abi"
+version = "0.1.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "hermit-abi"
+version = "0.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "hermit-abi"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
+
+[[package]]
+name = "indexmap"
+version = "1.9.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399"
+dependencies = [
+ "autocfg",
+ "hashbrown",
+]
+
+[[package]]
+name = "io-lifetimes"
+version = "1.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1abeb7a0dd0f8181267ff8adc397075586500b81b28a73e8a0208b00fc170fb3"
+dependencies = [
+ "libc",
+ "windows-sys 0.45.0",
+]
+
+[[package]]
+name = "is-terminal"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "22e18b0a45d56fe973d6db23972bf5bc46f988a4a2385deac9cc29572f09daef"
+dependencies = [
+ "hermit-abi 0.3.1",
+ "io-lifetimes",
+ "rustix",
+ "windows-sys 0.45.0",
+]
+
+[[package]]
+name = "itoa"
+version = "1.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440"
+
+[[package]]
+name = "lazy_static"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+
+[[package]]
+name = "libc"
+version = "0.2.139"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
+
+[[package]]
+name = "linux-raw-sys"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4"
+
+[[package]]
+name = "lock_api"
+version = "0.4.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df"
+dependencies = [
+ "autocfg",
+ "scopeguard",
+]
+
+[[package]]
+name = "log"
+version = "0.4.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "memchr"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
+
+[[package]]
+name = "miniz_oxide"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa"
+dependencies = [
+ "adler",
+]
+
+[[package]]
+name = "mio"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de"
+dependencies = [
+ "libc",
+ "log",
+ "wasi",
+ "windows-sys 0.42.0",
+]
+
+[[package]]
+name = "num_cpus"
+version = "1.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b"
+dependencies = [
+ "hermit-abi 0.2.6",
+ "libc",
+]
+
+[[package]]
+name = "num_threads"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "object"
+version = "0.30.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ea86265d3d3dcb6a27fc51bd29a4bf387fae9d2986b823079d4986af253eb439"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "once_cell"
+version = "1.17.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66"
+
+[[package]]
+name = "os_str_bytes"
+version = "6.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee"
+
+[[package]]
+name = "parking_lot"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
+dependencies = [
+ "lock_api",
+ "parking_lot_core",
+]
+
+[[package]]
+name = "parking_lot_core"
+version = "0.9.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "redox_syscall",
+ "smallvec",
+ "windows-sys 0.45.0",
+]
+
+[[package]]
+name = "percent-encoding"
+version = "2.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
+
+[[package]]
+name = "pin-project-lite"
+version = "0.2.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
+
+[[package]]
+name = "pin-utils"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
+
+[[package]]
+name = "proc-macro-error"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
+dependencies = [
+ "proc-macro-error-attr",
+ "proc-macro2",
+ "quote",
+ "syn",
+ "version_check",
+]
+
+[[package]]
+name = "proc-macro-error-attr"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "version_check",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.51"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "redox_syscall"
+version = "0.2.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
+dependencies = [
+ "bitflags",
+]
+
+[[package]]
+name = "rustc-demangle"
+version = "0.1.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342"
+
+[[package]]
+name = "rustix"
+version = "0.36.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f43abb88211988493c1abb44a70efa56ff0ce98f233b7b276146f1f3f7ba9644"
+dependencies = [
+ "bitflags",
+ "errno",
+ "io-lifetimes",
+ "libc",
+ "linux-raw-sys",
+ "windows-sys 0.45.0",
+]
+
+[[package]]
+name = "scopeguard"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
+
+[[package]]
+name = "serde"
+version = "1.0.152"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb"
+
+[[package]]
+name = "signal-hook"
+version = "0.3.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "732768f1176d21d09e076c23a93123d40bba92d50c4058da34d45c8de8e682b9"
+dependencies = [
+ "libc",
+ "signal-hook-registry",
+]
+
+[[package]]
+name = "signal-hook-mio"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af"
+dependencies = [
+ "libc",
+ "mio",
+ "signal-hook",
+]
+
+[[package]]
+name = "signal-hook-registry"
+version = "1.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "simple_logger"
+version = "4.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e190a521c2044948158666916d9e872cbb9984f755e9bb3b5b75a836205affcd"
+dependencies = [
+ "atty",
+ "log",
+ "time",
+ "windows-sys 0.42.0",
+]
+
+[[package]]
+name = "slab"
+version = "0.4.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "smallvec"
+version = "1.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
+
+[[package]]
+name = "socket2"
+version = "0.4.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd"
+dependencies = [
+ "libc",
+ "winapi",
+]
+
+[[package]]
+name = "strsim"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
+
+[[package]]
+name = "syn"
+version = "1.0.107"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "termcolor"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6"
+dependencies = [
+ "winapi-util",
+]
+
+[[package]]
+name = "thiserror"
+version = "1.0.38"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0"
+dependencies = [
+ "thiserror-impl",
+]
+
+[[package]]
+name = "thiserror-impl"
+version = "1.0.38"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "time"
+version = "0.3.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a561bf4617eebd33bca6434b988f39ed798e527f51a1e797d0ee4f61c0a38376"
+dependencies = [
+ "itoa",
+ "libc",
+ "num_threads",
+ "serde",
+ "time-core",
+ "time-macros",
+]
+
+[[package]]
+name = "time-core"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd"
+
+[[package]]
+name = "time-macros"
+version = "0.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d967f99f534ca7e495c575c62638eebc2898a8c84c119b89e250477bc4ba16b2"
+dependencies = [
+ "time-core",
+]
+
+[[package]]
+name = "tokio"
+version = "1.25.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c8e00990ebabbe4c14c08aca901caed183ecd5c09562a12c824bb53d3c3fd3af"
+dependencies = [
+ "autocfg",
+ "bytes",
+ "libc",
+ "memchr",
+ "mio",
+ "num_cpus",
+ "parking_lot",
+ "pin-project-lite",
+ "signal-hook-registry",
+ "socket2",
+ "tokio-macros",
+ "windows-sys 0.42.0",
+]
+
+[[package]]
+name = "tokio-macros"
+version = "1.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "tui"
+version = "0.19.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ccdd26cbd674007e649a272da4475fb666d3aa0ad0531da7136db6fab0e5bad1"
+dependencies = [
+ "bitflags",
+ "cassowary",
+ "crossterm",
+ "unicode-segmentation",
+ "unicode-width",
+]
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc"
+
+[[package]]
+name = "unicode-segmentation"
+version = "1.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"
+
+[[package]]
+name = "unicode-width"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
+
+[[package]]
+name = "version_check"
+version = "0.9.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
+
+[[package]]
+name = "wasi"
+version = "0.11.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
+
+[[package]]
+name = "winapi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+
+[[package]]
+name = "winapi-util"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+
+[[package]]
+name = "windows-sys"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
+dependencies = [
+ "windows_aarch64_gnullvm",
+ "windows_aarch64_msvc",
+ "windows_i686_gnu",
+ "windows_i686_msvc",
+ "windows_x86_64_gnu",
+ "windows_x86_64_gnullvm",
+ "windows_x86_64_msvc",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.45.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
+dependencies = [
+ "windows-targets",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.42.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7"
+dependencies = [
+ "windows_aarch64_gnullvm",
+ "windows_aarch64_msvc",
+ "windows_i686_gnu",
+ "windows_i686_msvc",
+ "windows_x86_64_gnu",
+ "windows_x86_64_gnullvm",
+ "windows_x86_64_msvc",
+]
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.42.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.42.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.42.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.42.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.42.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.42.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.42.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd"
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 00000000..996816d3
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,34 @@
+# SPDX-License-Identifier: MIT
+# Copyright (c) 2023 Robin Jarry
+
+[package]
+name = "aerc"
+version = "0.20.0"
+edition = "2021"
+authors = ["Robin Jarry <robin@jarry.cc>"]
+description = "A pretty good email client"
+readme = "README.md"
+homepage = "https://aerc-mail.org/"
+repository = "https://git.sr.ht/~rjarry/aerc"
+license = "MIT"
+
+[dependencies]
+anyhow = { version = "1.0.69", features = ["backtrace"] }
+bitflags = "1.3.2"
+clap = { version = "4.1.4", features = ["derive", "env"] }
+configparser = { version = "3.0.2", features = ["indexmap"] }
+crossterm = { version = "0.25.0", features = ["event-stream"] }
+derivative = "2.2.0"
+futures = "0.3.26"
+gtmpl = "0.7.1"
+log = "0.4.17"
+simple_logger = { version = "4.0.0", default-features = false, features = ["time", "timestamps"] }
+time = "0.3.17"
+tokio = { version = "1.25.0", features = ["full"] }
+tui = "0.19.0"
+
+[profile.release]
+lto = true
+codegen-units = 1
+strip = true
+debug-assertions = false
diff --git a/src/app/mod.rs b/src/app/mod.rs
new file mode 100644
index 00000000..27846065
--- /dev/null
+++ b/src/app/mod.rs
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: MIT
+// Copyright (c) 2023 Robin Jarry
+
+use std::collections::HashMap;
+use std::sync::Arc;
+
+use tokio::sync::mpsc::channel;
+use tokio::sync::mpsc::Receiver;
+use tokio::sync::mpsc::Sender;
+use tokio::sync::Mutex;
+use tokio::task::JoinHandle;
+
+use crate::config::AccountConfig;
+use crate::config::Config;
+use crate::worker::Worker;
+use crate::worker::WorkerMessage;
+
+pub struct App {
+ config: Arc<Mutex<Config>>,
+ worker_tasks: Vec<JoinHandle<()>>,
+ to_workers: HashMap<String, Sender<WorkerMessage>>,
+ from_workers: HashMap<String, Receiver<WorkerMessage>>,
+ // app internal state change notifications for UI
+ updates: Sender<()>,
+}
+
+impl App {
+ pub fn new(config: Arc<Mutex<Config>>, updates: Sender<()>) -> Self {
+ App {
+ config,
+ updates,
+ worker_tasks: Vec::new(),
+ to_workers: HashMap::new(),
+ from_workers: HashMap::new(),
+ }
+ }
+
+ pub fn invalidate(&self) {
+ // ignore if a pending tick is already present in the channel
+ let _ = self.updates.try_send(());
+ }
+
+ pub fn start_worker(&mut self, config: AccountConfig) {
+ let (from_worker_tx, from_worker_rx) = channel::<WorkerMessage>(32);
+ let (to_worker_tx, to_worker_rx) = channel::<WorkerMessage>(32);
+
+ self.to_workers.insert(config.name.clone(), to_worker_tx);
+ self.from_workers
+ .insert(config.name.clone(), from_worker_rx);
+
+ let handle = tokio::spawn(async move {
+ let worker = Worker::new(config, to_worker_rx, from_worker_tx);
+ let run = worker.run();
+ tokio::pin!(run);
+ run.await;
+ });
+ self.worker_tasks.push(handle);
+ }
+
+ pub async fn stop_workers(&self) {}
+}
diff --git a/src/cmd/mod.rs b/src/cmd/mod.rs
new file mode 100644
index 00000000..f596ebb2
--- /dev/null
+++ b/src/cmd/mod.rs
@@ -0,0 +1,4 @@
+// SPDX-License-Identifier: MIT
+// Copyright (c) 2023 Robin Jarry
+
+pub trait Command {}
diff --git a/src/config/accounts.rs b/src/config/accounts.rs
new file mode 100644
index 00000000..91bc612a
--- /dev/null
+++ b/src/config/accounts.rs
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: MIT
+// Copyright (c) 2023 Robin Jarry
+
+#[derive(Debug, Default, Clone)]
+pub struct AccountConfig {
+ pub name: String,
+ pub backend: BackendType,
+}
+
+#[derive(Debug, Default, Clone)]
+pub enum BackendType {
+ #[default]
+ IMAP,
+ Maildir,
+ Mbox,
+ Notmuch,
+}
diff --git a/src/config/columns.rs b/src/config/columns.rs
new file mode 100644
index 00000000..45b90f4c
--- /dev/null
+++ b/src/config/columns.rs
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: MIT
+// Copyright (c) 2023 Robin Jarry
+
+use bitflags::bitflags;
+use derivative::Derivative;
+use gtmpl::Template;
+
+#[derive(Derivative)]
+#[derivative(Debug, Default)]
+pub struct ColumnDef {
+ pub name: String,
+ pub flags: ColumnFlags,
+ pub width: f64,
+ #[derivative(Debug(format_with = "crate::config::templates::debug_template"))]
+ pub template: Template,
+}
+
+bitflags! {
+ #[derive(Default)]
+ pub struct ColumnFlags: u8 {
+ const ALIGN_LEFT = 1 << 0;
+ const ALIGN_CENTER = 1 << 1;
+ const ALIGN_RIGHT = 1 << 2 ;
+ const WIDTH_AUTO = 1 << 3 ; // whatever is left
+ const WIDTH_FRACTION = 1 << 4; // ratio of total width
+ const WIDTH_EXACT = 1 << 5; // exact number of characters
+ const WIDTH_FIT = 1 << 6; // fit to column content width
+ }
+}
diff --git a/src/config/mod.rs b/src/config/mod.rs
new file mode 100644
index 00000000..5709180a
--- /dev/null
+++ b/src/config/mod.rs
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: MIT
+// Copyright (c) 2023 Robin Jarry
+
+mod accounts;
+mod columns;
+mod style;
+mod templates;
+mod ui;
+
+use std::collections::HashMap;
+
+use anyhow::Result;
+use derivative::Derivative;
+
+pub use crate::config::accounts::AccountConfig;
+pub use crate::config::accounts::BackendType;
+pub use crate::config::ui::UiConfig;
+
+#[derive(Derivative)]
+#[derivative(Debug, Default)]
+pub struct Config {
+ pub ui: UiConfig,
+ pub accounts: HashMap<String, AccountConfig>,
+}
+
+impl Config {
+ pub fn parse(accounts: Vec<String>) -> Result<Self> {
+ let c = Self::default();
+ Ok(c)
+ }
+}
diff --git a/src/config/style.rs b/src/config/style.rs
new file mode 100644
index 00000000..357112ba
--- /dev/null
+++ b/src/config/style.rs
@@ -0,0 +1,5 @@
+// SPDX-License-Identifier: MIT
+// Copyright (c) 2023 Robin Jarry
+
+#[derive(Debug, Default)]
+pub struct StyleSet {}
diff --git a/src/config/templates.rs b/src/config/templates.rs
new file mode 100644
index 00000000..00e9cf59
--- /dev/null
+++ b/src/config/templates.rs
@@ -0,0 +1,10 @@
+// SPDX-License-Identifier: MIT
+// Copyright (c) 2023 Robin Jarry
+
+use std::fmt;
+
+use gtmpl::Template;
+
+pub fn debug_template(t: &Template, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
+ f.write_fmt(format_args!("Template({:?})", t.text))
+}
diff --git a/src/config/ui.rs b/src/config/ui.rs
new file mode 100644
index 00000000..b7b004e2
--- /dev/null
+++ b/src/config/ui.rs
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: MIT
+// Copyright (c) 2023 Robin Jarry
+
+use std::collections::HashMap;
+
+use derivative::Derivative;
+use gtmpl::Template;
+
+use crate::config::columns::ColumnDef;
+use crate::config::style::StyleSet;
+
+#[derive(Derivative)]
+#[derivative(Debug, Default)]
+pub struct UiConfig {
+ // message list
+ pub index_columns: Vec<ColumnDef>,
+ pub column_separator: String,
+ pub empty_message: String,
+ pub threading_enabled: bool,
+ pub force_client_threads: bool,
+ pub client_threads_delay: time::Duration,
+ pub sort: Vec<String>,
+ pub reverse_order: bool,
+ pub reverse_thread_order: bool,
+ pub sort_thread_siblings: bool,
+
+ // dirlist
+ #[derivative(Debug(format_with = "crate::config::templates::debug_template"))]
+ pub dirlist_left: Template,
+ #[derivative(Debug(format_with = "crate::config::templates::debug_template"))]
+ pub dirlist_right: Template,
+ pub sidebar_width: u8,
+ pub empty_dirlist: String,
+ pub dirlist_delay: time::Duration,
+ pub dirlist_tree: bool,
+ pub dirlist_collapse: u8,
+
+ // time formats
+ pub timestamp_format: String,
+ pub this_day_time_format: String,
+ pub this_week_time_format: String,
+ pub this_year_time_format: String,
+ pub msgview_timestamp_format: String,
+ pub msgview_this_day_time_format: String,
+ pub msgview_this_week_time_format: String,
+ pub msgview_this_year_time_format: String,
+
+ // icons
+ pub icon_unencrypted: String,
+ pub icon_encrypted: String,
+ pub icon_signed: String,
+ pub icon_signed_encrypted: String,
+ pub icon_unknown: String,
+ pub icon_invalid: String,
+ pub icon_attachment: String,
+
+ // style
+ pub stylesets_dirs: Vec<String>,
+ pub styleset_name: String,
+ style: StyleSet,
+
+ // general appearance
+ pub border_vertical: char,
+ pub border_horizontal: char,
+ pub spinner: String,
+ pub spinner_delimiter: String,
+ pub spinner_interval: time::Duration,
+ pub pinned_tab_marker: String,
+
+ // behaviour
+ pub automark_read: bool,
+ pub next_message_on_delete: bool,
+ pub mouse_enabled: bool,
+ pub fuzzy_complete: bool,
+ pub new_message_bell: bool,
+ pub completion_delay: time::Duration,
+ pub completion_min_chars: u8,
+ pub completion_popovers: bool,
+
+ // tabs
+ #[derivative(Debug(format_with = "crate::config::templates::debug_template"))]
+ pub tab_title_account: Template,
+ #[derivative(Debug(format_with = "crate::config::templates::debug_template"))]
+ pub tab_title_composer: Template,
+
+ // contextual
+ contextual_sections: Vec<UiContext>,
+ contextual_counts: HashMap<UiContextType, usize>,
+ contextual_cache: HashMap<UiContextKey, UiConfig>,
+}
+
+#[derive(Debug)]
+struct UiContext {}
+
+#[derive(Debug)]
+enum UiContextType {}
+
+#[derive(Debug)]
+struct UiContextKey {}
diff --git a/src/main.rs b/src/main.rs
new file mode 100644
index 00000000..894b8853
--- /dev/null
+++ b/src/main.rs
@@ -0,0 +1,142 @@
+// SPDX-License-Identifier: MIT
+// Copyright (c) 2023 Robin Jarry
+
+mod app;
+mod cmd;
+mod config;
+mod worker;
+
+use std::io;
+use std::panic;
+use std::sync::Arc;
+
+use anyhow::Result;
+use clap::Parser;
+use crossterm::cursor;
+use crossterm::event::DisableMouseCapture;
+use crossterm::event::EnableMouseCapture;
+use crossterm::event::Event;
+use crossterm::event::EventStream;
+use crossterm::event::KeyCode;
+use crossterm::event::KeyEventKind;
+use crossterm::terminal::disable_raw_mode;
+use crossterm::terminal::enable_raw_mode;
+use crossterm::terminal::EnterAlternateScreen;
+use crossterm::terminal::LeaveAlternateScreen;
+use crossterm::terminal::SetTitle;
+use crossterm::ExecutableCommand;
+use futures::future::FutureExt;
+use futures::StreamExt;
+use tokio::sync::mpsc::channel;
+use tokio::sync::mpsc::Receiver;
+use tokio::sync::Mutex;
+use tui::backend::Backend;
+use tui::backend::CrosstermBackend;
+use tui::Terminal;
+
+use crate::app::App;
+use crate::config::Config;
+
+/// A pretty good email client
+#[derive(Parser, Debug)]
+#[command(author, version, about, long_about = None)]
+struct Args {
+ /// Enabled account (by default, all accounts are enabled).
+ #[arg(short, long = "account", env = "AERC_ACCOUNTS")]
+ accounts: Vec<String>,
+}
+
+#[tokio::main]
+async fn main() -> Result<()> {
+ let default_hook = panic::take_hook();
+ panic::set_hook(Box::new(move |info| {
+ restore_term().unwrap();
+ default_hook(info);
+ }));
+
+ // Parse command line arguments and configuration files.
+ let args = Args::parse();
+ let config = Arc::new(Mutex::new(Config::parse(args.accounts)?));
+ let (updates_tx, updates_rx) = channel(1);
+ let app = Arc::new(Mutex::new(App::new(config.clone(), updates_tx)));
+
+ // Start email handling workers in the background.
+ for account in config.lock().await.accounts.values() {
+ app.lock().await.start_worker(account.clone());
+ }
+
+ // The UI must run in the "main" thread.
+ ui_loop(config, app.clone(), updates_rx).await?;
+
+ app.lock().await.stop_workers().await;
+
+ restore_term()?;
+
+ Ok(())
+}
+
+async fn ui_loop(
+ config: Arc<Mutex<Config>>,
+ app: Arc<Mutex<App>>,
+ mut app_updates: Receiver<()>,
+) -> Result<()> {
+ // Terminal initialization.
+ enable_raw_mode()?;
+
+ let mut backend = CrosstermBackend::new(io::stdout());
+
+ backend.execute(EnterAlternateScreen)?;
+ if config.lock().await.ui.mouse_enabled {
+ backend.execute(EnableMouseCapture)?;
+ }
+ backend.hide_cursor()?;
+ backend.execute(SetTitle("aerc"))?;
+
+ let terminal = Terminal::new(backend)?;
+
+ let mut term_events = EventStream::new();
+
+ loop {
+ // TODO: draw ui here
+ tokio::select!(
+ t = app_updates.recv() => match t {
+ Some(_) => (),
+ None => break,
+ },
+ e = term_events.next().fuse() => match e {
+ Some(Ok(event)) => match event {
+ Event::Key(key) => {
+ if key.kind == KeyEventKind::Press {
+ println!("key {:?}\r", key);
+ if key.code == KeyCode::Esc {
+ break;
+ }
+ }
+ }
+ Event::Mouse(mouse) => {
+ println!("mouse {:?}\r", mouse);
+ }
+ Event::Paste(buf) => {
+ println!("paste {:?}\r", buf);
+ }
+ _ => ()
+ }
+ Some(Err(e)) => println!("Error: {:?}\r", e),
+ None => break,
+ }
+ );
+ }
+
+ Ok(())
+}
+
+fn restore_term() -> Result<()> {
+ crossterm::execute!(
+ io::stdout(),
+ LeaveAlternateScreen,
+ DisableMouseCapture,
+ cursor::Show
+ )?;
+ disable_raw_mode()?;
+ Ok(())
+}
diff --git a/src/worker/imap/mod.rs b/src/worker/imap/mod.rs
new file mode 100644
index 00000000..07aaf7d1
--- /dev/null
+++ b/src/worker/imap/mod.rs
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: MIT
+// Copyright (c) 2023 Robin Jarry
+
+use crate::worker::Backend;
+
+pub struct IMAPBackend {}
+
+pub fn new() -> IMAPBackend {
+ IMAPBackend {}
+}
+
+impl Backend for IMAPBackend {}
diff --git a/src/worker/maildir/mod.rs b/src/worker/maildir/mod.rs
new file mode 100644
index 00000000..c4e7eb9a
--- /dev/null
+++ b/src/worker/maildir/mod.rs
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: MIT
+// Copyright (c) 2023 Robin Jarry
+
+use crate::worker::Backend;
+
+pub struct MaildirBackend {}
+
+pub fn new() -> MaildirBackend {
+ MaildirBackend {}
+}
+
+impl Backend for MaildirBackend {}
diff --git a/src/worker/mbox/mod.rs b/src/worker/mbox/mod.rs
new file mode 100644
index 00000000..c4453c5f
--- /dev/null
+++ b/src/worker/mbox/mod.rs
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: MIT
+// Copyright (c) 2023 Robin Jarry
+
+use crate::worker::Backend;
+
+pub struct MboxBackend {}
+
+pub fn new() -> MboxBackend {
+ MboxBackend {}
+}
+
+impl Backend for MboxBackend {}
diff --git a/src/worker/mod.rs b/src/worker/mod.rs
new file mode 100644
index 00000000..760ed82f
--- /dev/null
+++ b/src/worker/mod.rs
@@ -0,0 +1,46 @@
+// SPDX-License-Identifier: MIT
+// Copyright (c) 2023 Robin Jarry
+
+mod imap;
+mod maildir;
+mod mbox;
+mod notmuch;
+
+use tokio::sync::mpsc::Receiver;
+use tokio::sync::mpsc::Sender;
+
+use crate::config::AccountConfig;
+use crate::config::BackendType;
+
+pub struct Worker {
+ config: AccountConfig,
+ backend: Box<dyn Backend>,
+ from_app: Receiver<WorkerMessage>,
+ to_app: Sender<WorkerMessage>,
+}
+
+impl Worker {
+ pub fn new(
+ config: AccountConfig,
+ from_app: Receiver<WorkerMessage>,
+ to_app: Sender<WorkerMessage>,
+ ) -> Self {
+ let backend: Box<dyn Backend> = match config.backend {
+ BackendType::IMAP => Box::new(imap::new()),
+ BackendType::Maildir => Box::new(maildir::new()),
+ BackendType::Mbox => Box::new(mbox::new()),
+ BackendType::Notmuch => Box::new(notmuch::new()),
+ };
+ Worker {
+ config,
+ backend,
+ from_app,
+ to_app,
+ }
+ }
+
+ pub async fn run(self) {}
+}
+
+pub trait Backend: Send + Sync {}
+pub struct WorkerMessage {}
diff --git a/src/worker/notmuch/mod.rs b/src/worker/notmuch/mod.rs
new file mode 100644
index 00000000..1cc39a9c
--- /dev/null
+++ b/src/worker/notmuch/mod.rs
@@ -0,0 +1,12 @@
+// SPDX-License-Identifier: MIT
+// Copyright (c) 2023 Robin Jarry
+
+use crate::worker::Backend;
+
+pub struct NotmuchBackend {}
+
+pub fn new() -> NotmuchBackend {
+ NotmuchBackend {}
+}
+
+impl Backend for NotmuchBackend {}