Move TUI project; Increment cargo version

This commit is contained in:
Jeff 2023-12-29 23:57:09 -05:00
parent e57d3f6e60
commit 49a219f764
15 changed files with 1061 additions and 277 deletions

556
Cargo.lock generated
View File

@ -17,6 +17,18 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]]
name = "ahash"
version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01"
dependencies = [
"cfg-if",
"once_cell",
"version_check",
"zerocopy",
]
[[package]]
name = "aho-corasick"
version = "1.1.1"
@ -26,6 +38,12 @@ dependencies = [
"memchr",
]
[[package]]
name = "allocator-api2"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5"
[[package]]
name = "ansi_term"
version = "0.12.1"
@ -121,6 +139,9 @@ name = "bitflags"
version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635"
dependencies = [
"serde",
]
[[package]]
name = "bumpalo"
@ -134,6 +155,12 @@ version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223"
[[package]]
name = "cassowary"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53"
[[package]]
name = "cc"
version = "1.0.83"
@ -201,6 +228,33 @@ dependencies = [
"winapi",
]
[[package]]
name = "color-eyre"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a667583cca8c4f8436db8de46ea8233c42a7d9ae424a82d338f2e4675229204"
dependencies = [
"backtrace",
"color-spantrace",
"eyre",
"indenter",
"once_cell",
"owo-colors",
"tracing-error",
]
[[package]]
name = "color-spantrace"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd6be1b2a7e382e2b98b43b2adcca6bb0e465af0bdd38123873ae61eb17a72c2"
dependencies = [
"once_cell",
"owo-colors",
"tracing-core",
"tracing-error",
]
[[package]]
name = "colorchoice"
version = "1.0.0"
@ -213,9 +267,9 @@ version = "7.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ab77dbd8adecaf3f0db40581631b995f312a8a5ae3aa9993188bb8f23d83a5b"
dependencies = [
"crossterm",
"strum",
"strum_macros",
"crossterm 0.26.1",
"strum 0.24.1",
"strum_macros 0.24.3",
"unicode-width",
]
@ -284,6 +338,24 @@ dependencies = [
"winapi",
]
[[package]]
name = "crossterm"
version = "0.27.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df"
dependencies = [
"bitflags 2.4.0",
"crossterm_winapi",
"futures-core",
"libc",
"mio",
"parking_lot",
"serde",
"signal-hook",
"signal-hook-mio",
"winapi",
]
[[package]]
name = "crossterm_winapi"
version = "0.9.1"
@ -314,24 +386,58 @@ dependencies = [
"memchr",
]
[[package]]
name = "directories"
version = "5.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a49173b84e034382284f27f1af4dcbbd231ffa358c0fe316541a7337f376a35"
dependencies = [
"dirs-sys",
]
[[package]]
name = "dirs-sys"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c"
dependencies = [
"libc",
"option-ext",
"redox_users",
"windows-sys",
]
[[package]]
name = "dust-lang"
version = "0.3.92"
version = "0.4.0"
dependencies = [
"ansi_term",
"cc",
"clap",
"color-eyre",
"comfy-table",
"crossterm 0.27.0",
"csv",
"directories",
"futures",
"git2",
"lazy_static",
"rand",
"ratatui",
"rayon",
"reqwest",
"rustyline",
"serde",
"serde_json",
"signal-hook",
"tokio",
"tokio-util",
"toml",
"tracing",
"tracing-error",
"tracing-subscriber",
"tree-sitter",
"tui-textarea",
]
[[package]]
@ -392,6 +498,16 @@ dependencies = [
"str-buf",
]
[[package]]
name = "eyre"
version = "0.6.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6267a1fa6f59179ea4afc8e50fd8612a3cc60bc858f786ff877a4a8cb042799"
dependencies = [
"indenter",
"once_cell",
]
[[package]]
name = "fastrand"
version = "2.0.1"
@ -440,46 +556,87 @@ dependencies = [
]
[[package]]
name = "futures-channel"
version = "0.3.28"
name = "futures"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2"
checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0"
dependencies = [
"futures-channel",
"futures-core",
"futures-executor",
"futures-io",
"futures-sink",
"futures-task",
"futures-util",
]
[[package]]
name = "futures-channel"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78"
dependencies = [
"futures-core",
"futures-sink",
]
[[package]]
name = "futures-core"
version = "0.3.28"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c"
checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
[[package]]
name = "futures-executor"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d"
dependencies = [
"futures-core",
"futures-task",
"futures-util",
]
[[package]]
name = "futures-io"
version = "0.3.28"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964"
checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1"
[[package]]
name = "futures-macro"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.37",
]
[[package]]
name = "futures-sink"
version = "0.3.28"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e"
checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5"
[[package]]
name = "futures-task"
version = "0.3.28"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65"
checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004"
[[package]]
name = "futures-util"
version = "0.3.28"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533"
checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
dependencies = [
"futures-channel",
"futures-core",
"futures-io",
"futures-macro",
"futures-sink",
"futures-task",
"memchr",
"pin-project-lite",
@ -549,6 +706,10 @@ name = "hashbrown"
version = "0.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12"
dependencies = [
"ahash",
"allocator-api2",
]
[[package]]
name = "heck"
@ -652,6 +813,12 @@ dependencies = [
"unicode-normalization",
]
[[package]]
name = "indenter"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683"
[[package]]
name = "indexmap"
version = "1.9.3"
@ -672,12 +839,27 @@ dependencies = [
"hashbrown 0.14.1",
]
[[package]]
name = "indoc"
version = "2.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e186cfbae8084e513daff4240b4797e342f988cecda4fb6c939150f96315fd8"
[[package]]
name = "ipnet"
version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6"
[[package]]
name = "itertools"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0"
dependencies = [
"either",
]
[[package]]
name = "itoa"
version = "1.0.9"
@ -710,9 +892,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.148"
version = "0.2.151"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b"
checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4"
[[package]]
name = "libgit2-sys"
@ -728,6 +910,17 @@ dependencies = [
"pkg-config",
]
[[package]]
name = "libredox"
version = "0.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8"
dependencies = [
"bitflags 2.4.0",
"libc",
"redox_syscall 0.4.1",
]
[[package]]
name = "libssh2-sys"
version = "0.3.0"
@ -776,6 +969,24 @@ version = "0.4.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
[[package]]
name = "lru"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2994eeba8ed550fd9b47a0b38f0242bc3344e496483c6180b69139cc2fa5d1d7"
dependencies = [
"hashbrown 0.14.1",
]
[[package]]
name = "matchers"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558"
dependencies = [
"regex-automata 0.1.10",
]
[[package]]
name = "memchr"
version = "2.6.4"
@ -808,9 +1019,9 @@ dependencies = [
[[package]]
name = "mio"
version = "0.8.8"
version = "0.8.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2"
checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09"
dependencies = [
"libc",
"log",
@ -856,6 +1067,16 @@ dependencies = [
"libc",
]
[[package]]
name = "nu-ansi-term"
version = "0.46.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84"
dependencies = [
"overload",
"winapi",
]
[[package]]
name = "num_cpus"
version = "1.16.0"
@ -925,6 +1146,24 @@ dependencies = [
"vcpkg",
]
[[package]]
name = "option-ext"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
[[package]]
name = "overload"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
[[package]]
name = "owo-colors"
version = "3.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f"
[[package]]
name = "parking_lot"
version = "0.12.1"
@ -943,11 +1182,17 @@ checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447"
dependencies = [
"cfg-if",
"libc",
"redox_syscall",
"redox_syscall 0.3.5",
"smallvec",
"windows-targets",
]
[[package]]
name = "paste"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c"
[[package]]
name = "percent-encoding"
version = "2.3.0"
@ -1036,6 +1281,25 @@ dependencies = [
"getrandom",
]
[[package]]
name = "ratatui"
version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a5659e52e4ba6e07b2dad9f1158f578ef84a73762625ddb51536019f34d180eb"
dependencies = [
"bitflags 2.4.0",
"cassowary",
"crossterm 0.27.0",
"indoc",
"itertools",
"lru",
"paste",
"stability",
"strum 0.25.0",
"unicode-segmentation",
"unicode-width",
]
[[package]]
name = "rayon"
version = "1.8.0"
@ -1065,6 +1329,26 @@ dependencies = [
"bitflags 1.3.2",
]
[[package]]
name = "redox_syscall"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa"
dependencies = [
"bitflags 1.3.2",
]
[[package]]
name = "redox_users"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4"
dependencies = [
"getrandom",
"libredox",
"thiserror",
]
[[package]]
name = "regex"
version = "1.9.6"
@ -1073,8 +1357,17 @@ checksum = "ebee201405406dbf528b8b672104ae6d6d63e6d118cb10e4d51abbc7b58044ff"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
"regex-automata 0.3.9",
"regex-syntax 0.7.5",
]
[[package]]
name = "regex-automata"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
dependencies = [
"regex-syntax 0.6.29",
]
[[package]]
@ -1085,9 +1378,15 @@ checksum = "59b23e92ee4318893fa3fe3e6fb365258efbfe6ac6ab30f090cdcbb7aa37efa9"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
"regex-syntax 0.7.5",
]
[[package]]
name = "regex-syntax"
version = "0.6.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
[[package]]
name = "regex-syntax"
version = "0.7.5"
@ -1288,6 +1587,15 @@ dependencies = [
"serde",
]
[[package]]
name = "sharded-slab"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"
dependencies = [
"lazy_static",
]
[[package]]
name = "signal-hook"
version = "0.3.17"
@ -1345,14 +1653,24 @@ dependencies = [
[[package]]
name = "socket2"
version = "0.5.4"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e"
checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9"
dependencies = [
"libc",
"windows-sys",
]
[[package]]
name = "stability"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebd1b177894da2a2d9120208c3386066af06a488255caabc5de8ddca22dbc3ce"
dependencies = [
"quote",
"syn 1.0.109",
]
[[package]]
name = "str-buf"
version = "1.0.6"
@ -1371,6 +1689,15 @@ version = "0.24.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f"
[[package]]
name = "strum"
version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125"
dependencies = [
"strum_macros 0.25.3",
]
[[package]]
name = "strum_macros"
version = "0.24.3"
@ -1384,6 +1711,19 @@ dependencies = [
"syn 1.0.109",
]
[[package]]
name = "strum_macros"
version = "0.25.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0"
dependencies = [
"heck",
"proc-macro2",
"quote",
"rustversion",
"syn 2.0.37",
]
[[package]]
name = "syn"
version = "1.0.109"
@ -1435,11 +1775,41 @@ checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef"
dependencies = [
"cfg-if",
"fastrand",
"redox_syscall",
"redox_syscall 0.3.5",
"rustix",
"windows-sys",
]
[[package]]
name = "thiserror"
version = "1.0.52"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83a48fd946b02c0a526b2e9481c8e2a17755e47039164a86c4070446e3a4614d"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.52"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7fbe9b594d6568a6a1443250a7e67d80b74e1e96f6d1715e1e21cc1888291d3"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.37",
]
[[package]]
name = "thread_local"
version = "1.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152"
dependencies = [
"cfg-if",
"once_cell",
]
[[package]]
name = "tinyvec"
version = "1.6.0"
@ -1457,9 +1827,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokio"
version = "1.32.0"
version = "1.35.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17ed6077ed6cd6c74735e21f37eb16dc3935f96878b1fe961074089cc80893f9"
checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104"
dependencies = [
"backtrace",
"bytes",
@ -1467,10 +1837,23 @@ dependencies = [
"mio",
"num_cpus",
"pin-project-lite",
"socket2 0.5.4",
"signal-hook-registry",
"socket2 0.5.5",
"tokio-macros",
"windows-sys",
]
[[package]]
name = "tokio-macros"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.37",
]
[[package]]
name = "tokio-native-tls"
version = "0.3.1"
@ -1483,9 +1866,9 @@ dependencies = [
[[package]]
name = "tokio-util"
version = "0.7.9"
version = "0.7.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d68074620f57a0b21594d9735eb2e98ab38b17f80d3fcb189fca266771ca60d"
checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15"
dependencies = [
"bytes",
"futures-core",
@ -1537,22 +1920,73 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
[[package]]
name = "tracing"
version = "0.1.37"
version = "0.1.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8"
checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
dependencies = [
"cfg-if",
"pin-project-lite",
"tracing-attributes",
"tracing-core",
]
[[package]]
name = "tracing-core"
version = "0.1.31"
name = "tracing-attributes"
version = "0.1.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a"
checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.37",
]
[[package]]
name = "tracing-core"
version = "0.1.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
dependencies = [
"once_cell",
"valuable",
]
[[package]]
name = "tracing-error"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d686ec1c0f384b1277f097b2f279a2ecc11afe8c133c1aabf036a27cb4cd206e"
dependencies = [
"tracing",
"tracing-subscriber",
]
[[package]]
name = "tracing-log"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
dependencies = [
"log",
"once_cell",
"tracing-core",
]
[[package]]
name = "tracing-subscriber"
version = "0.3.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b"
dependencies = [
"matchers",
"nu-ansi-term",
"once_cell",
"regex",
"sharded-slab",
"smallvec",
"thread_local",
"tracing",
"tracing-core",
"tracing-log",
]
[[package]]
@ -1571,6 +2005,18 @@ version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed"
[[package]]
name = "tui-textarea"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3e38ced1f941a9cfc923fbf2fe6858443c42cc5220bfd35bdd3648371e7bd8e"
dependencies = [
"crossterm 0.27.0",
"ratatui",
"regex",
"unicode-width",
]
[[package]]
name = "unicode-bidi"
version = "0.3.13"
@ -1621,12 +2067,24 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
[[package]]
name = "valuable"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
[[package]]
name = "vcpkg"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]]
name = "version_check"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "want"
version = "0.3.1"
@ -1824,3 +2282,23 @@ dependencies = [
"cfg-if",
"windows-sys",
]
[[package]]
name = "zerocopy"
version = "0.7.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.7.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.37",
]

