Merge branch 'main' into zed

This commit is contained in:
Jeevitha Kannan K S 2024-11-11 22:14:28 +05:30
commit bfa9ea3bd7
No known key found for this signature in database
GPG Key ID: 5904C34A2F7CE333
23 changed files with 403 additions and 263 deletions

View File

@ -6,6 +6,10 @@ on:
- '**/*.sh' - '**/*.sh'
workflow_dispatch: workflow_dispatch:
permissions:
contents: read
pull-requests: write
jobs: jobs:
shellcheck: shellcheck:
name: Shellcheck name: Shellcheck

134
Cargo.lock generated
View File

@ -37,60 +37,16 @@ checksum = "67555e1f1ece39d737e28c8a017721287753af3f93225e4a445b29ccb0f5912c"
dependencies = [ dependencies = [
"nom", "nom",
"ratatui", "ratatui",
"simdutf8",
"smallvec", "smallvec",
"thiserror", "thiserror",
] ]
[[package]]
name = "anstream"
version = "0.6.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"is_terminal_polyfill",
"utf8parse",
]
[[package]] [[package]]
name = "anstyle" name = "anstyle"
version = "1.0.8" version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1"
[[package]]
name = "anstyle-parse"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a"
dependencies = [
"windows-sys",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8"
dependencies = [
"anstyle",
"windows-sys",
]
[[package]] [[package]]
name = "anyhow" name = "anyhow"
version = "1.0.88" version = "1.0.88"
@ -157,6 +113,12 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "cfg_aliases"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
[[package]] [[package]]
name = "clap" name = "clap"
version = "4.5.20" version = "4.5.20"
@ -173,10 +135,8 @@ version = "4.5.20"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54"
dependencies = [ dependencies = [
"anstream",
"anstyle", "anstyle",
"clap_lex", "clap_lex",
"strsim",
] ]
[[package]] [[package]]
@ -197,12 +157,6 @@ version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97"
[[package]]
name = "colorchoice"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0"
[[package]] [[package]]
name = "compact_str" name = "compact_str"
version = "0.8.0" version = "0.8.0"
@ -317,6 +271,12 @@ dependencies = [
"allocator-api2", "allocator-api2",
] ]
[[package]]
name = "hashbrown"
version = "0.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3"
[[package]] [[package]]
name = "heck" name = "heck"
version = "0.5.0" version = "0.5.0"
@ -359,12 +319,12 @@ dependencies = [
[[package]] [[package]]
name = "indexmap" name = "indexmap"
version = "2.5.0" version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da"
dependencies = [ dependencies = [
"equivalent", "equivalent",
"hashbrown", "hashbrown 0.15.1",
] ]
[[package]] [[package]]
@ -392,12 +352,6 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "is_terminal_polyfill"
version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
[[package]] [[package]]
name = "itertools" name = "itertools"
version = "0.13.0" version = "0.13.0"
@ -445,6 +399,7 @@ dependencies = [
"anstyle", "anstyle",
"clap", "clap",
"linutil_core", "linutil_core",
"nix 0.29.0",
"oneshot", "oneshot",
"portable-pty", "portable-pty",
"rand", "rand",
@ -487,7 +442,7 @@ version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37ee39891760e7d94734f6f63fedc29a2e4a152f836120753a72503f09fcf904" checksum = "37ee39891760e7d94734f6f63fedc29a2e4a152f836120753a72503f09fcf904"
dependencies = [ dependencies = [
"hashbrown", "hashbrown 0.14.5",
] ]
[[package]] [[package]]
@ -538,6 +493,18 @@ dependencies = [
"pin-utils", "pin-utils",
] ]
[[package]]
name = "nix"
version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46"
dependencies = [
"bitflags 2.6.0",
"cfg-if",
"cfg_aliases",
"libc",
]
[[package]] [[package]]
name = "nom" name = "nom"
version = "7.1.3" version = "7.1.3"
@ -623,7 +590,7 @@ dependencies = [
"lazy_static", "lazy_static",
"libc", "libc",
"log", "log",
"nix", "nix 0.25.1",
"serial", "serial",
"shared_library", "shared_library",
"shell-words", "shell-words",
@ -717,9 +684,9 @@ dependencies = [
[[package]] [[package]]
name = "redox_syscall" name = "redox_syscall"
version = "0.5.4" version = "0.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0884ad60e090bf1345b93da0a5de8923c93884cd03f40dfcfddd3b4bee661853" checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f"
dependencies = [ dependencies = [
"bitflags 2.6.0", "bitflags 2.6.0",
] ]
@ -907,24 +874,12 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "simdutf8"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a"
[[package]] [[package]]
name = "smallvec" name = "smallvec"
version = "1.13.2" version = "1.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
[[package]]
name = "smawk"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c"
[[package]] [[package]]
name = "static_assertions" name = "static_assertions"
version = "1.1.0" version = "1.1.0"
@ -937,12 +892,6 @@ version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b2231b7c3057d5e4ad0156fb3dc807d900806020c5ffa3ee6ff2c8c76fb8520" checksum = "2b2231b7c3057d5e4ad0156fb3dc807d900806020c5ffa3ee6ff2c8c76fb8520"
[[package]]
name = "strsim"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]] [[package]]
name = "strum" name = "strum"
version = "0.26.3" version = "0.26.3"
@ -996,11 +945,6 @@ name = "textwrap"
version = "0.16.1" version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9"
dependencies = [
"smawk",
"unicode-linebreak",
"unicode-width 0.1.14",
]
[[package]] [[package]]
name = "thiserror" name = "thiserror"
@ -1078,9 +1022,9 @@ dependencies = [
[[package]] [[package]]
name = "toml_edit" name = "toml_edit"
version = "0.22.20" version = "0.22.22"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5"
dependencies = [ dependencies = [
"indexmap", "indexmap",
"serde", "serde",
@ -1147,12 +1091,6 @@ version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
[[package]]
name = "unicode-linebreak"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f"
[[package]] [[package]]
name = "unicode-segmentation" name = "unicode-segmentation"
version = "1.11.0" version = "1.11.0"
@ -1341,9 +1279,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]] [[package]]
name = "winnow" name = "winnow"
version = "0.6.18" version = "0.6.20"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b"
dependencies = [ dependencies = [
"memchr", "memchr",
] ]

View File

@ -24,13 +24,16 @@ curl -fsSL https://christitus.com/linux | sh
```bash ```bash
curl -fsSL https://christitus.com/linuxdev | sh curl -fsSL https://christitus.com/linuxdev | sh
``` ```
<details>
<summary>CLI arguments</summary> ### CLI arguments
Linutil supports various command-line arguments to customize its behavior. Here are some common arguments you can use: Linutil supports various command-line arguments to customize its behavior. Here are some common arguments you can use:
- `-t, --theme <THEME>` : Set the theme to use in the application [default: default] [possible values: default, compatible]. - `-c, --config <CONFIG>` : Path to the configuration file.
- `--override-validation` : Show all available options, disregarding compatibility checks (UNSAFE). - `--override-validation` : Show all available options, disregarding compatibility checks (UNSAFE).
- `--size-bypass` : Bypass the terminal size limit.
- `-y, --skip-confirmation` : Skip confirmation prompt before executing commands.
- `-t, --theme <THEME>` : Set the theme to use in the application [default: `default`] [possible values: `default`, `compatible`].
- `-h, --help` : Print help. - `-h, --help` : Print help.
For more detailed usage, run: For more detailed usage, run:
@ -42,7 +45,6 @@ curl -fsSL https://christitus.com/linux | sh -s -- --help
```bash ```bash
linutil --help linutil --help
``` ```
</details>
## ⬇️ Installation ## ⬇️ Installation

View File

@ -0,0 +1,111 @@
#!/bin/sh -e
. ../common-script.sh
installAutoCpufreq() {
clear
AUTO_CPUFREQ_PATH="$HOME/.local/share/auto-cpufreq"
if ! command_exists auto-cpufreq; then
printf "%b\n" "${YELLOW}Installing auto-cpufreq.${RC}"
if ! command_exists git && [ "$PACKAGER" != "pacman" ]; then
printf "%b\n" "${YELLOW}Installing git.${RC}"
case "$PACKAGER" in
*)
"$ESCALATION_TOOL" "$PACKAGER" install -y git
;;
esac
fi
case "$PACKAGER" in
pacman)
if command_exists powerprofilesctl; then
printf "%b\n" "${YELLOW}Disabling powerprofilesctl service.${RC}"
"$ESCALATION_TOOL" systemctl disable --now power-profiles-daemon
fi
"$AUR_HELPER" -S --needed --noconfirm auto-cpufreq
"$ESCALATION_TOOL" systemctl enable --now auto-cpufreq
;;
*)
mkdir -p "$HOME/.local/share"
if [ -d "$AUTO_CPUFREQ_PATH" ]; then
rm -rf "$AUTO_CPUFREQ_PATH"
fi
printf "%b\n" "${YELLOW}Cloning auto-cpufreq repository.${RC}"
git clone --depth=1 https://github.com/AdnanHodzic/auto-cpufreq.git "$AUTO_CPUFREQ_PATH"
cd "$AUTO_CPUFREQ_PATH"
printf "%b\n" "${YELLOW}Running auto-cpufreq installer.${RC}"
"$ESCALATION_TOOL" ./auto-cpufreq-installer
"$ESCALATION_TOOL" auto-cpufreq --install
;;
esac
else
printf "%b\n" "${GREEN}auto-cpufreq is already installed.${RC}"
fi
}
applyTweak() {
printf "%b\n" "${YELLOW}Configuring auto-cpufreq.${RC}"
if command_exists auto-cpufreq; then
if ls /sys/class/power_supply/BAT* >/dev/null 2>&1; then
printf "%b\n" "${GREEN}System detected as laptop. Updating auto-cpufreq for laptop.${RC}"
"$ESCALATION_TOOL" auto-cpufreq --force powersave
else
printf "%b\n" "${GREEN}System detected as desktop. Updating auto-cpufreq for desktop.${RC}"
"$ESCALATION_TOOL" auto-cpufreq --force performance
fi
else
printf "%b\n" "${RED}auto-cpufreq is not installed.${RC}"
exit 1
fi
}
removeTweak() {
if command_exists auto-cpufreq; then
printf "%b\n" "${YELLOW}Removing auto-cpufreq tweak.${RC}"
"$ESCALATION_TOOL" auto-cpufreq --force reset
else
printf "%b\n" "${RED}auto-cpufreq is not installed.${RC}"
exit 1
fi
}
main() {
printf "%b\n" "${YELLOW}Do you want to apply the auto-cpufreq tweak or remove it?${RC}"
printf "%b\n" "${YELLOW}1) Apply tweak${RC}"
printf "%b\n" "${YELLOW}2) Remove tweak${RC}"
printf "%b\n" "${YELLOW}3) Exit${RC}"
printf "%b" "Enter your choice [1/3]: "
read -r choice
case "$choice" in
1)
applyTweak
;;
2)
removeTweak
;;
3)
printf "%b\n" "${GREEN}Exiting.${RC}"
exit 0
;;
*)
printf "%b\n" "${RED}Invalid choice. Exiting.${RC}"
exit 1
;;
esac
printf "%b\n" "${GREEN}auto-cpufreq setup complete.${RC}"
}
checkEnv
checkEscalationTool
installAutoCpufreq
main

