diff --git a/.travis.yml b/.travis.yml index df9218d..81ca7a4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,7 @@ os: - linux - osx + - windows language: rust rust: - stable @@ -22,6 +23,11 @@ matrix: rust: nightly before_script: - rustup component add rustfmt + - os: windows + rust: nightly + before_script: + - rustup component add rustfmt + allow_failures: - rust: nightly diff --git a/Cargo.lock b/Cargo.lock index 441d037..1e96650 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -99,6 +99,14 @@ dependencies = [ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "console" version = "0.10.3" @@ -179,6 +187,29 @@ dependencies = [ "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "crossterm" +version = "0.17.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "crossterm_winapi 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", + "signal-hook 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "crossterm_winapi" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "difference" version = "2.0.0" @@ -188,16 +219,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "diskonaut" version = "0.10.0" dependencies = [ + "crossterm 0.17.7 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "filesize 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "insta 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)", "jwalk 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "nix 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", - "signal-hook 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "structopt 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", - "termion 1.5.5 (registry+https://github.com/rust-lang/crates.io-index)", - "tui 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)", + "tui 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -277,14 +308,6 @@ dependencies = [ "serde_yaml 0.8.13 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "itertools" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "itoa" version = "0.4.6" @@ -314,6 +337,22 @@ name = "linked-hash-map" version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "lock_api" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "log" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "maybe-uninit" version = "2.0.0" @@ -335,6 +374,28 @@ dependencies = [ "adler32 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "mio" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "miow 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", + "ntapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "miow" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "socket2 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "nix" version = "0.17.0" @@ -347,6 +408,14 @@ dependencies = [ "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "ntapi" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "num_cpus" version = "1.13.0" @@ -356,16 +425,33 @@ dependencies = [ "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "numtoa" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "object" version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "parking_lot" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "lock_api 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "parking_lot_core 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "parking_lot_core" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", + "smallvec 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "proc-macro-error" version = "1.0.2" @@ -434,14 +520,6 @@ name = "redox_syscall" version = "0.1.56" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "redox_termios" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "rustc-demangle" version = "0.1.16" @@ -502,6 +580,7 @@ version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -514,6 +593,22 @@ dependencies = [ "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "smallvec" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "socket2" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "strsim" version = "0.8.0" @@ -581,17 +676,6 @@ dependencies = [ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "termion" -version = "1.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)", - "numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "termios" version = "0.3.2" @@ -610,14 +694,12 @@ dependencies = [ [[package]] name = "tui" -version = "0.9.5" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "cassowary 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "itertools 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "termion 1.5.5 (registry+https://github.com/rust-lang/crates.io-index)", + "crossterm 0.17.7 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -693,6 +775,7 @@ dependencies = [ "checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" "checksum clap 2.33.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bdfa80d47f954d53a35a64987ca1422f495b8d6483c0fe9f7117b36c2a792129" "checksum clicolors-control 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90082ee5dcdd64dc4e9e0d37fbf3ee325419e39c0092191e0393df65518f741e" +"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" "checksum console 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2586208b33573b7f76ccfbe5adb076394c88deaf81b84d7213969805b0a952a7" "checksum crossbeam 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "69323bff1fb41c635347b8ead484a5ca6c3f11914d784170b158d8449ab07f8e" "checksum crossbeam-channel 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cced8691919c02aac3cb0a1bc2e9b73d89e832bf9a06fc579d4e71b68a2da061" @@ -700,6 +783,8 @@ dependencies = [ "checksum crossbeam-epoch 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace" "checksum crossbeam-queue 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "774ba60a54c213d409d5353bda12d49cd68d14e45036a285234c8d6f91f92570" "checksum crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" +"checksum crossterm 0.17.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6f4919d60f26ae233e14233cc39746c8c8bb8cd7b05840ace83604917b51b6c7" +"checksum crossterm_winapi 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "057b7146d02fb50175fd7dbe5158f6097f33d02831f43b4ee8ae4ddf67b68f5c" "checksum difference 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198" "checksum dtoa 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "134951f4028bdadb9b84baf4232681efbf277da25144b9b0ad65df75946c422b" "checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" @@ -711,19 +796,24 @@ dependencies = [ "checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" "checksum hermit-abi 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "b9586eedd4ce6b3c498bc3b4dd92fc9f11166aa908a914071953768066c67909" "checksum insta 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8386e795fb3927131ea4cede203c529a333652eb6dc4ff29616b832b27e9b096" -"checksum itertools 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "284f18f85651fe11e8a991b2adb42cb078325c996ed026d994719efcfca1d54b" "checksum itoa 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" "checksum jwalk 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88746778a47f54f83bc0d3d8ba40ce83808024405356b4d521c2bf93c1273cd4" "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" "checksum libc 0.2.71 (registry+https://github.com/rust-lang/crates.io-index)" = "9457b06509d27052635f90d6466700c65095fdf75409b3fbdd903e988b886f49" "checksum linked-hash-map 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8dd5a6d5999d9907cda8ed67bbd137d3af8085216c2ac62de5be860bd41f304a" +"checksum lock_api 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75" +"checksum log 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" "checksum maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" "checksum memoffset 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b4fc2c02a7e374099d4ee95a193111f72d2110197fe200272371758f6c3643d8" "checksum miniz_oxide 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435" +"checksum mio 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6e9971bc8349a361217a8f2a41f5d011274686bd4436465ba51730921039d7fb" +"checksum miow 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "07b88fb9795d4d36d62a012dfbf49a8f5cf12751f36d31a9dbe66d528e58979e" "checksum nix 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)" = "50e4785f2c3b7589a0d0c1dd60285e1188adac4006e8abd6dd578e1567027363" +"checksum ntapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7a31937dea023539c72ddae0e3571deadc1414b300483fa7aaec176168cfa9d2" "checksum num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" -"checksum numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef" "checksum object 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1ab52be62400ca80aa00285d25253d7f7c437b7375c4de678f5405d3afe82ca5" +"checksum parking_lot 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e" +"checksum parking_lot_core 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d58c7c768d4ba344e3e8d72518ac13e259d7c7ade24167003b8488e10b6740a3" "checksum proc-macro-error 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "98e9e4b82e0ef281812565ea4751049f1bdcdfccda7d3f459f2e138a40c08678" "checksum proc-macro-error-attr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4f5444ead4e9935abd7f27dc51f7e852a0569ac888096d5ec2499470794e2e53" "checksum proc-macro2 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "beae6331a816b1f65d04c45b078fd8e6c93e8071771f41b8163255bbd8d7c8fa" @@ -731,7 +821,6 @@ dependencies = [ "checksum rayon 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "62f02856753d04e03e26929f820d0a0a337ebe71f849801eea335d464b349080" "checksum rayon-core 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e92e15d89083484e11353891f1af602cc661426deb9564c298b270c726973280" "checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" -"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" "checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" "checksum ryu 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" "checksum scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" @@ -741,6 +830,8 @@ dependencies = [ "checksum serde_yaml 0.8.13 (registry+https://github.com/rust-lang/crates.io-index)" = "ae3e2dd40a7cdc18ca80db804b7f461a39bb721160a85c9a1fa30134bf3c02a5" "checksum signal-hook 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "604508c1418b99dfe1925ca9224829bb2a8a9a04dda655cc01fcad46f4ab05ed" "checksum signal-hook-registry 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94f478ede9f64724c5d173d7bb56099ec3e2d9fc2774aac65d34b8b890405f41" +"checksum smallvec 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fbee7696b84bbf3d89a1c2eccff0850e3047ed46bfcd2e92c29a2d074d57e252" +"checksum socket2 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "b1fa70dc5c8104ec096f4fe7ede7a221d35ae13dcd19ba1ad9a81d2cab9a1c44" "checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" "checksum structopt 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "de2f5e239ee807089b62adce73e48c625e0ed80df02c7ab3f068f5db5281065c" "checksum structopt-derive 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "510413f9de616762a4fbeab62509bf15c729603b72d7cd71280fbca431b1c118" @@ -748,10 +839,9 @@ dependencies = [ "checksum syn-mid 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7be3539f6c128a931cf19dcee741c1af532c7fd387baa739c03dd2e96479338a" "checksum synstructure 0.12.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701" "checksum terminal_size 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "8038f95fc7a6f351163f4b964af631bd26c9e828f7db085f2a84aca56f70d13b" -"checksum termion 1.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "c22cec9d8978d906be5ac94bceb5a010d885c626c4c8855721a4dbd20e3ac905" "checksum termios 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6f0fcee7b24a25675de40d5bb4de6e41b0df07bc9856295e7e2b3a3600c400c2" "checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -"checksum tui 0.9.5 (registry+https://github.com/rust-lang/crates.io-index)" = "9533d39bef0ae8f510e8a99d78702e68d1bbf0b98a78ec9740509d287010ae1e" +"checksum tui 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "36626dee5ede9fd34015e9fb4fd7eedf3f3d05bdf1436aaef15b7d0a24233778" "checksum unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0" "checksum unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479" "checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" diff --git a/Cargo.toml b/Cargo.toml index ba04a39..45d858c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,15 +10,16 @@ license = "MIT" edition = "2018" [dependencies] -tui = "0.9" -termion = "1.5" +tui = {version="0.11", default-features = false, features = ['crossterm'] } +crossterm = "0.17" failure = "0.1" jwalk = "0.5" -signal-hook = "0.1.10" structopt = "0.3" filesize = "0.2.0" unicode-width = "0.1.7" nix = "0.17.0" +[target.'cfg(windows)'.dependencies] +winapi = { version = "0.3", features = ["securitybaseapi","debugapi"] } [dev-dependencies] insta = "0.16.0" diff --git a/src/input/controls.rs b/src/input/controls.rs index ed183ce..c643125 100644 --- a/src/input/controls.rs +++ b/src/input/controls.rs @@ -1,34 +1,44 @@ -use ::std::io::stdin; -use ::termion::event::Event; -use ::termion::event::Key; -use ::termion::input::TermRead; use ::tui::backend::Backend; +use crossterm::event::Event; +use crossterm::event::KeyModifiers; +use crossterm::event::{read, KeyCode, KeyEvent}; use crate::state::FileToDelete; use crate::App; #[derive(Clone)] -pub struct KeyboardEvents; +pub struct TerminalEvents; -impl Iterator for KeyboardEvents { +impl Iterator for TerminalEvents { type Item = Event; fn next(&mut self) -> Option { - match stdin().events().next() { - Some(Ok(ev)) => Some(ev), - _ => None, - } + Some(read().unwrap()) } } - macro_rules! key { (char $x:expr) => { - Event::Key(Key::Char($x)) + Event::Key(KeyEvent { + code: KeyCode::Char($x), + modifiers: KeyModifiers::NONE, + }) + }; + (shift $x:expr) => { + Event::Key(KeyEvent { + code: KeyCode::Char($x), + modifiers: KeyModifiers::SHIFT, + }) }; (ctrl $x:expr) => { - Event::Key(Key::Ctrl($x)) + Event::Key(KeyEvent { + code: KeyCode::Char($x), + modifiers: KeyModifiers::CONTROL, + }) }; ($x:ident) => { - Event::Key(Key::$x) + Event::Key(KeyEvent { + code: KeyCode::$x, + modifiers: KeyModifiers::NONE, + }) }; } @@ -49,7 +59,7 @@ pub fn handle_keypress_loading_mode(evt: Event, app: &mut App) { key!(char 'k') | key!(Up) | key!(ctrl 'p') => { app.move_selected_up(); } - key!(char '+') => { + key!(char '+') | key!(shift '+') => { app.zoom_in(); } key!(char '-') => { @@ -58,7 +68,7 @@ pub fn handle_keypress_loading_mode(evt: Event, app: &mut App) { key!(char '0') => { app.reset_zoom(); } - key!(char '\n') => { + key!(char '\n') | key!(Enter) => { app.handle_enter(); } key!(Backspace) => { @@ -91,7 +101,7 @@ pub fn handle_keypress_normal_mode(evt: Event, app: &mut App) { key!(char 'k') | key!(Up) | key!(ctrl 'p') => { app.move_selected_up(); } - key!(char '+') => { + key!(char '+') | key!(shift '+') => { app.zoom_in(); } key!(char '-') => { @@ -100,7 +110,7 @@ pub fn handle_keypress_normal_mode(evt: Event, app: &mut App) { key!(char '0') => { app.reset_zoom(); } - key!(char '\n') => { + key!(char '\n') | key!(Enter) => { app.handle_enter(); } key!(Esc) => { diff --git a/src/input/mod.rs b/src/input/mod.rs index 0662366..494e62a 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -1,5 +1,3 @@ -mod controls; -mod signals; +pub mod controls; pub use controls::*; -pub use signals::*; diff --git a/src/input/signals.rs b/src/input/signals.rs deleted file mode 100644 index 9a0c9d9..0000000 --- a/src/input/signals.rs +++ /dev/null @@ -1,23 +0,0 @@ -use ::signal_hook::iterator::Signals; - -pub type OnSigWinch = dyn Fn(Box) + Send; -pub type SigCleanup = dyn Fn() + Send; - -pub fn sigwinch() -> (Box, Box) { - let signals = Signals::new(&[signal_hook::SIGWINCH]).unwrap(); - let on_winch = { - let signals = signals.clone(); - move |cb: Box| { - for signal in signals.forever() { - match signal { - signal_hook::SIGWINCH => cb(), - _ => unreachable!(), - } - } - } - }; - let cleanup = move || { - signals.close(); - }; - (Box::new(on_winch), Box::new(cleanup)) -} diff --git a/src/main.rs b/src/main.rs index aeccf34..95b673d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,6 +4,7 @@ mod tests; mod app; mod input; mod messages; +mod os; mod state; mod ui; @@ -21,13 +22,15 @@ use ::std::sync::Arc; use ::std::thread::park_timeout; use ::std::{thread, time}; use ::structopt::StructOpt; -use ::termion::event::{Event as TermionEvent, Key}; -use ::termion::raw::IntoRawMode; + use ::tui::backend::Backend; -use ::tui::backend::TermionBackend; +use crossterm::event::KeyModifiers; +use crossterm::event::{Event as BackEvent, KeyCode, KeyEvent}; +use crossterm::terminal::{disable_raw_mode, enable_raw_mode}; +use tui::backend::CrosstermBackend; use app::{App, UiMode}; -use input::{sigwinch, KeyboardEvents}; +use input::TerminalEvents; use messages::{handle_events, Event, Instruction}; #[cfg(not(test))] @@ -63,13 +66,18 @@ fn main() { process::exit(2); } } +fn get_stdout() -> io::Result { + Ok(io::stdout()) +} fn try_main() -> Result<(), failure::Error> { let opts = Opt::from_args(); - match io::stdout().into_raw_mode() { + + match get_stdout() { Ok(stdout) => { - let terminal_backend = TermionBackend::new(stdout); - let keyboard_events = KeyboardEvents {}; + enable_raw_mode()?; + let terminal_backend = CrosstermBackend::new(stdout); + let terminal_events = TerminalEvents {}; let folder = match opts.folder { Some(folder) => folder, None => env::current_dir()?, @@ -79,7 +87,7 @@ fn try_main() -> Result<(), failure::Error> { } start( terminal_backend, - Box::new(keyboard_events), + Box::new(terminal_events), folder, opts.apparent_size, opts.disable_delete_confirmation, @@ -87,12 +95,13 @@ fn try_main() -> Result<(), failure::Error> { } Err(_) => failure::bail!("Failed to get stdout: are you trying to pipe 'diskonaut'?"), } + disable_raw_mode()?; Ok(()) } pub fn start( terminal_backend: B, - keyboard_events: Box + Send>, + terminal_events: Box + Send>, path: PathBuf, show_apparent_size: bool, disable_delete_confirmation: bool, @@ -100,7 +109,6 @@ pub fn start( B: Backend + Send + 'static, { let mut active_threads = vec![]; - let (on_sigwinch, cleanup) = sigwinch(); let (event_sender, event_receiver): (SyncSender, Receiver) = mpsc::sync_channel(1); @@ -129,10 +137,27 @@ pub fn start( let instruction_sender = instruction_sender.clone(); let running = running.clone(); move || { - for evt in keyboard_events { - if let TermionEvent::Key(Key::Char('y')) - | TermionEvent::Key(Key::Char('q')) - | TermionEvent::Key(Key::Ctrl('c')) = evt + for evt in terminal_events { + if let BackEvent::Resize(_x, _y) = evt { + if SHOULD_HANDLE_WIN_CHANGE { + let _ = instruction_sender.send(Instruction::ResetUiMode); + let _ = instruction_sender.send(Instruction::Render); + } + continue; + } + + if let BackEvent::Key(KeyEvent { + code: KeyCode::Char('y'), + modifiers: KeyModifiers::NONE, + }) + | BackEvent::Key(KeyEvent { + code: KeyCode::Char('q'), + modifiers: KeyModifiers::NONE, + }) + | BackEvent::Key(KeyEvent { + code: KeyCode::Char('c'), + modifiers: KeyModifiers::CONTROL, + }) = evt { // not ideal, but works in a pinch let _ = instruction_sender.send(Instruction::Keypress(evt)); @@ -220,22 +245,6 @@ pub fn start( ); } - if SHOULD_HANDLE_WIN_CHANGE { - active_threads.push( - thread::Builder::new() - .name("resize_handler".to_string()) - .spawn({ - move || { - on_sigwinch(Box::new(move || { - let _ = instruction_sender.send(Instruction::ResetUiMode); - let _ = instruction_sender.send(Instruction::Render); - })); - } - }) - .unwrap(), - ); - } - let mut app = App::new( terminal_backend, path, @@ -245,7 +254,6 @@ pub fn start( ); app.start(instruction_receiver); running.store(false, Ordering::Release); - cleanup(); for thread_handler in active_threads { thread_handler.join().unwrap(); diff --git a/src/messages/instruction.rs b/src/messages/instruction.rs index 3d8afaa..77c0d69 100644 --- a/src/messages/instruction.rs +++ b/src/messages/instruction.rs @@ -1,8 +1,9 @@ use ::std::fs::Metadata; use ::std::path::PathBuf; use ::std::sync::mpsc::Receiver; -use ::termion::event::Event as TermionEvent; + use ::tui::backend::Backend; +use crossterm::event::Event as BackEvent; use crate::input::{ handle_keypress_delete_file_mode, handle_keypress_error_message, handle_keypress_exiting_mode, @@ -22,7 +23,7 @@ pub enum Instruction { RenderAndUpdateBoard, Render, ResetUiMode, - Keypress(TermionEvent), + Keypress(BackEvent), IncrementFailedToRead, } diff --git a/src/os/mod.rs b/src/os/mod.rs new file mode 100644 index 0000000..346a06d --- /dev/null +++ b/src/os/mod.rs @@ -0,0 +1,5 @@ +#[cfg(target_os = "windows")] +pub(crate) mod windows; + +#[cfg(not(target_os = "windows"))] +pub(crate) mod unix; diff --git a/src/os/unix.rs b/src/os/unix.rs new file mode 100644 index 0000000..22647ad --- /dev/null +++ b/src/os/unix.rs @@ -0,0 +1,5 @@ +use nix::unistd::geteuid; + +pub(crate) fn is_user_admin() -> bool { + geteuid().is_root() +} diff --git a/src/os/windows.rs b/src/os/windows.rs new file mode 100644 index 0000000..03109b1 --- /dev/null +++ b/src/os/windows.rs @@ -0,0 +1,41 @@ +#[cfg(not(test))] +use winapi::um::winnt::{ + DOMAIN_ALIAS_RID_ADMINS, PVOID, SECURITY_BUILTIN_DOMAIN_RID, SECURITY_NT_AUTHORITY, + SID_IDENTIFIER_AUTHORITY, +}; + +#[cfg(not(test))] +use winapi::um::securitybaseapi::{AllocateAndInitializeSid, CheckTokenMembership}; +// https://stackoverflow.com/questions/4230602/detect-if-program-is-running-with-full-administrator-rights +#[cfg(not(test))] +pub(crate) fn is_user_admin() -> bool { + let mut auth_nt = SID_IDENTIFIER_AUTHORITY { + Value: SECURITY_NT_AUTHORITY, + }; + let mut admingroup = 0 as PVOID; + let ismember = unsafe { + assert!( + AllocateAndInitializeSid( + &mut auth_nt, + 2, + SECURITY_BUILTIN_DOMAIN_RID, + DOMAIN_ALIAS_RID_ADMINS, + 0, + 0, + 0, + 0, + 0, + 0, + &mut admingroup, + ) != 0 + ); + let mut member: i32 = 0; + assert!(CheckTokenMembership(0 as PVOID, admingroup, &mut member) != 0); + member != 0 + }; + ismember +} +#[cfg(test)] +pub(crate) fn is_user_admin() -> bool { + false +} diff --git a/src/tests/cases/snapshots/diskonaut__tests__cases__ui__enter_folder_small_width-2.snap b/src/tests/cases/snapshots/diskonaut__tests__cases__ui__enter_folder_small_width-2.snap index 5b3dd4b..68035d2 100644 --- a/src/tests/cases/snapshots/diskonaut__tests__cases__ui__enter_folder_small_width-2.snap +++ b/src/tests/cases/snapshots/diskonaut__tests__cases__ui__enter_folder_small_width-2.snap @@ -50,6 +50,6 @@ expression: "&terminal_draw_events_mirror[1]" - SELECTED: subfolder_with_quite_a_long_nam + subfolder_with_quite_a_long_name diff --git a/src/tests/cases/snapshots/diskonaut__tests__cases__ui__zoom_into_small_files-7.snap b/src/tests/cases/snapshots/diskonaut__tests__cases__ui__zoom_into_small_files-7.snap index c870f1a..a9f2c99 100644 --- a/src/tests/cases/snapshots/diskonaut__tests__cases__ui__zoom_into_small_files-7.snap +++ b/src/tests/cases/snapshots/diskonaut__tests__cases__ui__zoom_into_small_files-7.snap @@ -2,54 +2,54 @@ source: src/tests/cases/ui.rs expression: "&terminal_draw_events_mirror[6]" --- - - ┬ ─ - │ - │ - │ - │ - │ - │ - │ - │ - │ - file2 │ - │ - │ - 1.0M (41%) │ - │ - │ - │ - │ - │ - │ - │ - │ file1 - │ -├───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ 392.0K (17%) - │ - │ - │ - │ - │ - │ - │ - │ - │ - file3 │ - │ - │ - 1.0M (41%) │ - │ - │ - │ - │ - │ - │ - │ - ├────────────────────────────────┤ - │xxxxxxxxxxxxxxxxxxxxxxxxxx - ┴ ─ + 1 + ┬ ─ + │ + │ + │ + │ + │ + │ + │ + │ + │ + │ + │ + │ + │ + │ + │ + │ + │ + │ + │ + │ + │ file1 + file3 │ + │ 392.0K (28%) + 1.0M (71%) │ + │ + │ + │ + │ + │ + │ + │ + │ + │ + │ + │ + │ + │ + │ + │ + │ + │ + │ + │ + ├───────────────────────────────────────────────────────┤ + │xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + ┴ ─ diff --git a/src/tests/cases/snapshots/diskonaut__tests__cases__ui__zoom_into_small_files-8.snap b/src/tests/cases/snapshots/diskonaut__tests__cases__ui__zoom_into_small_files-8.snap index 4bf669c..66a5336 100644 --- a/src/tests/cases/snapshots/diskonaut__tests__cases__ui__zoom_into_small_files-8.snap +++ b/src/tests/cases/snapshots/diskonaut__tests__cases__ui__zoom_into_small_files-8.snap @@ -3,53 +3,53 @@ source: src/tests/cases/ui.rs expression: "&terminal_draw_events_mirror[7]" --- - - - - - - - - - - - - - - - - - - - - ┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ - │ │ - │ │ - │ Are you sure you want to quit? │ - │ │ - │ │ - │ │ - │ │ - │ (y/n) │ - │ │ - └─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ - - - - - - - - - - - - - - - - - + ─ ┬ + │ + │ + │ + │ + │ + │ + │ + │ + │ + file2 │ + │ + │ + 1.0M (41%) │ + │ + │ + │ + │ + │ + │ + │ + │ file1 + │ +├───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ 392.0K (17%) + │ + │ + │ + │ + │ + │ + │ + │ + │ + file3 │ + │ + │ + 1.0M (41%) │ + │ + │ + │ + │ + │ + │ + │ + ├ + │ + ─ ┴ diff --git a/src/tests/cases/test_utils.rs b/src/tests/cases/test_utils.rs index d4decf3..36db4aa 100644 --- a/src/tests/cases/test_utils.rs +++ b/src/tests/cases/test_utils.rs @@ -1,17 +1,39 @@ use ::std::iter; use ::std::sync::{Arc, Mutex}; -use ::termion::event::{Event, Key}; +use crossterm::event::KeyModifiers; +use crossterm::event::{Event, KeyCode, KeyEvent}; -use crate::tests::fakes::{KeyboardEvents, TerminalEvent, TestBackend}; +use crate::tests::fakes::{TerminalEvent, TerminalEvents, TestBackend}; -pub fn sleep_and_quit_events(sleep_num: usize, quit_after_confirm: bool) -> Box { +macro_rules! key { + (char $x:expr) => { + Event::Key(KeyEvent { + code: KeyCode::Char($x), + modifiers: KeyModifiers::NONE, + }) + }; + (ctrl $x:expr) => { + Event::Key(KeyEvent { + code: KeyCode::Char($x), + modifiers: KeyModifiers::CONTROL, + }) + }; + ($x:ident) => { + Event::Key(KeyEvent { + code: KeyCode::$x, + modifiers: KeyModifiers::NONE, + }) + }; +} + +pub fn sleep_and_quit_events(sleep_num: usize, quit_after_confirm: bool) -> Box { let mut events: Vec> = iter::repeat(None).take(sleep_num).collect(); - events.push(Some(Event::Key(Key::Ctrl('c')))); + events.push(Some(key!(ctrl 'c'))); if quit_after_confirm { events.push(None); - events.push(Some(Event::Key(Key::Char('y')))); + events.push(Some(key!(char 'y'))); } - Box::new(KeyboardEvents::new(events)) + Box::new(TerminalEvents::new(events)) } type BackendWithStreams = ( diff --git a/src/tests/cases/ui.rs b/src/tests/cases/ui.rs index 306cdf0..3f17af1 100644 --- a/src/tests/cases/ui.rs +++ b/src/tests/cases/ui.rs @@ -5,13 +5,34 @@ use ::std::iter; use ::std::path::{Path, PathBuf}; use ::insta::assert_snapshot; -use ::termion::event::{Event, Key}; +use crossterm::event::KeyModifiers; +use crossterm::event::{Event, KeyCode, KeyEvent}; use crate::start; -use crate::tests::cases::test_utils::{sleep_and_quit_events, test_backend_factory}; -use crate::tests::fakes::KeyboardEvents; +use crate::tests::cases::test_utils::*; use crate::tests::fakes::TerminalEvent::*; +use crate::tests::fakes::TerminalEvents; +macro_rules! key { + (char $x:expr) => { + Event::Key(KeyEvent { + code: KeyCode::Char($x), + modifiers: KeyModifiers::NONE, + }) + }; + (ctrl $x:expr) => { + Event::Key(KeyEvent { + code: KeyCode::Char($x), + modifiers: KeyModifiers::CONTROL, + }) + }; + ($x:ident) => { + Event::Key(KeyEvent { + code: KeyCode::$x, + modifiers: KeyModifiers::NONE, + }) + }; +} // this means we ask diskonaut to show the actual file size rather than the size taken on disk // // this is in order to make the tests more possible, so they will show the same result @@ -42,9 +63,6 @@ fn create_temp_file>(path: P, size: usize) -> Result<(), failure: Ok(()) } -// TODO: adjust tests for other platforms (currently the snapshots include the /tmp folder which -// might not work when running on mac/windows) - #[test] fn two_large_files_one_small_file() { let (terminal_events, terminal_draw_events, backend) = test_backend_factory(190, 50); @@ -73,15 +91,9 @@ fn two_large_files_one_small_file() { ); std::fs::remove_dir_all(temp_dir_path).expect("failed to remove temporary folder"); let terminal_draw_events_mirror = terminal_draw_events.lock().unwrap(); - println!( - "terminal_draw_events_mirror[0] {:?}", - terminal_draw_events_mirror[0] - ); - let expected_terminal_events = vec![ - Clear, HideCursor, Draw, Flush, Draw, Flush, Clear, ShowCursor, + Clear, HideCursor, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Clear, ShowCursor, ]; - assert_eq!( &terminal_events.lock().unwrap()[..], &expected_terminal_events[..] @@ -119,15 +131,9 @@ fn medium_width() { ); std::fs::remove_dir_all(temp_dir_path).expect("failed to remove temporary folder"); let terminal_draw_events_mirror = terminal_draw_events.lock().unwrap(); - println!( - "terminal_draw_events_mirror[0] {:?}", - terminal_draw_events_mirror[0] - ); - let expected_terminal_events = vec![ - Clear, HideCursor, Draw, Flush, Draw, Flush, Clear, ShowCursor, + Clear, HideCursor, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Clear, ShowCursor, ]; - assert_eq!( &terminal_events.lock().unwrap()[..], &expected_terminal_events[..] @@ -165,15 +171,9 @@ fn small_width() { ); std::fs::remove_dir_all(temp_dir_path).expect("failed to remove temporary folder"); let terminal_draw_events_mirror = terminal_draw_events.lock().unwrap(); - println!( - "terminal_draw_events_mirror[0] {:?}", - terminal_draw_events_mirror[0] - ); - let expected_terminal_events = vec![ - Clear, HideCursor, Draw, Flush, Draw, Flush, Clear, ShowCursor, + Clear, HideCursor, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Clear, ShowCursor, ]; - assert_eq!( &terminal_events.lock().unwrap()[..], &expected_terminal_events[..] @@ -212,15 +212,9 @@ fn small_width_long_folder_name() { ); std::fs::remove_dir_all(temp_dir_path).expect("failed to remove temporary folder"); let terminal_draw_events_mirror = terminal_draw_events.lock().unwrap(); - println!( - "terminal_draw_events_mirror[0] {:?}", - terminal_draw_events_mirror[0] - ); - let expected_terminal_events = vec![ - Clear, HideCursor, Draw, Flush, Draw, Flush, Clear, ShowCursor, + Clear, HideCursor, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Clear, ShowCursor, ]; - assert_eq!( &terminal_events.lock().unwrap()[..], &expected_terminal_events[..] @@ -259,13 +253,9 @@ fn too_small_width_one() { ); std::fs::remove_dir_all(temp_dir_path).expect("failed to remove temporary folder"); let terminal_draw_events_mirror = terminal_draw_events.lock().unwrap(); - println!( - "terminal_draw_events_mirror[0] {:?}", - terminal_draw_events_mirror[0] - ); - - let expected_terminal_events = vec![Clear, HideCursor, Draw, Flush, Clear, ShowCursor]; - + let expected_terminal_events = vec![ + Clear, HideCursor, Draw, HideCursor, Flush, Clear, ShowCursor, + ]; assert_eq!( &terminal_events.lock().unwrap()[..], &expected_terminal_events[..] @@ -303,13 +293,9 @@ fn too_small_width_two() { ); std::fs::remove_dir_all(temp_dir_path).expect("failed to remove temporary folder"); let terminal_draw_events_mirror = terminal_draw_events.lock().unwrap(); - println!( - "terminal_draw_events_mirror[0] {:?}", - terminal_draw_events_mirror[0] - ); - - let expected_terminal_events = vec![Clear, HideCursor, Draw, Flush, Clear, ShowCursor]; - + let expected_terminal_events = vec![ + Clear, HideCursor, Draw, HideCursor, Flush, Clear, ShowCursor, + ]; assert_eq!( &terminal_events.lock().unwrap()[..], &expected_terminal_events[..] @@ -335,13 +321,9 @@ fn too_small_width_three() { ); std::fs::remove_dir_all(temp_dir_path).expect("failed to remove temporary folder"); let terminal_draw_events_mirror = terminal_draw_events.lock().unwrap(); - println!( - "terminal_draw_events_mirror[0] {:?}", - terminal_draw_events_mirror[0] - ); - - let expected_terminal_events = vec![Clear, HideCursor, Draw, Flush, Clear, ShowCursor]; - + let expected_terminal_events = vec![ + Clear, HideCursor, Draw, HideCursor, Flush, Clear, ShowCursor, + ]; assert_eq!( &terminal_events.lock().unwrap()[..], &expected_terminal_events[..] @@ -367,13 +349,9 @@ fn too_small_width_four() { ); std::fs::remove_dir_all(temp_dir_path).expect("failed to remove temporary folder"); let terminal_draw_events_mirror = terminal_draw_events.lock().unwrap(); - println!( - "terminal_draw_events_mirror[0] {:?}", - terminal_draw_events_mirror[0] - ); - - let expected_terminal_events = vec![Clear, HideCursor, Draw, Flush, Clear, ShowCursor]; - + let expected_terminal_events = vec![ + Clear, HideCursor, Draw, HideCursor, Flush, Clear, ShowCursor, + ]; assert_eq!( &terminal_events.lock().unwrap()[..], &expected_terminal_events[..] @@ -399,13 +377,9 @@ fn too_small_width_five() { ); std::fs::remove_dir_all(temp_dir_path).expect("failed to remove temporary folder"); let terminal_draw_events_mirror = terminal_draw_events.lock().unwrap(); - println!( - "terminal_draw_events_mirror[0] {:?}", - terminal_draw_events_mirror[0] - ); - - let expected_terminal_events = vec![Clear, HideCursor, Draw, Flush, Clear, ShowCursor]; - + let expected_terminal_events = vec![ + Clear, HideCursor, Draw, HideCursor, Flush, Clear, ShowCursor, + ]; assert_eq!( &terminal_events.lock().unwrap()[..], &expected_terminal_events[..] @@ -431,13 +405,9 @@ fn too_small_height() { ); std::fs::remove_dir_all(temp_dir_path).expect("failed to remove temporary folder"); let terminal_draw_events_mirror = terminal_draw_events.lock().unwrap(); - println!( - "terminal_draw_events_mirror[0] {:?}", - terminal_draw_events_mirror[0] - ); - - let expected_terminal_events = vec![Clear, HideCursor, Draw, Flush, Clear, ShowCursor]; - + let expected_terminal_events = vec![ + Clear, HideCursor, Draw, HideCursor, Flush, Clear, ShowCursor, + ]; assert_eq!( &terminal_events.lock().unwrap()[..], &expected_terminal_events[..] @@ -508,7 +478,7 @@ fn eleven_files() { let terminal_draw_events_mirror = terminal_draw_events.lock().unwrap(); let expected_terminal_events = vec![ - Clear, HideCursor, Draw, Flush, Draw, Flush, Clear, ShowCursor, + Clear, HideCursor, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Clear, ShowCursor, ]; assert_eq!( &terminal_events.lock().unwrap()[..], @@ -525,19 +495,19 @@ fn enter_folder() { let (terminal_events, terminal_draw_events, backend) = test_backend_factory(190, 50); let mut events: Vec> = iter::repeat(None).take(1).collect(); - events.push(Some(Event::Key(Key::Char('j')))); // once to place selected marker on screen + events.push(Some(key!(char 'j'))); // once to place selected marker on screen events.push(None); - events.push(Some(Event::Key(Key::Char('\n')))); + events.push(Some(key!(char '\n'))); // here we sleep extra to allow the blink events to happen and be tested before the app exits // with the following ctrl-c events.push(None); events.push(None); events.push(None); events.push(None); - events.push(Some(Event::Key(Key::Ctrl('c')))); + events.push(Some(key!(ctrl 'c'))); events.push(None); - events.push(Some(Event::Key(Key::Char('y')))); - let keyboard_events = Box::new(KeyboardEvents::new(events)); + events.push(Some(key!(char 'y'))); + let keyboard_events = Box::new(TerminalEvents::new(events)); let temp_dir_path = create_root_temp_dir("enter_folder").expect("failed to create temp dir"); @@ -571,9 +541,9 @@ fn enter_folder() { .expect("could not acquire lock on terminal events"); let expected_terminal_events = vec![ - Clear, HideCursor, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Clear, ShowCursor, + Clear, HideCursor, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, HideCursor, + Flush, Draw, HideCursor, Flush, Clear, ShowCursor, ]; - assert_eq!( &terminal_events .lock() @@ -593,19 +563,19 @@ fn enter_folder_medium_width() { let (terminal_events, terminal_draw_events, backend) = test_backend_factory(90, 50); let mut events: Vec> = iter::repeat(None).take(1).collect(); - events.push(Some(Event::Key(Key::Char('j')))); // once to place selected marker on screen + events.push(Some(key!(char 'j'))); // once to place selected marker on screen events.push(None); - events.push(Some(Event::Key(Key::Char('\n')))); + events.push(Some(key!(char '\n'))); // here we sleep extra to allow the blink events to happen and be tested before the app exits // with the following ctrl-c events.push(None); events.push(None); events.push(None); events.push(None); - events.push(Some(Event::Key(Key::Ctrl('c')))); + events.push(Some(key!(ctrl 'c'))); events.push(None); - events.push(Some(Event::Key(Key::Char('y')))); - let keyboard_events = Box::new(KeyboardEvents::new(events)); + events.push(Some(key!(char 'y'))); + let keyboard_events = Box::new(TerminalEvents::new(events)); let temp_dir_path = create_root_temp_dir("enter_folder_medium_width").expect("failed to create temp dir"); @@ -640,7 +610,8 @@ fn enter_folder_medium_width() { .expect("could not acquire lock on terminal events"); let expected_terminal_events = vec![ - Clear, HideCursor, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Clear, ShowCursor, + Clear, HideCursor, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, HideCursor, + Flush, Draw, HideCursor, Flush, Clear, ShowCursor, ]; assert_eq!( @@ -662,19 +633,19 @@ fn enter_folder_small_width() { let (terminal_events, terminal_draw_events, backend) = test_backend_factory(60, 50); let mut events: Vec> = iter::repeat(None).take(1).collect(); - events.push(Some(Event::Key(Key::Char('j')))); // once to place selected marker on screen + events.push(Some(key!(char 'j'))); // once to place selected marker on screen events.push(None); - events.push(Some(Event::Key(Key::Char('\n')))); + events.push(Some(key!(char '\n'))); // here we sleep extra to allow the blink events to happen and be tested before the app exits // with the following ctrl-c events.push(None); events.push(None); events.push(None); events.push(None); - events.push(Some(Event::Key(Key::Ctrl('c')))); + events.push(Some(key!(ctrl 'c'))); events.push(None); - events.push(Some(Event::Key(Key::Char('y')))); - let keyboard_events = Box::new(KeyboardEvents::new(events)); + events.push(Some(key!(char 'y'))); + let keyboard_events = Box::new(TerminalEvents::new(events)); let temp_dir_path = create_root_temp_dir("enter_folder_small_width").expect("failed to create temp dir"); @@ -709,9 +680,9 @@ fn enter_folder_small_width() { .expect("could not acquire lock on terminal events"); let expected_terminal_events = vec![ - Clear, HideCursor, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Clear, ShowCursor, + Clear, HideCursor, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, HideCursor, + Flush, Draw, HideCursor, Flush, Clear, ShowCursor, ]; - assert_eq!( &terminal_events .lock() @@ -763,7 +734,7 @@ fn small_files() { let terminal_draw_events_mirror = terminal_draw_events.lock().unwrap(); let expected_terminal_events = vec![ - Clear, HideCursor, Draw, Flush, Draw, Flush, Clear, ShowCursor, + Clear, HideCursor, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Clear, ShowCursor, ]; assert_eq!( &terminal_events.lock().unwrap()[..], @@ -779,24 +750,24 @@ fn small_files() { fn zoom_into_small_files() { let (terminal_events, terminal_draw_events, backend) = test_backend_factory(190, 50); let mut events: Vec> = iter::repeat(None).take(2).collect(); - events.push(Some(Event::Key(Key::Char('+')))); + events.push(Some(key!(char '+'))); events.push(None); - events.push(Some(Event::Key(Key::Char('+')))); + events.push(Some(key!(char '+'))); events.push(None); - events.push(Some(Event::Key(Key::Char('+')))); + events.push(Some(key!(char '+'))); events.push(None); - events.push(Some(Event::Key(Key::Char('+')))); + events.push(Some(key!(char '+'))); events.push(None); - events.push(Some(Event::Key(Key::Char('-')))); + events.push(Some(key!(char '-'))); events.push(None); - events.push(Some(Event::Key(Key::Ctrl('-')))); + events.push(Some(key!(char '-'))); events.push(None); - events.push(Some(Event::Key(Key::Char('0')))); + events.push(Some(key!(char '0'))); events.push(None); - events.push(Some(Event::Key(Key::Ctrl('c')))); + events.push(Some(key!(ctrl 'c'))); events.push(None); - events.push(Some(Event::Key(Key::Char('y')))); - let keyboard_events = Box::new(KeyboardEvents::new(events)); + events.push(Some(key!(char 'y'))); + let keyboard_events = Box::new(TerminalEvents::new(events)); let temp_dir_path = create_root_temp_dir("zoom_into_small_files").expect("failed to create temp dir"); @@ -831,15 +802,16 @@ fn zoom_into_small_files() { let terminal_draw_events_mirror = terminal_draw_events.lock().unwrap(); let expected_terminal_events = vec![ - Clear, HideCursor, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Draw, - Flush, Draw, Flush, Draw, Flush, Clear, ShowCursor, + Clear, HideCursor, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, HideCursor, + Flush, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, + HideCursor, Flush, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Clear, ShowCursor, ]; assert_eq!( &terminal_events.lock().unwrap()[..], &expected_terminal_events[..] ); - assert_eq!(terminal_draw_events_mirror.len(), 8); + assert_eq!(terminal_draw_events_mirror.len(), 9); assert_snapshot!(&terminal_draw_events_mirror[0]); assert_snapshot!(&terminal_draw_events_mirror[1]); assert_snapshot!(&terminal_draw_events_mirror[2]); @@ -855,16 +827,16 @@ fn cannot_move_into_small_files() { let (terminal_events, terminal_draw_events, backend) = test_backend_factory(190, 50); let mut events: Vec> = iter::repeat(None).take(2).collect(); - events.push(Some(Event::Key(Key::Char('j')))); // once to place selected marker on screen + events.push(Some(key!(char 'j'))); // once to place selected marker on screen events.push(None); - events.push(Some(Event::Key(Key::Char('l')))); + events.push(Some(key!(char 'l'))); events.push(None); - events.push(Some(Event::Key(Key::Char('j')))); + events.push(Some(key!(char 'j'))); events.push(None); - events.push(Some(Event::Key(Key::Ctrl('c')))); + events.push(Some(key!(ctrl 'c'))); events.push(None); - events.push(Some(Event::Key(Key::Char('y')))); - let keyboard_events = Box::new(KeyboardEvents::new(events)); + events.push(Some(key!(char 'y'))); + let keyboard_events = Box::new(TerminalEvents::new(events)); let temp_dir_path = create_root_temp_dir("cannot_move_into_small_files").expect("failed to create temp dir"); @@ -928,8 +900,8 @@ fn cannot_move_into_small_files() { let terminal_draw_events_mirror = terminal_draw_events.lock().unwrap(); let expected_terminal_events = vec![ - Clear, HideCursor, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Clear, - ShowCursor, + Clear, HideCursor, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, HideCursor, + Flush, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Clear, ShowCursor, ]; assert_eq!( &terminal_events.lock().unwrap()[..], @@ -987,9 +959,9 @@ fn minimum_tile_sides() { let terminal_draw_events_mirror = terminal_draw_events.lock().unwrap(); let expected_terminal_events = vec![ - Clear, HideCursor, Draw, Flush, Draw, Flush, Clear, ShowCursor, + Clear, HideCursor, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Clear, ShowCursor, ]; - // let expected_terminal_events = vec![Clear, HideCursor, Draw, Flush, Draw, Flush, Clear, ShowCursor]; + assert_eq!( &terminal_events.lock().unwrap()[..], &expected_terminal_events[..] @@ -1005,20 +977,20 @@ fn move_down_and_enter_folder() { let (terminal_events, terminal_draw_events, backend) = test_backend_factory(190, 50); let mut events: Vec> = iter::repeat(None).take(2).collect(); - events.push(Some(Event::Key(Key::Char('j')))); // once to place selected marker on screen + events.push(Some(key!(char 'j'))); // once to place selected marker on screen events.push(None); - events.push(Some(Event::Key(Key::Char('j')))); + events.push(Some(key!(char 'j'))); events.push(None); - events.push(Some(Event::Key(Key::Char('\n')))); + events.push(Some(key!(char '\n'))); // here we sleep extra to allow the blink events to happen and be tested before the app exits // with the following ctrl-c events.push(None); events.push(None); events.push(None); - events.push(Some(Event::Key(Key::Ctrl('c')))); + events.push(Some(key!(ctrl 'c'))); events.push(None); - events.push(Some(Event::Key(Key::Char('y')))); - let keyboard_events = Box::new(KeyboardEvents::new(events)); + events.push(Some(key!(char 'y'))); + let keyboard_events = Box::new(TerminalEvents::new(events)); let temp_dir_path = create_root_temp_dir("move_down_and_enter_folder").expect("failed to create temp dir"); @@ -1053,10 +1025,9 @@ fn move_down_and_enter_folder() { .expect("could not acquire lock on terminal events"); let expected_terminal_events = vec![ - Clear, HideCursor, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Clear, - ShowCursor, + Clear, HideCursor, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, HideCursor, + Flush, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Clear, ShowCursor, ]; - assert_eq!( &terminal_events .lock() @@ -1077,20 +1048,20 @@ fn noop_when_entering_file() { let (terminal_events, terminal_draw_events, backend) = test_backend_factory(190, 50); let mut events: Vec> = iter::repeat(None).take(1).collect(); - events.push(Some(Event::Key(Key::Char('j')))); // once to place selected marker on screen + events.push(Some(key!(char 'j'))); // once to place selected marker on screen events.push(None); - events.push(Some(Event::Key(Key::Char('j')))); + events.push(Some(key!(char 'j'))); events.push(None); - events.push(Some(Event::Key(Key::Char('\n')))); + events.push(Some(key!(char '\n'))); // here we sleep extra to allow the blink events to happen and be tested before the app exits // with the following ctrl-c events.push(None); events.push(None); events.push(None); - events.push(Some(Event::Key(Key::Ctrl('c')))); + events.push(Some(key!(ctrl 'c'))); events.push(None); - events.push(Some(Event::Key(Key::Char('y')))); - let keyboard_events = Box::new(KeyboardEvents::new(events)); + events.push(Some(key!(char 'y'))); + let keyboard_events = Box::new(TerminalEvents::new(events)); let temp_dir_path = create_root_temp_dir("noop_when_entering_file").expect("failed to create temp dir"); @@ -1120,7 +1091,8 @@ fn noop_when_entering_file() { .expect("could not acquire lock on terminal events"); let expected_terminal_events = vec![ - Clear, HideCursor, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Clear, ShowCursor, + Clear, HideCursor, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, HideCursor, + Flush, Draw, HideCursor, Flush, Clear, ShowCursor, ]; assert_eq!( @@ -1142,22 +1114,22 @@ fn move_up_and_enter_folder() { let (terminal_events, terminal_draw_events, backend) = test_backend_factory(190, 50); let mut events: Vec> = iter::repeat(None).take(1).collect(); - events.push(Some(Event::Key(Key::Char('j')))); // once to place selected marker on screen + events.push(Some(key!(char 'j'))); // once to place selected marker on screen events.push(None); - events.push(Some(Event::Key(Key::Char('j')))); + events.push(Some(key!(char 'j'))); events.push(None); - events.push(Some(Event::Key(Key::Char('k')))); + events.push(Some(key!(char 'k'))); events.push(None); - events.push(Some(Event::Key(Key::Char('\n')))); + events.push(Some(key!(char '\n'))); // here we sleep extra to allow the blink events to happen and be tested before the app exits // with the following ctrl-c events.push(None); events.push(None); events.push(None); - events.push(Some(Event::Key(Key::Ctrl('c')))); + events.push(Some(key!(ctrl 'c'))); events.push(None); - events.push(Some(Event::Key(Key::Char('y')))); - let keyboard_events = Box::new(KeyboardEvents::new(events)); + events.push(Some(key!(char 'y'))); + let keyboard_events = Box::new(TerminalEvents::new(events)); let temp_dir_path = create_root_temp_dir("move_up_and_enter_folder").expect("failed to create temp dir"); @@ -1192,10 +1164,10 @@ fn move_up_and_enter_folder() { .expect("could not acquire lock on terminal events"); let expected_terminal_events = vec![ - Clear, HideCursor, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Draw, - Flush, Clear, ShowCursor, + Clear, HideCursor, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, HideCursor, + Flush, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Clear, + ShowCursor, ]; - assert_eq!( &terminal_events .lock() @@ -1217,20 +1189,20 @@ fn move_right_and_enter_folder() { let (terminal_events, terminal_draw_events, backend) = test_backend_factory(190, 50); let mut events: Vec> = iter::repeat(None).take(1).collect(); - events.push(Some(Event::Key(Key::Char('l')))); // once to place selected marker on screen + events.push(Some(key!(char 'l'))); // once to place selected marker on screen events.push(None); - events.push(Some(Event::Key(Key::Char('l')))); + events.push(Some(key!(char 'l'))); events.push(None); - events.push(Some(Event::Key(Key::Char('\n')))); + events.push(Some(key!(char '\n'))); // here we sleep extra to allow the blink events to happen and be tested before the app exits // with the following ctrl-c events.push(None); events.push(None); events.push(None); - events.push(Some(Event::Key(Key::Ctrl('c')))); + events.push(Some(key!(ctrl 'c'))); events.push(None); - events.push(Some(Event::Key(Key::Char('y')))); - let keyboard_events = Box::new(KeyboardEvents::new(events)); + events.push(Some(key!(char 'y'))); + let keyboard_events = Box::new(TerminalEvents::new(events)); let temp_dir_path = create_root_temp_dir("move_right_and_enter_folder").expect("failed to create temp dir"); @@ -1265,10 +1237,9 @@ fn move_right_and_enter_folder() { .expect("could not acquire lock on terminal events"); let expected_terminal_events = vec![ - Clear, HideCursor, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Clear, - ShowCursor, + Clear, HideCursor, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, HideCursor, + Flush, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Clear, ShowCursor, ]; - assert_eq!( &terminal_events .lock() @@ -1289,22 +1260,22 @@ fn move_left_and_enter_folder() { let (terminal_events, terminal_draw_events, backend) = test_backend_factory(190, 50); let mut events: Vec> = iter::repeat(None).take(1).collect(); - events.push(Some(Event::Key(Key::Char('l')))); // once to place selected marker on screen + events.push(Some(key!(char 'l'))); // once to place selected marker on screen events.push(None); - events.push(Some(Event::Key(Key::Char('l')))); + events.push(Some(key!(char 'l'))); events.push(None); - events.push(Some(Event::Key(Key::Char('h')))); + events.push(Some(key!(char 'h'))); events.push(None); - events.push(Some(Event::Key(Key::Char('\n')))); + events.push(Some(key!(char '\n'))); // here we sleep extra to allow the blink events to happen and be tested before the app exits // with the following ctrl-c events.push(None); events.push(None); events.push(None); - events.push(Some(Event::Key(Key::Ctrl('c')))); + events.push(Some(key!(ctrl 'c'))); events.push(None); - events.push(Some(Event::Key(Key::Char('y')))); - let keyboard_events = Box::new(KeyboardEvents::new(events)); + events.push(Some(key!(char 'y'))); + let keyboard_events = Box::new(TerminalEvents::new(events)); let temp_dir_path = create_root_temp_dir("move_left_and_enter_folder").expect("failed to create temp dir"); @@ -1339,10 +1310,10 @@ fn move_left_and_enter_folder() { .expect("could not acquire lock on terminal events"); let expected_terminal_events = vec![ - Clear, HideCursor, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Draw, - Flush, Clear, ShowCursor, + Clear, HideCursor, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, HideCursor, + Flush, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Clear, + ShowCursor, ]; - assert_eq!( &terminal_events .lock() @@ -1364,16 +1335,16 @@ fn enter_largest_folder_with_no_selected_tile() { let (terminal_events, terminal_draw_events, backend) = test_backend_factory(190, 50); let mut events: Vec> = iter::repeat(None).take(1).collect(); - events.push(Some(Event::Key(Key::Char('\n')))); + events.push(Some(key!(char '\n'))); // here we sleep extra to allow the blink events to happen and be tested before the app exits // with the following ctrl-c events.push(None); events.push(None); events.push(None); - events.push(Some(Event::Key(Key::Ctrl('c')))); + events.push(Some(key!(ctrl 'c'))); events.push(None); - events.push(Some(Event::Key(Key::Char('y')))); - let keyboard_events = Box::new(KeyboardEvents::new(events)); + events.push(Some(key!(char 'y'))); + let keyboard_events = Box::new(TerminalEvents::new(events)); let temp_dir_path = create_root_temp_dir("enter_largest_folder_with_no_selected_tile") .expect("failed to create temp dir"); @@ -1408,7 +1379,8 @@ fn enter_largest_folder_with_no_selected_tile() { .expect("could not acquire lock on terminal events"); let expected_terminal_events = vec![ - Clear, HideCursor, Draw, Flush, Draw, Flush, Draw, Flush, Clear, ShowCursor, + Clear, HideCursor, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, HideCursor, + Flush, Clear, ShowCursor, ]; assert_eq!( @@ -1429,16 +1401,16 @@ fn clear_selection_when_moving_off_screen_edges() { let (terminal_events, terminal_draw_events, backend) = test_backend_factory(190, 50); let mut events: Vec> = iter::repeat(None).take(1).collect(); - events.push(Some(Event::Key(Key::Char('l')))); // once to place selected marker on screen + events.push(Some(key!(char 'l'))); // once to place selected marker on screen events.push(None); - events.push(Some(Event::Key(Key::Char('l')))); + events.push(Some(key!(char 'l'))); events.push(None); - events.push(Some(Event::Key(Key::Char('l')))); + events.push(Some(key!(char 'l'))); events.push(None); - events.push(Some(Event::Key(Key::Ctrl('c')))); + events.push(Some(key!(ctrl 'c'))); events.push(None); - events.push(Some(Event::Key(Key::Char('y')))); - let keyboard_events = Box::new(KeyboardEvents::new(events)); + events.push(Some(key!(char 'y'))); + let keyboard_events = Box::new(TerminalEvents::new(events)); let temp_dir_path = create_root_temp_dir("noop_when_moving_off_screen_edges") .expect("failed to create temp dir"); @@ -1468,8 +1440,8 @@ fn clear_selection_when_moving_off_screen_edges() { .expect("could not acquire lock on terminal events"); let expected_terminal_events = vec![ - Clear, HideCursor, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Clear, - ShowCursor, + Clear, HideCursor, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, HideCursor, + Flush, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Clear, ShowCursor, ]; assert_eq!( &terminal_events @@ -1491,13 +1463,13 @@ fn esc_to_go_up() { let (terminal_events, terminal_draw_events, backend) = test_backend_factory(190, 50); let mut events: Vec> = iter::repeat(None).take(1).collect(); - events.push(Some(Event::Key(Key::Char('l')))); // once to place selected marker on screen + events.push(Some(key!(char 'l'))); // once to place selected marker on screen events.push(None); - events.push(Some(Event::Key(Key::Char('l')))); + events.push(Some(key!(char 'l'))); events.push(None); - events.push(Some(Event::Key(Key::Char('\n')))); + events.push(Some(key!(char '\n'))); events.push(None); - events.push(Some(Event::Key(Key::Esc))); + events.push(Some(key!(Esc))); // here we sleep extra to allow the blink events to happen and be tested before the app exits // with the following ctrl-c events.push(None); @@ -1505,10 +1477,10 @@ fn esc_to_go_up() { events.push(None); events.push(None); events.push(None); - events.push(Some(Event::Key(Key::Ctrl('c')))); + events.push(Some(key!(ctrl 'c'))); events.push(None); - events.push(Some(Event::Key(Key::Char('y')))); - let keyboard_events = Box::new(KeyboardEvents::new(events)); + events.push(Some(key!(char 'y'))); + let keyboard_events = Box::new(TerminalEvents::new(events)); let temp_dir_path = create_root_temp_dir("esc_to_go_up").expect("failed to create temp dir"); @@ -1542,10 +1514,10 @@ fn esc_to_go_up() { .expect("could not acquire lock on terminal events"); let expected_terminal_events = vec![ - Clear, HideCursor, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Draw, - Flush, Clear, ShowCursor, + Clear, HideCursor, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, HideCursor, + Flush, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Clear, + ShowCursor, ]; - assert_eq!( &terminal_events .lock() @@ -1567,28 +1539,28 @@ fn noop_when_pressing_esc_at_base_folder() { let (terminal_events, terminal_draw_events, backend) = test_backend_factory(190, 50); let mut events: Vec> = iter::repeat(None).take(1).collect(); - events.push(Some(Event::Key(Key::Char('l')))); // once to place selected marker on screen + events.push(Some(key!(char 'l'))); // once to place selected marker on screen events.push(None); - events.push(Some(Event::Key(Key::Char('l')))); + events.push(Some(key!(char 'l'))); events.push(None); - events.push(Some(Event::Key(Key::Char('\n')))); + events.push(Some(key!(char '\n'))); events.push(None); - events.push(Some(Event::Key(Key::Esc))); + events.push(Some(key!(Esc))); events.push(None); events.push(None); events.push(None); events.push(None); - events.push(Some(Event::Key(Key::Esc))); + events.push(Some(key!(Esc))); // here we sleep extra to allow the blink events to happen and be tested before the app exits // with the following ctrl-c events.push(None); events.push(None); events.push(None); events.push(None); - events.push(Some(Event::Key(Key::Ctrl('c')))); + events.push(Some(key!(ctrl 'c'))); events.push(None); - events.push(Some(Event::Key(Key::Char('y')))); - let keyboard_events = Box::new(KeyboardEvents::new(events)); + events.push(Some(key!(char 'y'))); + let keyboard_events = Box::new(TerminalEvents::new(events)); let temp_dir_path = create_root_temp_dir("noop_when_pressing_esc_at_base_folder") .expect("failed to create temp dir"); @@ -1623,10 +1595,10 @@ fn noop_when_pressing_esc_at_base_folder() { .expect("could not acquire lock on terminal events"); let expected_terminal_events = vec![ - Clear, HideCursor, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Draw, - Flush, Draw, Flush, Draw, Flush, Draw, Flush, Clear, ShowCursor, + Clear, HideCursor, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, HideCursor, + Flush, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, + HideCursor, Flush, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Clear, ShowCursor, ]; - assert_eq!( &terminal_events .lock() @@ -1651,19 +1623,19 @@ fn delete_file() { let (terminal_events, terminal_draw_events, backend) = test_backend_factory(190, 50); let mut events: Vec> = iter::repeat(None).take(1).collect(); - events.push(Some(Event::Key(Key::Char('l')))); // once to place selected marker on screen + events.push(Some(key!(char 'l'))); // once to place selected marker on screen events.push(None); - events.push(Some(Event::Key(Key::Backspace))); + events.push(Some(key!(Backspace))); events.push(None); - events.push(Some(Event::Key(Key::Char('y')))); + events.push(Some(key!(char 'y'))); events.push(None); events.push(None); events.push(None); events.push(None); - events.push(Some(Event::Key(Key::Ctrl('c')))); + events.push(Some(key!(ctrl 'c'))); events.push(None); - events.push(Some(Event::Key(Key::Char('y')))); - let keyboard_events = Box::new(KeyboardEvents::new(events)); + events.push(Some(key!(char 'y'))); + let keyboard_events = Box::new(TerminalEvents::new(events)); let temp_dir_path = create_root_temp_dir("delete_file").expect("failed to create temp dir"); @@ -1696,8 +1668,9 @@ fn delete_file() { .expect("could not acquire lock on terminal events"); let expected_terminal_events = vec![ - Clear, HideCursor, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Draw, - Flush, Draw, Flush, Draw, Flush, Clear, ShowCursor, + Clear, HideCursor, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, HideCursor, + Flush, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, + HideCursor, Flush, Draw, HideCursor, Flush, Clear, ShowCursor, ]; assert_eq!( &terminal_events @@ -1742,17 +1715,17 @@ fn delete_file_no_confirmation() { let (terminal_events, terminal_draw_events, backend) = test_backend_factory(190, 50); let mut events: Vec> = iter::repeat(None).take(1).collect(); - events.push(Some(Event::Key(Key::Char('l')))); // once to place selected marker on screen + events.push(Some(key!(char 'l'))); // once to place selected marker on screen events.push(None); - events.push(Some(Event::Key(Key::Backspace))); + events.push(Some(key!(Backspace))); events.push(None); events.push(None); events.push(None); events.push(None); - events.push(Some(Event::Key(Key::Ctrl('c')))); + events.push(Some(key!(ctrl 'c'))); events.push(None); - events.push(Some(Event::Key(Key::Char('y')))); - let keyboard_events = Box::new(KeyboardEvents::new(events)); + events.push(Some(key!(char 'y'))); + let keyboard_events = Box::new(TerminalEvents::new(events)); let temp_dir_path = create_root_temp_dir("delete_file_no_confirmation").expect("failed to create temp dir"); @@ -1786,8 +1759,9 @@ fn delete_file_no_confirmation() { .expect("could not acquire lock on terminal events"); let expected_terminal_events = vec![ - Clear, HideCursor, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Draw, - Flush, Draw, Flush, Clear, ShowCursor, + Clear, HideCursor, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, HideCursor, + Flush, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, + HideCursor, Flush, Clear, ShowCursor, ]; assert_eq!( &terminal_events @@ -1832,19 +1806,19 @@ fn cant_delete_file_with_term_too_small() { let (terminal_events, terminal_draw_events, backend) = test_backend_factory(49, 50); let mut events: Vec> = iter::repeat(None).take(1).collect(); - events.push(Some(Event::Key(Key::Char('l')))); // once to place selected marker on screen + events.push(Some(key!(char 'l'))); // once to place selected marker on screen events.push(None); - events.push(Some(Event::Key(Key::Backspace))); + events.push(Some(key!(Backspace))); events.push(None); - events.push(Some(Event::Key(Key::Char('y')))); + events.push(Some(key!(char 'y'))); events.push(None); events.push(None); events.push(None); events.push(None); - events.push(Some(Event::Key(Key::Ctrl('c')))); + events.push(Some(key!(ctrl 'c'))); events.push(None); - events.push(Some(Event::Key(Key::Char('y')))); - let keyboard_events = Box::new(KeyboardEvents::new(events)); + events.push(Some(key!(char 'y'))); + let keyboard_events = Box::new(TerminalEvents::new(events)); let temp_dir_path = create_root_temp_dir("cant_delete_file_with_term_too_small") .expect("failed to create temp dir"); @@ -1877,7 +1851,9 @@ fn cant_delete_file_with_term_too_small() { .lock() .expect("could not acquire lock on terminal events"); - let expected_terminal_events = vec![Clear, HideCursor, Draw, Flush, Clear, ShowCursor]; + let expected_terminal_events = vec![ + Clear, HideCursor, Draw, HideCursor, Flush, Clear, ShowCursor, + ]; assert_eq!( &terminal_events .lock() @@ -1915,23 +1891,23 @@ fn delete_folder() { let (terminal_events, terminal_draw_events, backend) = test_backend_factory(190, 50); let mut events: Vec> = iter::repeat(None).take(1).collect(); - events.push(Some(Event::Key(Key::Char('l')))); // once to place selected marker on screen + events.push(Some(key!(char 'l'))); // once to place selected marker on screen events.push(None); - events.push(Some(Event::Key(Key::Char('l')))); + events.push(Some(key!(char 'l'))); events.push(None); - events.push(Some(Event::Key(Key::Backspace))); + events.push(Some(key!(Backspace))); events.push(None); - events.push(Some(Event::Key(Key::Char('y')))); + events.push(Some(key!(char 'y'))); // here we sleep extra to allow the blink events to happen and be tested before the app exits // with the following ctrl-c events.push(None); events.push(None); events.push(None); events.push(None); - events.push(Some(Event::Key(Key::Ctrl('c')))); + events.push(Some(key!(ctrl 'c'))); events.push(None); - events.push(Some(Event::Key(Key::Char('y')))); - let keyboard_events = Box::new(KeyboardEvents::new(events)); + events.push(Some(key!(char 'y'))); + let keyboard_events = Box::new(TerminalEvents::new(events)); let temp_dir_path = create_root_temp_dir("delete_folder").expect("failed to create temp dir"); @@ -1964,8 +1940,9 @@ fn delete_folder() { .expect("could not acquire lock on terminal events"); let expected_terminal_events = vec![ - Clear, HideCursor, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Draw, - Flush, Draw, Flush, Draw, Flush, Draw, Flush, Clear, ShowCursor, + Clear, HideCursor, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, HideCursor, + Flush, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, + HideCursor, Flush, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Clear, ShowCursor, ]; assert_eq!( &terminal_events @@ -2012,21 +1989,21 @@ fn delete_folder_no_confirmation() { let (terminal_events, terminal_draw_events, backend) = test_backend_factory(190, 50); let mut events: Vec> = iter::repeat(None).take(1).collect(); - events.push(Some(Event::Key(Key::Char('l')))); // once to place selected marker on screen + events.push(Some(key!(char 'l'))); // once to place selected marker on screen events.push(None); - events.push(Some(Event::Key(Key::Char('l')))); + events.push(Some(key!(char 'l'))); events.push(None); - events.push(Some(Event::Key(Key::Backspace))); + events.push(Some(key!(Backspace))); // here we sleep extra to allow the blink events to happen and be tested before the app exits // with the following ctrl-c events.push(None); events.push(None); events.push(None); events.push(None); - events.push(Some(Event::Key(Key::Ctrl('c')))); + events.push(Some(key!(ctrl 'c'))); events.push(None); - events.push(Some(Event::Key(Key::Char('y')))); - let keyboard_events = Box::new(KeyboardEvents::new(events)); + events.push(Some(key!(char 'y'))); + let keyboard_events = Box::new(TerminalEvents::new(events)); let temp_dir_path = create_root_temp_dir("delete_folder_no_confirmation").expect("failed to create temp dir"); @@ -2060,8 +2037,9 @@ fn delete_folder_no_confirmation() { .expect("could not acquire lock on terminal events"); let expected_terminal_events = vec![ - Clear, HideCursor, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Draw, - Flush, Draw, Flush, Draw, Flush, Clear, ShowCursor, + Clear, HideCursor, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, HideCursor, + Flush, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, + HideCursor, Flush, Draw, HideCursor, Flush, Clear, ShowCursor, ]; assert_eq!( &terminal_events @@ -2108,25 +2086,25 @@ fn delete_folder_small_window() { let (terminal_events, terminal_draw_events, backend) = test_backend_factory(60, 50); let mut events: Vec> = iter::repeat(None).take(1).collect(); - events.push(Some(Event::Key(Key::Char('j')))); // once to place selected marker on screen + events.push(Some(key!(char 'j'))); // once to place selected marker on screen events.push(None); - events.push(Some(Event::Key(Key::Char('j')))); + events.push(Some(key!(char 'j'))); events.push(None); - events.push(Some(Event::Key(Key::Char('j')))); + events.push(Some(key!(char 'j'))); events.push(None); - events.push(Some(Event::Key(Key::Backspace))); + events.push(Some(key!(Backspace))); events.push(None); - events.push(Some(Event::Key(Key::Char('y')))); + events.push(Some(key!(char 'y'))); // here we sleep extra to allow the blink events to happen and be tested before the app exits // with the following ctrl-c events.push(None); events.push(None); events.push(None); events.push(None); - events.push(Some(Event::Key(Key::Ctrl('c')))); + events.push(Some(key!(ctrl 'c'))); events.push(None); - events.push(Some(Event::Key(Key::Char('y')))); - let keyboard_events = Box::new(KeyboardEvents::new(events)); + events.push(Some(key!(char 'y'))); + let keyboard_events = Box::new(TerminalEvents::new(events)); let temp_dir_path = create_root_temp_dir("delete_folder_small_window").expect("failed to create temp dir"); @@ -2160,8 +2138,10 @@ fn delete_folder_small_window() { .expect("could not acquire lock on terminal events"); let expected_terminal_events = vec![ - Clear, HideCursor, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Draw, - Flush, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Clear, ShowCursor, + Clear, HideCursor, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, HideCursor, + Flush, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, + HideCursor, Flush, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, HideCursor, + Flush, Clear, ShowCursor, ]; assert_eq!( &terminal_events @@ -2210,23 +2190,23 @@ fn delete_folder_small_window_no_confirmation() { let (terminal_events, terminal_draw_events, backend) = test_backend_factory(60, 50); let mut events: Vec> = iter::repeat(None).take(1).collect(); - events.push(Some(Event::Key(Key::Char('j')))); // once to place selected marker on screen + events.push(Some(key!(char 'j'))); // once to place selected marker on screen events.push(None); - events.push(Some(Event::Key(Key::Char('j')))); + events.push(Some(key!(char 'j'))); events.push(None); - events.push(Some(Event::Key(Key::Char('j')))); + events.push(Some(key!(char 'j'))); events.push(None); - events.push(Some(Event::Key(Key::Backspace))); + events.push(Some(key!(Backspace))); events.push(None); // here we sleep extra to allow the blink events to happen and be tested before the app exits // with the following ctrl-c events.push(None); events.push(None); events.push(None); - events.push(Some(Event::Key(Key::Ctrl('c')))); + events.push(Some(key!(ctrl 'c'))); events.push(None); - events.push(Some(Event::Key(Key::Char('y')))); - let keyboard_events = Box::new(KeyboardEvents::new(events)); + events.push(Some(key!(char 'y'))); + let keyboard_events = Box::new(TerminalEvents::new(events)); let temp_dir_path = create_root_temp_dir("delete_folder_small_window_no_confirmation") .expect("failed to create temp dir"); @@ -2260,8 +2240,9 @@ fn delete_folder_small_window_no_confirmation() { .expect("could not acquire lock on terminal events"); let expected_terminal_events = vec![ - Clear, HideCursor, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Draw, - Flush, Draw, Flush, Draw, Flush, Draw, Flush, Clear, ShowCursor, + Clear, HideCursor, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, HideCursor, + Flush, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, + HideCursor, Flush, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Clear, ShowCursor, ]; assert_eq!( &terminal_events @@ -2308,23 +2289,23 @@ fn delete_folder_with_multiple_children() { let (terminal_events, terminal_draw_events, backend) = test_backend_factory(190, 50); let mut events: Vec> = iter::repeat(None).take(1).collect(); - events.push(Some(Event::Key(Key::Char('l')))); // once to place selected marker on screen + events.push(Some(key!(char 'l'))); // once to place selected marker on screen events.push(None); - events.push(Some(Event::Key(Key::Char('l')))); + events.push(Some(key!(char 'l'))); events.push(None); - events.push(Some(Event::Key(Key::Backspace))); + events.push(Some(key!(Backspace))); events.push(None); - events.push(Some(Event::Key(Key::Char('y')))); + events.push(Some(key!(char 'y'))); // here we sleep extra to allow the blink events to happen and be tested before the app exits // with the following ctrl-c events.push(None); events.push(None); events.push(None); events.push(None); - events.push(Some(Event::Key(Key::Ctrl('c')))); + events.push(Some(key!(ctrl 'c'))); events.push(None); - events.push(Some(Event::Key(Key::Char('y')))); - let keyboard_events = Box::new(KeyboardEvents::new(events)); + events.push(Some(key!(char 'y'))); + let keyboard_events = Box::new(TerminalEvents::new(events)); let temp_dir_path = create_root_temp_dir("delete_folder_with_multiple_children") .expect("failed to create temp dir"); @@ -2375,9 +2356,11 @@ fn delete_folder_with_multiple_children() { .expect("could not acquire lock on terminal events"); let expected_terminal_events = vec![ - Clear, HideCursor, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Draw, - Flush, Draw, Flush, Draw, Flush, Draw, Flush, Clear, ShowCursor, + Clear, HideCursor, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, HideCursor, + Flush, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, + HideCursor, Flush, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Clear, ShowCursor, ]; + assert_eq!( &terminal_events .lock() @@ -2438,21 +2421,21 @@ fn delete_folder_with_multiple_children_no_confirmation() { let (terminal_events, terminal_draw_events, backend) = test_backend_factory(190, 50); let mut events: Vec> = iter::repeat(None).take(1).collect(); - events.push(Some(Event::Key(Key::Char('l')))); // once to place selected marker on screen + events.push(Some(key!(char 'l'))); // once to place selected marker on screen events.push(None); - events.push(Some(Event::Key(Key::Char('l')))); + events.push(Some(key!(char 'l'))); events.push(None); - events.push(Some(Event::Key(Key::Backspace))); + events.push(Some(key!(Backspace))); events.push(None); // here we sleep extra to allow the blink events to happen and be tested before the app exits // with the following ctrl-c events.push(None); events.push(None); events.push(None); - events.push(Some(Event::Key(Key::Ctrl('c')))); + events.push(Some(key!(ctrl 'c'))); events.push(None); - events.push(Some(Event::Key(Key::Char('y')))); - let keyboard_events = Box::new(KeyboardEvents::new(events)); + events.push(Some(key!(char 'y'))); + let keyboard_events = Box::new(TerminalEvents::new(events)); let temp_dir_path = create_root_temp_dir("delete_folder_with_multiple_children_no_confirmation") @@ -2504,8 +2487,9 @@ fn delete_folder_with_multiple_children_no_confirmation() { .expect("could not acquire lock on terminal events"); let expected_terminal_events = vec![ - Clear, HideCursor, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Draw, - Flush, Draw, Flush, Draw, Flush, Clear, ShowCursor, + Clear, HideCursor, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, HideCursor, + Flush, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, + HideCursor, Flush, Draw, HideCursor, Flush, Clear, ShowCursor, ]; assert_eq!( &terminal_events @@ -2566,12 +2550,12 @@ fn pressing_delete_with_no_selected_tile() { let (terminal_events, terminal_draw_events, backend) = test_backend_factory(190, 50); let mut events: Vec> = iter::repeat(None).take(1).collect(); - events.push(Some(Event::Key(Key::Backspace))); + events.push(Some(key!(Backspace))); events.push(None); - events.push(Some(Event::Key(Key::Ctrl('c')))); + events.push(Some(key!(ctrl 'c'))); events.push(None); - events.push(Some(Event::Key(Key::Char('y')))); - let keyboard_events = Box::new(KeyboardEvents::new(events)); + events.push(Some(key!(char 'y'))); + let keyboard_events = Box::new(TerminalEvents::new(events)); let temp_dir_path = create_root_temp_dir("pressing_delete_with_no_selected_tile") .expect("failed to create temp dir"); @@ -2605,7 +2589,7 @@ fn pressing_delete_with_no_selected_tile() { .expect("could not acquire lock on terminal events"); let expected_terminal_events = vec![ - Clear, HideCursor, Draw, Flush, Draw, Flush, Clear, ShowCursor, + Clear, HideCursor, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Clear, ShowCursor, ]; assert_eq!( &terminal_events @@ -2645,16 +2629,16 @@ fn delete_file_press_n() { let (terminal_events, terminal_draw_events, backend) = test_backend_factory(190, 50); let mut events: Vec> = iter::repeat(None).take(1).collect(); - events.push(Some(Event::Key(Key::Char('l')))); // once to place selected marker on screen + events.push(Some(key!(char 'l'))); // once to place selected marker on screen events.push(None); - events.push(Some(Event::Key(Key::Backspace))); + events.push(Some(key!(Backspace))); events.push(None); - events.push(Some(Event::Key(Key::Char('n')))); + events.push(Some(key!(char 'n'))); events.push(None); - events.push(Some(Event::Key(Key::Ctrl('c')))); + events.push(Some(key!(ctrl 'c'))); events.push(None); - events.push(Some(Event::Key(Key::Char('y')))); - let keyboard_events = Box::new(KeyboardEvents::new(events)); + events.push(Some(key!(char 'y'))); + let keyboard_events = Box::new(TerminalEvents::new(events)); let temp_dir_path = create_root_temp_dir("delete_file_press_n").expect("failed to create temp dir"); @@ -2688,8 +2672,8 @@ fn delete_file_press_n() { .expect("could not acquire lock on terminal events"); let expected_terminal_events = vec![ - Clear, HideCursor, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Clear, - ShowCursor, + Clear, HideCursor, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, HideCursor, + Flush, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Clear, ShowCursor, ]; assert_eq!( &terminal_events @@ -2755,15 +2739,9 @@ fn files_with_size_zero() { ); std::fs::remove_dir_all(temp_dir_path).expect("failed to remove temporary folder"); let terminal_draw_events_mirror = terminal_draw_events.lock().unwrap(); - println!( - "terminal_draw_events_mirror[0] {:?}", - terminal_draw_events_mirror[0] - ); - let expected_terminal_events = vec![ - Clear, HideCursor, Draw, Flush, Draw, Flush, Clear, ShowCursor, + Clear, HideCursor, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Clear, ShowCursor, ]; - assert_eq!( &terminal_events.lock().unwrap()[..], &expected_terminal_events[..] @@ -2789,15 +2767,9 @@ fn empty_folder() { ); std::fs::remove_dir_all(temp_dir_path).expect("failed to remove temporary folder"); let terminal_draw_events_mirror = terminal_draw_events.lock().unwrap(); - println!( - "terminal_draw_events_mirror[0] {:?}", - terminal_draw_events_mirror[0] - ); - let expected_terminal_events = vec![ - Clear, HideCursor, Draw, Flush, Draw, Flush, Clear, ShowCursor, + Clear, HideCursor, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Clear, ShowCursor, ]; - assert_eq!( &terminal_events.lock().unwrap()[..], &expected_terminal_events[..] @@ -2807,28 +2779,28 @@ fn empty_folder() { assert_snapshot!(&terminal_draw_events_mirror[0]); assert_snapshot!(&terminal_draw_events_mirror[1]); } - +#[cfg(not(target_os = "windows"))] #[test] fn permission_denied_when_deleting() { let (terminal_events, terminal_draw_events, backend) = test_backend_factory(190, 50); let mut events: Vec> = iter::repeat(None).take(1).collect(); - events.push(Some(Event::Key(Key::Char('l')))); // once to place selected marker on screen + events.push(Some(key!(char 'l'))); // once to place selected marker on screen events.push(None); - events.push(Some(Event::Key(Key::Char('\n')))); + events.push(Some(key!(char '\n'))); events.push(None); - events.push(Some(Event::Key(Key::Char('l')))); // once to place selected marker on screen + events.push(Some(key!(char 'l'))); // once to place selected marker on screen events.push(None); - events.push(Some(Event::Key(Key::Backspace))); + events.push(Some(key!(Backspace))); events.push(None); - events.push(Some(Event::Key(Key::Char('y')))); + events.push(Some(key!(char 'y'))); events.push(None); - events.push(Some(Event::Key(Key::Esc))); + events.push(Some(key!(Esc))); events.push(None); - events.push(Some(Event::Key(Key::Ctrl('c')))); + events.push(Some(key!(ctrl 'c'))); events.push(None); - events.push(Some(Event::Key(Key::Char('y')))); - let keyboard_events = Box::new(KeyboardEvents::new(events)); + events.push(Some(key!(char 'y'))); + let keyboard_events = Box::new(TerminalEvents::new(events)); let temp_dir_path = create_root_temp_dir("permission_denied_when_deleting").expect("failed to create temp dir"); @@ -2873,8 +2845,9 @@ fn permission_denied_when_deleting() { std::fs::remove_dir_all(temp_dir_path).expect("failed to remove temporary folder"); let expected_terminal_events = vec![ - Clear, HideCursor, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Draw, - Flush, Draw, Flush, Draw, Flush, Draw, Flush, Clear, ShowCursor, + Clear, HideCursor, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, HideCursor, + Flush, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, + HideCursor, Flush, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Clear, ShowCursor, ]; assert_eq!( @@ -2895,26 +2868,26 @@ fn permission_denied_when_deleting() { assert_snapshot!(&terminal_draw_events_mirror[7]); assert_snapshot!(&terminal_draw_events_mirror[8]); } - +#[cfg(not(target_os = "windows"))] #[test] fn permission_denied_when_deleting_no_confirmation() { let (terminal_events, terminal_draw_events, backend) = test_backend_factory(190, 50); let mut events: Vec> = iter::repeat(None).take(1).collect(); - events.push(Some(Event::Key(Key::Char('l')))); // once to place selected marker on screen + events.push(Some(key!(char 'l'))); // once to place selected marker on screen events.push(None); - events.push(Some(Event::Key(Key::Char('\n')))); + events.push(Some(key!(char '\n'))); events.push(None); - events.push(Some(Event::Key(Key::Char('l')))); // once to place selected marker on screen + events.push(Some(key!(char 'l'))); // once to place selected marker on screen events.push(None); - events.push(Some(Event::Key(Key::Backspace))); + events.push(Some(key!(Backspace))); events.push(None); - events.push(Some(Event::Key(Key::Esc))); + events.push(Some(key!(Esc))); events.push(None); - events.push(Some(Event::Key(Key::Ctrl('c')))); + events.push(Some(key!(ctrl 'c'))); events.push(None); - events.push(Some(Event::Key(Key::Char('y')))); - let keyboard_events = Box::new(KeyboardEvents::new(events)); + events.push(Some(key!(char 'y'))); + let keyboard_events = Box::new(TerminalEvents::new(events)); let temp_dir_path = create_root_temp_dir("permission_denied_when_deleting_no_confirmation") .expect("failed to create temp dir"); @@ -2959,8 +2932,9 @@ fn permission_denied_when_deleting_no_confirmation() { std::fs::remove_dir_all(temp_dir_path).expect("failed to remove temporary folder"); let expected_terminal_events = vec![ - Clear, HideCursor, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Draw, Flush, Draw, - Flush, Draw, Flush, Draw, Flush, Clear, ShowCursor, + Clear, HideCursor, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, HideCursor, + Flush, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Draw, + HideCursor, Flush, Draw, HideCursor, Flush, Clear, ShowCursor, ]; assert_eq!( @@ -3007,15 +2981,9 @@ fn small_files_with_y_as_zero() { ); std::fs::remove_dir_all(temp_dir_path).expect("failed to remove temporary folder"); let terminal_draw_events_mirror = terminal_draw_events.lock().unwrap(); - println!( - "terminal_draw_events_mirror[0] {:?}", - terminal_draw_events_mirror[0] - ); - let expected_terminal_events = vec![ - Clear, HideCursor, Draw, Flush, Draw, Flush, Clear, ShowCursor, + Clear, HideCursor, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Clear, ShowCursor, ]; - assert_eq!( &terminal_events.lock().unwrap()[..], &expected_terminal_events[..] @@ -3056,15 +3024,9 @@ fn small_files_with_x_as_zero() { ); std::fs::remove_dir_all(temp_dir_path).expect("failed to remove temporary folder"); let terminal_draw_events_mirror = terminal_draw_events.lock().unwrap(); - println!( - "terminal_draw_events_mirror[0] {:?}", - terminal_draw_events_mirror[0] - ); - let expected_terminal_events = vec![ - Clear, HideCursor, Draw, Flush, Draw, Flush, Clear, ShowCursor, + Clear, HideCursor, Draw, HideCursor, Flush, Draw, HideCursor, Flush, Clear, ShowCursor, ]; - assert_eq!( &terminal_events.lock().unwrap()[..], &expected_terminal_events[..] diff --git a/src/tests/fakes/fake_input.rs b/src/tests/fakes/fake_input.rs index b36737c..a8637e6 100644 --- a/src/tests/fakes/fake_input.rs +++ b/src/tests/fakes/fake_input.rs @@ -1,17 +1,17 @@ use ::std::{thread, time}; -use ::termion::event::Event; +use crossterm::event::Event; -pub struct KeyboardEvents { +pub struct TerminalEvents { pub events: Vec>, } -impl KeyboardEvents { +impl TerminalEvents { pub fn new(mut events: Vec>) -> Self { events.reverse(); // this is so that we do not have to shift the array - KeyboardEvents { events } + TerminalEvents { events } } } -impl Iterator for KeyboardEvents { +impl Iterator for TerminalEvents { type Item = Event; fn next(&mut self) -> Option { match self.events.pop() { diff --git a/src/ui/bottom_line.rs b/src/ui/bottom_line.rs index bd6402f..928183f 100644 --- a/src/ui/bottom_line.rs +++ b/src/ui/bottom_line.rs @@ -13,7 +13,7 @@ fn render_currently_selected(buf: &mut Buffer, currently_selected: &Tile, max_le let descendants = currently_selected.descendants; let (style, lines) = match currently_selected.file_type { FileType::File => ( - Style::default().modifier(Modifier::BOLD), + Style::default().add_modifier(Modifier::BOLD), vec![ format!("SELECTED: {} ({})", file_name, size), format!("SELECTED: {}", file_name), @@ -21,7 +21,9 @@ fn render_currently_selected(buf: &mut Buffer, currently_selected: &Tile, max_le ], ), FileType::Folder => ( - Style::default().fg(Color::Blue).modifier(Modifier::BOLD), + Style::default() + .fg(Color::Blue) + .add_modifier(Modifier::BOLD), vec![ format!( "SELECTED: {} ({}, {} files)", @@ -77,21 +79,21 @@ fn render_controls_legend(buf: &mut Buffer, hide_delete: bool, max_len: u16, y: 1, y, long_controls_line, - Style::default().modifier(Modifier::BOLD), + Style::default().add_modifier(Modifier::BOLD), ); } else if max_len >= short_controls_line.chars().count() as u16 { buf.set_string( 1, y, short_controls_line, - Style::default().modifier(Modifier::BOLD), + Style::default().add_modifier(Modifier::BOLD), ); } else { buf.set_string( 1, y, too_small_line, - Style::default().modifier(Modifier::BOLD), + Style::default().add_modifier(Modifier::BOLD), ); } } @@ -128,8 +130,8 @@ impl<'a> Widget for BottomLine<'a> { fn render(self, area: Rect, buf: &mut Buffer) { let small_files_legend = "(x = Small files)"; let small_files_len = small_files_legend.chars().count() as u16; - let max_status_len = area.width - small_files_len; - let max_controls_len = area.width; + let max_status_len = area.width - small_files_len - 1; + let max_controls_len = area.width - 1; let status_line_y = area.y + area.height - 2; let controls_line_y = status_line_y + 1; if let Some(currently_selected) = self.currently_selected { @@ -142,7 +144,10 @@ impl<'a> Widget for BottomLine<'a> { area.width - small_files_len - 1, status_line_y, small_files_legend, - Style::default(), + Style::default() + .fg(Color::Reset) + .bg(Color::Reset) + .remove_modifier(Modifier::all()), ); let small_files_legend_character = buf.get_mut(area.width - small_files_len, status_line_y); small_files_legend_character.set_style(Style::default().bg(Color::White).fg(Color::Black)); diff --git a/src/ui/display.rs b/src/ui/display.rs index e5db312..f9fd292 100644 --- a/src/ui/display.rs +++ b/src/ui/display.rs @@ -46,7 +46,7 @@ where ui_effects: &UiEffects, ) { self.terminal - .draw(|mut f| { + .draw(|f| { let full_screen = f.size(); let current_path = file_tree.get_current_path(); let current_path_size = file_tree.get_current_folder_size(); @@ -77,9 +77,8 @@ where ) .split(full_screen); - // TODO: we have to do this because otherwise we get "Trying to access area outside the - // buffer" errors from tui - // we need to investigate if it's a bug in TUI or with us + // -1 cos we draw starting at offset 1 in both x and y directions + chunks[1].width -= 1; chunks[1].height -= 1; board.change_area(&chunks[1]); diff --git a/src/ui/grid/draw_rect.rs b/src/ui/grid/draw_rect.rs index 0f7b300..73b29a1 100644 --- a/src/ui/grid/draw_rect.rs +++ b/src/ui/grid/draw_rect.rs @@ -67,11 +67,11 @@ pub fn tile_style(tile: &Tile, selected: bool) -> (Option