View File

@ -1,7 +1,7 @@
[package]
name = "dust-lang"
description = "General purpose programming language"
version = "0.3.92"
version = "0.4.0"
repository = "https://git.jeffa.io/jeff/dust.git"
edition = "2021"
license = "MIT"
@ -10,6 +10,9 @@ license = "MIT"
name = "dust"
path = "src/main.rs"
[[bin]]
name = "tui"
[profile.dev]
opt-level = 1
[profile.dev.package."*"]
@ -18,17 +21,30 @@ opt-level = 3
[dependencies]
ansi_term = "0.12.1"
clap = { version = "4.4.4", features = ["derive"] }
color-eyre = "0.6.2"
comfy-table = "7.0.1"
crossterm = { version = "0.27.0", features = ["serde", "event-stream"] }
csv = "1.2.2"
directories = "5.0.1"
futures = "0.3.30"
git2 = "0.18.1"
lazy_static = "1.4.0"
rand = "0.8.5"
ratatui = "0.25.0"
rayon = "1.8.0"
reqwest = { version = "0.11.20", features = ["blocking", "json"] }
rustyline = { version = "12.0.0", features = ["derive", "with-file-history"] }
serde = { version = "1.0.188", features = ["derive"] }
serde_json = "1.0.107"
signal-hook = "0.3.17"
tokio = { version = "1.35.1", features = ["signal-hook-registry", "macros", "signal", "rt", "time", "rt-multi-thread"] }
tokio-util = "0.7.10"
toml = "0.8.1"
tracing = "0.1.40"
tracing-error = "0.2.0"
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
tree-sitter = "0.20.10"
tui-textarea = { version = "0.4.0", features = ["search"] }
[build-dependencies]
cc = "1.0"