View File

@ -25,7 +25,12 @@ installBrave() {
;; ;;
dnf) dnf)
"$ESCALATION_TOOL" "$PACKAGER" install -y dnf-plugins-core "$ESCALATION_TOOL" "$PACKAGER" install -y dnf-plugins-core
dnf_version=$(dnf --version | head -n 1 | cut -d '.' -f 1)
if [ "$dnf_version" -eq 4 ]; then
"$ESCALATION_TOOL" "$PACKAGER" config-manager --add-repo https://brave-browser-rpm-release.s3.brave.com/brave-browser.repo "$ESCALATION_TOOL" "$PACKAGER" config-manager --add-repo https://brave-browser-rpm-release.s3.brave.com/brave-browser.repo
else
"$ESCALATION_TOOL" "$PACKAGER" config-manager addrepo --from-repofile=https://brave-browser-rpm-release.s3.brave.com/brave-browser.repo
fi
"$ESCALATION_TOOL" rpm --import https://brave-browser-rpm-release.s3.brave.com/brave-core.asc "$ESCALATION_TOOL" rpm --import https://brave-browser-rpm-release.s3.brave.com/brave-core.asc
"$ESCALATION_TOOL" "$PACKAGER" install -y brave-browser "$ESCALATION_TOOL" "$PACKAGER" install -y brave-browser
;; ;;

