From ec5c4c4e0c6e2215a2a909964c8037f264987033 Mon Sep 17 00:00:00 2001 From: Simon Walker Date: Thu, 28 Nov 2024 10:32:12 +0000 Subject: [PATCH 01/10] Create new tui package --- Cargo.lock | 4 ++++ Cargo.toml | 1 + tui/Cargo.toml | 8 ++++++++ tui/src/main.rs | 3 +++ 4 files changed, 16 insertions(+) create mode 100644 tui/Cargo.toml create mode 100644 tui/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index 0c17c34e..5a671216 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5266,6 +5266,10 @@ version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17f77d76d837a7830fe1d4f12b7b4ba4192c1888001c7164257e4bc6d21d96b4" +[[package]] +name = "tui" +version = "0.1.0" + [[package]] name = "type-map" version = "0.5.0" diff --git a/Cargo.toml b/Cargo.toml index 47613ba5..24e749c3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ members = [ "launch_configuration", "dap-codec", "gui2", + "tui", ] [profile.dev] diff --git a/tui/Cargo.toml b/tui/Cargo.toml new file mode 100644 index 00000000..f7ed87e1 --- /dev/null +++ b/tui/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "tui" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/tui/src/main.rs b/tui/src/main.rs new file mode 100644 index 00000000..e7a11a96 --- /dev/null +++ b/tui/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} From bc08811e0d5c2633dc11c8a2b6e61ae6e2f45fb1 Mon Sep 17 00:00:00 2001 From: Simon Walker Date: Thu, 28 Nov 2024 10:42:58 +0000 Subject: [PATCH 02/10] Add dependencies --- Cargo.lock | 8 ++++++++ gui2/Cargo.toml | 9 ++++++++- tui/Cargo.toml | 17 +++++++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 5a671216..e935124e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5269,6 +5269,14 @@ checksum = "17f77d76d837a7830fe1d4f12b7b4ba4192c1888001c7164257e4bc6d21d96b4" [[package]] name = "tui" version = "0.1.0" +dependencies = [ + "debugger", + "launch_configuration", + "sentry", + "server", + "state", + "transport", +] [[package]] name = "type-map" diff --git a/gui2/Cargo.toml b/gui2/Cargo.toml index 8dd6ccd0..50b59933 100644 --- a/gui2/Cargo.toml +++ b/gui2/Cargo.toml @@ -26,7 +26,14 @@ launch_configuration = { path = "../launch_configuration" } debugger = { path = "../debugger" } transport = { path = "../transport" } crossbeam-channel.workspace = true -sentry = { version = "0.34.0", optional = true, default-features = false, features = [ "reqwest", "rustls", "backtrace", "contexts", "panic", "debug-images" ] } +sentry = { version = "0.34.0", optional = true, default-features = false, features = [ + "reqwest", + "rustls", + "backtrace", + "contexts", + "panic", + "debug-images", +] } [dev-dependencies] tracing-subscriber.workspace = true diff --git a/tui/Cargo.toml b/tui/Cargo.toml index f7ed87e1..7b143c73 100644 --- a/tui/Cargo.toml +++ b/tui/Cargo.toml @@ -6,3 +6,20 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +debugger = { path = "../debugger" } +# TODO: should not need this +transport = { path = "../transport" } +server = { path = "../server" } +state = { path = "../state" } +launch_configuration = { path = "../launch_configuration" } +sentry = { version = "0.34.0", optional = true, default-features = false, features = [ + "reqwest", + "rustls", + "backtrace", + "contexts", + "panic", + "debug-images", +] } + +[features] +sentry = ["dep:sentry"] From a8eaae834b09be6abd5a32858566fa226e6cbf9b Mon Sep 17 00:00:00 2001 From: Simon Walker Date: Thu, 28 Nov 2024 16:25:57 +0000 Subject: [PATCH 03/10] Set up hello world with ratatui --- Cargo.lock | 284 +++++++++++++++++++++++++++++++++++++++++++----- tui/Cargo.toml | 2 + tui/src/main.rs | 13 ++- 3 files changed, 271 insertions(+), 28 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e935124e..5c239aee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -401,7 +401,7 @@ dependencies = [ "futures-lite 2.3.0", "parking", "polling 3.6.0", - "rustix 0.38.32", + "rustix 0.38.41", "slab", "tracing", "windows-sys 0.52.0", @@ -446,7 +446,7 @@ dependencies = [ "cfg-if", "event-listener 3.1.0", "futures-lite 1.13.0", - "rustix 0.38.32", + "rustix 0.38.41", "windows-sys 0.48.0", ] @@ -465,7 +465,7 @@ dependencies = [ "cfg-if", "event-listener 5.3.0", "futures-lite 2.3.0", - "rustix 0.38.32", + "rustix 0.38.41", "tracing", "windows-sys 0.52.0", ] @@ -493,7 +493,7 @@ dependencies = [ "cfg-if", "futures-core", "futures-io", - "rustix 0.38.32", + "rustix 0.38.41", "signal-hook-registry", "slab", "windows-sys 0.48.0", @@ -764,7 +764,7 @@ dependencies = [ "bitflags 2.5.0", "log", "polling 3.6.0", - "rustix 0.38.32", + "rustix 0.38.41", "slab", "thiserror 1.0.68", ] @@ -776,17 +776,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f0ea9b9476c7fad82841a8dbb380e2eae480c21910feba80725b46931ed8f02" dependencies = [ "calloop", - "rustix 0.38.32", + "rustix 0.38.41", "wayland-backend", "wayland-client", ] +[[package]] +name = "cassowary" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" + [[package]] name = "cast" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" +[[package]] +name = "castaway" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0abae9be0aaf9ea96a3b1b8b1b55c602ca751eba1b1500220cea4ecbafe7c0d5" +dependencies = [ + "rustversion", +] + [[package]] name = "cc" version = "1.0.94" @@ -987,7 +1002,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" dependencies = [ "termcolor", - "unicode-width", + "unicode-width 0.1.11", ] [[package]] @@ -1070,6 +1085,20 @@ dependencies = [ "memchr", ] +[[package]] +name = "compact_str" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6050c3a16ddab2e412160b31f2c871015704239bca62f72f6e5f0be631d3f644" +dependencies = [ + "castaway", + "cfg-if", + "itoa", + "rustversion", + "ryu", + "static_assertions", +] + [[package]] name = "concurrent-queue" version = "2.4.0" @@ -1228,6 +1257,31 @@ version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" +[[package]] +name = "crossterm" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" +dependencies = [ + "bitflags 2.5.0", + "crossterm_winapi", + "mio", + "parking_lot 0.12.1", + "rustix 0.38.41", + "signal-hook", + "signal-hook-mio", + "winapi", +] + +[[package]] +name = "crossterm_winapi" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" +dependencies = [ + "winapi", +] + [[package]] name = "crunchy" version = "0.2.2" @@ -1311,6 +1365,41 @@ dependencies = [ "zbus 4.1.2", ] +[[package]] +name = "darling" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.87", +] + +[[package]] +name = "darling_macro" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.87", +] + [[package]] name = "dconf_rs" version = "0.3.0" @@ -1381,6 +1470,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21d8ad60dd5b13a4ee6bd8fa2d5d88965c597c67bce32b5fc49c94f55cb50810" +[[package]] +name = "diff" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" + [[package]] name = "digest" version = "0.10.7" @@ -1478,7 +1573,7 @@ dependencies = [ "bytemuck", "drm-ffi", "drm-fourcc", - "rustix 0.38.32", + "rustix 0.38.41", ] [[package]] @@ -1488,7 +1583,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41334f8405792483e32ad05fbb9c5680ff4e84491883d2947a4757dc54cb2ac6" dependencies = [ "drm-sys", - "rustix 0.38.32", + "rustix 0.38.41", ] [[package]] @@ -2730,6 +2825,12 @@ dependencies = [ "objc2 0.4.1", ] +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + [[package]] name = "idna" version = "0.5.0" @@ -2769,6 +2870,26 @@ dependencies = [ "hashbrown 0.14.3", ] +[[package]] +name = "indoc" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5" + +[[package]] +name = "instability" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b829f37dead9dc39df40c2d3376c179fdfd2ac771f53f55d3c30dc096a3c0c6e" +dependencies = [ + "darling", + "indoc", + "pretty_assertions", + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "instant" version = "0.1.12" @@ -2824,6 +2945,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.11" @@ -2927,9 +3057,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.153" +version = "0.2.166" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "c2ccc108bbc0b1331bd061864e7cd823c0cab660bbe6970e66e2c0614decde36" [[package]] name = "libloading" @@ -2998,9 +3128,9 @@ checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "linux-raw-sys" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "linux-raw-sys" @@ -3190,6 +3320,7 @@ checksum = "4569e456d394deccd22ce1c1913e6ea0e54519f577285001215d33557431afe4" dependencies = [ "hermit-abi", "libc", + "log", "wasi", "windows-sys 0.52.0", ] @@ -3861,7 +3992,7 @@ dependencies = [ "concurrent-queue", "hermit-abi", "pin-project-lite", - "rustix 0.38.32", + "rustix 0.38.41", "tracing", "windows-sys 0.52.0", ] @@ -3884,6 +4015,16 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8cf8e6a8aa66ce33f63993ffc4ea4271eb5b0530a9002db8455ea6050c77bfa" +[[package]] +name = "pretty_assertions" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ae130e2f271fbc2ac3a40fb1d07180839cdbbe443c7a27e1e3c13c5cac0116d" +dependencies = [ + "diff", + "yansi", +] + [[package]] name = "proc-macro-crate" version = "1.3.1" @@ -3905,9 +4046,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] @@ -3991,6 +4132,27 @@ version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f60fcc7d6849342eff22c4350c8b9a989ee8ceabc4b481253e8946b9fe83d684" +[[package]] +name = "ratatui" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eabd94c2f37801c20583fc49dd5cd6b0ba68c716787c2dd6ed18571e1e63117b" +dependencies = [ + "bitflags 2.5.0", + "cassowary", + "compact_str", + "crossterm", + "indoc", + "instability", + "itertools 0.13.0", + "lru", + "paste", + "strum", + "unicode-segmentation", + "unicode-truncate", + "unicode-width 0.2.0", +] + [[package]] name = "raw-window-handle" version = "0.5.2" @@ -4285,14 +4447,14 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.32" +version = "0.38.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" +checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6" dependencies = [ "bitflags 2.5.0", "errno", "libc", - "linux-raw-sys 0.4.13", + "linux-raw-sys 0.4.14", "windows-sys 0.52.0", ] @@ -4337,6 +4499,12 @@ dependencies = [ "untrusted", ] +[[package]] +name = "rustversion" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" + [[package]] name = "rustybuzz" version = "0.11.0" @@ -4601,6 +4769,27 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "signal-hook" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-mio" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd" +dependencies = [ + "libc", + "mio", + "signal-hook", +] + [[package]] name = "signal-hook-registry" version = "1.4.1" @@ -4659,7 +4848,7 @@ dependencies = [ "libc", "log", "memmap2 0.9.4", - "rustix 0.38.32", + "rustix 0.38.41", "thiserror 1.0.68", "wayland-backend", "wayland-client", @@ -4731,7 +4920,7 @@ dependencies = [ "objc", "raw-window-handle 0.6.0", "redox_syscall 0.5.1", - "rustix 0.38.32", + "rustix 0.38.41", "tiny-xlib", "wasm-bindgen", "wayland-backend", @@ -4787,6 +4976,28 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "strum" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.87", +] + [[package]] name = "subtle" version = "2.5.0" @@ -4877,7 +5088,7 @@ checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ "cfg-if", "fastrand 2.0.2", - "rustix 0.38.32", + "rustix 0.38.41", "windows-sys 0.52.0", ] @@ -5270,8 +5481,10 @@ checksum = "17f77d76d837a7830fe1d4f12b7b4ba4192c1888001c7164257e4bc6d21d96b4" name = "tui" version = "0.1.0" dependencies = [ + "crossterm", "debugger", "launch_configuration", + "ratatui", "sentry", "server", "state", @@ -5370,12 +5583,29 @@ version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" +[[package]] +name = "unicode-truncate" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3644627a5af5fa321c95b9b235a72fd24cd29c648c2c379431e6628655627bf" +dependencies = [ + "itertools 0.13.0", + "unicode-segmentation", + "unicode-width 0.1.11", +] + [[package]] name = "unicode-width" version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" +[[package]] +name = "unicode-width" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" + [[package]] name = "unicode-xid" version = "0.2.4" @@ -5563,7 +5793,7 @@ checksum = "9d50fa61ce90d76474c87f5fc002828d81b32677340112b4ef08079a9d459a40" dependencies = [ "cc", "downcast-rs", - "rustix 0.38.32", + "rustix 0.38.41", "scoped-tls", "smallvec", "wayland-sys", @@ -5576,7 +5806,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "82fb96ee935c2cea6668ccb470fb7771f6215d1691746c2d896b447a00ad3f1f" dependencies = [ "bitflags 2.5.0", - "rustix 0.38.32", + "rustix 0.38.41", "wayland-backend", "wayland-scanner", ] @@ -5598,7 +5828,7 @@ version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71ce5fa868dd13d11a0d04c5e2e65726d0897be8de247c0c5a65886e283231ba" dependencies = [ - "rustix 0.38.32", + "rustix 0.38.41", "wayland-client", "xcursor", ] @@ -6155,7 +6385,7 @@ dependencies = [ "raw-window-handle 0.5.2", "raw-window-handle 0.6.0", "redox_syscall 0.3.5", - "rustix 0.38.32", + "rustix 0.38.41", "sctk-adwaita", "smithay-client-toolkit", "smol_str", @@ -6233,7 +6463,7 @@ dependencies = [ "libc", "libloading 0.8.3", "once_cell", - "rustix 0.38.32", + "rustix 0.38.41", "x11rb-protocol", ] diff --git a/tui/Cargo.toml b/tui/Cargo.toml index 7b143c73..35ffff66 100644 --- a/tui/Cargo.toml +++ b/tui/Cargo.toml @@ -20,6 +20,8 @@ sentry = { version = "0.34.0", optional = true, default-features = false, featur "panic", "debug-images", ] } +ratatui = "0.29.0" +crossterm = "0.28.1" [features] sentry = ["dep:sentry"] diff --git a/tui/src/main.rs b/tui/src/main.rs index e7a11a96..6ecb02ca 100644 --- a/tui/src/main.rs +++ b/tui/src/main.rs @@ -1,3 +1,14 @@ +use crossterm::event::{self, Event}; +use ratatui::Frame; fn main() { - println!("Hello, world!"); + let mut terminal = ratatui::init(); + loop { + terminal.draw(draw).expect("failed to draw frame"); + if matches!(event::read().expect("failed to read event"), Event::Key(_)) { + break; + } + } + ratatui::restore(); } + +fn draw(_frame: &mut Frame) {} From c4be02805bcf24bf2e1182830e4a047c808894e2 Mon Sep 17 00:00:00 2001 From: Simon Walker Date: Thu, 28 Nov 2024 16:30:28 +0000 Subject: [PATCH 04/10] Set up `run` function --- Cargo.lock | 1 + tui/Cargo.toml | 1 + tui/src/main.rs | 25 ++++++++++++++++++++----- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5c239aee..d0c25b1d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5481,6 +5481,7 @@ checksum = "17f77d76d837a7830fe1d4f12b7b4ba4192c1888001c7164257e4bc6d21d96b4" name = "tui" version = "0.1.0" dependencies = [ + "color-eyre", "crossterm", "debugger", "launch_configuration", diff --git a/tui/Cargo.toml b/tui/Cargo.toml index 35ffff66..1899fb57 100644 --- a/tui/Cargo.toml +++ b/tui/Cargo.toml @@ -6,6 +6,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +color-eyre.workspace = true debugger = { path = "../debugger" } # TODO: should not need this transport = { path = "../transport" } diff --git a/tui/src/main.rs b/tui/src/main.rs index 6ecb02ca..577e86f1 100644 --- a/tui/src/main.rs +++ b/tui/src/main.rs @@ -1,14 +1,29 @@ +use color_eyre::eyre::{self, Context}; use crossterm::event::{self, Event}; -use ratatui::Frame; -fn main() { +use ratatui::{prelude::Backend, Frame, Terminal}; + +fn main() -> eyre::Result<()> { let mut terminal = ratatui::init(); + terminal.clear().wrap_err("clearing the terminal")?; + let app_result = run(terminal); + ratatui::restore(); + app_result +} + +fn run(mut terminal: Terminal) -> eyre::Result<()> +where + T: Backend, +{ loop { - terminal.draw(draw).expect("failed to draw frame"); - if matches!(event::read().expect("failed to read event"), Event::Key(_)) { + terminal.draw(draw).wrap_err("failed to draw frame")?; + if matches!( + event::read().wrap_err("failed to read event")?, + Event::Key(_) + ) { break; } } - ratatui::restore(); + Ok(()) } fn draw(_frame: &mut Frame) {} From 7473f7a9e8acf5a4f0c7fdaf00a0c5a759bccae2 Mon Sep 17 00:00:00 2001 From: Simon Walker Date: Thu, 28 Nov 2024 22:30:08 +0000 Subject: [PATCH 05/10] Play with layouts --- tui/src/main.rs | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/tui/src/main.rs b/tui/src/main.rs index 577e86f1..61d209bd 100644 --- a/tui/src/main.rs +++ b/tui/src/main.rs @@ -1,6 +1,8 @@ use color_eyre::eyre::{self, Context}; -use crossterm::event::{self, Event}; -use ratatui::{prelude::Backend, Frame, Terminal}; +use crossterm::event::{self, Event, KeyCode, KeyEventKind}; +use ratatui::layout::{Constraint, Direction, Layout}; +use ratatui::style::Stylize; +use ratatui::{prelude::Backend, widgets::Paragraph, Frame, Terminal}; fn main() -> eyre::Result<()> { let mut terminal = ratatui::init(); @@ -16,14 +18,27 @@ where { loop { terminal.draw(draw).wrap_err("failed to draw frame")?; - if matches!( - event::read().wrap_err("failed to read event")?, - Event::Key(_) - ) { - break; + + // event handling + if let Event::Key(key) = event::read()? { + if key.kind == KeyEventKind::Press && key.code == KeyCode::Char('q') { + return Ok(()); + } } } Ok(()) } -fn draw(_frame: &mut Frame) {} +fn draw(frame: &mut Frame) { + let layout = Layout::default() + .direction(Direction::Vertical) + .constraints(vec![Constraint::Percentage(50), Constraint::Percentage(50)]) + .split(frame.area()); + + let greeting = Paragraph::new("Hello Ratatui! (press 'q' to quit)") + .white() + .on_black(); + let bottom = Paragraph::new("Bottom paragraph").white(); + frame.render_widget(greeting, layout[0]); + frame.render_widget(bottom, layout[1]); +} From 80727336571f0bf464cbee9c6cdda24e8969c91b Mon Sep 17 00:00:00 2001 From: Simon Walker Date: Fri, 29 Nov 2024 21:57:47 +0000 Subject: [PATCH 06/10] Split layout --- tui/src/main.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tui/src/main.rs b/tui/src/main.rs index 61d209bd..0b5f75e1 100644 --- a/tui/src/main.rs +++ b/tui/src/main.rs @@ -30,10 +30,14 @@ where } fn draw(frame: &mut Frame) { + let outer_layout = Layout::default() + .direction(Direction::Horizontal) + .constraints(vec![Constraint::Percentage(40), Constraint::Percentage(60)]) + .split(frame.area()); let layout = Layout::default() .direction(Direction::Vertical) .constraints(vec![Constraint::Percentage(50), Constraint::Percentage(50)]) - .split(frame.area()); + .split(outer_layout[0]); let greeting = Paragraph::new("Hello Ratatui! (press 'q' to quit)") .white() From 475f24de2a6da1a882acaaee043bae9f993ae540 Mon Sep 17 00:00:00 2001 From: Simon Walker Date: Sun, 1 Dec 2024 22:22:49 +0000 Subject: [PATCH 07/10] Handle external events --- Cargo.lock | 1 + tui/Cargo.toml | 1 + tui/src/main.rs | 33 +++++++++++++++++++++++++++++---- 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d0c25b1d..562710a3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5482,6 +5482,7 @@ name = "tui" version = "0.1.0" dependencies = [ "color-eyre", + "crossbeam-channel", "crossterm", "debugger", "launch_configuration", diff --git a/tui/Cargo.toml b/tui/Cargo.toml index 1899fb57..cd3185b8 100644 --- a/tui/Cargo.toml +++ b/tui/Cargo.toml @@ -23,6 +23,7 @@ sentry = { version = "0.34.0", optional = true, default-features = false, featur ] } ratatui = "0.29.0" crossterm = "0.28.1" +crossbeam-channel.workspace = true [features] sentry = ["dep:sentry"] diff --git a/tui/src/main.rs b/tui/src/main.rs index 0b5f75e1..fa3a658d 100644 --- a/tui/src/main.rs +++ b/tui/src/main.rs @@ -1,4 +1,5 @@ use color_eyre::eyre::{self, Context}; +use crossbeam_channel::{select, Receiver}; use crossterm::event::{self, Event, KeyCode, KeyEventKind}; use ratatui::layout::{Constraint, Direction, Layout}; use ratatui::style::Stylize; @@ -7,26 +8,47 @@ use ratatui::{prelude::Backend, widgets::Paragraph, Frame, Terminal}; fn main() -> eyre::Result<()> { let mut terminal = ratatui::init(); terminal.clear().wrap_err("clearing the terminal")?; - let app_result = run(terminal); + let (_tx, rx) = crossbeam_channel::unbounded::<()>(); + let app_result = run(terminal, rx); ratatui::restore(); app_result } -fn run(mut terminal: Terminal) -> eyre::Result<()> +fn run(mut terminal: Terminal, debugger_events: Receiver<()>) -> eyre::Result<()> where T: Backend, { + // set up background thread for terminal events + let (term_tx, term_rx) = crossbeam_channel::unbounded(); + std::thread::spawn(move || { + loop { + let event = event::read()?; + let _ = term_tx.send(event); + } + + // this return value is needed for function typing + #[allow(unreachable_code)] + Ok::<_, std::io::Error>(()) + }); + loop { terminal.draw(draw).wrap_err("failed to draw frame")?; // event handling - if let Event::Key(key) = event::read()? { + select! { + // terminal events + recv(term_rx) -> msg => if let Event::Key(key) = msg? { if key.kind == KeyEventKind::Press && key.code == KeyCode::Char('q') { return Ok(()); } + }, + recv(debugger_events) -> msg => { + if let Ok(msg) = msg { + dbg!(msg); + } + }, } } - Ok(()) } fn draw(frame: &mut Frame) { @@ -43,6 +65,9 @@ fn draw(frame: &mut Frame) { .white() .on_black(); let bottom = Paragraph::new("Bottom paragraph").white(); + let p = Paragraph::new("Foo").white().bold(); + frame.render_widget(greeting, layout[0]); frame.render_widget(bottom, layout[1]); + frame.render_widget(p, outer_layout[1]); } From fae3e97313607af85044dd86150f1447ffe0f91c Mon Sep 17 00:00:00 2001 From: Simon Walker Date: Sun, 1 Dec 2024 22:30:54 +0000 Subject: [PATCH 08/10] Set up example of outside application events --- tui/src/main.rs | 38 +++++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/tui/src/main.rs b/tui/src/main.rs index fa3a658d..1271d212 100644 --- a/tui/src/main.rs +++ b/tui/src/main.rs @@ -2,19 +2,32 @@ use color_eyre::eyre::{self, Context}; use crossbeam_channel::{select, Receiver}; use crossterm::event::{self, Event, KeyCode, KeyEventKind}; use ratatui::layout::{Constraint, Direction, Layout}; -use ratatui::style::Stylize; -use ratatui::{prelude::Backend, widgets::Paragraph, Frame, Terminal}; +use ratatui::{prelude::*, widgets::Paragraph, Frame, Terminal}; +use std::time::Duration; + +struct App { + value: i32, +} fn main() -> eyre::Result<()> { let mut terminal = ratatui::init(); terminal.clear().wrap_err("clearing the terminal")?; - let (_tx, rx) = crossbeam_channel::unbounded::<()>(); - let app_result = run(terminal, rx); + let (tx, rx) = crossbeam_channel::unbounded::<()>(); + std::thread::spawn(move || loop { + std::thread::sleep(Duration::from_secs(1)); + let _ = tx.send(()); + }); + let mut app = App { value: 0 }; + let app_result = run(&mut app, terminal, rx); ratatui::restore(); app_result } -fn run(mut terminal: Terminal, debugger_events: Receiver<()>) -> eyre::Result<()> +fn run( + app: &mut App, + mut terminal: Terminal, + debugger_events: Receiver<()>, +) -> eyre::Result<()> where T: Backend, { @@ -32,8 +45,6 @@ where }); loop { - terminal.draw(draw).wrap_err("failed to draw frame")?; - // event handling select! { // terminal events @@ -43,15 +54,18 @@ where } }, recv(debugger_events) -> msg => { - if let Ok(msg) = msg { - dbg!(msg); + if let Ok(_) = msg { + app.value += 1; } }, } + terminal + .draw(|frame| draw(app, frame)) + .wrap_err("failed to draw frame")?; } } -fn draw(frame: &mut Frame) { +fn draw(app: &mut App, frame: &mut Frame) { let outer_layout = Layout::default() .direction(Direction::Horizontal) .constraints(vec![Constraint::Percentage(40), Constraint::Percentage(60)]) @@ -65,7 +79,9 @@ fn draw(frame: &mut Frame) { .white() .on_black(); let bottom = Paragraph::new("Bottom paragraph").white(); - let p = Paragraph::new("Foo").white().bold(); + let p = Paragraph::new(format!("App value: {}", app.value)) + .white() + .bold(); frame.render_widget(greeting, layout[0]); frame.render_widget(bottom, layout[1]); From 85fc68bf97f43880ccc2d57c4516cf95d8cb48b4 Mon Sep 17 00:00:00 2001 From: Simon Walker Date: Mon, 2 Dec 2024 17:29:28 +0000 Subject: [PATCH 09/10] Expand on tui example --- tui/src/main.rs | 60 ++++++++++++++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 23 deletions(-) diff --git a/tui/src/main.rs b/tui/src/main.rs index 1271d212..80e53a17 100644 --- a/tui/src/main.rs +++ b/tui/src/main.rs @@ -1,12 +1,12 @@ use color_eyre::eyre::{self, Context}; -use crossbeam_channel::{select, Receiver}; +use crossbeam_channel::{select, Receiver, Select, SelectTimeoutError}; use crossterm::event::{self, Event, KeyCode, KeyEventKind}; use ratatui::layout::{Constraint, Direction, Layout}; use ratatui::{prelude::*, widgets::Paragraph, Frame, Terminal}; use std::time::Duration; struct App { - value: i32, + should_quit: bool, } fn main() -> eyre::Result<()> { @@ -17,7 +17,7 @@ fn main() -> eyre::Result<()> { std::thread::sleep(Duration::from_secs(1)); let _ = tx.send(()); }); - let mut app = App { value: 0 }; + let mut app = App { should_quit: false }; let app_result = run(&mut app, terminal, rx); ratatui::restore(); app_result @@ -45,45 +45,59 @@ where }); loop { + // rendering + terminal + .draw(|frame| draw(app, frame)) + .wrap_err("failed to draw frame")?; + // event handling select! { // terminal events recv(term_rx) -> msg => if let Event::Key(key) = msg? { - if key.kind == KeyEventKind::Press && key.code == KeyCode::Char('q') { - return Ok(()); - } - }, - recv(debugger_events) -> msg => { - if let Ok(_) = msg { - app.value += 1; - } - }, + if key.kind == KeyEventKind::Press && key.code == KeyCode::Char('q') { + return Ok(()); + } + }, + recv(debugger_events) -> msg => { + if let Ok(_) = msg { + } + }, + } + + if app.should_quit { + return Ok(()); } - terminal - .draw(|frame| draw(app, frame)) - .wrap_err("failed to draw frame")?; } } -fn draw(app: &mut App, frame: &mut Frame) { +fn draw(app: &App, frame: &mut Frame) { let outer_layout = Layout::default() .direction(Direction::Horizontal) .constraints(vec![Constraint::Percentage(40), Constraint::Percentage(60)]) .split(frame.area()); - let layout = Layout::default() + let left_panel = Layout::default() .direction(Direction::Vertical) .constraints(vec![Constraint::Percentage(50), Constraint::Percentage(50)]) .split(outer_layout[0]); + let variables_frame = left_panel[0]; + let stack_frame = left_panel[1]; + + let right_panel = Layout::default() + .direction(Direction::Vertical) + .constraints(vec![Constraint::Percentage(60), Constraint::Percentage(40)]) + .split(outer_layout[1]); + let code_view = right_panel[0]; + let breakpoints_view = right_panel[1]; let greeting = Paragraph::new("Hello Ratatui! (press 'q' to quit)") .white() .on_black(); let bottom = Paragraph::new("Bottom paragraph").white(); - let p = Paragraph::new(format!("App value: {}", app.value)) - .white() - .bold(); + let p = Paragraph::new(format!("App value")).white().bold(); + let breakpoints = Paragraph::new(format!("breakpoints")).white().bold(); - frame.render_widget(greeting, layout[0]); - frame.render_widget(bottom, layout[1]); - frame.render_widget(p, outer_layout[1]); + frame.render_widget(greeting, variables_frame); + frame.render_widget(bottom, stack_frame); + frame.render_widget(p, code_view); + frame.render_widget(breakpoints, breakpoints_view); } From 05b7a9ff8cfd5fd77850740626eff4fab3499a32 Mon Sep 17 00:00:00 2001 From: Simon Walker Date: Mon, 2 Dec 2024 17:35:11 +0000 Subject: [PATCH 10/10] Extract breakpoints widget --- tui/src/main.rs | 9 ++++++--- tui/src/widgets/breakpoints.rs | 15 +++++++++++++++ tui/src/widgets/mod.rs | 1 + 3 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 tui/src/widgets/breakpoints.rs create mode 100644 tui/src/widgets/mod.rs diff --git a/tui/src/main.rs b/tui/src/main.rs index 80e53a17..da7036e6 100644 --- a/tui/src/main.rs +++ b/tui/src/main.rs @@ -4,6 +4,9 @@ use crossterm::event::{self, Event, KeyCode, KeyEventKind}; use ratatui::layout::{Constraint, Direction, Layout}; use ratatui::{prelude::*, widgets::Paragraph, Frame, Terminal}; use std::time::Duration; +use widgets::breakpoints::BreakpointsView; + +mod widgets; struct App { should_quit: bool, @@ -87,17 +90,17 @@ fn draw(app: &App, frame: &mut Frame) { .constraints(vec![Constraint::Percentage(60), Constraint::Percentage(40)]) .split(outer_layout[1]); let code_view = right_panel[0]; - let breakpoints_view = right_panel[1]; + let breakpoints_area = right_panel[1]; let greeting = Paragraph::new("Hello Ratatui! (press 'q' to quit)") .white() .on_black(); let bottom = Paragraph::new("Bottom paragraph").white(); let p = Paragraph::new(format!("App value")).white().bold(); - let breakpoints = Paragraph::new(format!("breakpoints")).white().bold(); frame.render_widget(greeting, variables_frame); frame.render_widget(bottom, stack_frame); frame.render_widget(p, code_view); - frame.render_widget(breakpoints, breakpoints_view); + + frame.render_widget(BreakpointsView::default(), breakpoints_area); } diff --git a/tui/src/widgets/breakpoints.rs b/tui/src/widgets/breakpoints.rs new file mode 100644 index 00000000..d76e90e9 --- /dev/null +++ b/tui/src/widgets/breakpoints.rs @@ -0,0 +1,15 @@ +use ratatui::prelude::Stylize; +use ratatui::widgets::{Paragraph, Widget}; + +#[derive(Default)] +pub struct BreakpointsView; + +impl Widget for BreakpointsView { + fn render(self, area: ratatui::prelude::Rect, buf: &mut ratatui::prelude::Buffer) + where + Self: Sized, + { + let breakpoints = Paragraph::new(format!("breakpoints")).white().bold(); + breakpoints.render(area, buf); + } +} diff --git a/tui/src/widgets/mod.rs b/tui/src/widgets/mod.rs new file mode 100644 index 00000000..22c64d1d --- /dev/null +++ b/tui/src/widgets/mod.rs @@ -0,0 +1 @@ +pub mod breakpoints;