View File

@ -6,4 +6,4 @@ fib = (i <int>) <int> {
}
}
fib(5)
fib(8)

View File

@ -5,3 +5,5 @@ y = numbers:1
z = numbers:2
assert_equal(x + y, z)
numbers

88
src/bin/tui/app.rs Normal file
View File

@ -0,0 +1,88 @@
use std::path::PathBuf;
use crossterm::event::KeyCode;
use dust_lang::Map;
use ratatui::Frame;
use tokio::sync::mpsc::{UnboundedReceiver, UnboundedSender};
use crate::{interpreter_display::InterpreterDisplay, terminal::Terminal, Action, Elm, Result};
pub struct App {
action_rx: UnboundedReceiver<Action>,
action_tx: UnboundedSender<Action>,
interpreter_display: InterpreterDisplay,
should_quit: bool,
}
impl App {
pub fn new(
action_rx: UnboundedReceiver<Action>,
action_tx: UnboundedSender<Action>,
path: PathBuf,
) -> Result<Self> {
let interpreter_display = InterpreterDisplay::new(Map::new(), path)?;
Ok(App {
action_rx,
action_tx,
interpreter_display,
should_quit: false,
})
}
pub async fn run(&mut self) -> Result<()> {
let mut terminal = Terminal::new()?.tick_rate(4.0).frame_rate(30.0);
terminal.enter()?;
loop {
if self.should_quit {
break;
}
if let Some(action) = terminal.next().await {
self.action_tx.send(action)?;
} else {
continue;
};
while let Ok(action) = self.action_rx.try_recv() {
if let Action::Render = action {
terminal.draw(|frame| {
self.view(frame);
})?;
}
let next_action = self.update(action)?;
if let Some(action) = next_action {
self.action_tx.send(action)?;
}
}
}
terminal.exit()?;
Ok(())
}
}
impl Elm for App {
fn update(&mut self, message: Action) -> Result<Option<Action>> {
match message {
Action::Quit => self.should_quit = true,
Action::Key(key_event) => {
if let KeyCode::Esc = key_event.code {
return Ok(Some(Action::Quit));
}
}
_ => {}
}
self.interpreter_display.update(message)
}
fn view(&self, frame: &mut Frame) {
self.interpreter_display.view(frame)
}
}