View File

@ -15,7 +15,12 @@ installVivaldi() {
;; ;;
dnf) dnf)
"$ESCALATION_TOOL" "$PACKAGER" install -y dnf-plugins-core "$ESCALATION_TOOL" "$PACKAGER" install -y dnf-plugins-core
dnf_version=$(dnf --version | head -n 1 | cut -d '.' -f 1)
if [ "$dnf_version" -eq 4 ]; then
"$ESCALATION_TOOL" "$PACKAGER" config-manager --add-repo https://repo.vivaldi.com/stable/vivaldi-fedora.repo "$ESCALATION_TOOL" "$PACKAGER" config-manager --add-repo https://repo.vivaldi.com/stable/vivaldi-fedora.repo
else
"$ESCALATION_TOOL" "$PACKAGER" config-manager addrepo --from-repofile=https://repo.vivaldi.com/stable/vivaldi-fedora.repo
fi
"$ESCALATION_TOOL" "$PACKAGER" install -y vivaldi-stable "$ESCALATION_TOOL" "$PACKAGER" install -y vivaldi-stable
;; ;;
zypper) zypper)

View File

@ -4,8 +4,17 @@
installNgrok() { installNgrok() {
if ! command_exists ngrok; then if ! command_exists ngrok; then
printf "%b\n" "${YELLOW}Installing Ngrok...${RC}" printf "%b\n" "${YELLOW}Installing Ngrok.${RC}"
curl -sSLO https://bin.equinox.io/c/bNyj1mQVY4c/ngrok-v3-stable-linux-amd64.tgz | "$ESCALATION_TOOL" tar -xz -C /usr/local/bin case "$ARCH" in
x86_64)
url="https://bin.equinox.io/c/bNyj1mQVY4c/ngrok-v3-stable-linux-amd64.tgz"
;;
aarch64)
url="https://bin.equinox.io/c/bNyj1mQVY4c/ngrok-v3-stable-linux-arm64.tgz"
;;
esac
curl -sSL "$url" -o ngrok.tgz
"$ESCALATION_TOOL" tar -xzf ngrok.tgz -C /usr/local/bin
else else
printf "%b\n" "${GREEN}Ngrok is already installed.${RC}" printf "%b\n" "${GREEN}Ngrok is already installed.${RC}"
fi fi

View File

@ -23,7 +23,12 @@ installSublime() {
;; ;;
dnf) dnf)
"$ESCALATION_TOOL" rpm -v --import https://download.sublimetext.com/sublimehq-rpm-pub.gpg "$ESCALATION_TOOL" rpm -v --import https://download.sublimetext.com/sublimehq-rpm-pub.gpg
"$ESCALATION_TOOL" "$PACKAGER" config-manager --add-repo https://download.sublimetext.com/rpm/stable/x86_64/sublime-text.repo dnf_version=$(dnf --version | head -n 1 | cut -d '.' -f 1)
if [ "$dnf_version" -eq 4 ]; then
"$ESCALATION_TOOL" "$PACKAGER" config-manager --add-repo https://download.sublimetext.com/rpm/dev/x86_64/sublime-text.repo
else
"$ESCALATION_TOOL" "$PACKAGER" config-manager addrepo --from-repofile=https://download.sublimetext.com/rpm/dev/x86_64/sublime-text.repo
fi
"$ESCALATION_TOOL" "$PACKAGER" install -y sublime-text "$ESCALATION_TOOL" "$PACKAGER" install -y sublime-text
;; ;;
*) *)

View File

