Compare commits
No commits in common. "2a3d1ffdbcbed36da35ad1e163026b686dfe2ce8" and "bbd3dc8ff1b3d69bf45e140fc1989d94372e24cc" have entirely different histories.
2a3d1ffdbc
...
bbd3dc8ff1
15
CHANGELOG.md
15
CHANGELOG.md
@ -4,21 +4,6 @@ All notable changes to this project will be documented in this file.
|
|||||||
|
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
|
|
||||||
## [0.5.0] - 2026-03-01
|
|
||||||
|
|
||||||
### Added
|
|
||||||
- Interactive configuration wizard on first run with styled prompts
|
|
||||||
- `lipgloss` dependency for beautiful terminal UI with Tokyo Night theme colors
|
|
||||||
- Emoji-enhanced prompts and feedback during setup
|
|
||||||
- Configure project paths interactively with comma-separated input
|
|
||||||
- Configure `max_depth` for project discovery scanning
|
|
||||||
- Configure cache settings (`cache_enabled`, `cache_ttl_hours`)
|
|
||||||
- Configure default session windows interactively
|
|
||||||
- Configure panes within each window with custom names
|
|
||||||
- Configure startup commands for each pane (e.g., `nvim .`, `npm run dev`)
|
|
||||||
- New `ui` module with styled render functions for all prompts
|
|
||||||
- Comprehensive summary showing all configured settings after setup
|
|
||||||
|
|
||||||
## [0.4.2] - 2026-03-01
|
## [0.4.2] - 2026-03-01
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|||||||
370
Cargo.lock
generated
370
Cargo.lock
generated
@ -58,33 +58,12 @@ version = "1.0.100"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61"
|
checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "approx"
|
|
||||||
version = "0.5.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6"
|
|
||||||
dependencies = [
|
|
||||||
"num-traits",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "autocfg"
|
|
||||||
version = "1.5.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "2.10.0"
|
version = "2.10.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3"
|
checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "by_address"
|
|
||||||
version = "1.2.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "64fa3c856b712db6612c019f14756e64e4bcea13337a6b33b696333a9eaa2d06"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
version = "1.0.4"
|
version = "1.0.4"
|
||||||
@ -137,64 +116,6 @@ version = "1.0.4"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
|
checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "convert_case"
|
|
||||||
version = "0.10.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "633458d4ef8c78b72454de2d54fd6ab2e60f9e02be22f3c6104cdc8a4e0fceb9"
|
|
||||||
dependencies = [
|
|
||||||
"unicode-segmentation",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "crossterm"
|
|
||||||
version = "0.29.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d8b9f2e4c67f833b660cdb0a3523065869fb35570177239812ed4c905aeff87b"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags",
|
|
||||||
"crossterm_winapi",
|
|
||||||
"derive_more",
|
|
||||||
"document-features",
|
|
||||||
"mio",
|
|
||||||
"parking_lot",
|
|
||||||
"rustix",
|
|
||||||
"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 = "derive_more"
|
|
||||||
version = "2.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134"
|
|
||||||
dependencies = [
|
|
||||||
"derive_more-impl",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "derive_more-impl"
|
|
||||||
version = "2.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb"
|
|
||||||
dependencies = [
|
|
||||||
"convert_case",
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"rustc_version",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dirs"
|
name = "dirs"
|
||||||
version = "5.0.1"
|
version = "5.0.1"
|
||||||
@ -237,15 +158,6 @@ dependencies = [
|
|||||||
"windows-sys 0.61.2",
|
"windows-sys 0.61.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "document-features"
|
|
||||||
version = "0.2.12"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61"
|
|
||||||
dependencies = [
|
|
||||||
"litrs",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "equivalent"
|
name = "equivalent"
|
||||||
version = "1.0.2"
|
version = "1.0.2"
|
||||||
@ -262,12 +174,6 @@ dependencies = [
|
|||||||
"windows-sys 0.61.2",
|
"windows-sys 0.61.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "fast-srgb8"
|
|
||||||
version = "1.0.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "dd2e7510819d6fbf51a5545c8f922716ecfb14df168a3242f7d33e0239efe6a1"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fastrand"
|
name = "fastrand"
|
||||||
version = "2.3.0"
|
version = "2.3.0"
|
||||||
@ -363,9 +269,9 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.182"
|
version = "0.2.177"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6800badb6cb2082ffd7b6a67e6125bb39f18782f793520caee8cb8846be06112"
|
checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libredox"
|
name = "libredox"
|
||||||
@ -383,33 +289,6 @@ version = "0.11.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039"
|
checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "lipgloss"
|
|
||||||
version = "0.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "12c1d116ae421d84dfea8bacb5d5fcce330d8b3f03a4867cd1e4860eecd94fb4"
|
|
||||||
dependencies = [
|
|
||||||
"crossterm",
|
|
||||||
"palette",
|
|
||||||
"strip-ansi-escapes",
|
|
||||||
"unicode-width",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "litrs"
|
|
||||||
version = "1.0.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "lock_api"
|
|
||||||
version = "0.4.14"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965"
|
|
||||||
dependencies = [
|
|
||||||
"scopeguard",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "log"
|
name = "log"
|
||||||
version = "0.4.29"
|
version = "0.4.29"
|
||||||
@ -422,27 +301,6 @@ version = "2.7.6"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
|
checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "mio"
|
|
||||||
version = "1.1.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"log",
|
|
||||||
"wasi",
|
|
||||||
"windows-sys 0.61.2",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "num-traits"
|
|
||||||
version = "0.2.19"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
|
||||||
dependencies = [
|
|
||||||
"autocfg",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.21.3"
|
version = "1.21.3"
|
||||||
@ -461,95 +319,6 @@ version = "0.2.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
|
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "palette"
|
|
||||||
version = "0.7.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "4cbf71184cc5ecc2e4e1baccdb21026c20e5fc3dcf63028a086131b3ab00b6e6"
|
|
||||||
dependencies = [
|
|
||||||
"approx",
|
|
||||||
"fast-srgb8",
|
|
||||||
"palette_derive",
|
|
||||||
"phf",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "palette_derive"
|
|
||||||
version = "0.7.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f5030daf005bface118c096f510ffb781fc28f9ab6a32ab224d8631be6851d30"
|
|
||||||
dependencies = [
|
|
||||||
"by_address",
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "parking_lot"
|
|
||||||
version = "0.12.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a"
|
|
||||||
dependencies = [
|
|
||||||
"lock_api",
|
|
||||||
"parking_lot_core",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "parking_lot_core"
|
|
||||||
version = "0.9.12"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
"libc",
|
|
||||||
"redox_syscall",
|
|
||||||
"smallvec",
|
|
||||||
"windows-link",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "phf"
|
|
||||||
version = "0.11.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078"
|
|
||||||
dependencies = [
|
|
||||||
"phf_macros",
|
|
||||||
"phf_shared",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "phf_generator"
|
|
||||||
version = "0.11.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d"
|
|
||||||
dependencies = [
|
|
||||||
"phf_shared",
|
|
||||||
"rand",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "phf_macros"
|
|
||||||
version = "0.11.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216"
|
|
||||||
dependencies = [
|
|
||||||
"phf_generator",
|
|
||||||
"phf_shared",
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "phf_shared"
|
|
||||||
version = "0.11.3"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5"
|
|
||||||
dependencies = [
|
|
||||||
"siphasher",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "prettyplease"
|
name = "prettyplease"
|
||||||
version = "0.2.37"
|
version = "0.2.37"
|
||||||
@ -584,30 +353,6 @@ version = "5.3.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
|
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand"
|
|
||||||
version = "0.8.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
|
||||||
dependencies = [
|
|
||||||
"rand_core",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand_core"
|
|
||||||
version = "0.6.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "redox_syscall"
|
|
||||||
version = "0.5.18"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redox_users"
|
name = "redox_users"
|
||||||
version = "0.4.6"
|
version = "0.4.6"
|
||||||
@ -630,15 +375,6 @@ dependencies = [
|
|||||||
"thiserror 2.0.17",
|
"thiserror 2.0.17",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rustc_version"
|
|
||||||
version = "0.4.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
|
|
||||||
dependencies = [
|
|
||||||
"semver",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustix"
|
name = "rustix"
|
||||||
version = "1.1.3"
|
version = "1.1.3"
|
||||||
@ -667,12 +403,6 @@ dependencies = [
|
|||||||
"winapi-util",
|
"winapi-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "scopeguard"
|
|
||||||
version = "1.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "semver"
|
name = "semver"
|
||||||
version = "1.0.27"
|
version = "1.0.27"
|
||||||
@ -740,58 +470,6 @@ dependencies = [
|
|||||||
"dirs 6.0.0",
|
"dirs 6.0.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "signal-hook"
|
|
||||||
version = "0.3.18"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"signal-hook-registry",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "signal-hook-mio"
|
|
||||||
version = "0.2.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b75a19a7a740b25bc7944bdee6172368f988763b744e3d4dfe753f6b4ece40cc"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"mio",
|
|
||||||
"signal-hook",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "signal-hook-registry"
|
|
||||||
version = "1.4.8"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b"
|
|
||||||
dependencies = [
|
|
||||||
"errno",
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "siphasher"
|
|
||||||
version = "1.0.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "smallvec"
|
|
||||||
version = "1.15.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "strip-ansi-escapes"
|
|
||||||
version = "0.2.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "2a8f8038e7e7969abb3f1b7c2a811225e9296da208539e0f79c5251d6cac0025"
|
|
||||||
dependencies = [
|
|
||||||
"vte",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strsim"
|
name = "strsim"
|
||||||
version = "0.11.1"
|
version = "0.11.1"
|
||||||
@ -869,7 +547,6 @@ dependencies = [
|
|||||||
"anyhow",
|
"anyhow",
|
||||||
"clap",
|
"clap",
|
||||||
"dirs 5.0.1",
|
"dirs 5.0.1",
|
||||||
"lipgloss",
|
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"shellexpand",
|
"shellexpand",
|
||||||
@ -925,18 +602,6 @@ version = "1.0.20"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "462eeb75aeb73aea900253ce739c8e18a67423fadf006037cd3ff27e82748a06"
|
checksum = "462eeb75aeb73aea900253ce739c8e18a67423fadf006037cd3ff27e82748a06"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unicode-segmentation"
|
|
||||||
version = "1.12.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unicode-width"
|
|
||||||
version = "0.2.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-xid"
|
name = "unicode-xid"
|
||||||
version = "0.2.6"
|
version = "0.2.6"
|
||||||
@ -949,15 +614,6 @@ version = "0.2.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "vte"
|
|
||||||
version = "0.14.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "231fdcd7ef3037e8330d8e17e61011a2c244126acc0a982f4040ac3f9f0bc077"
|
|
||||||
dependencies = [
|
|
||||||
"memchr",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "walkdir"
|
name = "walkdir"
|
||||||
version = "2.5.0"
|
version = "2.5.0"
|
||||||
@ -1026,22 +682,6 @@ dependencies = [
|
|||||||
"semver",
|
"semver",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "winapi"
|
|
||||||
version = "0.3.9"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
|
||||||
dependencies = [
|
|
||||||
"winapi-i686-pc-windows-gnu",
|
|
||||||
"winapi-x86_64-pc-windows-gnu",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "winapi-i686-pc-windows-gnu"
|
|
||||||
version = "0.4.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi-util"
|
name = "winapi-util"
|
||||||
version = "0.1.11"
|
version = "0.1.11"
|
||||||
@ -1051,12 +691,6 @@ dependencies = [
|
|||||||
"windows-sys 0.61.2",
|
"windows-sys 0.61.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "winapi-x86_64-pc-windows-gnu"
|
|
||||||
version = "0.4.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-link"
|
name = "windows-link"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "tmuxido"
|
name = "tmuxido"
|
||||||
version = "0.5.0"
|
version = "0.4.3"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
@ -15,4 +15,3 @@ walkdir = "2.4"
|
|||||||
anyhow = "1.0"
|
anyhow = "1.0"
|
||||||
shellexpand = "3.1"
|
shellexpand = "3.1"
|
||||||
clap = { version = "4.5", features = ["derive"] }
|
clap = { version = "4.5", features = ["derive"] }
|
||||||
lipgloss = "0.1"
|
|
||||||
|
|||||||
204
src/config.rs
204
src/config.rs
@ -4,7 +4,6 @@ use std::fs;
|
|||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use crate::session::SessionConfig;
|
use crate::session::SessionConfig;
|
||||||
use crate::ui;
|
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize)]
|
#[derive(Debug, Deserialize, Serialize)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
@ -90,171 +89,20 @@ impl Config {
|
|||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
// Run interactive configuration wizard
|
let default_config = Self::default_config();
|
||||||
let paths = Self::prompt_for_paths()?;
|
let toml_string = toml::to_string_pretty(&default_config)
|
||||||
let max_depth = Self::prompt_for_max_depth()?;
|
.context("Failed to serialize default config")?;
|
||||||
let cache_enabled = Self::prompt_for_cache_enabled()?;
|
|
||||||
let cache_ttl_hours = if cache_enabled {
|
|
||||||
Self::prompt_for_cache_ttl()?
|
|
||||||
} else {
|
|
||||||
24
|
|
||||||
};
|
|
||||||
let windows = Self::prompt_for_windows()?;
|
|
||||||
|
|
||||||
// Render styled success message before moving windows
|
|
||||||
ui::render_config_created(&paths, max_depth, cache_enabled, cache_ttl_hours, &windows);
|
|
||||||
|
|
||||||
let config = Config {
|
|
||||||
paths: paths.clone(),
|
|
||||||
max_depth,
|
|
||||||
cache_enabled,
|
|
||||||
cache_ttl_hours,
|
|
||||||
default_session: SessionConfig { windows },
|
|
||||||
};
|
|
||||||
|
|
||||||
let toml_string =
|
|
||||||
toml::to_string_pretty(&config).context("Failed to serialize config")?;
|
|
||||||
|
|
||||||
fs::write(&config_path, toml_string).with_context(|| {
|
fs::write(&config_path, toml_string).with_context(|| {
|
||||||
format!("Failed to write config file: {}", config_path.display())
|
format!("Failed to write config file: {}", config_path.display())
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
eprintln!("Created default config at: {}", config_path.display());
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(config_path)
|
Ok(config_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prompt_for_paths() -> Result<Vec<String>> {
|
|
||||||
// Render styled welcome banner
|
|
||||||
ui::render_welcome_banner();
|
|
||||||
|
|
||||||
// Get input with styled prompt
|
|
||||||
let input = ui::render_paths_prompt()?;
|
|
||||||
let paths = Self::parse_paths_input(&input);
|
|
||||||
|
|
||||||
if paths.is_empty() {
|
|
||||||
ui::render_fallback_message();
|
|
||||||
Ok(vec![
|
|
||||||
dirs::home_dir()
|
|
||||||
.unwrap_or_default()
|
|
||||||
.join("Projects")
|
|
||||||
.to_string_lossy()
|
|
||||||
.to_string(),
|
|
||||||
])
|
|
||||||
} else {
|
|
||||||
Ok(paths)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn prompt_for_max_depth() -> Result<usize> {
|
|
||||||
ui::render_section_header("Scan Settings");
|
|
||||||
let input = ui::render_max_depth_prompt()?;
|
|
||||||
|
|
||||||
if input.is_empty() {
|
|
||||||
return Ok(5);
|
|
||||||
}
|
|
||||||
|
|
||||||
match input.parse::<usize>() {
|
|
||||||
Ok(n) if n > 0 => Ok(n),
|
|
||||||
_ => {
|
|
||||||
eprintln!("Invalid value, using default: 5");
|
|
||||||
Ok(5)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn prompt_for_cache_enabled() -> Result<bool> {
|
|
||||||
ui::render_section_header("Cache Settings");
|
|
||||||
let input = ui::render_cache_enabled_prompt()?;
|
|
||||||
|
|
||||||
if input.is_empty() || input == "y" || input == "yes" {
|
|
||||||
Ok(true)
|
|
||||||
} else if input == "n" || input == "no" {
|
|
||||||
Ok(false)
|
|
||||||
} else {
|
|
||||||
eprintln!("Invalid value, using default: yes");
|
|
||||||
Ok(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn prompt_for_cache_ttl() -> Result<u64> {
|
|
||||||
let input = ui::render_cache_ttl_prompt()?;
|
|
||||||
|
|
||||||
if input.is_empty() {
|
|
||||||
return Ok(24);
|
|
||||||
}
|
|
||||||
|
|
||||||
match input.parse::<u64>() {
|
|
||||||
Ok(n) if n > 0 => Ok(n),
|
|
||||||
_ => {
|
|
||||||
eprintln!("Invalid value, using default: 24");
|
|
||||||
Ok(24)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn prompt_for_windows() -> Result<Vec<crate::session::Window>> {
|
|
||||||
ui::render_section_header("Default Session");
|
|
||||||
let input = ui::render_windows_prompt()?;
|
|
||||||
|
|
||||||
let window_names: Vec<String> = input
|
|
||||||
.split(',')
|
|
||||||
.map(|s| s.trim().to_string())
|
|
||||||
.filter(|s| !s.is_empty())
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let names = if window_names.is_empty() {
|
|
||||||
vec!["editor".to_string(), "terminal".to_string()]
|
|
||||||
} else {
|
|
||||||
window_names
|
|
||||||
};
|
|
||||||
|
|
||||||
// Configure panes for each window
|
|
||||||
let mut windows = Vec::new();
|
|
||||||
for name in names {
|
|
||||||
let panes = Self::prompt_for_panes(&name)?;
|
|
||||||
windows.push(crate::session::Window {
|
|
||||||
name,
|
|
||||||
panes,
|
|
||||||
layout: None,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(windows)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn prompt_for_panes(window_name: &str) -> Result<Vec<String>> {
|
|
||||||
let input = ui::render_panes_prompt(window_name)?;
|
|
||||||
|
|
||||||
let pane_names: Vec<String> = input
|
|
||||||
.split(',')
|
|
||||||
.map(|s| s.trim().to_string())
|
|
||||||
.filter(|s| !s.is_empty())
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
if pane_names.is_empty() {
|
|
||||||
// Single pane, no commands
|
|
||||||
return Ok(vec![]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ask for commands for each pane
|
|
||||||
let mut panes = Vec::new();
|
|
||||||
for pane_name in pane_names {
|
|
||||||
let command = ui::render_pane_command_prompt(&pane_name)?;
|
|
||||||
panes.push(command);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(panes)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_paths_input(input: &str) -> Vec<String> {
|
|
||||||
input
|
|
||||||
.trim()
|
|
||||||
.split(',')
|
|
||||||
.map(|s| s.trim().to_string())
|
|
||||||
.filter(|s| !s.is_empty())
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn default_config() -> Self {
|
fn default_config() -> Self {
|
||||||
Config {
|
Config {
|
||||||
paths: vec![
|
paths: vec![
|
||||||
@ -305,46 +153,4 @@ mod tests {
|
|||||||
let result: Result<Config, _> = toml::from_str("not valid toml ]][[");
|
let result: Result<Config, _> = toml::from_str("not valid toml ]][[");
|
||||||
assert!(result.is_err());
|
assert!(result.is_err());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn should_parse_single_path() {
|
|
||||||
let input = "~/Projects";
|
|
||||||
let paths = Config::parse_paths_input(input);
|
|
||||||
assert_eq!(paths, vec!["~/Projects"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn should_parse_multiple_paths_with_commas() {
|
|
||||||
let input = "~/Projects, ~/work, ~/repos";
|
|
||||||
let paths = Config::parse_paths_input(input);
|
|
||||||
assert_eq!(paths, vec!["~/Projects", "~/work", "~/repos"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn should_trim_whitespace_from_paths() {
|
|
||||||
let input = " ~/Projects , ~/work ";
|
|
||||||
let paths = Config::parse_paths_input(input);
|
|
||||||
assert_eq!(paths, vec!["~/Projects", "~/work"]);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn should_return_empty_vec_for_empty_input() {
|
|
||||||
let input = "";
|
|
||||||
let paths = Config::parse_paths_input(input);
|
|
||||||
assert!(paths.is_empty());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn should_return_empty_vec_for_whitespace_only() {
|
|
||||||
let input = " ";
|
|
||||||
let paths = Config::parse_paths_input(input);
|
|
||||||
assert!(paths.is_empty());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn should_handle_empty_parts_between_commas() {
|
|
||||||
let input = "~/Projects,,~/work";
|
|
||||||
let paths = Config::parse_paths_input(input);
|
|
||||||
assert_eq!(paths, vec!["~/Projects", "~/work"]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,6 @@ pub mod config;
|
|||||||
pub mod deps;
|
pub mod deps;
|
||||||
pub mod self_update;
|
pub mod self_update;
|
||||||
pub mod session;
|
pub mod session;
|
||||||
pub mod ui;
|
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use cache::ProjectCache;
|
use cache::ProjectCache;
|
||||||
|
|||||||
328
src/ui.rs
328
src/ui.rs
@ -1,328 +0,0 @@
|
|||||||
use crate::session::Window;
|
|
||||||
use anyhow::{Context, Result};
|
|
||||||
use lipgloss::{Color, Style};
|
|
||||||
use std::io::{self, Write};
|
|
||||||
|
|
||||||
// Tokyo Night theme colors (as RGB tuples)
|
|
||||||
fn color_blue() -> Color {
|
|
||||||
Color::from_rgb(122, 162, 247)
|
|
||||||
} // #7AA2F7
|
|
||||||
fn color_purple() -> Color {
|
|
||||||
Color::from_rgb(187, 154, 247)
|
|
||||||
} // #BB9AF7
|
|
||||||
fn color_light_gray() -> Color {
|
|
||||||
Color::from_rgb(169, 177, 214)
|
|
||||||
} // #A9B1D6
|
|
||||||
fn color_dark_gray() -> Color {
|
|
||||||
Color::from_rgb(86, 95, 137)
|
|
||||||
} // #565F89
|
|
||||||
fn color_green() -> Color {
|
|
||||||
Color::from_rgb(158, 206, 106)
|
|
||||||
} // #9ECE6A
|
|
||||||
fn color_orange() -> Color {
|
|
||||||
Color::from_rgb(224, 175, 104)
|
|
||||||
} // #E0AF68
|
|
||||||
|
|
||||||
/// Renders a styled welcome screen for first-time setup
|
|
||||||
pub fn render_welcome_banner() {
|
|
||||||
let title_style = Style::new().bold(true).foreground(color_blue());
|
|
||||||
|
|
||||||
let subtitle_style = Style::new().foreground(color_purple());
|
|
||||||
|
|
||||||
let text_style = Style::new().foreground(color_light_gray());
|
|
||||||
|
|
||||||
let hint_style = Style::new().italic(true).foreground(color_dark_gray());
|
|
||||||
|
|
||||||
println!();
|
|
||||||
println!("{}", title_style.render(" 🚀 Welcome to tmuxido!"));
|
|
||||||
println!();
|
|
||||||
println!(
|
|
||||||
"{}",
|
|
||||||
subtitle_style.render(" 📁 Let's set up your project directories")
|
|
||||||
);
|
|
||||||
println!();
|
|
||||||
println!(
|
|
||||||
"{}",
|
|
||||||
text_style.render(" Please specify where tmuxido should look for your projects.")
|
|
||||||
);
|
|
||||||
println!();
|
|
||||||
println!(
|
|
||||||
"{}",
|
|
||||||
text_style.render(" You can add multiple paths separated by commas:")
|
|
||||||
);
|
|
||||||
println!();
|
|
||||||
println!(
|
|
||||||
"{}",
|
|
||||||
hint_style.render(" 💡 Example: ~/Projects, ~/work, ~/personal/repos")
|
|
||||||
);
|
|
||||||
println!();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Renders a prompt asking for paths
|
|
||||||
pub fn render_paths_prompt() -> Result<String> {
|
|
||||||
let prompt_style = Style::new().bold(true).foreground(color_green());
|
|
||||||
|
|
||||||
print!(" {} ", prompt_style.render("❯ Paths:"));
|
|
||||||
io::stdout().flush().context("Failed to flush stdout")?;
|
|
||||||
|
|
||||||
let mut input = String::new();
|
|
||||||
io::stdin()
|
|
||||||
.read_line(&mut input)
|
|
||||||
.context("Failed to read input")?;
|
|
||||||
|
|
||||||
Ok(input.trim().to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Renders a success message after config is created with all settings
|
|
||||||
pub fn render_config_created(
|
|
||||||
paths: &[String],
|
|
||||||
max_depth: usize,
|
|
||||||
cache_enabled: bool,
|
|
||||||
cache_ttl_hours: u64,
|
|
||||||
windows: &[Window],
|
|
||||||
) {
|
|
||||||
let success_style = Style::new().bold(true).foreground(color_green());
|
|
||||||
let label_style = Style::new().foreground(color_light_gray());
|
|
||||||
let value_style = Style::new().bold(true).foreground(color_blue());
|
|
||||||
let path_style = Style::new().foreground(color_blue());
|
|
||||||
let window_style = Style::new().foreground(color_purple());
|
|
||||||
let info_style = Style::new().foreground(color_dark_gray());
|
|
||||||
let bool_enabled_style = Style::new().bold(true).foreground(color_green());
|
|
||||||
let bool_disabled_style = Style::new().bold(true).foreground(color_orange());
|
|
||||||
|
|
||||||
println!();
|
|
||||||
println!("{}", success_style.render(" ✅ Configuration saved!"));
|
|
||||||
println!();
|
|
||||||
|
|
||||||
// Project discovery section
|
|
||||||
println!("{}", label_style.render(" 📁 Project Discovery:"));
|
|
||||||
println!(
|
|
||||||
" {} {} {}",
|
|
||||||
label_style.render("Max scan depth:"),
|
|
||||||
value_style.render(&max_depth.to_string()),
|
|
||||||
label_style.render("levels")
|
|
||||||
);
|
|
||||||
println!();
|
|
||||||
|
|
||||||
// Paths
|
|
||||||
println!("{}", label_style.render(" 📂 Directories:"));
|
|
||||||
for path in paths {
|
|
||||||
println!(" {}", path_style.render(&format!("• {}", path)));
|
|
||||||
}
|
|
||||||
println!();
|
|
||||||
|
|
||||||
// Cache settings
|
|
||||||
println!("{}", label_style.render(" 💾 Cache Settings:"));
|
|
||||||
let cache_status = if cache_enabled {
|
|
||||||
bool_enabled_style.render("enabled")
|
|
||||||
} else {
|
|
||||||
bool_disabled_style.render("disabled")
|
|
||||||
};
|
|
||||||
println!(" {} {}", label_style.render("Status:"), cache_status);
|
|
||||||
if cache_enabled {
|
|
||||||
println!(
|
|
||||||
" {} {} {}",
|
|
||||||
label_style.render("TTL:"),
|
|
||||||
value_style.render(&cache_ttl_hours.to_string()),
|
|
||||||
label_style.render("hours")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
println!();
|
|
||||||
|
|
||||||
// Default session
|
|
||||||
println!("{}", label_style.render(" 🪟 Default Windows:"));
|
|
||||||
for window in windows {
|
|
||||||
println!(" {}", window_style.render(&format!("◦ {}", window.name)));
|
|
||||||
if !window.panes.is_empty() {
|
|
||||||
for (i, pane) in window.panes.iter().enumerate() {
|
|
||||||
let pane_display = if pane.is_empty() {
|
|
||||||
format!(" └─ pane {} (shell)", i + 1)
|
|
||||||
} else {
|
|
||||||
format!(" └─ pane {}: {}", i + 1, pane)
|
|
||||||
};
|
|
||||||
println!("{}", info_style.render(&pane_display));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
println!();
|
|
||||||
|
|
||||||
println!(
|
|
||||||
"{}",
|
|
||||||
info_style.render(
|
|
||||||
" ⚙️ You can edit ~/.config/tmuxido/tmuxido.toml anytime to change these settings."
|
|
||||||
)
|
|
||||||
);
|
|
||||||
println!();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Renders a warning when user provides no input (fallback to default)
|
|
||||||
pub fn render_fallback_message() {
|
|
||||||
let warning_style = Style::new().italic(true).foreground(color_orange());
|
|
||||||
|
|
||||||
println!();
|
|
||||||
println!(
|
|
||||||
"{}",
|
|
||||||
warning_style.render(" ⚠️ No paths provided. Using default: ~/Projects")
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Renders a section header for grouping related settings
|
|
||||||
pub fn render_section_header(title: &str) {
|
|
||||||
let header_style = Style::new().bold(true).foreground(color_purple());
|
|
||||||
|
|
||||||
println!();
|
|
||||||
println!("{}", header_style.render(&format!(" 📋 {}", title)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Renders a prompt for max_depth with instructions
|
|
||||||
pub fn render_max_depth_prompt() -> Result<String> {
|
|
||||||
let prompt_style = Style::new().bold(true).foreground(color_green());
|
|
||||||
let hint_style = Style::new().italic(true).foreground(color_dark_gray());
|
|
||||||
|
|
||||||
println!(
|
|
||||||
"{}",
|
|
||||||
hint_style.render(" How many levels deep should tmuxido search for git repositories?")
|
|
||||||
);
|
|
||||||
println!(
|
|
||||||
"{}",
|
|
||||||
hint_style.render(" Higher values = deeper search, but slower. Default: 5")
|
|
||||||
);
|
|
||||||
print!(" {} ", prompt_style.render("❯ Max depth:"));
|
|
||||||
io::stdout().flush().context("Failed to flush stdout")?;
|
|
||||||
|
|
||||||
let mut input = String::new();
|
|
||||||
io::stdin()
|
|
||||||
.read_line(&mut input)
|
|
||||||
.context("Failed to read input")?;
|
|
||||||
|
|
||||||
Ok(input.trim().to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Renders a prompt for cache_enabled with instructions
|
|
||||||
pub fn render_cache_enabled_prompt() -> Result<String> {
|
|
||||||
let prompt_style = Style::new().bold(true).foreground(color_green());
|
|
||||||
let hint_style = Style::new().italic(true).foreground(color_dark_gray());
|
|
||||||
|
|
||||||
println!(
|
|
||||||
"{}",
|
|
||||||
hint_style.render(" Enable caching to speed up project discovery?")
|
|
||||||
);
|
|
||||||
println!(
|
|
||||||
"{}",
|
|
||||||
hint_style.render(" Cache avoids rescanning unchanged directories. Default: yes (y)")
|
|
||||||
);
|
|
||||||
print!(" {} ", prompt_style.render("❯ Enable cache? (y/n):"));
|
|
||||||
io::stdout().flush().context("Failed to flush stdout")?;
|
|
||||||
|
|
||||||
let mut input = String::new();
|
|
||||||
io::stdin()
|
|
||||||
.read_line(&mut input)
|
|
||||||
.context("Failed to read input")?;
|
|
||||||
|
|
||||||
Ok(input.trim().to_lowercase())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Renders a prompt for cache_ttl_hours with instructions
|
|
||||||
pub fn render_cache_ttl_prompt() -> Result<String> {
|
|
||||||
let prompt_style = Style::new().bold(true).foreground(color_green());
|
|
||||||
let hint_style = Style::new().italic(true).foreground(color_dark_gray());
|
|
||||||
|
|
||||||
println!(
|
|
||||||
"{}",
|
|
||||||
hint_style.render(" How long should the cache remain valid (in hours)?")
|
|
||||||
);
|
|
||||||
println!(
|
|
||||||
"{}",
|
|
||||||
hint_style.render(" After this time, tmuxido will rescan your directories. Default: 24")
|
|
||||||
);
|
|
||||||
print!(" {} ", prompt_style.render("❯ Cache TTL (hours):"));
|
|
||||||
io::stdout().flush().context("Failed to flush stdout")?;
|
|
||||||
|
|
||||||
let mut input = String::new();
|
|
||||||
io::stdin()
|
|
||||||
.read_line(&mut input)
|
|
||||||
.context("Failed to read input")?;
|
|
||||||
|
|
||||||
Ok(input.trim().to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Renders a prompt for default session windows with instructions
|
|
||||||
pub fn render_windows_prompt() -> Result<String> {
|
|
||||||
let prompt_style = Style::new().bold(true).foreground(color_green());
|
|
||||||
let hint_style = Style::new().italic(true).foreground(color_dark_gray());
|
|
||||||
|
|
||||||
println!(
|
|
||||||
"{}",
|
|
||||||
hint_style.render(" What windows should be created by default in new tmux sessions?")
|
|
||||||
);
|
|
||||||
println!(
|
|
||||||
"{}",
|
|
||||||
hint_style.render(" Enter window names separated by commas. Default: editor, terminal")
|
|
||||||
);
|
|
||||||
println!(
|
|
||||||
"{}",
|
|
||||||
hint_style.render(" 💡 Tip: Common choices are 'editor', 'terminal', 'server', 'logs'")
|
|
||||||
);
|
|
||||||
print!(" {} ", prompt_style.render("❯ Window names:"));
|
|
||||||
io::stdout().flush().context("Failed to flush stdout")?;
|
|
||||||
|
|
||||||
let mut input = String::new();
|
|
||||||
io::stdin()
|
|
||||||
.read_line(&mut input)
|
|
||||||
.context("Failed to read input")?;
|
|
||||||
|
|
||||||
Ok(input.trim().to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Renders a prompt asking for panes in a specific window
|
|
||||||
pub fn render_panes_prompt(window_name: &str) -> Result<String> {
|
|
||||||
let prompt_style = Style::new().bold(true).foreground(color_green());
|
|
||||||
let hint_style = Style::new().italic(true).foreground(color_dark_gray());
|
|
||||||
let window_style = Style::new().bold(true).foreground(color_purple());
|
|
||||||
|
|
||||||
println!();
|
|
||||||
println!(" Configuring window: {}", window_style.render(window_name));
|
|
||||||
println!(
|
|
||||||
"{}",
|
|
||||||
hint_style
|
|
||||||
.render(" Enter pane names separated by commas, or leave empty for a single pane.")
|
|
||||||
);
|
|
||||||
println!("{}", hint_style.render(" 💡 Example: code, logs, tests"));
|
|
||||||
print!(" {} ", prompt_style.render("❯ Pane names:"));
|
|
||||||
io::stdout().flush().context("Failed to flush stdout")?;
|
|
||||||
|
|
||||||
let mut input = String::new();
|
|
||||||
io::stdin()
|
|
||||||
.read_line(&mut input)
|
|
||||||
.context("Failed to read input")?;
|
|
||||||
|
|
||||||
Ok(input.trim().to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Renders a prompt for a pane command
|
|
||||||
pub fn render_pane_command_prompt(pane_name: &str) -> Result<String> {
|
|
||||||
let prompt_style = Style::new().bold(true).foreground(color_green());
|
|
||||||
let hint_style = Style::new().italic(true).foreground(color_dark_gray());
|
|
||||||
let pane_style = Style::new().foreground(color_blue());
|
|
||||||
|
|
||||||
println!(
|
|
||||||
"{}",
|
|
||||||
hint_style.render(&format!(
|
|
||||||
" What command should run in pane '{}' on startup?",
|
|
||||||
pane_style.render(pane_name)
|
|
||||||
))
|
|
||||||
);
|
|
||||||
println!(
|
|
||||||
"{}",
|
|
||||||
hint_style.render(" Leave empty to run the default shell, or enter a command like 'nvim', 'npm run dev'")
|
|
||||||
);
|
|
||||||
print!(" {} ", prompt_style.render("❯ Command:"));
|
|
||||||
io::stdout().flush().context("Failed to flush stdout")?;
|
|
||||||
|
|
||||||
let mut input = String::new();
|
|
||||||
io::stdin()
|
|
||||||
.read_line(&mut input)
|
|
||||||
.context("Failed to read input")?;
|
|
||||||
|
|
||||||
Ok(input.trim().to_string())
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user