feat: Refactor to using tokio instead of async-std

This commit is contained in:
Dheepak Krishnamurthy 2022-04-18 22:47:09 -06:00
parent 7a1246f0bd
commit 7c6a1f77e3
11 changed files with 998 additions and 1323 deletions

476
Cargo.lock generated
View file

@ -38,152 +38,6 @@ version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dabe5a181f83789739c194cbe5a897dde195078fac08568d09221fd6137a7ba8" checksum = "dabe5a181f83789739c194cbe5a897dde195078fac08568d09221fd6137a7ba8"
[[package]]
name = "async-attributes"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3203e79f4dd9bdda415ed03cf14dae5a2bf775c683a00f94e9cd1faf0f596e5"
dependencies = [
"quote",
"syn",
]
[[package]]
name = "async-channel"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2114d64672151c0c5eaa5e131ec84a74f06e1e559830dabba01ca30605d66319"
dependencies = [
"concurrent-queue",
"event-listener",
"futures-core",
]
[[package]]
name = "async-executor"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "871f9bb5e0a22eeb7e8cf16641feb87c9dc67032ccf8ff49e772eb9941d3a965"
dependencies = [
"async-task",
"concurrent-queue",
"fastrand",
"futures-lite",
"once_cell",
"slab",
]
[[package]]
name = "async-global-executor"
version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9586ec52317f36de58453159d48351bc244bc24ced3effc1fce22f3d48664af6"
dependencies = [
"async-channel",
"async-executor",
"async-io",
"async-mutex",
"blocking",
"futures-lite",
"num_cpus",
"once_cell",
]
[[package]]
name = "async-io"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a811e6a479f2439f0c04038796b5cfb3d2ad56c230e0f2d3f7b04d68cfee607b"
dependencies = [
"concurrent-queue",
"futures-lite",
"libc",
"log",
"once_cell",
"parking",
"polling",
"slab",
"socket2",
"waker-fn",
"winapi",
]
[[package]]
name = "async-lock"
version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6a8ea61bf9947a1007c5cada31e647dbc77b103c679858150003ba697ea798b"
dependencies = [
"event-listener",
]
[[package]]
name = "async-mutex"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "479db852db25d9dbf6204e6cb6253698f175c15726470f78af0d918e99d6156e"
dependencies = [
"event-listener",
]
[[package]]
name = "async-process"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83137067e3a2a6a06d67168e49e68a0957d215410473a740cea95a2425c0b7c6"
dependencies = [
"async-io",
"blocking",
"cfg-if",
"event-listener",
"futures-lite",
"libc",
"once_cell",
"signal-hook",
"winapi",
]
[[package]]
name = "async-std"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8056f1455169ab86dd47b47391e4ab0cbd25410a70e9fe675544f49bafaf952"
dependencies = [
"async-attributes",
"async-channel",
"async-global-executor",
"async-io",
"async-lock",
"async-process",
"crossbeam-utils",
"futures-channel",
"futures-core",
"futures-io",
"futures-lite",
"gloo-timers",
"kv-log-macro",
"log",
"memchr",
"num_cpus",
"once_cell",
"pin-project-lite",
"pin-utils",
"slab",
"wasm-bindgen-futures",
]
[[package]]
name = "async-task"
version = "4.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e91831deabf0d6d7ec49552e489aed63b7456a7a3c46cff62adad428110b0af0"
[[package]]
name = "atomic-waker"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "065374052e7df7ee4047b1160cca5e1467a12351a40b3da123c870ba0b8eda2a"
[[package]] [[package]]
name = "atty" name = "atty"
version = "0.2.14" version = "0.2.14"
@ -233,30 +87,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]] [[package]]
name = "blocking" name = "bytes"
version = "1.1.0" version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "046e47d4b2d391b1f6f8b407b1deb8dee56c1852ccd868becf2710f601b5f427" checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
dependencies = [
"async-channel",
"async-task",
"atomic-waker",
"fastrand",
"futures-lite",
"once_cell",
]
[[package]]
name = "bumpalo"
version = "3.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c"
[[package]]
name = "cache-padded"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1db59621ec70f09c5e9b597b220c7a2b43611f4710dc03ceb8748637775692c"
[[package]] [[package]]
name = "cassowary" name = "cassowary"
@ -339,15 +173,6 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "concurrent-queue"
version = "1.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30ed07550be01594c6026cff2a1d7fe9c8f683caa798e12b68694ac9e88286a3"
dependencies = [
"cache-padded",
]
[[package]] [[package]]
name = "console" name = "console"
version = "0.15.0" version = "0.15.0"
@ -361,16 +186,6 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "crossbeam-utils"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db"
dependencies = [
"cfg-if",
"lazy_static",
]
[[package]] [[package]]
name = "crossterm" name = "crossterm"
version = "0.22.1" version = "0.22.1"
@ -380,7 +195,7 @@ dependencies = [
"bitflags", "bitflags",
"crossterm_winapi", "crossterm_winapi",
"libc", "libc",
"mio", "mio 0.7.14",
"parking_lot 0.11.2", "parking_lot 0.11.2",
"signal-hook", "signal-hook",
"signal-hook-mio", "signal-hook-mio",
@ -389,15 +204,15 @@ dependencies = [
[[package]] [[package]]
name = "crossterm" name = "crossterm"
version = "0.23.1" version = "0.23.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1fd7173631a4e9e2ca8b32ae2fad58aab9843ea5aaf56642661937d87e28a3e" checksum = "a2102ea4f781910f8a5b98dd061f4c2023f479ce7bb1236330099ceb5a93cf17"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"crossterm_winapi", "crossterm_winapi",
"futures-core", "futures-core",
"libc", "libc",
"mio", "mio 0.8.2",
"parking_lot 0.12.0", "parking_lot 0.12.0",
"signal-hook", "signal-hook",
"signal-hook-mio", "signal-hook-mio",
@ -413,16 +228,6 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "ctor"
version = "0.1.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ccc0a48a9b826acdf4028595adc9db92caea352f7af011a3034acd172a52a0aa"
dependencies = [
"quote",
"syn",
]
[[package]] [[package]]
name = "darling" name = "darling"
version = "0.10.2" version = "0.10.2"
@ -563,12 +368,6 @@ dependencies = [
"str-buf", "str-buf",
] ]
[[package]]
name = "event-listener"
version = "2.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7531096570974c3a9dcf9e4b8e1cede1ec26cf5046219fb3b9d897503b9be59"
[[package]] [[package]]
name = "failure" name = "failure"
version = "0.1.8" version = "0.1.8"
@ -591,15 +390,6 @@ dependencies = [
"synstructure", "synstructure",
] ]
[[package]]
name = "fastrand"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "779d043b6a0b90cc4c0ed7ee380a6504394cee7efd7db050e3774eee387324b2"
dependencies = [
"instant",
]
[[package]] [[package]]
name = "fd-lock" name = "fd-lock"
version = "3.0.2" version = "3.0.2"
@ -665,21 +455,6 @@ version = "0.3.21"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b"
[[package]]
name = "futures-lite"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7694489acd39452c77daa48516b894c153f192c3578d5a839b62c58099fcbf48"
dependencies = [
"fastrand",
"futures-core",
"futures-io",
"memchr",
"parking",
"pin-project-lite",
"waker-fn",
]
[[package]] [[package]]
name = "futures-macro" name = "futures-macro"
version = "0.3.21" version = "0.3.21"
@ -703,12 +478,6 @@ version = "0.3.21"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a"
[[package]]
name = "futures-timer"
version = "3.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c"
[[package]] [[package]]
name = "futures-util" name = "futures-util"
version = "0.3.21" version = "0.3.21"
@ -735,7 +504,7 @@ checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"libc", "libc",
"wasi", "wasi 0.10.0+wasi-snapshot-preview1",
] ]
[[package]] [[package]]
@ -744,19 +513,6 @@ version = "0.26.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4" checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4"
[[package]]
name = "gloo-timers"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f16c88aa13d2656ef20d1c042086b8767bbe2bdb62526894275a1b062161b2e"
dependencies = [
"futures-channel",
"futures-core",
"js-sys",
"wasm-bindgen",
"web-sys",
]
[[package]] [[package]]
name = "hashbrown" name = "hashbrown"
version = "0.11.2" version = "0.11.2"
@ -824,24 +580,6 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35"
[[package]]
name = "js-sys"
version = "0.3.55"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84"
dependencies = [
"wasm-bindgen",
]
[[package]]
name = "kv-log-macro"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f"
dependencies = [
"log",
]
[[package]] [[package]]
name = "lazy_static" name = "lazy_static"
version = "1.4.0" version = "1.4.0"
@ -850,9 +588,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.112" version = "0.2.124"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" checksum = "21a41fed9d98f27ab1c6d161da622a4fa35e8a54a8adc24bbf3ddd0ef70b0e50"
[[package]] [[package]]
name = "linked-hash-map" name = "linked-hash-map"
@ -877,7 +615,6 @@ checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"serde", "serde",
"value-bag",
] ]
[[package]] [[package]]
@ -957,6 +694,20 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "mio"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52da4364ffb0e4fe33a9841a98a3f3014fb964045ce4f7a45a398243c8d6b0c9"
dependencies = [
"libc",
"log",
"miow",
"ntapi",
"wasi 0.11.0+wasi-snapshot-preview1",
"winapi",
]
[[package]] [[package]]
name = "miow" name = "miow"
version = "0.3.7" version = "0.3.7"
@ -1070,12 +821,6 @@ dependencies = [
"memchr", "memchr",
] ]
[[package]]
name = "parking"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72"
[[package]] [[package]]
name = "parking_lot" name = "parking_lot"
version = "0.11.2" version = "0.11.2"
@ -1142,19 +887,6 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "polling"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "685404d509889fade3e86fe3a5803bca2ec09b0c0778d5ada6ec8bf7a8de5259"
dependencies = [
"cfg-if",
"libc",
"log",
"wepoll-ffi",
"winapi",
]
[[package]] [[package]]
name = "ppv-lite86" name = "ppv-lite86"
version = "0.2.16" version = "0.2.16"
@ -1407,12 +1139,13 @@ dependencies = [
[[package]] [[package]]
name = "signal-hook-mio" name = "signal-hook-mio"
version = "0.2.1" version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29fd5867f1c4f2c5be079aee7a2adf1152ebb04a4bc4d341f504b7dece607ed4" checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af"
dependencies = [ dependencies = [
"libc", "libc",
"mio", "mio 0.7.14",
"mio 0.8.2",
"signal-hook", "signal-hook",
] ]
@ -1439,9 +1172,9 @@ checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309"
[[package]] [[package]]
name = "socket2" name = "socket2"
version = "0.4.2" version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5dc90fe6c7be1a323296982db1836d1ea9e47b6839496dde9a541bc496df3516" checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0"
dependencies = [ dependencies = [
"libc", "libc",
"winapi", "winapi",
@ -1508,16 +1241,14 @@ name = "taskwarrior-tui"
version = "0.22.0" version = "0.22.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-std",
"better-panic", "better-panic",
"cassowary", "cassowary",
"chrono", "chrono",
"clap", "clap",
"clap_complete", "clap_complete",
"crossterm 0.23.1", "crossterm 0.23.2",
"dirs", "dirs",
"futures", "futures",
"futures-timer",
"itertools", "itertools",
"lazy_static", "lazy_static",
"log", "log",
@ -1531,6 +1262,8 @@ dependencies = [
"shellexpand", "shellexpand",
"shlex", "shlex",
"task-hookrs", "task-hookrs",
"tokio",
"tokio-stream",
"tui", "tui",
"unicode-segmentation", "unicode-segmentation",
"unicode-truncate", "unicode-truncate",
@ -1602,10 +1335,52 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
dependencies = [ dependencies = [
"libc", "libc",
"wasi", "wasi 0.10.0+wasi-snapshot-preview1",
"winapi", "winapi",
] ]
[[package]]
name = "tokio"
version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2af73ac49756f3f7c01172e34a23e5d0216f6c32333757c2c61feb2bbff5a5ee"
dependencies = [
"bytes",
"libc",
"memchr",
"mio 0.8.2",
"num_cpus",
"once_cell",
"parking_lot 0.12.0",
"pin-project-lite",
"signal-hook-registry",
"socket2",
"tokio-macros",
"winapi",
]
[[package]]
name = "tokio-macros"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b557f72f448c511a979e2564e55d74e6c4432fc96ff4f6241bc6bded342643b7"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tokio-stream"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50145484efff8818b5ccd256697f36863f587da82cf8b409c53adf1e840798e3"
dependencies = [
"futures-core",
"pin-project-lite",
"tokio",
]
[[package]] [[package]]
name = "traitobject" name = "traitobject"
version = "0.1.0" version = "0.1.0"
@ -1686,16 +1461,6 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "value-bag"
version = "1.0.0-alpha.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79923f7731dc61ebfba3633098bf3ac533bbd35ccd8c57e7088d9a5eebe0263f"
dependencies = [
"ctor",
"version_check",
]
[[package]] [[package]]
name = "version_check" name = "version_check"
version = "0.9.4" version = "0.9.4"
@ -1712,12 +1477,6 @@ dependencies = [
"nom", "nom",
] ]
[[package]]
name = "waker-fn"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca"
[[package]] [[package]]
name = "wasi" name = "wasi"
version = "0.10.0+wasi-snapshot-preview1" version = "0.10.0+wasi-snapshot-preview1"
@ -1725,89 +1484,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
[[package]] [[package]]
name = "wasm-bindgen" name = "wasi"
version = "0.2.78" version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
dependencies = [
"cfg-if",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.78"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b"
dependencies = [
"bumpalo",
"lazy_static",
"log",
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-futures"
version = "0.4.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e8d7523cb1f2a4c96c1317ca690031b714a51cc14e05f712446691f413f5d39"
dependencies = [
"cfg-if",
"js-sys",
"wasm-bindgen",
"web-sys",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.78"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.78"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab"
dependencies = [
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.78"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc"
[[package]]
name = "web-sys"
version = "0.3.55"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb"
dependencies = [
"js-sys",
"wasm-bindgen",
]
[[package]]
name = "wepoll-ffi"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d743fdedc5c64377b5fc2bc036b01c7fd642205a0d96356034ae3404d49eb7fb"
dependencies = [
"cc",
]
[[package]] [[package]]
name = "winapi" name = "winapi"

View file

@ -19,15 +19,13 @@ crossterm-backend = ["tui/crossterm", "crossterm"]
[dependencies] [dependencies]
anyhow = "1.0.56" anyhow = "1.0.56"
async-std = { version = "1.10.0", features = ["attributes", "unstable"] }
better-panic = "0.3.0" better-panic = "0.3.0"
cassowary = "0.3.0" cassowary = "0.3.0"
chrono = "0.4.19" chrono = "0.4.19"
clap = { version = "3.1.6", features = ["derive"] } clap = { version = "3.1.6", features = ["derive"] }
crossterm = { version = "0.23.1", optional = true, default-features = false, features = ["event-stream"] } crossterm = { version = "0.23.2", optional = true, default-features = false, features = ["event-stream"] }
dirs = "4.0.0" dirs = "4.0.0"
futures = "0.3.21" futures = "0.3.21"
futures-timer = "3.0.2"
itertools = "0.10.3" itertools = "0.10.3"
lazy_static = "1.4.0" lazy_static = "1.4.0"
log = "0.4.14" log = "0.4.14"
@ -41,6 +39,8 @@ serde_json = "1.0.79"
shellexpand = "2.1.0" shellexpand = "2.1.0"
shlex = "1.1.0" shlex = "1.1.0"
task-hookrs = { git = "https://github.com/kdheepak/task-hookrs" } task-hookrs = { git = "https://github.com/kdheepak/task-hookrs" }
tokio = { version = "1.17.0", features = ["full"] }
tokio-stream = "0.1.3"
tui = { version = "0.17.0", optional = true, default-features = false } tui = { version = "0.17.0", optional = true, default-features = false }
unicode-segmentation = "1.9.0" unicode-segmentation = "1.9.0"
unicode-truncate = "0.2.0" unicode-truncate = "0.2.0"

1305
src/app.rs

File diff suppressed because it is too large Load diff

View file

@ -38,7 +38,7 @@ impl TaskWarriorBool for str {
} }
#[derive(Debug)] #[derive(Debug)]
pub struct UDA { pub struct Uda {
label: String, label: String,
kind: String, kind: String,
values: Option<Vec<String>>, values: Option<Vec<String>>,
@ -85,6 +85,8 @@ pub struct Config {
pub uda_style_report_selection: Style, pub uda_style_report_selection: Style,
pub uda_style_calendar_title: Style, pub uda_style_calendar_title: Style,
pub uda_style_calendar_today: Style, pub uda_style_calendar_today: Style,
pub uda_style_navbar: Style,
pub uda_style_command: Style,
pub uda_style_report_completion_pane: Style, pub uda_style_report_completion_pane: Style,
pub uda_style_report_completion_pane_highlight: Style, pub uda_style_report_completion_pane_highlight: Style,
pub uda_shortcuts: Vec<String>, pub uda_shortcuts: Vec<String>,
@ -95,7 +97,7 @@ pub struct Config {
pub uda_task_report_prompt_on_done: bool, pub uda_task_report_prompt_on_done: bool,
pub uda_task_report_date_time_vague_more_precise: bool, pub uda_task_report_date_time_vague_more_precise: bool,
pub uda_context_menu_select_on_move: bool, pub uda_context_menu_select_on_move: bool,
pub uda: Vec<UDA>, pub uda: Vec<Uda>,
} }
impl Config { impl Config {
@ -144,6 +146,8 @@ impl Config {
let uda_style_report_scrollbar_area = Self::get_uda_style("report.scrollbar.area", data); let uda_style_report_scrollbar_area = Self::get_uda_style("report.scrollbar.area", data);
let uda_style_calendar_title = Self::get_uda_style("calendar.title", data); let uda_style_calendar_title = Self::get_uda_style("calendar.title", data);
let uda_style_calendar_today = Self::get_uda_style("calendar.today", data); let uda_style_calendar_today = Self::get_uda_style("calendar.today", data);
let uda_style_navbar = Self::get_uda_style("navbar", data);
let uda_style_command = Self::get_uda_style("command", data);
let uda_style_context_active = Self::get_uda_style("context.active", data); let uda_style_context_active = Self::get_uda_style("context.active", data);
let uda_style_report_completion_pane = Self::get_uda_style("report.completion-pane", data); let uda_style_report_completion_pane = Self::get_uda_style("report.completion-pane", data);
let uda_style_report_completion_pane_highlight = Self::get_uda_style("report.completion-pane-highlight", data); let uda_style_report_completion_pane_highlight = Self::get_uda_style("report.completion-pane-highlight", data);
@ -157,6 +161,8 @@ impl Config {
let uda_style_calendar_title = uda_style_calendar_title.unwrap_or_default(); let uda_style_calendar_title = uda_style_calendar_title.unwrap_or_default();
let uda_style_calendar_today = let uda_style_calendar_today =
uda_style_calendar_today.unwrap_or_else(|| Style::default().add_modifier(Modifier::BOLD)); uda_style_calendar_today.unwrap_or_else(|| Style::default().add_modifier(Modifier::BOLD));
let uda_style_navbar = uda_style_navbar.unwrap_or_else(|| Style::default().add_modifier(Modifier::REVERSED));
let uda_style_command = uda_style_command.unwrap_or_else(|| Style::default().add_modifier(Modifier::REVERSED));
let uda_style_context_active = uda_style_context_active.unwrap_or_default(); let uda_style_context_active = uda_style_context_active.unwrap_or_default();
let uda_style_report_completion_pane = uda_style_report_completion_pane let uda_style_report_completion_pane = uda_style_report_completion_pane
.unwrap_or_else(|| Style::default().fg(Color::Black).bg(Color::Rgb(223, 223, 223))); .unwrap_or_else(|| Style::default().fg(Color::Black).bg(Color::Rgb(223, 223, 223)));
@ -204,6 +210,8 @@ impl Config {
uda_style_context_active, uda_style_context_active,
uda_style_calendar_title, uda_style_calendar_title,
uda_style_calendar_today, uda_style_calendar_today,
uda_style_navbar,
uda_style_command,
uda_style_report_completion_pane, uda_style_report_completion_pane,
uda_style_report_completion_pane_highlight, uda_style_report_completion_pane_highlight,
uda_style_report_scrollbar, uda_style_report_scrollbar,

View file

@ -1,24 +1,24 @@
use crossterm::{ use crossterm::event::KeyEvent;
event::{self, DisableMouseCapture, EnableMouseCapture, EventStream}, use futures::StreamExt;
execute,
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
};
use tui::{backend::CrosstermBackend, Terminal};
use async_std::channel::unbounded;
use async_std::sync::Arc;
use async_std::task;
use futures::prelude::*;
use futures::{future::FutureExt, select, StreamExt};
use futures_timer::Delay;
use std::io::{self, Write};
use std::sync::atomic::{AtomicBool, Ordering};
use std::time::{Duration, Instant};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tokio::{sync::mpsc, sync::oneshot, task::JoinHandle};
use crossterm::event::{
KeyCode::{
BackTab, Backspace, Char, Delete, Down, End, Enter, Esc, Home, Insert, Left, Null, PageDown, PageUp, Right,
Tab, Up, F,
},
KeyModifiers,
};
#[derive(Debug, Clone, Copy)]
pub enum Event<I> {
Input(I),
Tick,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, PartialOrd, Eq)] #[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, PartialOrd, Eq)]
pub enum Key { pub enum KeyCode {
CtrlBackspace, CtrlBackspace,
CtrlDelete, CtrlDelete,
AltBackspace, AltBackspace,
@ -44,108 +44,87 @@ pub enum Key {
Tab, Tab,
} }
#[derive(Debug, Clone, Copy)] pub struct EventLoop {
pub struct EventConfig { pub rx: mpsc::UnboundedReceiver<Event<KeyCode>>,
pub tick_rate: Duration, pub tx: mpsc::UnboundedSender<Event<KeyCode>>,
pub abort: mpsc::UnboundedSender<()>,
pub handle: JoinHandle<()>,
pub tick_rate: std::time::Duration,
} }
#[derive(Debug, Clone, Copy)] impl EventLoop {
pub enum Event<I> { pub fn new(tick_rate: Option<std::time::Duration>) -> Self {
Input(I), let (tx, rx) = mpsc::unbounded_channel();
Tick, let _tx = tx.clone();
} let mut reader = crossterm::event::EventStream::new();
let should_tick = tick_rate.is_some();
let tick_rate = tick_rate.unwrap_or(std::time::Duration::from_millis(250));
pub struct Events { let (abort, mut recv) = mpsc::unbounded_channel();
pub rx: async_std::channel::Receiver<Event<Key>>,
}
impl Events {
pub fn with_config(config: EventConfig) -> Events {
use crossterm::event::{
KeyCode::{
BackTab, Backspace, Char, Delete, Down, End, Enter, Esc, Home, Insert, Left, Null, PageDown, PageUp,
Right, Tab, Up, F,
},
KeyModifiers,
};
let tick_rate = config.tick_rate;
let (tx, rx) = unbounded::<Event<Key>>();
task::spawn_local(async move {
let mut reader = EventStream::new();
let handle = tokio::spawn(async move {
loop { loop {
let mut delay = Delay::new(tick_rate).fuse(); let delay = tokio::time::sleep(tick_rate);
let mut event = reader.next().fuse(); let event = reader.next();
select! { tokio::select! {
_ = delay => { _ = recv.recv() => break,
tx.send(Event::Tick).await.ok(); _ = delay, if should_tick => {
_tx.send(Event::Tick).unwrap();
}, },
_ = _tx.closed() => break,
maybe_event = event => { maybe_event = event => {
if let Some(Ok(event::Event::Key(key))) = maybe_event { if let Some(Ok(crossterm::event::Event::Key(key))) = maybe_event {
let key = match key.code { let key = match key.code {
Backspace => { Backspace => {
match key.modifiers { match key.modifiers {
KeyModifiers::CONTROL => Key::CtrlBackspace, KeyModifiers::CONTROL => KeyCode::CtrlBackspace,
KeyModifiers::ALT => Key::AltBackspace, KeyModifiers::ALT => KeyCode::AltBackspace,
_ => Key::Backspace, _ => KeyCode::Backspace,
} }
}, },
Delete => { Delete => {
match key.modifiers { match key.modifiers {
KeyModifiers::CONTROL => Key::CtrlDelete, KeyModifiers::CONTROL => KeyCode::CtrlDelete,
KeyModifiers::ALT => Key::AltDelete, KeyModifiers::ALT => KeyCode::AltDelete,
_ => Key::Delete, _ => KeyCode::Delete,
} }
}, },
Enter => Key::Char('\n'), Enter => KeyCode::Char('\n'),
Left => Key::Left, Left => KeyCode::Left,
Right => Key::Right, Right => KeyCode::Right,
Up => Key::Up, Up => KeyCode::Up,
Down => Key::Down, Down => KeyCode::Down,
Home => Key::Home, Home => KeyCode::Home,
End => Key::End, End => KeyCode::End,
PageUp => Key::PageUp, PageUp => KeyCode::PageUp,
PageDown => Key::PageDown, PageDown => KeyCode::PageDown,
Tab => Key::Tab, Tab => KeyCode::Tab,
BackTab => Key::BackTab, BackTab => KeyCode::BackTab,
Insert => Key::Insert, Insert => KeyCode::Insert,
F(k) => Key::F(k), F(k) => KeyCode::F(k),
Null => Key::Null, Null => KeyCode::Null,
Esc => Key::Esc, Esc => KeyCode::Esc,
Char(c) => match key.modifiers { Char(c) => match key.modifiers {
KeyModifiers::NONE | KeyModifiers::SHIFT => Key::Char(c), KeyModifiers::NONE | KeyModifiers::SHIFT => KeyCode::Char(c),
KeyModifiers::CONTROL => Key::Ctrl(c), KeyModifiers::CONTROL => KeyCode::Ctrl(c),
KeyModifiers::ALT => Key::Alt(c), KeyModifiers::ALT => KeyCode::Alt(c),
_ => Key::Null, _ => KeyCode::Null,
}, },
}; };
tx.send(Event::Input(key)).await.unwrap(); _tx.send(Event::Input(key)).unwrap();
task::sleep(Duration::from_millis(1)).await; }
task::yield_now().await;
};
} }
} }
} }
}); });
Events { rx }
}
/// Attempts to read an event. Self {
/// This function will block the current thread. tx,
pub async fn next(&self) -> Result<Event<Key>, async_std::channel::RecvError> { rx,
self.rx.recv().await handle,
} tick_rate,
abort,
pub fn leave_tui_mode(terminal: &mut Terminal<CrosstermBackend<io::Stdout>>) { }
disable_raw_mode().unwrap();
execute!(io::stdout(), LeaveAlternateScreen, DisableMouseCapture).unwrap();
terminal.show_cursor().unwrap();
}
pub fn enter_tui_mode(terminal: &mut Terminal<CrosstermBackend<io::Stdout>>) {
execute!(io::stdout(), EnterAlternateScreen, EnableMouseCapture).unwrap();
enable_raw_mode().unwrap();
terminal.resize(terminal.size().unwrap()).unwrap();
} }
} }

View file

@ -1,5 +1,5 @@
#![allow(clippy::eval_order_dependence)] #![allow(clippy::eval_order_dependence)]
use crate::event::Key; use crate::event::KeyCode;
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::collections::HashSet; use std::collections::HashSet;
@ -8,85 +8,85 @@ use std::hash::Hash;
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
pub struct KeyConfig { pub struct KeyConfig {
pub quit: Key, pub quit: KeyCode,
pub refresh: Key, pub refresh: KeyCode,
pub go_to_bottom: Key, pub go_to_bottom: KeyCode,
pub go_to_top: Key, pub go_to_top: KeyCode,
pub down: Key, pub down: KeyCode,
pub up: Key, pub up: KeyCode,
pub page_down: Key, pub page_down: KeyCode,
pub page_up: Key, pub page_up: KeyCode,
pub delete: Key, pub delete: KeyCode,
pub done: Key, pub done: KeyCode,
pub start_stop: Key, pub start_stop: KeyCode,
pub quick_tag: Key, pub quick_tag: KeyCode,
pub select: Key, pub select: KeyCode,
pub select_all: Key, pub select_all: KeyCode,
pub undo: Key, pub undo: KeyCode,
pub edit: Key, pub edit: KeyCode,
pub modify: Key, pub modify: KeyCode,
pub shell: Key, pub shell: KeyCode,
pub log: Key, pub log: KeyCode,
pub add: Key, pub add: KeyCode,
pub annotate: Key, pub annotate: KeyCode,
pub help: Key, pub help: KeyCode,
pub filter: Key, pub filter: KeyCode,
pub zoom: Key, pub zoom: KeyCode,
pub context_menu: Key, pub context_menu: KeyCode,
pub next_tab: Key, pub next_tab: KeyCode,
pub previous_tab: Key, pub previous_tab: KeyCode,
pub shortcut0: Key, pub shortcut0: KeyCode,
pub shortcut1: Key, pub shortcut1: KeyCode,
pub shortcut2: Key, pub shortcut2: KeyCode,
pub shortcut3: Key, pub shortcut3: KeyCode,
pub shortcut4: Key, pub shortcut4: KeyCode,
pub shortcut5: Key, pub shortcut5: KeyCode,
pub shortcut6: Key, pub shortcut6: KeyCode,
pub shortcut7: Key, pub shortcut7: KeyCode,
pub shortcut8: Key, pub shortcut8: KeyCode,
pub shortcut9: Key, pub shortcut9: KeyCode,
} }
impl Default for KeyConfig { impl Default for KeyConfig {
fn default() -> Self { fn default() -> Self {
Self { Self {
quit: Key::Char('q'), quit: KeyCode::Char('q'),
refresh: Key::Char('r'), refresh: KeyCode::Char('r'),
go_to_bottom: Key::Char('G'), go_to_bottom: KeyCode::Char('G'),
go_to_top: Key::Char('g'), go_to_top: KeyCode::Char('g'),
down: Key::Char('j'), down: KeyCode::Char('j'),
up: Key::Char('k'), up: KeyCode::Char('k'),
page_down: Key::Char('J'), page_down: KeyCode::Char('J'),
page_up: Key::Char('K'), page_up: KeyCode::Char('K'),
delete: Key::Char('x'), delete: KeyCode::Char('x'),
done: Key::Char('d'), done: KeyCode::Char('d'),
start_stop: Key::Char('s'), start_stop: KeyCode::Char('s'),
quick_tag: Key::Char('t'), quick_tag: KeyCode::Char('t'),
select: Key::Char('v'), select: KeyCode::Char('v'),
select_all: Key::Char('V'), select_all: KeyCode::Char('V'),
undo: Key::Char('u'), undo: KeyCode::Char('u'),
edit: Key::Char('e'), edit: KeyCode::Char('e'),
modify: Key::Char('m'), modify: KeyCode::Char('m'),
shell: Key::Char('!'), shell: KeyCode::Char('!'),
log: Key::Char('l'), log: KeyCode::Char('l'),
add: Key::Char('a'), add: KeyCode::Char('a'),
annotate: Key::Char('A'), annotate: KeyCode::Char('A'),
help: Key::Char('?'), help: KeyCode::Char('?'),
filter: Key::Char('/'), filter: KeyCode::Char('/'),
zoom: Key::Char('z'), zoom: KeyCode::Char('z'),
context_menu: Key::Char('c'), context_menu: KeyCode::Char('c'),
next_tab: Key::Char(']'), next_tab: KeyCode::Char(']'),
previous_tab: Key::Char('['), previous_tab: KeyCode::Char('['),
shortcut0: Key::Char('0'), shortcut0: KeyCode::Char('0'),
shortcut1: Key::Char('1'), shortcut1: KeyCode::Char('1'),
shortcut2: Key::Char('2'), shortcut2: KeyCode::Char('2'),
shortcut3: Key::Char('3'), shortcut3: KeyCode::Char('3'),
shortcut4: Key::Char('4'), shortcut4: KeyCode::Char('4'),
shortcut5: Key::Char('5'), shortcut5: KeyCode::Char('5'),
shortcut6: Key::Char('6'), shortcut6: KeyCode::Char('6'),
shortcut7: Key::Char('7'), shortcut7: KeyCode::Char('7'),
shortcut8: Key::Char('8'), shortcut8: KeyCode::Char('8'),
shortcut9: Key::Char('9'), shortcut9: KeyCode::Char('9'),
} }
} }
} }
@ -195,12 +195,12 @@ impl KeyConfig {
} }
} }
fn get_config(config: &str, data: &str) -> Option<Key> { fn get_config(config: &str, data: &str) -> Option<KeyCode> {
for line in data.split('\n') { for line in data.split('\n') {
if line.starts_with(config) { if line.starts_with(config) {
let line = line.trim_start_matches(config).trim_start().trim_end().to_string(); let line = line.trim_start_matches(config).trim_start().trim_end().to_string();
if line.len() == 1 { if line.len() == 1 {
return Some(Key::Char(line.chars().next().unwrap())); return Some(KeyCode::Char(line.chars().next().unwrap()));
} }
} else if line.starts_with(&config.replace('-', "_")) { } else if line.starts_with(&config.replace('-', "_")) {
let line = line let line = line
@ -209,7 +209,7 @@ impl KeyConfig {
.trim_end() .trim_end()
.to_string(); .to_string();
if line.len() == 1 { if line.len() == 1 {
return Some(Key::Char(line.chars().next().unwrap())); return Some(KeyCode::Char(line.chars().next().unwrap()));
} }
} }
} }

View file

@ -1,6 +1,7 @@
#![allow(dead_code)] #![allow(dead_code)]
#![allow(unused_imports)] #![allow(unused_imports)]
#![allow(unused_variables)] #![allow(unused_variables)]
#![allow(clippy::too_many_arguments)]
mod action; mod action;
mod app; mod app;
@ -16,6 +17,7 @@ mod pane;
mod scrollbar; mod scrollbar;
mod table; mod table;
mod task_report; mod task_report;
mod ui;
use log::{debug, error, info, log_enabled, trace, warn, Level, LevelFilter}; use log::{debug, error, info, log_enabled, trace, warn, Level, LevelFilter};
use log4rs::append::file::FileAppender; use log4rs::append::file::FileAppender;
@ -29,9 +31,6 @@ use std::path::{Path, PathBuf};
use std::time::Duration; use std::time::Duration;
use anyhow::Result; use anyhow::Result;
use async_std::prelude::*;
use async_std::sync::{Arc, Mutex};
use async_std::task;
use crossterm::{ use crossterm::{
cursor, cursor,
event::{DisableMouseCapture, EnableMouseCapture, EventStream}, event::{DisableMouseCapture, EnableMouseCapture, EventStream},
@ -46,20 +45,11 @@ use path_clean::PathClean;
use app::{Mode, TaskwarriorTui}; use app::{Mode, TaskwarriorTui};
use crate::action::Action; use crate::action::Action;
use crate::event::{Event, EventConfig, Events, Key}; use crate::event::Event;
use crate::keyconfig::KeyConfig; use crate::keyconfig::KeyConfig;
const LOG_PATTERN: &str = "{d(%Y-%m-%d %H:%M:%S)} | {l} | {f}:{L} | {m}{n}"; const LOG_PATTERN: &str = "{d(%Y-%m-%d %H:%M:%S)} | {l} | {f}:{L} | {m}{n}";
pub fn setup_terminal() -> Terminal<CrosstermBackend<io::Stdout>> {
enable_raw_mode().expect("Running not in terminal");
let mut stdout = io::stdout();
execute!(stdout, EnterAlternateScreen).unwrap();
execute!(stdout, Clear(ClearType::All)).unwrap();
let backend = CrosstermBackend::new(stdout);
Terminal::new(backend).unwrap()
}
pub fn destruct_terminal() { pub fn destruct_terminal() {
disable_raw_mode().unwrap(); disable_raw_mode().unwrap();
execute!(io::stdout(), LeaveAlternateScreen, DisableMouseCapture).unwrap(); execute!(io::stdout(), LeaveAlternateScreen, DisableMouseCapture).unwrap();
@ -116,7 +106,24 @@ pub fn absolute_path(path: impl AsRef<Path>) -> io::Result<PathBuf> {
Ok(absolute_path) Ok(absolute_path)
} }
fn main() { async fn tui_main(report: &str) -> Result<()> {
panic::set_hook(Box::new(|panic_info| {
destruct_terminal();
better_panic::Settings::auto().create_panic_handler()(panic_info);
}));
let mut app = app::TaskwarriorTui::new(report).await?;
let mut terminal = app.start_tui().await?;
let r = app.run(&mut terminal).await;
app.pause_tui().await?;
r
}
fn main() -> Result<()> {
better_panic::install(); better_panic::install();
let matches = cli::generate_cli_app().get_matches(); let matches = cli::generate_cli_app().get_matches();
@ -180,91 +187,14 @@ fn main() {
debug!("getting matches from clap..."); debug!("getting matches from clap...");
debug!("report = {:?}", &report); debug!("report = {:?}", &report);
debug!("config = {:?}", &config); debug!("config = {:?}", &config);
let r = task::block_on(tui_main(report));
let r = tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()?
.block_on(async { tui_main(report).await });
if let Err(err) = r { if let Err(err) = r {
eprintln!("\x1b[0;31m[taskwarrior-tui error]\x1b[0m: {}\n\nIf you need additional help, please report as a github issue on https://github.com/kdheepak/taskwarrior-tui", err); eprintln!("\x1b[0;31m[taskwarrior-tui error]\x1b[0m: {}\n\nIf you need additional help, please report as a github issue on https://github.com/kdheepak/taskwarrior-tui", err);
std::process::exit(1); std::process::exit(1);
} }
}
async fn tui_main(report: &str) -> Result<()> {
panic::set_hook(Box::new(|panic_info| {
destruct_terminal();
better_panic::Settings::auto().create_panic_handler()(panic_info);
}));
let maybeapp = TaskwarriorTui::new(report);
if maybeapp.is_err() {
destruct_terminal();
return Err(maybeapp.err().unwrap());
}
let mut app = maybeapp.unwrap();
let mut terminal = setup_terminal();
app.render(&mut terminal).unwrap();
// Setup event handlers
let events = Events::with_config(EventConfig {
tick_rate: Duration::from_millis(app.config.uda_tick_rate),
});
loop {
app.render(&mut terminal).unwrap();
// Handle input
match events.next().await? {
Event::Input(input) => {
debug!("Received input = {:?}", input);
if (input == app.keyconfig.edit
|| input == app.keyconfig.shortcut1
|| input == app.keyconfig.shortcut2
|| input == app.keyconfig.shortcut3
|| input == app.keyconfig.shortcut4
|| input == app.keyconfig.shortcut5
|| input == app.keyconfig.shortcut6
|| input == app.keyconfig.shortcut7
|| input == app.keyconfig.shortcut8
|| input == app.keyconfig.shortcut9)
&& app.mode == Mode::Tasks(Action::Report)
{
Events::leave_tui_mode(&mut terminal);
}
let r = app.handle_input(input);
if (input == app.keyconfig.edit
|| input == app.keyconfig.shortcut1
|| input == app.keyconfig.shortcut2
|| input == app.keyconfig.shortcut3
|| input == app.keyconfig.shortcut4
|| input == app.keyconfig.shortcut5
|| input == app.keyconfig.shortcut6
|| input == app.keyconfig.shortcut7
|| input == app.keyconfig.shortcut8
|| input == app.keyconfig.shortcut9)
&& app.mode == Mode::Tasks(Action::Report)
{
Events::enter_tui_mode(&mut terminal);
}
if r.is_err() {
destruct_terminal();
return r;
}
}
Event::Tick => {
trace!("Tick event");
let r = app.update(false);
if r.is_err() {
destruct_terminal();
return r;
}
}
}
if app.should_quit {
destruct_terminal();
break;
}
}
Ok(()) Ok(())
} }

View file

@ -20,7 +20,7 @@ use tui::{
use crate::action::Action; use crate::action::Action;
use crate::app::{Mode, TaskwarriorTui}; use crate::app::{Mode, TaskwarriorTui};
use crate::event::Key; use crate::event::KeyCode;
use crate::pane::Pane; use crate::pane::Pane;
use crate::table::TableState; use crate::table::TableState;
use itertools::Itertools; use itertools::Itertools;

View file

@ -2,14 +2,14 @@ use anyhow::Result;
use crate::action::Action; use crate::action::Action;
use crate::app::{Mode, TaskwarriorTui}; use crate::app::{Mode, TaskwarriorTui};
use crate::event::Key; use crate::event::KeyCode;
use std::ops::Index; use std::ops::Index;
pub mod context; pub mod context;
pub mod project; pub mod project;
pub trait Pane { pub trait Pane {
fn handle_input(app: &mut TaskwarriorTui, input: Key) -> Result<()>; fn handle_input(app: &mut TaskwarriorTui, input: KeyCode) -> Result<()>;
fn change_focus_to_left_pane(app: &mut TaskwarriorTui) { fn change_focus_to_left_pane(app: &mut TaskwarriorTui) {
match app.mode { match app.mode {
Mode::Tasks(_) => {} Mode::Tasks(_) => {}

View file

@ -20,7 +20,7 @@ use tui::{
use crate::action::Action; use crate::action::Action;
use crate::app::{Mode, TaskwarriorTui}; use crate::app::{Mode, TaskwarriorTui};
use crate::event::Key; use crate::event::KeyCode;
use crate::pane::Pane; use crate::pane::Pane;
use crate::table::TableState; use crate::table::TableState;
use itertools::Itertools; use itertools::Itertools;
@ -148,16 +148,16 @@ impl ProjectsState {
} }
impl Pane for ProjectsState { impl Pane for ProjectsState {
fn handle_input(app: &mut TaskwarriorTui, input: Key) -> Result<()> { fn handle_input(app: &mut TaskwarriorTui, input: KeyCode) -> Result<()> {
if input == app.keyconfig.quit || input == Key::Ctrl('c') { if input == app.keyconfig.quit || input == KeyCode::Ctrl('c') {
app.should_quit = true; app.should_quit = true;
} else if input == app.keyconfig.next_tab { } else if input == app.keyconfig.next_tab {
Self::change_focus_to_right_pane(app); Self::change_focus_to_right_pane(app);
} else if input == app.keyconfig.previous_tab { } else if input == app.keyconfig.previous_tab {
Self::change_focus_to_left_pane(app); Self::change_focus_to_left_pane(app);
} else if input == Key::Down || input == app.keyconfig.down { } else if input == KeyCode::Down || input == app.keyconfig.down {
self::focus_on_next_project(app); self::focus_on_next_project(app);
} else if input == Key::Up || input == app.keyconfig.up { } else if input == KeyCode::Up || input == app.keyconfig.up {
self::focus_on_previous_project(app); self::focus_on_previous_project(app);
} else if input == app.keyconfig.select { } else if input == app.keyconfig.select {
self::update_task_filter_by_selection(app)?; self::update_task_filter_by_selection(app)?;
@ -192,25 +192,5 @@ fn update_task_filter_by_selection(app: &mut TaskwarriorTui) -> Result<()> {
let mut filter = current_filter.replace(&last_project_pattern, ""); let mut filter = current_filter.replace(&last_project_pattern, "");
filter = format!("{}{}", filter, new_project_pattern); filter = format!("{}{}", filter, new_project_pattern);
app.filter.update(filter.as_str(), filter.len()); app.filter.update(filter.as_str(), filter.len());
app.update(true)?;
Ok(()) Ok(())
} }
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_project_summary() {
let app = TaskwarriorTui::new("next");
if app.is_err() {
return;
}
let mut app = app.unwrap();
app.update(true).unwrap();
dbg!(&app.projects.rows);
dbg!(&app.projects.list);
}
}

37
src/ui.rs Normal file
View file

@ -0,0 +1,37 @@
use tui::{
backend::Backend,
layout::{Alignment, Constraint, Direction, Layout, Rect},
style::{Color, Modifier, Style},
symbols,
text::{Span, Spans},
widgets::{Block, BorderType, Borders, Cell, LineGauge, Paragraph, Row, Table},
Frame,
};
use crate::app::TaskwarriorTui;
pub fn draw<B>(rect: &mut Frame<B>, app: &TaskwarriorTui)
where
B: Backend,
{
let size = rect.size();
let chunks = Layout::default()
.direction(Direction::Vertical)
.constraints([Constraint::Length(3), Constraint::Min(10), Constraint::Length(3)].as_ref())
.split(size);
let title = draw_title();
rect.render_widget(title, chunks[0]);
}
fn draw_title<'a>() -> Paragraph<'a> {
Paragraph::new("Taskwarrior TUI")
.style(Style::default().fg(Color::LightCyan))
.alignment(Alignment::Center)
.block(
Block::default()
.borders(Borders::ALL)
.style(Style::default().fg(Color::White))
.border_type(BorderType::Plain),
)
}