@ -28,7 +28,12 @@ install_docker() {
;; ;;
dnf) dnf)
"$ESCALATION_TOOL" "$PACKAGER" -y install dnf-plugins-core "$ESCALATION_TOOL" "$PACKAGER" -y install dnf-plugins-core
dnf_version=$(dnf --version | head -n 1 | cut -d '.' -f 1)
if [ "$dnf_version" -eq 4 ]; then
"$ESCALATION_TOOL" "$PACKAGER" config-manager --add-repo https://download.docker.com/linux/fedora/docker-ce.repo "$ESCALATION_TOOL" "$PACKAGER" config-manager --add-repo https://download.docker.com/linux/fedora/docker-ce.repo
else
"$ESCALATION_TOOL" "$PACKAGER" config-manager addrepo --from-repofile=https://download.docker.com/linux/fedora/docker-ce.repo
fi
"$ESCALATION_TOOL" "$PACKAGER" -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin "$ESCALATION_TOOL" "$PACKAGER" -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin
"$ESCALATION_TOOL" systemctl enable --now docker "$ESCALATION_TOOL" systemctl enable --now docker
;; ;;
@ -58,7 +63,12 @@ install_docker_compose() {
;; ;;
dnf) dnf)
"$ESCALATION_TOOL" "$PACKAGER" -y install dnf-plugins-core "$ESCALATION_TOOL" "$PACKAGER" -y install dnf-plugins-core
dnf_version=$(dnf --version | head -n 1 | cut -d '.' -f 1)
if [ "$dnf_version" -eq 4 ]; then
"$ESCALATION_TOOL" "$PACKAGER" config-manager --add-repo https://download.docker.com/linux/fedora/docker-ce.repo "$ESCALATION_TOOL" "$PACKAGER" config-manager --add-repo https://download.docker.com/linux/fedora/docker-ce.repo
else
"$ESCALATION_TOOL" "$PACKAGER" config-manager addrepo --from-repofile=https://download.docker.com/linux/fedora/docker-ce.repo
fi
"$ESCALATION_TOOL" "$PACKAGER" install -y docker-compose-plugin "$ESCALATION_TOOL" "$PACKAGER" install -y docker-compose-plugin
;; ;;
zypper) zypper)

View File

@ -233,6 +233,12 @@ description = "Universal Android Debloater (UAD) is a tool designed to help user
script = "android-debloat.sh" script = "android-debloat.sh"
task_list = "I" task_list = "I"
[[data]]
name = "Auto CPU Frequency"
description = "Automatic CPU speed & power optimizer.\nhttps://github.com/AdnanHodzic/auto-cpufreq"
script = "auto-cpufreq.sh"
task_list = "I SS"
[[data]] [[data]]
name = "Bash Prompt" name = "Bash Prompt"
description = "The .bashrc file is a script that runs every time a new terminal session is started in Unix-like operating systems. It is used to configure the shell session, set up aliases, define functions, and more, making the terminal easier to use and more powerful. This command configures the key sections and functionalities defined in the .bashrc file from CTT's mybash repository. https://github.com/ChrisTitusTech/mybash" description = "The .bashrc file is a script that runs every time a new terminal session is started in Unix-like operating systems. It is used to configure the shell session, set up aliases, define functions, and more, making the terminal easier to use and more powerful. This command configures the key sections and functionalities defined in the .bashrc file from CTT's mybash repository. https://github.com/ChrisTitusTech/mybash"

View File