3
src/bin/tui/error.rs Normal file
View File

@ -0,0 +1,3 @@
pub type Result<T> = std::result::Result<T, Error>;
pub enum Error {}

View File

@ -0,0 +1,53 @@
use std::{fs::read_to_string, path::PathBuf, time::SystemTime};
use dust_lang::{Interpreter, Map, Value};
use ratatui::Frame;
use crate::{value_display::ValueDisplay, Action, Elm, Result};
pub struct InterpreterDisplay {
interpreter: Interpreter,
path: PathBuf,
value_display: ValueDisplay,
modified: SystemTime,
}
impl InterpreterDisplay {
pub fn new(context: Map, path: PathBuf) -> Result<Self> {
let interpreter = Interpreter::new(context)?;
let value_display = ValueDisplay::new(Value::default());
let modified = SystemTime::now();
Ok(Self {
interpreter,
path,
value_display,
modified,
})
}
}
impl Elm for InterpreterDisplay {
fn update(&mut self, message: Action) -> Result<Option<Action>> {
match message {
Action::Tick => {
let last_modified = self.path.metadata()?.modified()?;
if last_modified != self.modified {
let source = read_to_string(&self.path)?;
let value = self.interpreter.run(&source)?;
self.value_display = ValueDisplay::new(value);
self.modified = last_modified;
}
}
_ => {}
}
self.value_display.update(message)
}
fn view(&self, frame: &mut Frame) {
self.value_display.view(frame)
}
}

