mirror of
https://github.com/ChrisTitusTech/linutil.git
synced 2024-11-25 06:24:26 +00:00
Merge pull request #153 from lj3954/simple_additions
feat: Use TOML data to add tabs to UI.
This commit is contained in:
commit
5b2f5f20b2
153
Cargo.lock
generated
153
Cargo.lock
generated
|
@ -269,6 +269,22 @@ version = "1.12.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b"
|
checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "equivalent"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "errno"
|
||||||
|
version = "0.3.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"windows-sys 0.52.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "filedescriptor"
|
name = "filedescriptor"
|
||||||
version = "0.8.2"
|
version = "0.8.2"
|
||||||
|
@ -302,6 +318,15 @@ version = "0.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "home"
|
||||||
|
version = "0.5.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5"
|
||||||
|
dependencies = [
|
||||||
|
"windows-sys 0.52.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iana-time-zone"
|
name = "iana-time-zone"
|
||||||
version = "0.1.60"
|
version = "0.1.60"
|
||||||
|
@ -344,6 +369,16 @@ dependencies = [
|
||||||
"quote",
|
"quote",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "indexmap"
|
||||||
|
version = "2.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c"
|
||||||
|
dependencies = [
|
||||||
|
"equivalent",
|
||||||
|
"hashbrown",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ioctl-rs"
|
name = "ioctl-rs"
|
||||||
version = "0.1.6"
|
version = "0.1.6"
|
||||||
|
@ -395,6 +430,12 @@ version = "0.2.155"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
|
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "linux-raw-sys"
|
||||||
|
version = "0.4.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lock_api"
|
name = "lock_api"
|
||||||
version = "0.4.12"
|
version = "0.4.12"
|
||||||
|
@ -420,6 +461,12 @@ dependencies = [
|
||||||
"hashbrown",
|
"hashbrown",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memchr"
|
||||||
|
version = "2.7.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memoffset"
|
name = "memoffset"
|
||||||
version = "0.6.5"
|
version = "0.6.5"
|
||||||
|
@ -626,6 +673,19 @@ dependencies = [
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustix"
|
||||||
|
version = "0.38.34"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.5.0",
|
||||||
|
"errno",
|
||||||
|
"libc",
|
||||||
|
"linux-raw-sys",
|
||||||
|
"windows-sys 0.52.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustversion"
|
name = "rustversion"
|
||||||
version = "1.0.17"
|
version = "1.0.17"
|
||||||
|
@ -644,6 +704,35 @@ version = "1.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde"
|
||||||
|
version = "1.0.205"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e33aedb1a7135da52b7c21791455563facbbcc43d0f0f66165b42c21b3dfb150"
|
||||||
|
dependencies = [
|
||||||
|
"serde_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_derive"
|
||||||
|
version = "1.0.205"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "692d6f5ac90220161d6774db30c662202721e64aed9058d2c394f451261420c1"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_spanned"
|
||||||
|
version = "0.6.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serial"
|
name = "serial"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
|
@ -832,6 +921,40 @@ dependencies = [
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml"
|
||||||
|
version = "0.8.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
"serde_spanned",
|
||||||
|
"toml_datetime",
|
||||||
|
"toml_edit",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml_datetime"
|
||||||
|
version = "0.6.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml_edit"
|
||||||
|
version = "0.22.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d"
|
||||||
|
dependencies = [
|
||||||
|
"indexmap",
|
||||||
|
"serde",
|
||||||
|
"serde_spanned",
|
||||||
|
"toml_datetime",
|
||||||
|
"winnow",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tui"
|
name = "tui"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -844,8 +967,11 @@ dependencies = [
|
||||||
"oneshot",
|
"oneshot",
|
||||||
"portable-pty",
|
"portable-pty",
|
||||||
"ratatui",
|
"ratatui",
|
||||||
|
"serde",
|
||||||
"tempdir",
|
"tempdir",
|
||||||
|
"toml",
|
||||||
"tui-term",
|
"tui-term",
|
||||||
|
"which",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -992,6 +1118,18 @@ version = "0.2.92"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96"
|
checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "which"
|
||||||
|
version = "6.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3d9c5ed668ee1f17edb3b627225343d210006a90bb1e3745ce1f30b1fb115075"
|
||||||
|
dependencies = [
|
||||||
|
"either",
|
||||||
|
"home",
|
||||||
|
"rustix",
|
||||||
|
"winsafe",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi"
|
name = "winapi"
|
||||||
version = "0.3.9"
|
version = "0.3.9"
|
||||||
|
@ -1162,6 +1300,15 @@ version = "0.52.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0"
|
checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winnow"
|
||||||
|
version = "0.6.18"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winreg"
|
name = "winreg"
|
||||||
version = "0.10.1"
|
version = "0.10.1"
|
||||||
|
@ -1171,6 +1318,12 @@ dependencies = [
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winsafe"
|
||||||
|
version = "0.0.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zerocopy"
|
name = "zerocopy"
|
||||||
version = "0.7.34"
|
version = "0.7.34"
|
||||||
|
|
|
@ -14,6 +14,9 @@ ratatui = "0.27.0"
|
||||||
tui-term = "0.1.12"
|
tui-term = "0.1.12"
|
||||||
include_dir = "0.7.4"
|
include_dir = "0.7.4"
|
||||||
tempdir = "0.3.7"
|
tempdir = "0.3.7"
|
||||||
|
serde = { version = "1.0.205", features = ["derive"] }
|
||||||
|
toml = "0.8.19"
|
||||||
|
which = "6.0.2"
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "linutil"
|
name = "linutil"
|
||||||
|
|
4
build.rs
Normal file
4
build.rs
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
fn main() {
|
||||||
|
// Rebuild program if any file in commands directory changes.
|
||||||
|
println!("cargo:rerun-if-changed=src/commands");
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
#!/bin/sh -e
|
#!/bin/sh -e
|
||||||
|
|
||||||
. ./common-script.sh
|
. ../common-script.sh
|
||||||
|
|
||||||
setupAlacritty() {
|
setupAlacritty() {
|
||||||
echo "Install Alacritty if not already installed..."
|
echo "Install Alacritty if not already installed..."
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#!/bin/sh -e
|
#!/bin/sh -e
|
||||||
. ./common-script.sh
|
. ../common-script.sh
|
||||||
|
|
||||||
makeDWM(){
|
makeDWM(){
|
||||||
cd $HOME && git clone https://github.com/ChrisTitusTech/dwm-titus.git # CD to Home directory to install dwm-titus
|
cd $HOME && git clone https://github.com/ChrisTitusTech/dwm-titus.git # CD to Home directory to install dwm-titus
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#!/bin/sh -e
|
#!/bin/sh -e
|
||||||
|
|
||||||
. ./common-script.sh
|
. ../common-script.sh
|
||||||
|
|
||||||
setupKitty() {
|
setupKitty() {
|
||||||
echo "Install Kitty if not already installed..."
|
echo "Install Kitty if not already installed..."
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#!/bin/sh -e
|
#!/bin/sh -e
|
||||||
|
|
||||||
. ./common-script.sh
|
. ../common-script.sh
|
||||||
|
|
||||||
setupRofi() {
|
setupRofi() {
|
||||||
echo "Install Rofi if not already installed..."
|
echo "Install Rofi if not already installed..."
|
||||||
|
|
29
src/commands/applications-setup/tab_data.toml
Normal file
29
src/commands/applications-setup/tab_data.toml
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
name = "Applications Setup"
|
||||||
|
|
||||||
|
[[data]]
|
||||||
|
name = "Alacritty"
|
||||||
|
script = "alacritty-setup.sh"
|
||||||
|
|
||||||
|
[[data]]
|
||||||
|
name = "Bash Prompt"
|
||||||
|
command = "bash -c \"$(curl -s https://raw.githubusercontent.com/ChrisTitusTech/mybash/main/setup.sh)\""
|
||||||
|
|
||||||
|
[[data]]
|
||||||
|
name = "DWM-Titus"
|
||||||
|
script = "dwmtitus-setup.sh"
|
||||||
|
|
||||||
|
[[data]]
|
||||||
|
name = "Kitty"
|
||||||
|
script = "kitty-setup.sh"
|
||||||
|
|
||||||
|
[[data]]
|
||||||
|
name = "Neovim"
|
||||||
|
command = "bash -c \"$(curl -s https://raw.githubusercontent.com/ChrisTitusTech/neovim/main/setup.sh)\""
|
||||||
|
|
||||||
|
[[data]]
|
||||||
|
name = "Rofi"
|
||||||
|
script = "rofi-setup.sh"
|
||||||
|
|
||||||
|
[[data]]
|
||||||
|
name = "ZSH Prompt"
|
||||||
|
script = "zsh-setup.sh"
|
|
@ -1,6 +1,6 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
. ./common-script.sh
|
. ../common-script.sh
|
||||||
|
|
||||||
# Function to install zsh
|
# Function to install zsh
|
||||||
install_zsh() {
|
install_zsh() {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#!/bin/sh -e
|
#!/bin/sh -e
|
||||||
|
|
||||||
. ./common-script.sh
|
. ../common-script.sh
|
||||||
|
|
||||||
installPkg() {
|
installPkg() {
|
||||||
echo "Install UFW if not already installed..."
|
echo "Install UFW if not already installed..."
|
||||||
|
|
5
src/commands/security/tab_data.toml
Normal file
5
src/commands/security/tab_data.toml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
name = "Security"
|
||||||
|
|
||||||
|
[[data]]
|
||||||
|
name = "Firewall Baselines (CTT)"
|
||||||
|
script = "firewall-baselines.sh"
|
|
@ -1,6 +1,6 @@
|
||||||
#!/bin/sh -e
|
#!/bin/sh -e
|
||||||
|
|
||||||
. ./common-script.sh
|
. ../common-script.sh
|
||||||
|
|
||||||
# Check if the home directory and linuxtoolbox folder exist, create them if they don't
|
# Check if the home directory and linuxtoolbox folder exist, create them if they don't
|
||||||
LINUXTOOLBOXDIR="$HOME/linuxtoolbox"
|
LINUXTOOLBOXDIR="$HOME/linuxtoolbox"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#!/bin/sh -e
|
#!/bin/sh -e
|
||||||
|
|
||||||
. ./common-script.sh
|
. ../common-script.sh
|
||||||
|
|
||||||
installDepend() {
|
installDepend() {
|
||||||
## Check for dependencies.
|
## Check for dependencies.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#!/bin/sh -e
|
#!/bin/sh -e
|
||||||
|
|
||||||
. ./common-script.sh
|
. ../common-script.sh
|
||||||
|
|
||||||
# Check if the home directory and linuxtoolbox folder exist, create them if they don't
|
# Check if the home directory and linuxtoolbox folder exist, create them if they don't
|
||||||
LINUXTOOLBOXDIR="$HOME/linuxtoolbox"
|
LINUXTOOLBOXDIR="$HOME/linuxtoolbox"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#!/bin/sh -e
|
#!/bin/sh -e
|
||||||
|
|
||||||
. ./common-script.sh
|
. ../common-script.sh
|
||||||
|
|
||||||
removeSnaps() {
|
removeSnaps() {
|
||||||
case $PACKAGER in
|
case $PACKAGER in
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#!/bin/sh -e
|
#!/bin/sh -e
|
||||||
|
|
||||||
. ./common-script.sh
|
. ../common-script.sh
|
||||||
|
|
||||||
fastUpdate() {
|
fastUpdate() {
|
||||||
case ${PACKAGER} in
|
case ${PACKAGER} in
|
37
src/commands/system-setup/tab_data.toml
Normal file
37
src/commands/system-setup/tab_data.toml
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
name = "System Setup"
|
||||||
|
|
||||||
|
[[data]]
|
||||||
|
name = "Arch Linux"
|
||||||
|
|
||||||
|
[[data.preconditions]]
|
||||||
|
matches = true
|
||||||
|
data = "command_exists"
|
||||||
|
values = ["pacman"]
|
||||||
|
|
||||||
|
[[data.entries]]
|
||||||
|
name = "Yay AUR Helper"
|
||||||
|
script = "arch/yay-setup.sh"
|
||||||
|
|
||||||
|
[[data.entries]]
|
||||||
|
name = "Paru AUR Helper"
|
||||||
|
script = "arch/paru-setup.sh"
|
||||||
|
|
||||||
|
[[data]]
|
||||||
|
name = "Full System Update"
|
||||||
|
script = "system-update.sh"
|
||||||
|
|
||||||
|
[[data]]
|
||||||
|
name = "Build Prerequisites"
|
||||||
|
script = "1-compile-setup.sh"
|
||||||
|
|
||||||
|
[[data]]
|
||||||
|
name = "Gaming Dependencies"
|
||||||
|
script = "2-gaming-setup.sh"
|
||||||
|
|
||||||
|
[[data]]
|
||||||
|
name = "Global Theme"
|
||||||
|
script = "3-global-theme.sh"
|
||||||
|
|
||||||
|
[[data]]
|
||||||
|
name = "Remove Snaps"
|
||||||
|
script = "4-remove-snaps.sh"
|
1
src/commands/tabs.toml
Normal file
1
src/commands/tabs.toml
Normal file
|
@ -0,0 +1 @@
|
||||||
|
directories = ["system-setup", "applications-setup", "security", "utils"]
|
|
@ -1,5 +1,5 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
source ./utils/monitor-control/utility_functions.sh
|
source ./utility_functions.sh
|
||||||
|
|
||||||
# Function to auto-detect displays and set common resolution
|
# Function to auto-detect displays and set common resolution
|
||||||
auto_detect_displays() {
|
auto_detect_displays() {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
source ./utils/monitor-control/utility_functions.sh
|
source ./utility_functions.sh
|
||||||
|
|
||||||
# Function to change monitor orientation
|
# Function to change monitor orientation
|
||||||
change_orientation() {
|
change_orientation() {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
source ./utils/monitor-control/utility_functions.sh
|
source ./utility_functions.sh
|
||||||
|
|
||||||
RESET='\033[0m'
|
RESET='\033[0m'
|
||||||
BOLD='\033[1m'
|
BOLD='\033[1m'
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
source ./utils/monitor-control/utility_functions.sh
|
source ./utility_functions.sh
|
||||||
|
|
||||||
# Function to duplicate displays
|
# Function to duplicate displays
|
||||||
duplicate_displays() {
|
duplicate_displays() {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
source ./utils/monitor-control/utility_functions.sh
|
source ./utility_functions.sh
|
||||||
|
|
||||||
RESET='\033[0m'
|
RESET='\033[0m'
|
||||||
BOLD='\033[1m'
|
BOLD='\033[1m'
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
source ./utils/monitor-control/utility_functions.sh
|
source ./utility_functions.sh
|
||||||
|
|
||||||
# Function to extend displays
|
# Function to extend displays
|
||||||
extend_displays() {
|
extend_displays() {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
source ./utils/monitor-control/utility_functions.sh
|
source ./utility_functions.sh
|
||||||
|
|
||||||
# Function to manage monitor arrangement
|
# Function to manage monitor arrangement
|
||||||
manage_arrangement() {
|
manage_arrangement() {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
source ./utils/monitor-control/utility_functions.sh
|
source ./utility_functions.sh
|
||||||
|
|
||||||
# Function to reset scaling back to 1 (native resolution) for all monitors
|
# Function to reset scaling back to 1 (native resolution) for all monitors
|
||||||
reset_scaling() {
|
reset_scaling() {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
source ./utils/monitor-control/utility_functions.sh
|
source ./utility_functions.sh
|
||||||
|
|
||||||
# Function to scale smaller monitors to the highest resolution of a bigger monitor
|
# Function to scale smaller monitors to the highest resolution of a bigger monitor
|
||||||
scale_monitors() {
|
scale_monitors() {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
source ./utils/monitor-control/utility_functions.sh
|
source ./utility_functions.sh
|
||||||
|
|
||||||
# Function to set a monitor as primary
|
# Function to set a monitor as primary
|
||||||
set_primary_monitor() {
|
set_primary_monitor() {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
source ./utils/monitor-control/utility_functions.sh
|
source ./utility_functions.sh
|
||||||
|
|
||||||
RESET='\033[0m'
|
RESET='\033[0m'
|
||||||
BOLD='\033[1m'
|
BOLD='\033[1m'
|
||||||
|
|
66
src/commands/utils/tab_data.toml
Normal file
66
src/commands/utils/tab_data.toml
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
name = "Utilities"
|
||||||
|
|
||||||
|
[[data]]
|
||||||
|
name = "WiFi Manager"
|
||||||
|
script = "wifi-control.sh"
|
||||||
|
|
||||||
|
[[data]]
|
||||||
|
name = "Bluetooth Manager"
|
||||||
|
script = "bluetooth-control.sh"
|
||||||
|
|
||||||
|
[[data]]
|
||||||
|
name = "Monitor Control"
|
||||||
|
|
||||||
|
[[data.preconditions]]
|
||||||
|
matches = true
|
||||||
|
data = { environment = "XDG_SESSION_TYPE" }
|
||||||
|
values = ["x11"]
|
||||||
|
|
||||||
|
[[data.entries]]
|
||||||
|
name = "Set Resolution"
|
||||||
|
script = "monitor-control/set_resolutions.sh"
|
||||||
|
|
||||||
|
[[data.entries]]
|
||||||
|
name = "Set Resolution"
|
||||||
|
script = "monitor-control/set_resolutions.sh"
|
||||||
|
|
||||||
|
[[data.entries]]
|
||||||
|
name = "Duplicate Displays"
|
||||||
|
script = "monitor-control/duplicate_displays.sh"
|
||||||
|
|
||||||
|
[[data.entries]]
|
||||||
|
name = "Extend Displays"
|
||||||
|
script = "monitor-control/extend_displays.sh"
|
||||||
|
|
||||||
|
[[data.entries]]
|
||||||
|
name = "Auto Detect Displays"
|
||||||
|
script = "monitor-control/auto_detect_displays.sh"
|
||||||
|
|
||||||
|
[[data.entries]]
|
||||||
|
name = "Enable Monitor"
|
||||||
|
script = "monitor-control/enable_monitor.sh"
|
||||||
|
|
||||||
|
[[data.entries]]
|
||||||
|
name = "Disable Monitor"
|
||||||
|
script = "monitor-control/disable_monitor.sh"
|
||||||
|
|
||||||
|
[[data.entries]]
|
||||||
|
name = "Set Primary Monitor"
|
||||||
|
script = "monitor-control/set_primary_monitor.sh"
|
||||||
|
|
||||||
|
[[data.entries]]
|
||||||
|
name = "Change Orientation"
|
||||||
|
script = "monitor-control/change_orientation.sh"
|
||||||
|
|
||||||
|
[[data.entries]]
|
||||||
|
name = "Manage Arrangement"
|
||||||
|
script = "monitor-control/manage_arrangement.sh"
|
||||||
|
|
||||||
|
[[data.entries]]
|
||||||
|
name = "Scale Monitors"
|
||||||
|
script = "monitor-control/scale_monitor.sh"
|
||||||
|
|
||||||
|
[[data.entries]]
|
||||||
|
name = "Reset Scaling"
|
||||||
|
script = "monitor-control/reset_scaling.sh"
|
||||||
|
matches = true
|
|
@ -7,7 +7,6 @@ use ratatui::{
|
||||||
widgets::{Block, Borders, List},
|
widgets::{Block, Borders, List},
|
||||||
Frame,
|
Frame,
|
||||||
};
|
};
|
||||||
use std::path::PathBuf;
|
|
||||||
|
|
||||||
pub struct FloatingText {
|
pub struct FloatingText {
|
||||||
text: Vec<String>,
|
text: Vec<String>,
|
||||||
|
@ -19,7 +18,7 @@ impl FloatingText {
|
||||||
Self { text, scroll: 0 }
|
Self { text, scroll: 0 }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_command(command: &Command, mut full_path: PathBuf) -> Option<Self> {
|
pub fn from_command(command: &Command) -> Option<Self> {
|
||||||
let lines = match command {
|
let lines = match command {
|
||||||
Command::Raw(cmd) => {
|
Command::Raw(cmd) => {
|
||||||
// Reconstruct the line breaks and file formatting after the
|
// Reconstruct the line breaks and file formatting after the
|
||||||
|
@ -27,9 +26,8 @@ impl FloatingText {
|
||||||
cmd.lines().map(|line| line.to_string()).collect()
|
cmd.lines().map(|line| line.to_string()).collect()
|
||||||
}
|
}
|
||||||
Command::LocalFile(file_path) => {
|
Command::LocalFile(file_path) => {
|
||||||
full_path.push(file_path);
|
let file_contents = std::fs::read_to_string(file_path)
|
||||||
let file_contents = std::fs::read_to_string(&full_path)
|
.map_err(|_| format!("File not found: {:?}", file_path))
|
||||||
.map_err(|_| format!("File not found: {:?}", &full_path))
|
|
||||||
.unwrap();
|
.unwrap();
|
||||||
file_contents.lines().map(|line| line.to_string()).collect()
|
file_contents.lines().map(|line| line.to_string()).collect()
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,20 +34,21 @@ struct Args {
|
||||||
#[arg(default_value_t = Theme::Default)]
|
#[arg(default_value_t = Theme::Default)]
|
||||||
#[arg(help = "Set the theme to use in the application")]
|
#[arg(help = "Set the theme to use in the application")]
|
||||||
theme: Theme,
|
theme: Theme,
|
||||||
|
#[arg(long, default_value_t = false)]
|
||||||
|
#[clap(help = "Show all available options, disregarding compatibility checks (UNSAFE)")]
|
||||||
|
override_validation: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() -> std::io::Result<()> {
|
fn main() -> std::io::Result<()> {
|
||||||
let args = Args::parse();
|
let args = Args::parse();
|
||||||
|
|
||||||
let theme = args.theme;
|
|
||||||
|
|
||||||
let commands_dir = include_dir!("src/commands");
|
let commands_dir = include_dir!("src/commands");
|
||||||
let temp_dir: TempDir = TempDir::new("linutil_scripts").unwrap();
|
let temp_dir: TempDir = TempDir::new("linutil_scripts").unwrap();
|
||||||
commands_dir
|
commands_dir
|
||||||
.extract(temp_dir.path())
|
.extract(temp_dir.path())
|
||||||
.expect("Failed to extract the saved directory");
|
.expect("Failed to extract the saved directory");
|
||||||
|
|
||||||
let mut state = AppState::new(theme, temp_dir.path().to_owned());
|
let mut state = AppState::new(args.theme, temp_dir.path(), args.override_validation);
|
||||||
|
|
||||||
stdout().execute(EnterAlternateScreen)?;
|
stdout().execute(EnterAlternateScreen)?;
|
||||||
enable_raw_mode()?;
|
enable_raw_mode()?;
|
||||||
|
|
|
@ -13,7 +13,7 @@ use ratatui::{
|
||||||
};
|
};
|
||||||
use std::{
|
use std::{
|
||||||
io::Write,
|
io::Write,
|
||||||
path::Path,
|
path::PathBuf,
|
||||||
sync::{Arc, Mutex},
|
sync::{Arc, Mutex},
|
||||||
thread::JoinHandle,
|
thread::JoinHandle,
|
||||||
};
|
};
|
||||||
|
@ -22,10 +22,10 @@ use tui_term::{
|
||||||
widget::PseudoTerminal,
|
widget::PseudoTerminal,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Hash, Eq, PartialEq)]
|
||||||
pub enum Command {
|
pub enum Command {
|
||||||
Raw(&'static str),
|
Raw(String),
|
||||||
LocalFile(&'static str),
|
LocalFile(PathBuf),
|
||||||
None, // Directory
|
None, // Directory
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,7 +126,7 @@ impl FloatContent for RunningCommand {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RunningCommand {
|
impl RunningCommand {
|
||||||
pub fn new(command: Command, temp_path: &Path) -> Self {
|
pub fn new(command: Command) -> Self {
|
||||||
let pty_system = NativePtySystem::default();
|
let pty_system = NativePtySystem::default();
|
||||||
|
|
||||||
// Build the command based on the provided Command enum variant
|
// Build the command based on the provided Command enum variant
|
||||||
|
@ -137,13 +137,14 @@ impl RunningCommand {
|
||||||
cmd.arg(prompt);
|
cmd.arg(prompt);
|
||||||
}
|
}
|
||||||
Command::LocalFile(file) => {
|
Command::LocalFile(file) => {
|
||||||
cmd.arg(file);
|
cmd.arg(&file);
|
||||||
|
if let Some(parent) = file.parent() {
|
||||||
|
cmd.cwd(parent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Command::None => panic!("Command::None was treated as a command"),
|
Command::None => panic!("Command::None was treated as a command"),
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.cwd(temp_path);
|
|
||||||
|
|
||||||
// Open a pseudo-terminal with initial size
|
// Open a pseudo-terminal with initial size
|
||||||
let pair = pty_system
|
let pair = pty_system
|
||||||
.openpty(PtySize {
|
.openpty(PtySize {
|
||||||
|
|
43
src/state.rs
43
src/state.rs
|
@ -2,7 +2,7 @@ use crate::{
|
||||||
float::{Float, FloatContent},
|
float::{Float, FloatContent},
|
||||||
floating_text::FloatingText,
|
floating_text::FloatingText,
|
||||||
running_command::{Command, RunningCommand},
|
running_command::{Command, RunningCommand},
|
||||||
tabs::{ListNode, TABS},
|
tabs::{ListNode, Tab},
|
||||||
theme::Theme,
|
theme::Theme,
|
||||||
};
|
};
|
||||||
use crossterm::event::{KeyCode, KeyEvent, KeyEventKind};
|
use crossterm::event::{KeyCode, KeyEvent, KeyEventKind};
|
||||||
|
@ -14,15 +14,15 @@ use ratatui::{
|
||||||
widgets::{Block, Borders, List, ListState, Paragraph},
|
widgets::{Block, Borders, List, ListState, Paragraph},
|
||||||
Frame,
|
Frame,
|
||||||
};
|
};
|
||||||
use std::path::PathBuf;
|
use std::path::Path;
|
||||||
|
|
||||||
pub struct AppState {
|
pub struct AppState {
|
||||||
/// Selected theme
|
/// Selected theme
|
||||||
pub theme: Theme,
|
theme: Theme,
|
||||||
/// Path to the root of the unpacked files in /tmp
|
|
||||||
temp_path: PathBuf,
|
|
||||||
/// Currently focused area
|
/// Currently focused area
|
||||||
focus: Focus,
|
focus: Focus,
|
||||||
|
/// List of tabs
|
||||||
|
tabs: Vec<Tab>,
|
||||||
/// Current tab
|
/// Current tab
|
||||||
current_tab: ListState,
|
current_tab: ListState,
|
||||||
/// Current search query
|
/// Current search query
|
||||||
|
@ -51,12 +51,13 @@ struct ListEntry {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AppState {
|
impl AppState {
|
||||||
pub fn new(theme: Theme, temp_path: PathBuf) -> Self {
|
pub fn new(theme: Theme, temp_path: &Path, override_validation: bool) -> Self {
|
||||||
let root_id = TABS[0].tree.root().id();
|
let tabs = crate::tabs::get_tabs(temp_path, !override_validation);
|
||||||
|
let root_id = tabs[0].tree.root().id();
|
||||||
let mut state = Self {
|
let mut state = Self {
|
||||||
theme,
|
theme,
|
||||||
temp_path,
|
|
||||||
focus: Focus::List,
|
focus: Focus::List,
|
||||||
|
tabs,
|
||||||
current_tab: ListState::default().with_selected(Some(0)),
|
current_tab: ListState::default().with_selected(Some(0)),
|
||||||
search_query: String::new(),
|
search_query: String::new(),
|
||||||
items: vec![],
|
items: vec![],
|
||||||
|
@ -67,7 +68,8 @@ impl AppState {
|
||||||
state
|
state
|
||||||
}
|
}
|
||||||
pub fn draw(&mut self, frame: &mut Frame) {
|
pub fn draw(&mut self, frame: &mut Frame) {
|
||||||
let longest_tab_display_len = TABS
|
let longest_tab_display_len = self
|
||||||
|
.tabs
|
||||||
.iter()
|
.iter()
|
||||||
.map(|tab| tab.name.len() + self.theme.tab_icon().len())
|
.map(|tab| tab.name.len() + self.theme.tab_icon().len())
|
||||||
.max()
|
.max()
|
||||||
|
@ -85,7 +87,11 @@ impl AppState {
|
||||||
.constraints([Constraint::Length(3), Constraint::Min(1)])
|
.constraints([Constraint::Length(3), Constraint::Min(1)])
|
||||||
.split(horizontal[0]);
|
.split(horizontal[0]);
|
||||||
|
|
||||||
let tabs = TABS.iter().map(|tab| tab.name).collect::<Vec<_>>();
|
let tabs = self
|
||||||
|
.tabs
|
||||||
|
.iter()
|
||||||
|
.map(|tab| tab.name.as_str())
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
let tab_hl_style = if let Focus::TabList = self.focus {
|
let tab_hl_style = if let Focus::TabList = self.focus {
|
||||||
Style::default().reversed().fg(self.theme.tab_color())
|
Style::default().reversed().fg(self.theme.tab_color())
|
||||||
|
@ -186,7 +192,7 @@ impl AppState {
|
||||||
self.focus = Focus::List
|
self.focus = Focus::List
|
||||||
}
|
}
|
||||||
KeyCode::Char('j') | KeyCode::Down
|
KeyCode::Char('j') | KeyCode::Down
|
||||||
if self.current_tab.selected().unwrap() + 1 < TABS.len() =>
|
if self.current_tab.selected().unwrap() + 1 < self.tabs.len() =>
|
||||||
{
|
{
|
||||||
self.current_tab.select_next();
|
self.current_tab.select_next();
|
||||||
self.refresh_tab();
|
self.refresh_tab();
|
||||||
|
@ -224,7 +230,7 @@ impl AppState {
|
||||||
}
|
}
|
||||||
pub fn update_items(&mut self) {
|
pub fn update_items(&mut self) {
|
||||||
if self.search_query.is_empty() {
|
if self.search_query.is_empty() {
|
||||||
let curr = TABS[self.current_tab.selected().unwrap()]
|
let curr = self.tabs[self.current_tab.selected().unwrap()]
|
||||||
.tree
|
.tree
|
||||||
.get(*self.visit_stack.last().unwrap())
|
.get(*self.visit_stack.last().unwrap())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -241,7 +247,7 @@ impl AppState {
|
||||||
self.items.clear();
|
self.items.clear();
|
||||||
|
|
||||||
let query_lower = self.search_query.to_lowercase();
|
let query_lower = self.search_query.to_lowercase();
|
||||||
for tab in TABS.iter() {
|
for tab in self.tabs.iter() {
|
||||||
let mut stack = vec![tab.tree.root().id()];
|
let mut stack = vec![tab.tree.root().id()];
|
||||||
while let Some(node_id) = stack.pop() {
|
while let Some(node_id) = stack.pop() {
|
||||||
let node = tab.tree.get(node_id).unwrap();
|
let node = tab.tree.get(node_id).unwrap();
|
||||||
|
@ -259,7 +265,7 @@ impl AppState {
|
||||||
stack.extend(node.children().map(|child| child.id()));
|
stack.extend(node.children().map(|child| child.id()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.items.sort_by(|a, b| a.node.name.cmp(b.node.name));
|
self.items.sort_by(|a, b| a.node.name.cmp(&b.node.name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Checks ehther the current tree node is the root node (can we go up the tree or no)
|
/// Checks ehther the current tree node is the root node (can we go up the tree or no)
|
||||||
|
@ -299,14 +305,14 @@ impl AppState {
|
||||||
}
|
}
|
||||||
fn enable_preview(&mut self) {
|
fn enable_preview(&mut self) {
|
||||||
if let Some(command) = self.get_selected_command(false) {
|
if let Some(command) = self.get_selected_command(false) {
|
||||||
if let Some(preview) = FloatingText::from_command(&command, self.temp_path.clone()) {
|
if let Some(preview) = FloatingText::from_command(&command) {
|
||||||
self.spawn_float(preview, 80, 80);
|
self.spawn_float(preview, 80, 80);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn handle_enter(&mut self) {
|
fn handle_enter(&mut self) {
|
||||||
if let Some(cmd) = self.get_selected_command(true) {
|
if let Some(cmd) = self.get_selected_command(true) {
|
||||||
let command = RunningCommand::new(cmd, &self.temp_path);
|
let command = RunningCommand::new(cmd);
|
||||||
self.spawn_float(command, 80, 80);
|
self.spawn_float(command, 80, 80);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -323,7 +329,10 @@ impl AppState {
|
||||||
self.update_items();
|
self.update_items();
|
||||||
}
|
}
|
||||||
fn refresh_tab(&mut self) {
|
fn refresh_tab(&mut self) {
|
||||||
self.visit_stack = vec![TABS[self.current_tab.selected().unwrap()].tree.root().id()];
|
self.visit_stack = vec![self.tabs[self.current_tab.selected().unwrap()]
|
||||||
|
.tree
|
||||||
|
.root()
|
||||||
|
.id()];
|
||||||
self.selection.select(Some(0));
|
self.selection.select(Some(0));
|
||||||
self.update_items();
|
self.update_items();
|
||||||
}
|
}
|
||||||
|
|
341
src/tabs.rs
341
src/tabs.rs
|
@ -1,175 +1,190 @@
|
||||||
use std::sync::LazyLock;
|
|
||||||
|
|
||||||
use ego_tree::{tree, Tree};
|
|
||||||
|
|
||||||
use crate::running_command::Command;
|
use crate::running_command::Command;
|
||||||
|
use ego_tree::{NodeMut, Tree};
|
||||||
|
use serde::Deserialize;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct TabList {
|
||||||
|
directories: Vec<PathBuf>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct TabEntry {
|
||||||
|
name: String,
|
||||||
|
data: Vec<Entry>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct Entry {
|
||||||
|
name: String,
|
||||||
|
#[allow(dead_code)]
|
||||||
|
#[serde(default)]
|
||||||
|
description: String,
|
||||||
|
#[serde(default)]
|
||||||
|
preconditions: Option<Vec<Precondition>>,
|
||||||
|
#[serde(default)]
|
||||||
|
entries: Option<Vec<Entry>>,
|
||||||
|
#[serde(default)]
|
||||||
|
command: Option<String>,
|
||||||
|
#[serde(default)]
|
||||||
|
script: Option<PathBuf>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Entry {
|
||||||
|
fn is_supported(&self) -> bool {
|
||||||
|
self.preconditions.as_deref().map_or(true, |preconditions| {
|
||||||
|
preconditions.iter().all(
|
||||||
|
|Precondition {
|
||||||
|
matches,
|
||||||
|
data,
|
||||||
|
values,
|
||||||
|
}| {
|
||||||
|
match data {
|
||||||
|
SystemDataType::Environment(var_name) => std::env::var(var_name)
|
||||||
|
.map_or(false, |var| values.contains(&var) == *matches),
|
||||||
|
SystemDataType::File(path) => {
|
||||||
|
std::fs::read_to_string(path).map_or(false, |data| {
|
||||||
|
values
|
||||||
|
.iter()
|
||||||
|
.any(|matching_value| data.contains(matching_value))
|
||||||
|
== *matches
|
||||||
|
})
|
||||||
|
}
|
||||||
|
SystemDataType::CommandExists => values
|
||||||
|
.iter()
|
||||||
|
.all(|command| which::which(command).is_ok() == *matches),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct Precondition {
|
||||||
|
// If true, the data must be contained within the list of values.
|
||||||
|
// Otherwise, the data must not be contained within the list of values
|
||||||
|
matches: bool,
|
||||||
|
data: SystemDataType,
|
||||||
|
values: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
enum SystemDataType {
|
||||||
|
#[serde(rename = "environment")]
|
||||||
|
Environment(String),
|
||||||
|
#[serde(rename = "file")]
|
||||||
|
File(PathBuf),
|
||||||
|
#[serde(rename = "command_exists")]
|
||||||
|
CommandExists,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Hash, Eq, PartialEq)]
|
||||||
pub struct Tab {
|
pub struct Tab {
|
||||||
pub name: &'static str,
|
pub name: String,
|
||||||
pub tree: Tree<ListNode>,
|
pub tree: Tree<ListNode>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Hash, Eq, PartialEq)]
|
||||||
pub struct ListNode {
|
pub struct ListNode {
|
||||||
pub name: &'static str,
|
pub name: String,
|
||||||
pub command: Command,
|
pub command: Command,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub static TABS: LazyLock<Vec<Tab>> = LazyLock::new(|| {
|
pub fn get_tabs(command_dir: &Path, validate: bool) -> Vec<Tab> {
|
||||||
vec![
|
let tab_files = TabList::get_tabs(command_dir);
|
||||||
Tab {
|
let tabs = tab_files.into_iter().map(|path| {
|
||||||
name: "System Setup",
|
let directory = path.parent().unwrap().to_owned();
|
||||||
tree: tree!(ListNode {
|
let data = std::fs::read_to_string(path).expect("Failed to read tab data");
|
||||||
name: "root",
|
let mut tab_data: TabEntry = toml::from_str(&data).expect("Failed to parse tab data");
|
||||||
command: Command::None,
|
|
||||||
} => {
|
if validate {
|
||||||
ListNode {
|
filter_entries(&mut tab_data.data);
|
||||||
name: "Arch Linux",
|
|
||||||
command: Command::None,
|
|
||||||
} => {
|
|
||||||
ListNode {
|
|
||||||
name: "Yay AUR Helper",
|
|
||||||
command: Command::LocalFile("system-setup/arch/yay-setup.sh"),
|
|
||||||
},
|
|
||||||
ListNode {
|
|
||||||
name: "Paru AUR Helper",
|
|
||||||
command: Command::LocalFile("system-setup/arch/paru-setup.sh"),
|
|
||||||
}
|
}
|
||||||
},
|
(tab_data, directory)
|
||||||
ListNode {
|
|
||||||
name: "Full System Update",
|
|
||||||
command: Command::LocalFile("system-update.sh"),
|
|
||||||
},
|
|
||||||
ListNode {
|
|
||||||
name: "Build Prerequisites",
|
|
||||||
command: Command::LocalFile("system-setup/1-compile-setup.sh"),
|
|
||||||
},
|
|
||||||
ListNode {
|
|
||||||
name: "Gaming Dependencies",
|
|
||||||
command: Command::LocalFile("system-setup/2-gaming-setup.sh"),
|
|
||||||
},
|
|
||||||
ListNode {
|
|
||||||
name: "Global Theme",
|
|
||||||
command: Command::LocalFile("system-setup/3-global-theme.sh"),
|
|
||||||
},
|
|
||||||
ListNode {
|
|
||||||
name: "Remove Snaps",
|
|
||||||
command: Command::LocalFile("system-setup/4-remove-snaps.sh"),
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
Tab {
|
|
||||||
name: "Applications Setup",
|
|
||||||
tree: tree!(ListNode {
|
|
||||||
name: "root",
|
|
||||||
command: Command::None,
|
|
||||||
} => {
|
|
||||||
ListNode {
|
|
||||||
name: "Alacritty",
|
|
||||||
command: Command::LocalFile("applications-setup/alacritty-setup.sh"),
|
|
||||||
},
|
|
||||||
ListNode {
|
|
||||||
name: "Bash Prompt",
|
|
||||||
command: Command::Raw("bash -c \"$(curl -s https://raw.githubusercontent.com/ChrisTitusTech/mybash/main/setup.sh)\""),
|
|
||||||
},
|
|
||||||
ListNode {
|
|
||||||
name: "DWM-Titus",
|
|
||||||
command: Command::LocalFile("applications-setup/dwmtitus-setup.sh")
|
|
||||||
},
|
|
||||||
ListNode {
|
|
||||||
name: "Kitty",
|
|
||||||
command: Command::LocalFile("applications-setup/kitty-setup.sh")
|
|
||||||
},
|
|
||||||
ListNode {
|
|
||||||
name: "Neovim",
|
|
||||||
command: Command::Raw("bash -c \"$(curl -s https://raw.githubusercontent.com/ChrisTitusTech/neovim/main/setup.sh)\""),
|
|
||||||
},
|
|
||||||
ListNode {
|
|
||||||
name: "Rofi",
|
|
||||||
command: Command::LocalFile("applications-setup/rofi-setup.sh"),
|
|
||||||
},
|
|
||||||
ListNode {
|
|
||||||
name: "ZSH Prompt",
|
|
||||||
command: Command::LocalFile("applications-setup/zsh-setup.sh"),
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
Tab {
|
|
||||||
name: "Security",
|
|
||||||
tree: tree!(ListNode {
|
|
||||||
name: "root",
|
|
||||||
command: Command::None,
|
|
||||||
} => {
|
|
||||||
ListNode {
|
|
||||||
name: "Firewall Baselines (CTT)",
|
|
||||||
command: Command::LocalFile("security/firewall-baselines.sh"),
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
Tab {
|
|
||||||
name: "Utilities",
|
|
||||||
tree: tree!(ListNode {
|
|
||||||
name: "root",
|
|
||||||
command: Command::None,
|
|
||||||
} => {
|
|
||||||
ListNode {
|
|
||||||
name: "Wifi Manager",
|
|
||||||
command: Command::LocalFile("utils/wifi-control.sh"),
|
|
||||||
},
|
|
||||||
ListNode {
|
|
||||||
name: "Bluetooth Manager",
|
|
||||||
command: Command::LocalFile("utils/bluetooth-control.sh"),
|
|
||||||
},
|
|
||||||
ListNode {
|
|
||||||
name: "MonitorControl(xorg)",
|
|
||||||
command: Command::None,
|
|
||||||
} => {
|
|
||||||
ListNode {
|
|
||||||
name: "Set Resolution",
|
|
||||||
command: Command::LocalFile("utils/monitor-control/set_resolutions.sh"),
|
|
||||||
},
|
|
||||||
ListNode {
|
|
||||||
name: "Duplicate Displays",
|
|
||||||
command: Command::LocalFile("utils/monitor-control/duplicate_displays.sh"),
|
|
||||||
},
|
|
||||||
ListNode {
|
|
||||||
name: "Extend Displays",
|
|
||||||
command: Command::LocalFile("utils/monitor-control/extend_displays.sh"),
|
|
||||||
},
|
|
||||||
ListNode {
|
|
||||||
name: "Auto Detect Displays",
|
|
||||||
command: Command::LocalFile("utils/monitor-control/auto_detect_displays.sh"),
|
|
||||||
},
|
|
||||||
ListNode {
|
|
||||||
name: "Enable Monitor",
|
|
||||||
command: Command::LocalFile("utils/monitor-control/enable_monitor.sh"),
|
|
||||||
},
|
|
||||||
ListNode {
|
|
||||||
name: "Disable Monitor",
|
|
||||||
command: Command::LocalFile("utils/monitor-control/disable_monitor.sh"),
|
|
||||||
},
|
|
||||||
ListNode {
|
|
||||||
name: "Set Primary Monitor",
|
|
||||||
command: Command::LocalFile("utils/monitor-control/set_primary_monitor.sh"),
|
|
||||||
},
|
|
||||||
ListNode {
|
|
||||||
name: "Change Orientation",
|
|
||||||
command: Command::LocalFile("utils/monitor-control/change_orientation.sh"),
|
|
||||||
},
|
|
||||||
ListNode {
|
|
||||||
name: "Manage Arrangement",
|
|
||||||
command: Command::LocalFile("utils/monitor-control/manage_arrangement.sh"),
|
|
||||||
},
|
|
||||||
ListNode {
|
|
||||||
name: "Scale Monitors",
|
|
||||||
command: Command::LocalFile("utils/monitor-control/scale_monitor.sh"),
|
|
||||||
},
|
|
||||||
ListNode {
|
|
||||||
name: "Reset Scaling",
|
|
||||||
command: Command::LocalFile("utils/monitor-control/reset_scaling.sh"),
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
]
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let tabs: Vec<Tab> = tabs
|
||||||
|
.map(|(TabEntry { name, data }, directory)| {
|
||||||
|
let mut tree = Tree::new(ListNode {
|
||||||
|
name: "root".to_string(),
|
||||||
|
command: Command::None,
|
||||||
|
});
|
||||||
|
let mut root = tree.root_mut();
|
||||||
|
create_directory(data, &mut root, &directory);
|
||||||
|
Tab { name, tree }
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
if tabs.is_empty() {
|
||||||
|
panic!("No tabs found");
|
||||||
|
}
|
||||||
|
tabs
|
||||||
|
}
|
||||||
|
|
||||||
|
fn filter_entries(entries: &mut Vec<Entry>) {
|
||||||
|
entries.retain_mut(|entry| {
|
||||||
|
if !entry.is_supported() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if let Some(entries) = &mut entry.entries {
|
||||||
|
filter_entries(entries);
|
||||||
|
!entries.is_empty()
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_directory(data: Vec<Entry>, node: &mut NodeMut<ListNode>, command_dir: &Path) {
|
||||||
|
for entry in data {
|
||||||
|
if [
|
||||||
|
entry.entries.is_some(),
|
||||||
|
entry.command.is_some(),
|
||||||
|
entry.script.is_some(),
|
||||||
|
]
|
||||||
|
.iter()
|
||||||
|
.filter(|&&x| x)
|
||||||
|
.count()
|
||||||
|
> 1
|
||||||
|
{
|
||||||
|
panic!("Entry must have only one data type");
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(entries) = entry.entries {
|
||||||
|
let mut node = node.append(ListNode {
|
||||||
|
name: entry.name,
|
||||||
|
command: Command::None,
|
||||||
|
});
|
||||||
|
create_directory(entries, &mut node, command_dir);
|
||||||
|
} else if let Some(command) = entry.command {
|
||||||
|
node.append(ListNode {
|
||||||
|
name: entry.name,
|
||||||
|
command: Command::Raw(command),
|
||||||
|
});
|
||||||
|
} else if let Some(script) = entry.script {
|
||||||
|
let dir = command_dir.join(script);
|
||||||
|
if !dir.exists() {
|
||||||
|
panic!("Script {} does not exist", dir.display());
|
||||||
|
}
|
||||||
|
node.append(ListNode {
|
||||||
|
name: entry.name,
|
||||||
|
command: Command::LocalFile(dir),
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
panic!("Entry must have data");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl TabList {
|
||||||
|
fn get_tabs(command_dir: &Path) -> Vec<PathBuf> {
|
||||||
|
let tab_files = std::fs::read_to_string(command_dir.join("tabs.toml"))
|
||||||
|
.expect("Failed to read tabs.toml");
|
||||||
|
let data: Self = toml::from_str(&tab_files).expect("Failed to parse tabs.toml");
|
||||||
|
|
||||||
|
data.directories
|
||||||
|
.into_iter()
|
||||||
|
.map(|path| command_dir.join(path).join("tab_data.toml"))
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user