@ -3,7 +3,7 @@
. ../common-script.sh . ../common-script.sh
checkGpu() { checkGpu() {
if lspci | grep -i nvidia > /dev/null; then if lspci | grep -i nvidia >/dev/null; then
printf "%b\n" "${RED}Waydroid is not compatible with NVIDIA GPUs.${RC}" printf "%b\n" "${RED}Waydroid is not compatible with NVIDIA GPUs.${RC}"
exit 1 exit 1
fi fi
@ -15,24 +15,27 @@ installWaydroid() {
case "$PACKAGER" in case "$PACKAGER" in
pacman) pacman)
"$AUR_HELPER" -S --needed --noconfirm waydroid "$AUR_HELPER" -S --needed --noconfirm waydroid
if ! command_exists dkms; then if ! command_exists dkms; then
"$ESCALATION_TOOL" "$PACKAGER" -S --needed --noconfirm dkms
fi
installed_kernels=$("$PACKAGER" -Q | grep -E '^linux(| |-rt|-rt-lts|-hardened|-zen|-lts)[^-headers]' | cut -d ' ' -f 1) installed_kernels=$("$PACKAGER" -Q | grep -E '^linux(| |-rt|-rt-lts|-hardened|-zen|-lts)[^-headers]' | cut -d ' ' -f 1)
for kernel in $installed_kernels; do for kernel in $installed_kernels; do
header="${kernel}-headers" header="${kernel}-headers"
printf "%b\n" "${CYAN}Installing headers for $kernel...${RC}" printf "%b\n" "${CYAN}Installing headers for $kernel...${RC}"
"$ESCALATION_TOOL" "$PACKAGER" -S --needed --noconfirm "$header" "$ESCALATION_TOOL" "$PACKAGER" -S --needed --noconfirm "$header"
done done
"$ESCALATION_TOOL" "$PACKAGER" -S --needed --noconfirm dkms
fi
"$AUR_HELPER" -S --needed --noconfirm binder_linux-dkms "$AUR_HELPER" -S --needed --noconfirm binder_linux-dkms
"$ESCALATION_TOOL" modprobe binder-linux device=binder,hwbinder,vndbinder "$ESCALATION_TOOL" modprobe binder-linux device=binder,hwbinder,vndbinder
;; ;;
apt-get|nala) apt-get | nala)
curl https://repo.waydro.id | "$ESCALATION_TOOL" sh curl https://repo.waydro.id | "$ESCALATION_TOOL" sh
"$ESCALATION_TOOL" "$PACKAGER" install -y waydroid "$ESCALATION_TOOL" "$PACKAGER" install -y waydroid
if command_exists dkms; then if command_exists dkms; then
"$ESCALATION_TOOL" "$PACKAGER" install -y git "$ESCALATION_TOOL" "$PACKAGER" install -y git
mkdir -p "$HOME/.local/share/" # only create it if it doesnt exist mkdir -p "$HOME/.local/share/"
git clone https://github.com/choff/anbox-modules.git "$HOME/.local/share/anbox-modules" git clone https://github.com/choff/anbox-modules.git "$HOME/.local/share/anbox-modules"
cd "$HOME/.local/share/anbox-modules" cd "$HOME/.local/share/anbox-modules"
"$ESCALATION_TOOL" cp anbox.conf /etc/modules-load.d/ "$ESCALATION_TOOL" cp anbox.conf /etc/modules-load.d/
@ -47,7 +50,7 @@ installWaydroid() {
"$ESCALATION_TOOL" "$PACKAGER" install -y waydroid "$ESCALATION_TOOL" "$PACKAGER" install -y waydroid
if command_exists dkms; then if command_exists dkms; then
"$ESCALATION_TOOL" "$PACKAGER" install -y git "$ESCALATION_TOOL" "$PACKAGER" install -y git
mkdir -p "$HOME/.local/share/" # only create it if it doesnt exist mkdir -p "$HOME/.local/share/"
git clone https://github.com/choff/anbox-modules.git "$HOME/.local/share/anbox-modules" git clone https://github.com/choff/anbox-modules.git "$HOME/.local/share/anbox-modules"
cd "$HOME/.local/share/anbox-modules" cd "$HOME/.local/share/anbox-modules"
"$ESCALATION_TOOL" cp anbox.conf /etc/modules-load.d/ "$ESCALATION_TOOL" cp anbox.conf /etc/modules-load.d/

View File

@ -86,6 +86,13 @@ checkAURHelper() {
checkEscalationTool() { checkEscalationTool() {
## Check for escalation tools. ## Check for escalation tools.
if [ -z "$ESCALATION_TOOL_CHECKED" ]; then if [ -z "$ESCALATION_TOOL_CHECKED" ]; then
if [ "$(id -u)" = "0" ]; then
ESCALATION_TOOL="eval"
ESCALATION_TOOL_CHECKED=true
printf "%b\n" "${CYAN}Running as root, no escalation needed${RC}"
return 0
fi
ESCALATION_TOOLS='sudo doas' ESCALATION_TOOLS='sudo doas'
for tool in ${ESCALATION_TOOLS}; do for tool in ${ESCALATION_TOOLS}; do
if command_exists "${tool}"; then if command_exists "${tool}"; then

View File

@ -1,101 +0,0 @@
#!/bin/sh -e
. ../common-script.sh
installAutoCpufreq() {
clear
printf "%b\n" "${YELLOW}Checking if auto-cpufreq is already installed...${RC}"
# Check if auto-cpufreq is already installed
if command_exists auto-cpufreq; then
printf "%b\n" "${GREEN}auto-cpufreq is already installed.${RC}"
else
printf "%b\n" "${YELLOW}Installing auto-cpufreq...${RC}"
# Install git if not already installed
if ! command_exists git; then
printf "%b\n" "${YELLOW}git not found. Installing git...${RC}"
case "$PACKAGER" in
pacman)
"$ESCALATION_TOOL" "$PACKAGER" -S --needed --noconfirm git
;;
apk)
"$ESCALATION_TOOL" "$PACKAGER" add git
;;
*)
"$ESCALATION_TOOL" "$PACKAGER" install -y git
;;
esac
fi
# Clone the auto-cpufreq repository and run the installer
if [ ! -d "auto-cpufreq" ]; then
printf "%b\n" "${YELLOW}Cloning auto-cpufreq repository...${RC}"
git clone https://github.com/AdnanHodzic/auto-cpufreq.git
fi
cd auto-cpufreq
printf "%b\n" "${YELLOW}Running auto-cpufreq installer...${RC}"
"$ESCALATION_TOOL" ./auto-cpufreq-installer
"$ESCALATION_TOOL" auto-cpufreq --install
cd ..
fi
}
configureAutoCpufreq() {
printf "%b\n" "${YELLOW}Configuring auto-cpufreq...${RC}"
if command_exists auto-cpufreq; then
# Check if the system has a battery to determine if it's a laptop
if ls /sys/class/power_supply/BAT* >/dev/null 2>&1; then
printf "%b\n" "${GREEN}System detected as laptop. Updating auto-cpufreq for laptop...${RC}"
"$ESCALATION_TOOL" auto-cpufreq --force powersave
else
printf "%b\n" "${GREEN}System detected as desktop. Updating auto-cpufreq for desktop...${RC}"
"$ESCALATION_TOOL" auto-cpufreq --force performance
fi
else
printf "%b\n" "${RED}auto-cpufreq is not installed, skipping configuration.${RC}"
fi
}
removeAutoCpufreqTweak() {
printf "%b\n" "${YELLOW}Removing auto-cpufreq tweak...${RC}"
if command_exists auto-cpufreq; then
printf "%b\n" "${YELLOW}Resetting auto-cpufreq configuration...${RC}"
"$ESCALATION_TOOL" auto-cpufreq --force reset
else
printf "%b\n" "${RED}auto-cpufreq is not installed, skipping removal.${RC}"
fi
}
apply_or_remove_auto_cpufreq() {
# Prompt user for action
printf "%b\n" "${YELLOW}Do you want to apply the auto-cpufreq tweak or remove it?${RC}"
printf "%b\n" "${YELLOW}1) Apply tweak${RC}"
printf "%b\n" "${YELLOW}2) Remove tweak${RC}"
printf "%b" "Enter your choice [1/2]: "
read -r choice
case $choice in
1)
configureAutoCpufreq
;;
2)
removeAutoCpufreqTweak
;;
*)
printf "%b\n" "${RED}Invalid choice. Exiting.${RC}"
exit 1
;;
esac
printf "%b\n" "${GREEN}auto-cpufreq setup complete.${RC}"
}
checkEnv
checkEscalationTool
installAutoCpufreq
apply_or_remove_auto_cpufreq

View File

@ -127,11 +127,6 @@ name = "Auto Login"
script = "auto-login.sh" script = "auto-login.sh"
task_list = "DE setup" task_list = "DE setup"
[[data]]
name = "Auto Power Profiling"
script = "power-profile.sh"
task_list = "I"
[[data]] [[data]]
name = "Bluetooth Manager" name = "Bluetooth Manager"
description = "This utility is designed to manage bluetooth in your system" description = "This utility is designed to manage bluetooth in your system"