View File

@ -1,4 +1,9 @@
mod log;
pub mod app;
pub mod buffer;
pub mod error;
pub mod interpreter_display;
pub mod log;
pub mod value_display;
use std::{
ops::{Deref, DerefMut},
@ -14,8 +19,9 @@ use crossterm::{
},
terminal::{EnterAlternateScreen, LeaveAlternateScreen},
};
use dust_lang::Value;
use futures::{FutureExt, StreamExt};
use ratatui::backend::CrosstermBackend as Backend;
use ratatui::{backend::CrosstermBackend as Backend, Frame};
use serde::{Deserialize, Serialize};
use tokio::{
sync::mpsc::{self, UnboundedReceiver, UnboundedSender},
@ -23,8 +29,13 @@ use tokio::{
};
use tokio_util::sync::CancellationToken;
pub trait Elm {
fn update(&mut self, message: Action) -> Result<Option<Action>>;
fn view(&self, frame: &mut Frame);
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum Event {
pub enum Action {
Init,
Quit,
Error,
@ -37,14 +48,15 @@ pub enum Event {
Key(KeyEvent),
Mouse(MouseEvent),
Resize(u16, u16),
UpdateValue(Value),
}
pub struct Tui {
pub terminal: ratatui::Terminal<Backend<std::io::Stderr>>,
pub task: JoinHandle<()>,
pub cancellation_token: CancellationToken,
pub event_rx: UnboundedReceiver<Event>,
pub event_tx: UnboundedSender<Event>,
pub event_rx: UnboundedReceiver<Action>,
pub event_tx: UnboundedSender<Action>,
pub frame_rate: f64,
pub tick_rate: f64,
pub mouse: bool,
@ -105,7 +117,7 @@ impl Tui {
let mut reader = crossterm::event::EventStream::new();
let mut tick_interval = tokio::time::interval(tick_delay);
let mut render_interval = tokio::time::interval(render_delay);
_event_tx.send(Event::Init).unwrap();
_event_tx.send(Action::Init).unwrap();
loop {
let tick_delay = tick_interval.tick();
let render_delay = render_interval.tick();
@ -120,37 +132,37 @@ impl Tui {
match evt {
CrosstermEvent::Key(key) => {
if key.kind == KeyEventKind::Press {
_event_tx.send(Event::Key(key)).unwrap();
_event_tx.send(Action::Key(key)).unwrap();
}
},
CrosstermEvent::Mouse(mouse) => {
_event_tx.send(Event::Mouse(mouse)).unwrap();
_event_tx.send(Action::Mouse(mouse)).unwrap();
},
CrosstermEvent::Resize(x, y) => {
_event_tx.send(Event::Resize(x, y)).unwrap();
_event_tx.send(Action::Resize(x, y)).unwrap();
},
CrosstermEvent::FocusLost => {
_event_tx.send(Event::FocusLost).unwrap();
_event_tx.send(Action::FocusLost).unwrap();
},
CrosstermEvent::FocusGained => {
_event_tx.send(Event::FocusGained).unwrap();
_event_tx.send(Action::FocusGained).unwrap();
},
CrosstermEvent::Paste(s) => {
_event_tx.send(Event::Paste(s)).unwrap();
_event_tx.send(Action::Paste(s)).unwrap();
},
}
}
Some(Err(_)) => {
_event_tx.send(Event::Error).unwrap();
_event_tx.send(Action::Error).unwrap();
}
None => {},
}
},
_ = tick_delay => {
_event_tx.send(Event::Tick).unwrap();
_event_tx.send(Action::Tick).unwrap();
},
_ = render_delay => {
_event_tx.send(Event::Render).unwrap();
_event_tx.send(Action::Render).unwrap();
},
}
}
@ -219,7 +231,7 @@ impl Tui {
Ok(())
}
pub async fn next(&mut self) -> Option<Event> {
pub async fn next(&mut self) -> Option<Action> {
self.event_rx.recv().await
}
}

View File

@ -17,19 +17,18 @@ lazy_static! {
pub static ref LOG_FILE: String = format!("{}.log", env!("CARGO_PKG_NAME"));
}
fn project_directory() -> Option<ProjectDirs> {
pub fn project_directory() -> Option<ProjectDirs> {
ProjectDirs::from("io", "jeffa", env!("CARGO_PKG_NAME"))
}
pub fn get_data_dir() -> PathBuf {
let directory = if let Some(s) = DATA_FOLDER.clone() {
s
if let Some(path) = DATA_FOLDER.clone() {
path
} else if let Some(proj_dirs) = project_directory() {
proj_dirs.data_local_dir().to_path_buf()
} else {
PathBuf::from(".").join(".data")
};
directory
}
}
pub fn initialize_logging() -> Result<()> {

67
src/bin/tui/main.rs Normal file
View File

@ -0,0 +1,67 @@
pub mod app;
pub mod interpreter_display;
pub mod log;
pub mod terminal;
pub mod value_display;
use std::path::PathBuf;
use crate::{
app::App,
log::{get_data_dir, initialize_logging},
};
use clap::Parser;
use color_eyre::Result;
use crossterm::event::{KeyEvent, MouseEvent};
use dust_lang::Value;
use ratatui::Frame;
use serde::{Deserialize, Serialize};
use tokio::sync::mpsc;
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
struct Cli {
/// File with source to be run and watched by the shell.
path: Option<String>,
}
pub trait Elm {
fn update(&mut self, message: Action) -> Result<Option<Action>>;
fn view(&self, frame: &mut Frame);
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum Action {
Init,
Quit,
Error,
Closed,
Tick,
Render,
FocusGained,
FocusLost,
Paste(String),
Key(KeyEvent),
Mouse(MouseEvent),
Resize(u16, u16),
UpdateValue(Value),
}
#[tokio::main]
async fn main() {
initialize_logging().unwrap();
let args = Cli::parse();
let (action_tx, action_rx) = mpsc::unbounded_channel();
let path = if let Some(path) = args.path {
PathBuf::from(path)
} else {
PathBuf::from(format!("{}/scratch.ds", get_data_dir().to_string_lossy()))
};
let mut app = App::new(action_rx, action_tx, path).unwrap();
let run_result = app.run().await;
if let Err(report) = run_result {
eprintln!("{report}")
}
}

229
src/bin/tui/terminal.rs Normal file
View File

@ -0,0 +1,229 @@
use std::{
io::{stderr, Stderr},
ops::{Deref, DerefMut},
time::Duration,
};
use color_eyre::eyre::Result;
use crossterm::{
cursor,
event::{
DisableBracketedPaste, DisableMouseCapture, EnableBracketedPaste, EnableMouseCapture,
Event, KeyEventKind,
},
terminal::{EnterAlternateScreen, LeaveAlternateScreen},
};
use futures::{FutureExt, StreamExt};
use ratatui::prelude::CrosstermBackend;
use tokio::{
sync::mpsc::{self, UnboundedReceiver, UnboundedSender},
task::JoinHandle,
};
use tokio_util::sync::CancellationToken;
use crate::{log, Action};
pub struct Terminal {
pub terminal: ratatui::Terminal<CrosstermBackend<Stderr>>,
pub task: JoinHandle<()>,
pub cancellation_token: CancellationToken,
pub event_rx: UnboundedReceiver<Action>,
pub event_tx: UnboundedSender<Action>,
pub frame_rate: f64,
pub tick_rate: f64,
pub mouse: bool,
pub paste: bool,
}
impl Terminal {
pub fn new() -> Result<Self> {
let tick_rate = 4.0;
let frame_rate = 60.0;
let terminal = ratatui::Terminal::new(CrosstermBackend::new(stderr()))?;
let (event_tx, event_rx) = mpsc::unbounded_channel();
let cancellation_token = CancellationToken::new();
let task = tokio::spawn(async {});
let mouse = false;
let paste = false;
Ok(Self {
terminal,
task,
cancellation_token,
event_rx,
event_tx,
frame_rate,
tick_rate,
mouse,
paste,
})
}
pub fn tick_rate(mut self, tick_rate: f64) -> Self {
self.tick_rate = tick_rate;
self
}
pub fn frame_rate(mut self, frame_rate: f64) -> Self {
self.frame_rate = frame_rate;
self
}
pub fn mouse(mut self, mouse: bool) -> Self {
self.mouse = mouse;
self
}
pub fn paste(mut self, paste: bool) -> Self {
self.paste = paste;
self
}
pub fn start(&mut self) {
let tick_delay = std::time::Duration::from_secs_f64(1.0 / self.tick_rate);
let render_delay = std::time::Duration::from_secs_f64(1.0 / self.frame_rate);
self.cancel();
self.cancellation_token = CancellationToken::new();
let _cancellation_token = self.cancellation_token.clone();
let _event_tx = self.event_tx.clone();
self.task = tokio::spawn(async move {
let mut reader = crossterm::event::EventStream::new();
let mut tick_interval = tokio::time::interval(tick_delay);
let mut render_interval = tokio::time::interval(render_delay);
_event_tx.send(Action::Init).unwrap();
loop {
let tick_delay = tick_interval.tick();
let render_delay = render_interval.tick();
let crossterm_event = reader.next().fuse();
tokio::select! {
_ = _cancellation_token.cancelled() => {
break;
}
maybe_event = crossterm_event => {
match maybe_event {
Some(Ok(evt)) => {
match evt {
Event::Key(key) => {
if key.kind == KeyEventKind::Press {
_event_tx.send(Action::Key(key)).unwrap();
}
},
Event::Mouse(mouse) => {
_event_tx.send(Action::Mouse(mouse)).unwrap();
},
Event::Resize(x, y) => {
_event_tx.send(Action::Resize(x, y)).unwrap();
},
Event::FocusLost => {
_event_tx.send(Action::FocusLost).unwrap();
},
Event::FocusGained => {
_event_tx.send(Action::FocusGained).unwrap();
},
Event::Paste(s) => {
_event_tx.send(Action::Paste(s)).unwrap();
},
}
}
Some(Err(_)) => {
_event_tx.send(Action::Error).unwrap();
}
None => {},
}
},
_ = tick_delay => {
_event_tx.send(Action::Tick).unwrap();
},
_ = render_delay => {
_event_tx.send(Action::Render).unwrap();
},
}
}
});
}
pub fn stop(&self) -> Result<()> {
self.cancel();
let mut counter = 0;
while !self.task.is_finished() {
std::thread::sleep(Duration::from_millis(1));
counter += 1;
if counter > 50 {
self.task.abort();
}
if counter > 100 {
log::error!("Failed to abort task in 100 milliseconds for unknown reason");
break;
}
}
Ok(())
}
pub fn enter(&mut self) -> Result<()> {
crossterm::terminal::enable_raw_mode()?;
crossterm::execute!(std::io::stderr(), EnterAlternateScreen, cursor::Hide)?;
if self.mouse {
crossterm::execute!(std::io::stderr(), EnableMouseCapture)?;
}
if self.paste {
crossterm::execute!(std::io::stderr(), EnableBracketedPaste)?;
}
self.start();
Ok(())
}
pub fn exit(&mut self) -> Result<()> {
self.stop()?;
if crossterm::terminal::is_raw_mode_enabled()? {
self.flush()?;
if self.paste {
crossterm::execute!(std::io::stderr(), DisableBracketedPaste)?;
}
if self.mouse {
crossterm::execute!(std::io::stderr(), DisableMouseCapture)?;
}
crossterm::execute!(std::io::stderr(), LeaveAlternateScreen, cursor::Show)?;
crossterm::terminal::disable_raw_mode()?;
}
Ok(())
}
pub fn cancel(&self) {
self.cancellation_token.cancel();
}
pub fn suspend(&mut self) -> Result<()> {
self.exit()?;
#[cfg(not(windows))]
signal_hook::low_level::raise(signal_hook::consts::signal::SIGTSTP)?;
Ok(())
}
pub fn resume(&mut self) -> Result<()> {
self.enter()?;
Ok(())
}
pub async fn next(&mut self) -> Option<Action> {
self.event_rx.recv().await
}
}
impl Deref for Terminal {
type Target = ratatui::Terminal<CrosstermBackend<Stderr>>;
fn deref(&self) -> &Self::Target {
&self.terminal
}
}
impl DerefMut for Terminal {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.terminal
}
}
impl Drop for Terminal {
fn drop(&mut self) {
self.exit().unwrap();
}
}

View File

@ -0,0 +1,52 @@
use dust_lang::Value;
use ratatui::{
style::{Color, Style},
widgets::{Block, Borders, List, Paragraph},
Frame,
};
use crate::{Action, Elm, Result};
pub struct ValueDisplay {
value: Value,
}
impl ValueDisplay {
pub fn new(value: Value) -> Self {
ValueDisplay { value }
}
}
impl Elm for ValueDisplay {
fn update(&mut self, _message: Action) -> Result<Option<Action>> {
Ok(None)
}
fn view(&self, frame: &mut Frame) {
match &self.value {
Value::List(list) => {
let widget = List::new(list.items().iter().map(|value| value.to_string()))
.block(Block::default().title("list").borders(Borders::all()));
frame.render_widget(widget, frame.size());
}
Value::Map(_) => todo!(),
Value::Function(_) => todo!(),
Value::String(string) => {
let widget =
Paragraph::new(string.as_str()).style(Style::default().fg(Color::Green));
frame.render_widget(widget, frame.size());
}
Value::Float(_) => todo!(),
Value::Integer(integer) => {
let widget =
Paragraph::new(integer.to_string()).style(Style::default().fg(Color::Red));
frame.render_widget(widget, frame.size());
}
Value::Boolean(_) => todo!(),
Value::Option(_) => todo!(),
}
}
}

View File

@ -1,182 +0,0 @@
use dust_lang::Result;
use ratatui::{
layout::{Constraint, Direction, Layout},
prelude::*,
style::{Modifier, Style},
text::{Line, Span},
widgets::{Block, Borders, Paragraph},
};
use std::{
borrow::Cow,
fmt::Display,
fs::File,
io::{self, Write},
path::PathBuf,
};
use tui_textarea::{CursorMove, Input, Key, TextArea};
use super::Action;
pub struct Editor<'a> {
current: usize,
buffers: Vec<Buffer<'a>>,
message: Option<Cow<'static, str>>,
}
impl<'a> Editor<'a> {
pub fn new() -> Result<Self> {
Ok(Self {
current: 0,
buffers: Vec::new(),
message: None,
})
}
pub fn current_buffer(&self) -> &Buffer {
&self.buffers[self.current]
}
pub fn add_buffer(&mut self, buffer: Buffer<'a>) {
self.buffers.push(buffer);
}
pub fn run(&mut self, frame: &mut Frame, areas: &[Rect]) -> Option<Action> {
let buffer = &self.buffers[self.current];
let textarea = &buffer.textarea;
let widget = textarea.widget();
frame.render_widget(widget, areas[0]);
// Render status line
let modified = if buffer.modified { " [modified]" } else { "" };
let slot = format!("[{}/{}]", self.current + 1, self.buffers.len());
let path_text = if let Some(path) = &buffer.path {
format!(" {}{} ", path.display(), modified)
} else {
"scratch".to_string()
};
let (row, col) = textarea.cursor();
let cursor = format!("({},{})", row + 1, col + 1);
let status_chunks = Layout::default()
.direction(Direction::Horizontal)
.constraints(
[
Constraint::Length(slot.len() as u16),
Constraint::Min(1),
Constraint::Length(cursor.len() as u16),
]
.as_ref(),
)
.split(areas[1]);
let status_style = Style::default().add_modifier(Modifier::REVERSED);
frame.render_widget(Paragraph::new(slot).style(status_style), status_chunks[0]);
frame.render_widget(
Paragraph::new(path_text).style(status_style),
status_chunks[1],
);
frame.render_widget(Paragraph::new(cursor).style(status_style), status_chunks[2]);
// Render message at bottom
let message = if let Some(message) = self.message.take() {
Line::from(Span::raw(message))
} else {
Line::from(vec![
Span::raw("Press "),
Span::styled("^Q", Style::default().add_modifier(Modifier::BOLD)),
Span::raw(" to quit, "),
Span::styled("^S", Style::default().add_modifier(Modifier::BOLD)),
Span::raw(" to save, "),
Span::styled("^G", Style::default().add_modifier(Modifier::BOLD)),
Span::raw(" to search, "),
Span::styled("^T", Style::default().add_modifier(Modifier::BOLD)),
Span::raw(" to switch buffer "),
Span::styled("^R", Style::default().add_modifier(Modifier::BOLD)),
Span::raw(" to run"),
])
};
frame.render_widget(Paragraph::new(message), areas[2]);
match crossterm::event::read().unwrap().into() {
Input {
key: Key::Char('r'),
ctrl: true,
..
} => return Some(Action::Submit),
Input {
key: Key::Char('q'),
ctrl: true,
..
} => return Some(Action::Quit),
Input {
key: Key::Char('t'),
ctrl: true,
..
} => {
self.current = (self.current + 1) % self.buffers.len();
self.message = Some(format!("Switched to buffer #{}", self.current + 1).into());
}
Input {
key: Key::Char('s'),
ctrl: true,
..
} => {
self.buffers[self.current].save().unwrap();
self.message = Some("Saved!".into());
}
input => {
let buffer = &mut self.buffers[self.current];
buffer.modified = buffer.textarea.input(input);
}
}
None
}
}
pub struct Buffer<'a> {
textarea: TextArea<'a>,
path: Option<PathBuf>,
modified: bool,
}
impl<'a> Buffer<'a> {
pub fn new(content: String) -> Result<Self> {
let mut textarea = TextArea::new(content.lines().map(|line| line.to_string()).collect());
textarea.set_line_number_style(Style::default().fg(Color::DarkGray));
Ok(Self {
textarea,
path: None,
modified: false,
})
}
pub fn content(&self) -> String {
self.textarea.lines().join("\n")
}
fn save(&mut self) -> io::Result<()> {
if !self.modified {
return Ok(());
}
let file = if let Some(path) = &self.path {
File::create(path)?
} else {
File::create("/tmp/dust_buffer")?
};
let mut writer = io::BufWriter::new(file);
for line in self.textarea.lines() {
writer.write_all(line.as_bytes())?;
writer.write_all(b"\n")?;
}
self.modified = false;
Ok(())
}
}

View File

@ -1,33 +0,0 @@
use dust_lang::Value;
use ratatui::{prelude::Rect, widgets::Paragraph, Frame};
pub struct OutputDisplay {
values: Vec<Value>,
}
impl OutputDisplay {
pub fn new() -> Self {
OutputDisplay { values: Vec::new() }
}
pub fn add_value(&mut self, value: Value) {
self.values.push(value);
}
pub fn run(&self, frame: &mut Frame, area: Rect) {
for value in &self.values {
match value {
Value::List(_) => todo!(),
Value::Map(_) => todo!(),
Value::Function(_) => todo!(),
Value::String(string) => frame.render_widget(Paragraph::new(string.as_str()), area),
Value::Float(_) => todo!(),
Value::Integer(integer) => {
frame.render_widget(Paragraph::new(integer.to_string()), area)
}
Value::Boolean(_) => todo!(),
Value::Option(_) => todo!(),
}
}
}
}

View File