feat(platform): windows version (#74)
* init checkin * tests now compile * Update linux.rs * fixed linux build * fmt * most tests pass * all tests pass * reinstate delete after test * remove old snaps * oops on the crossterm dep * fix fmt * add windows test to travis * travis windows tests linux messed up term after q * fmt * clean as per PR * more pr clean * tests done on windows * oops * non windows tests * more cleanup * fmt * one last clean * linux->unix * linux->unix * style(cleanup): minor fixes * style(cleanup): moar minor fixes Co-authored-by: Aram Drevekenin <aram@poor.dev>
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
178
Cargo.lock
generated
178
Cargo.lock
generated
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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<Event> {
|
||||
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<B: Backend>(evt: Event, app: &mut App<B>) {
|
||||
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<B: Backend>(evt: Event, app: &mut App<B>) {
|
||||
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<B: Backend>(evt: Event, app: &mut App<B>) {
|
||||
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<B: Backend>(evt: Event, app: &mut App<B>) {
|
||||
key!(char '0') => {
|
||||
app.reset_zoom();
|
||||
}
|
||||
key!(char '\n') => {
|
||||
key!(char '\n') | key!(Enter) => {
|
||||
app.handle_enter();
|
||||
}
|
||||
key!(Esc) => {
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
mod controls;
|
||||
mod signals;
|
||||
pub mod controls;
|
||||
|
||||
pub use controls::*;
|
||||
pub use signals::*;
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
use ::signal_hook::iterator::Signals;
|
||||
|
||||
pub type OnSigWinch = dyn Fn(Box<dyn Fn()>) + Send;
|
||||
pub type SigCleanup = dyn Fn() + Send;
|
||||
|
||||
pub fn sigwinch() -> (Box<OnSigWinch>, Box<SigCleanup>) {
|
||||
let signals = Signals::new(&[signal_hook::SIGWINCH]).unwrap();
|
||||
let on_winch = {
|
||||
let signals = signals.clone();
|
||||
move |cb: Box<dyn Fn()>| {
|
||||
for signal in signals.forever() {
|
||||
match signal {
|
||||
signal_hook::SIGWINCH => cb(),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
let cleanup = move || {
|
||||
signals.close();
|
||||
};
|
||||
(Box::new(on_winch), Box::new(cleanup))
|
||||
}
|
||||
70
src/main.rs
70
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<io::Stdout> {
|
||||
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<B>(
|
||||
terminal_backend: B,
|
||||
keyboard_events: Box<dyn Iterator<Item = TermionEvent> + Send>,
|
||||
terminal_events: Box<dyn Iterator<Item = BackEvent> + Send>,
|
||||
path: PathBuf,
|
||||
show_apparent_size: bool,
|
||||
disable_delete_confirmation: bool,
|
||||
@@ -100,7 +109,6 @@ pub fn start<B>(
|
||||
B: Backend + Send + 'static,
|
||||
{
|
||||
let mut active_threads = vec![];
|
||||
let (on_sigwinch, cleanup) = sigwinch();
|
||||
|
||||
let (event_sender, event_receiver): (SyncSender<Event>, Receiver<Event>) =
|
||||
mpsc::sync_channel(1);
|
||||
@@ -129,10 +137,27 @@ pub fn start<B>(
|
||||
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<B>(
|
||||
);
|
||||
}
|
||||
|
||||
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<B>(
|
||||
);
|
||||
app.start(instruction_receiver);
|
||||
running.store(false, Ordering::Release);
|
||||
cleanup();
|
||||
|
||||
for thread_handler in active_threads {
|
||||
thread_handler.join().unwrap();
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
|
||||
5
src/os/mod.rs
Normal file
5
src/os/mod.rs
Normal file
@@ -0,0 +1,5 @@
|
||||
#[cfg(target_os = "windows")]
|
||||
pub(crate) mod windows;
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
pub(crate) mod unix;
|
||||
5
src/os/unix.rs
Normal file
5
src/os/unix.rs
Normal file
@@ -0,0 +1,5 @@
|
||||
use nix::unistd::geteuid;
|
||||
|
||||
pub(crate) fn is_user_admin() -> bool {
|
||||
geteuid().is_root()
|
||||
}
|
||||
41
src/os/windows.rs
Normal file
41
src/os/windows.rs
Normal file
@@ -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
|
||||
}
|
||||
@@ -50,6 +50,6 @@ expression: "&terminal_draw_events_mirror[1]"
|
||||
|
||||
|
||||
|
||||
SELECTED: subfolder_with_quite_a_long_nam
|
||||
subfolder_with_quite_a_long_name
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
┴ ─
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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%) │
|
||||
│
|
||||
│
|
||||
│
|
||||
│
|
||||
│
|
||||
│
|
||||
│
|
||||
├
|
||||
│
|
||||
─ ┴
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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<KeyboardEvents> {
|
||||
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<TerminalEvents> {
|
||||
let mut events: Vec<Option<Event>> = 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 = (
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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<Option<Event>>,
|
||||
}
|
||||
|
||||
impl KeyboardEvents {
|
||||
impl TerminalEvents {
|
||||
pub fn new(mut events: Vec<Option<Event>>) -> 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<Event> {
|
||||
match self.events.pop() {
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -67,11 +67,11 @@ pub fn tile_style(tile: &Tile, selected: bool) -> (Option<Style>, Style, Style)
|
||||
Style::default()
|
||||
.fg(Color::Magenta)
|
||||
.bg(Color::Gray)
|
||||
.modifier(Modifier::BOLD),
|
||||
.add_modifier(Modifier::BOLD),
|
||||
Style::default()
|
||||
.fg(Color::Magenta)
|
||||
.bg(Color::Gray)
|
||||
.modifier(Modifier::BOLD),
|
||||
.add_modifier(Modifier::BOLD),
|
||||
),
|
||||
(false, FileType::File) => (None, Style::default(), Style::default()),
|
||||
(true, FileType::Folder) => (
|
||||
@@ -79,12 +79,14 @@ pub fn tile_style(tile: &Tile, selected: bool) -> (Option<Style>, Style, Style)
|
||||
Style::default()
|
||||
.fg(Color::White)
|
||||
.bg(Color::Blue)
|
||||
.modifier(Modifier::BOLD),
|
||||
.add_modifier(Modifier::BOLD),
|
||||
Style::default().fg(Color::Black).bg(Color::Blue),
|
||||
),
|
||||
(false, FileType::Folder) => (
|
||||
None,
|
||||
Style::default().fg(Color::Blue).modifier(Modifier::BOLD),
|
||||
Style::default()
|
||||
.fg(Color::Blue)
|
||||
.add_modifier(Modifier::BOLD),
|
||||
Style::default(),
|
||||
),
|
||||
};
|
||||
|
||||
@@ -10,7 +10,7 @@ fn render_confirm_prompt(buf: &mut Buffer, confirm_rect: &Rect) {
|
||||
let text_style = Style::default()
|
||||
.bg(Color::Black)
|
||||
.fg(Color::White)
|
||||
.modifier(Modifier::BOLD);
|
||||
.add_modifier(Modifier::BOLD);
|
||||
|
||||
let possible_confirm_texts = [
|
||||
"Are you sure you want to quit?",
|
||||
@@ -83,7 +83,7 @@ impl<'a> Widget for ConfirmBox {
|
||||
let fill_style = Style::default()
|
||||
.bg(Color::Black)
|
||||
.fg(Color::White)
|
||||
.modifier(Modifier::BOLD);
|
||||
.add_modifier(Modifier::BOLD);
|
||||
|
||||
draw_filled_rect(buf, fill_style, &confirm_rect);
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ impl<'a> Widget for ErrorBox<'a> {
|
||||
let fill_style = Style::default()
|
||||
.bg(Color::Black)
|
||||
.fg(Color::Red)
|
||||
.modifier(Modifier::BOLD);
|
||||
.add_modifier(Modifier::BOLD);
|
||||
let text_max_length = message_rect.width - 4;
|
||||
|
||||
// here we truncate the end and not the middle because
|
||||
|
||||
@@ -19,6 +19,8 @@ fn truncated_file_name_line(file_to_delete: &FileToDelete, max_len: u16) -> Stri
|
||||
.last()
|
||||
.expect("could not find file to delete")
|
||||
.to_string_lossy();
|
||||
#[cfg(test)]
|
||||
let full_path = str::replace(&full_path, "\\", "/");
|
||||
if max_len > full_path.len() as u16 {
|
||||
full_path
|
||||
} else {
|
||||
@@ -32,7 +34,7 @@ fn render_deletion_prompt(buf: &mut Buffer, message_rect: &Rect, file_to_delete:
|
||||
let text_style = Style::default()
|
||||
.bg(Color::Black)
|
||||
.fg(Color::Red)
|
||||
.modifier(Modifier::BOLD);
|
||||
.add_modifier(Modifier::BOLD);
|
||||
let question_line = match file_to_delete.file_type {
|
||||
FileType::File => {
|
||||
if max_text_len >= 17 {
|
||||
@@ -98,7 +100,7 @@ fn render_deletion_in_progress(
|
||||
let text_style = Style::default()
|
||||
.bg(Color::Black)
|
||||
.fg(Color::Red)
|
||||
.modifier(Modifier::BOLD);
|
||||
.add_modifier(Modifier::BOLD);
|
||||
let deleting_line_start_position =
|
||||
((message_rect.width - deleting_line.len() as u16) as f64 / 2.0).ceil() as u16
|
||||
+ message_rect.x;
|
||||
@@ -156,7 +158,7 @@ impl<'a> Widget for MessageBox<'a> {
|
||||
let fill_style = Style::default()
|
||||
.bg(Color::Black)
|
||||
.fg(Color::Red)
|
||||
.modifier(Modifier::BOLD);
|
||||
.add_modifier(Modifier::BOLD);
|
||||
|
||||
draw_filled_rect(buf, fill_style, &message_rect);
|
||||
if self.deletion_in_progress {
|
||||
|
||||
@@ -37,7 +37,7 @@ impl<'a> Widget for WarningBox {
|
||||
let fill_style = Style::default()
|
||||
.bg(Color::Black)
|
||||
.fg(Color::Yellow)
|
||||
.modifier(Modifier::BOLD);
|
||||
.add_modifier(Modifier::BOLD);
|
||||
let text_max_length = warning_rect.width - 4;
|
||||
let mut warning_text_start_position: u16 = 0;
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ impl<'a> Widget for TermTooSmall {
|
||||
((area.x + area.width) / 2) as u16 - ((line.chars().count() / 2) as u16),
|
||||
area.y + area.height / 2,
|
||||
line,
|
||||
Style::default().modifier(Modifier::BOLD),
|
||||
Style::default().add_modifier(Modifier::BOLD),
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,10 @@ use crate::ui::format::DisplaySize;
|
||||
use crate::ui::title::{CellSizeOpt, TitleTelescope};
|
||||
use crate::ui::FolderInfo;
|
||||
|
||||
use nix::unistd::geteuid;
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
use crate::os::unix::is_user_admin;
|
||||
#[cfg(target_os = "windows")]
|
||||
use crate::os::windows::is_user_admin;
|
||||
|
||||
pub struct TitleLine<'a> {
|
||||
base_path_info: FolderInfo<'a>,
|
||||
@@ -87,8 +90,7 @@ impl<'a> Widget for TitleLine<'a> {
|
||||
}
|
||||
current_path_relative_to_base.to_string_lossy().into_owned()
|
||||
};
|
||||
|
||||
let separator = if base_path.ends_with('/') {
|
||||
let separator = if base_path.ends_with(::std::path::MAIN_SEPARATOR) {
|
||||
// eg. if base_path is "/", we don't want current path to
|
||||
// also start with "/" otherwise we'll have "//path_to_my/location"
|
||||
// instead of "/path_to_my/location"
|
||||
@@ -96,6 +98,12 @@ impl<'a> Widget for TitleLine<'a> {
|
||||
} else {
|
||||
format!("{}", ::std::path::MAIN_SEPARATOR)
|
||||
};
|
||||
#[cfg(test)]
|
||||
let current_path = str::replace(¤t_path, "\\", "/");
|
||||
#[cfg(test)]
|
||||
let base_path = str::replace(&base_path, "\\", "/");
|
||||
#[cfg(test)]
|
||||
let separator = str::replace(&separator, "\\", "/");
|
||||
let total_size = DisplaySize(self.base_path_info.size as f64);
|
||||
let total_descendants = &self.base_path_info.num_descendants;
|
||||
let current_folder_size = DisplaySize(self.current_path_info.size as f64);
|
||||
@@ -104,7 +112,7 @@ impl<'a> Widget for TitleLine<'a> {
|
||||
|
||||
let mut default_style = Style::default().fg(Color::Yellow);
|
||||
if !self.show_loading {
|
||||
default_style = default_style.modifier(Modifier::BOLD);
|
||||
default_style = default_style.add_modifier(Modifier::BOLD);
|
||||
};
|
||||
let mut title_telescope = TitleTelescope::new(default_style);
|
||||
if self.show_loading {
|
||||
@@ -136,7 +144,7 @@ impl<'a> Widget for TitleLine<'a> {
|
||||
CellSizeOpt::new(" (errors)".to_string()).style(default_style.fg(Color::Red)),
|
||||
]);
|
||||
}
|
||||
if geteuid().is_root() {
|
||||
if is_user_admin() {
|
||||
title_telescope.append_to_left_side(vec![
|
||||
CellSizeOpt::new(format!(" (CAUTION: running as root)"))
|
||||
.style(default_style.fg(Color::Red)),
|
||||
|
||||
@@ -193,15 +193,17 @@ impl TitleTelescope {
|
||||
fn draw_loading_chars(&self, text_length: u16, rect: Rect, buf: &mut Buffer) {
|
||||
let index_in_text = (self.loading_indicator as u16 % (text_length)) as u16;
|
||||
buf.get_mut(rect.x + 1 + index_in_text, rect.y)
|
||||
.set_modifier(Modifier::BOLD);
|
||||
.set_style(Style::default().add_modifier(Modifier::BOLD));
|
||||
if index_in_text >= text_length - 2 {
|
||||
buf.get_mut(rect.x + 1, rect.y).set_modifier(Modifier::BOLD);
|
||||
buf.get_mut(rect.x + 2, rect.y).set_modifier(Modifier::BOLD);
|
||||
buf.get_mut(rect.x + 1, rect.y)
|
||||
.set_style(Style::default().add_modifier(Modifier::BOLD));
|
||||
buf.get_mut(rect.x + 2, rect.y)
|
||||
.set_style(Style::default().add_modifier(Modifier::BOLD));
|
||||
} else {
|
||||
buf.get_mut(rect.x + 1 + index_in_text + 1, rect.y)
|
||||
.set_modifier(Modifier::BOLD);
|
||||
.set_style(Style::default().add_modifier(Modifier::BOLD));
|
||||
buf.get_mut(rect.x + 1 + index_in_text + 2, rect.y)
|
||||
.set_modifier(Modifier::BOLD);
|
||||
.set_style(Style::default().add_modifier(Modifier::BOLD));
|
||||
}
|
||||
}
|
||||
fn line_index_len(&self, i: usize) -> usize {
|
||||
|
||||
Reference in New Issue
Block a user