View File

@ -1,5 +1,5 @@
.\" manpage for Linutil .\" manpage for Linutil
.TH "linutil" "1" "October 2024" "" "Linutil Manual" .TH "linutil" "1" "November 2024" "Linutil 2024.10.31" "Linutil Manual"
.SH NAME .SH NAME
linutil \- Chris Titus Tech's Linux Toolbox linutil \- Chris Titus Tech's Linux Toolbox
@ -26,6 +26,18 @@ curl -fsSL https://christitus.com/linuxdev | sh
\fB\-c\fR, \fB\-\-config\fR \fI<path>\fR \fB\-c\fR, \fB\-\-config\fR \fI<path>\fR
Path to the configuration file. Path to the configuration file.
.TP
\fB\-\-override\-validation\fR
Show all available entries, disregarding compatibility checks (\fBUNSAFE\fR).
.TP
\fB\-\-size\-bypass\fR
Bypass the terminal size limit.
.TP
\fB\-y\fR, \fB\-\-skip\-confirmation\fR
Skip confirmation prompt before executing commands.
.TP .TP
\fB\-t\fR, \fB\-\-theme\fR \fI<theme>\fR \fB\-t\fR, \fB\-\-theme\fR \fI<theme>\fR
Set the theme to use in the TUI. Set the theme to use in the TUI.
@ -36,18 +48,6 @@ Possible values:
.br .br
Defaults to \fIdefault\fR. Defaults to \fIdefault\fR.
.TP
\fB\-y\fR, \fB\-\-skip\-confirmation\fR
Skip confirmation prompt before executing commands.
.TP
\fB\-\-override\-validation\fR
Show all available entries, disregarding compatibility checks. (\fBUNSAFE\fR)
.TP
\fB\-\-size\-bypass\fR
Bypass the terminal size limit
.TP .TP
\fB\-h\fR, \fB\-\-help\fR \fB\-h\fR, \fB\-\-help\fR
Print help. Print help.

View File

@ -14,22 +14,23 @@ default = ["tips"]
tips = ["rand"] tips = ["rand"]
[dependencies] [dependencies]
clap = { version = "4.5.20", features = ["derive"] } clap = { version = "4.5.20", features = ["derive", "std"], default-features = false }
oneshot = "0.1.8" oneshot = { version = "0.1.8", features = ["std"], default-features = false }
portable-pty = "0.8.1" portable-pty = "0.8.1"
ratatui = "0.29.0" ratatui = { version = "0.29.0", features = ["crossterm"], default-features = false }
tui-term = "0.2.0" tui-term = "0.2.0"
temp-dir = "0.1.14" temp-dir = "0.1.14"
time = { version = "0.3.36", features = ["local-offset", "macros", "formatting"] } time = { version = "0.3.36", features = ["formatting", "local-offset", "macros"], default-features = false }
unicode-width = "0.2.0" unicode-width = { version = "0.2.0", default-features = false }
rand = { version = "0.8.5", optional = true } rand = { version = "0.8.5", optional = true }
linutil_core = { path = "../core", version = "24.9.28" } linutil_core = { version = "24.9.28", path = "../core" }
tree-sitter-highlight = "0.24.3" tree-sitter-highlight = "0.24.3"
tree-sitter-bash = "0.23.1" tree-sitter-bash = "0.23.1"
textwrap = "0.16.1" textwrap = { version = "0.16.1", default-features = false }
anstyle = "1.0.8" anstyle = { version = "1.0.8", default-features = false }
ansi-to-tui = "7.0.0" ansi-to-tui = { version = "7.0.0", default-features = false }
zips = "0.1.7" zips = "0.1.7"
nix = { version = "0.29.0", features = [ "user" ] }
[[bin]] [[bin]]
name = "linutil" name = "linutil"

View File

@ -3,7 +3,7 @@ use std::borrow::Cow;
use crate::{float::FloatContent, hint::Shortcut}; use crate::{float::FloatContent, hint::Shortcut};
use ratatui::{ use ratatui::{
crossterm::event::{KeyCode, KeyEvent}, crossterm::event::{KeyCode, KeyEvent, MouseEvent, MouseEventKind},
layout::Alignment, layout::Alignment,
prelude::*, prelude::*,
widgets::{Block, Borders, Clear, List}, widgets::{Block, Borders, Clear, List},
@ -85,6 +85,19 @@ impl FloatContent for ConfirmPrompt {
frame.render_widget(List::new(paths_text), inner_area); frame.render_widget(List::new(paths_text), inner_area);
} }
fn handle_mouse_event(&mut self, event: &MouseEvent) -> bool {
match event.kind {
MouseEventKind::ScrollDown => {
self.scroll_down();
}
MouseEventKind::ScrollUp => {
self.scroll_up();
}
_ => {}
}
false
}
fn handle_key_event(&mut self, key: &KeyEvent) -> bool { fn handle_key_event(&mut self, key: &KeyEvent) -> bool {
use KeyCode::*; use KeyCode::*;
self.status = match key.code { self.status = match key.code {

View File

@ -1,5 +1,5 @@
use ratatui::{ use ratatui::{
crossterm::event::{KeyCode, KeyEvent}, crossterm::event::{KeyCode, KeyEvent, MouseEvent},
layout::{Constraint, Direction, Layout, Rect}, layout::{Constraint, Direction, Layout, Rect},
Frame, Frame,
}; };
@ -9,6 +9,7 @@ use crate::hint::Shortcut;
pub trait FloatContent { pub trait FloatContent {
fn draw(&mut self, frame: &mut Frame, area: Rect); fn draw(&mut self, frame: &mut Frame, area: Rect);
fn handle_key_event(&mut self, key: &KeyEvent) -> bool; fn handle_key_event(&mut self, key: &KeyEvent) -> bool;
fn handle_mouse_event(&mut self, key: &MouseEvent) -> bool;
fn is_finished(&self) -> bool; fn is_finished(&self) -> bool;
fn get_shortcut_list(&self) -> (&str, Box<[Shortcut]>); fn get_shortcut_list(&self) -> (&str, Box<[Shortcut]>);
} }
@ -53,6 +54,10 @@ impl<Content: FloatContent + ?Sized> Float<Content> {
self.content.draw(frame, popup_area); self.content.draw(frame, popup_area);
} }
pub fn handle_mouse_event(&mut self, event: &MouseEvent) {
self.content.handle_mouse_event(event);
}
// Returns true if the floating window is finished. // Returns true if the floating window is finished.
pub fn handle_key_event(&mut self, key: &KeyEvent) -> bool { pub fn handle_key_event(&mut self, key: &KeyEvent) -> bool {
match key.code { match key.code {

View File

@ -9,7 +9,7 @@ use crate::{float::FloatContent, hint::Shortcut};
use linutil_core::Command; use linutil_core::Command;
use ratatui::{ use ratatui::{
crossterm::event::{KeyCode, KeyEvent}, crossterm::event::{KeyCode, KeyEvent, MouseEvent, MouseEventKind},
layout::Rect, layout::Rect,
style::{Style, Stylize}, style::{Style, Stylize},
text::Line, text::Line,
@ -283,6 +283,17 @@ impl FloatContent for FloatingText {
frame.render_widget(list, inner_area); frame.render_widget(list, inner_area);
} }
fn handle_mouse_event(&mut self, event: &MouseEvent) -> bool {
match event.kind {
MouseEventKind::ScrollDown => self.scroll_down(),
MouseEventKind::ScrollUp => self.scroll_up(),
MouseEventKind::ScrollLeft => self.scroll_left(),
MouseEventKind::ScrollRight => self.scroll_right(),
_ => {}
}
false
}
fn handle_key_event(&mut self, key: &KeyEvent) -> bool { fn handle_key_event(&mut self, key: &KeyEvent) -> bool {
use KeyCode::*; use KeyCode::*;
match key.code { match key.code {

View File

@ -3,6 +3,7 @@ mod filter;
mod float; mod float;
mod floating_text; mod floating_text;
mod hint; mod hint;
mod root;
mod running_command; mod running_command;
pub mod state; pub mod state;
mod theme; mod theme;
@ -19,7 +20,7 @@ use clap::Parser;
use ratatui::{ use ratatui::{
backend::CrosstermBackend, backend::CrosstermBackend,
crossterm::{ crossterm::{
event::{self, DisableMouseCapture, Event, KeyEventKind}, event::{self, DisableMouseCapture, EnableMouseCapture, Event, KeyEventKind},
style::ResetColor, style::ResetColor,
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}, terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
ExecutableCommand, ExecutableCommand,
@ -63,6 +64,8 @@ fn main() -> io::Result<()> {
); );
stdout().execute(EnterAlternateScreen)?; stdout().execute(EnterAlternateScreen)?;
stdout().execute(EnableMouseCapture)?;
enable_raw_mode()?; enable_raw_mode()?;
let mut terminal = Terminal::new(CrosstermBackend::new(stdout()))?; let mut terminal = Terminal::new(CrosstermBackend::new(stdout()))?;
terminal.clear()?; terminal.clear()?;
@ -92,8 +95,8 @@ fn run(
// It's guaranteed that the `read()` won't block when the `poll()` // It's guaranteed that the `read()` won't block when the `poll()`
// function returns `true` // function returns `true`
if let Event::Key(key) = event::read()? { match event::read()? {
// We are only interested in Press and Repeat events Event::Key(key) => {
if key.kind != KeyEventKind::Press && key.kind != KeyEventKind::Repeat { if key.kind != KeyEventKind::Press && key.kind != KeyEventKind::Repeat {
continue; continue;
} }
@ -102,5 +105,12 @@ fn run(
return Ok(()); return Ok(());
} }
} }
Event::Mouse(mouse_event) => {
if !state.handle_mouse(&mouse_event) {
return Ok(());
}
}
_ => {}
}
} }
} }

17
tui/src/root.rs Normal file
View File

@ -0,0 +1,17 @@
use crate::floating_text::FloatingText;
#[cfg(unix)]
use nix::unistd::Uid;
const ROOT_WARNING: &str = "WARNING: You are running this utility as root!\n
This means you have full system access and commands can potentially damage your system if used incorrectly.\n
Please proceed with caution and make sure you understand what each script does before executing it.";
#[cfg(unix)]
pub fn check_root_status() -> Option<FloatingText> {
(Uid::effective().is_root()).then_some(FloatingText::new(
ROOT_WARNING.into(),
"Root User Warning",
true,
))
}

View File

@ -5,7 +5,7 @@ use portable_pty::{
ChildKiller, CommandBuilder, ExitStatus, MasterPty, NativePtySystem, PtySize, PtySystem, ChildKiller, CommandBuilder, ExitStatus, MasterPty, NativePtySystem, PtySize, PtySystem,
}; };
use ratatui::{ use ratatui::{
crossterm::event::{KeyCode, KeyEvent, KeyModifiers}, crossterm::event::{KeyCode, KeyEvent, KeyModifiers, MouseEvent, MouseEventKind},
layout::{Rect, Size}, layout::{Rect, Size},
style::{Color, Style, Stylize}, style::{Color, Style, Stylize},
text::{Line, Span}, text::{Line, Span},
@ -104,6 +104,18 @@ impl FloatContent for RunningCommand {
frame.render_widget(pseudo_term, area); frame.render_widget(pseudo_term, area);
} }
fn handle_mouse_event(&mut self, event: &MouseEvent) -> bool {
match event.kind {
MouseEventKind::ScrollUp => {
self.scroll_offset = self.scroll_offset.saturating_add(1);
}
MouseEventKind::ScrollDown => {
self.scroll_offset = self.scroll_offset.saturating_sub(1);
}
_ => {}
}
true
}
/// Handle key events of the running command "window". Returns true when the "window" should be /// Handle key events of the running command "window". Returns true when the "window" should be
/// closed /// closed
fn handle_key_event(&mut self, key: &KeyEvent) -> bool { fn handle_key_event(&mut self, key: &KeyEvent) -> bool {

View File

@ -4,6 +4,7 @@ use crate::{
float::{Float, FloatContent}, float::{Float, FloatContent},
floating_text::FloatingText, floating_text::FloatingText,
hint::{create_shortcut_list, Shortcut}, hint::{create_shortcut_list, Shortcut},
root::check_root_status,
running_command::RunningCommand, running_command::RunningCommand,
theme::Theme, theme::Theme,
}; };
@ -12,8 +13,8 @@ use linutil_core::{ego_tree::NodeId, Config, ListNode, TabList};
#[cfg(feature = "tips")] #[cfg(feature = "tips")]
use rand::Rng; use rand::Rng;
use ratatui::{ use ratatui::{
crossterm::event::{KeyCode, KeyEvent, KeyEventKind, KeyModifiers}, crossterm::event::{KeyCode, KeyEvent, KeyEventKind, KeyModifiers, MouseEvent, MouseEventKind},
layout::{Alignment, Constraint, Direction, Flex, Layout}, layout::{Alignment, Constraint, Direction, Flex, Layout, Position, Rect},
style::{Style, Stylize}, style::{Style, Stylize},
text::{Line, Span, Text}, text::{Line, Span, Text},
widgets::{Block, Borders, List, ListState, Paragraph}, widgets::{Block, Borders, List, ListState, Paragraph},
@ -41,6 +42,8 @@ P* - privileged *
"; ";
pub struct AppState { pub struct AppState {
/// Areas of tabs
areas: Option<Areas>,
/// Selected theme /// Selected theme
theme: Theme, theme: Theme,
/// Currently focused area /// Currently focused area
@ -79,6 +82,11 @@ pub struct ListEntry {
pub has_children: bool, pub has_children: bool,
} }
pub struct Areas {
tab_list: Rect,
list: Rect,
}
enum SelectedItem { enum SelectedItem {
UpDir, UpDir,
Directory, Directory,
@ -100,6 +108,7 @@ impl AppState {
let auto_execute_commands = config_path.map(|path| Config::from_file(&path).auto_execute); let auto_execute_commands = config_path.map(|path| Config::from_file(&path).auto_execute);
let mut state = Self { let mut state = Self {
areas: None,
theme, theme,
focus: Focus::List, focus: Focus::List,
tabs, tabs,
@ -116,6 +125,11 @@ impl AppState {
skip_confirmation, skip_confirmation,
}; };
#[cfg(unix)]
if let Some(root_warning) = check_root_status() {
state.spawn_float(root_warning, 60, 40);
}
state.update_items(); state.update_items();
if let Some(auto_execute_commands) = auto_execute_commands { if let Some(auto_execute_commands) = auto_execute_commands {
state.handle_initial_auto_execute(&auto_execute_commands); state.handle_initial_auto_execute(&auto_execute_commands);
@ -315,6 +329,11 @@ impl AppState {
.split(horizontal[0]); .split(horizontal[0]);
frame.render_widget(label, left_chunks[0]); frame.render_widget(label, left_chunks[0]);
self.areas = Some(Areas {
tab_list: left_chunks[1],
list: horizontal[1],
});
let tabs = self let tabs = self
.tabs .tabs
.iter() .iter()
@ -469,6 +488,59 @@ impl AppState {
frame.render_widget(keybind_para, vertical[1]); frame.render_widget(keybind_para, vertical[1]);
} }
pub fn handle_mouse(&mut self, event: &MouseEvent) -> bool {
if !self.drawable {
return true;
}
if matches!(self.focus, Focus::TabList | Focus::List) {
let position = Position::new(event.column, event.row);
let mouse_in_tab_list = self.areas.as_ref().unwrap().tab_list.contains(position);
let mouse_in_list = self.areas.as_ref().unwrap().list.contains(position);
match event.kind {
MouseEventKind::Moved => {
if mouse_in_list {
self.focus = Focus::List
} else if mouse_in_tab_list {
self.focus = Focus::TabList
}
}
MouseEventKind::ScrollDown => {
if mouse_in_tab_list {
if self.current_tab.selected().unwrap() != self.tabs.len() - 1 {
self.current_tab.select_next();
}
self.refresh_tab();
} else if mouse_in_list {
self.selection.select_next()
}
}
MouseEventKind::ScrollUp => {
if mouse_in_tab_list {
if self.current_tab.selected().unwrap() != 0 {
self.current_tab.select_previous();
}
self.refresh_tab();
} else if mouse_in_list {
self.selection.select_previous()
}
}
_ => {}
}
}
match &mut self.focus {
Focus::FloatingWindow(float) => {
float.content.handle_mouse_event(event);
}
Focus::ConfirmationPrompt(confirm) => {
confirm.content.handle_mouse_event(event);
}
_ => {}
}
true
}
pub fn handle_key(&mut self, key: &KeyEvent) -> bool { pub fn handle_key(&mut self, key: &KeyEvent) -> bool {
// This should be defined first to allow closing // This should be defined first to allow closing
// the application even when not drawable ( If terminal is small ) // the application even when not drawable ( If terminal is small )