diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..9990317a --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,56 @@ +# Contributing Guidelines for Linutil + +Thank you for considering contributing to Linutil! We appreciate your effort in helping improve this project. To ensure that your contributions align with the goals and quality standards of Linutil, please follow these guidelines: + +## 1. Setting Up Your Development Environment + +1. **Clone the repo**: Start by cloning the Linutil repository to your local machine. + ```bash + git clone https://github.com/christitustech/linutil.git + cd linutil + ``` +2. **Install Rust**: Make sure you have Rust installed on your machine. If you don't, you can install it by following the instructions at [rust-lang.org](https://www.rust-lang.org/tools/install). +3. **Edit the files you want to change**: Make your changes to the relevant files. +4. **Test your changes**: Run `cargo run` to test your modifications in a local environment and ensure everything works as expected. + +## 2. Make Meaningful Changes + +- **Have a clear reason**: Donโ€™t change the way things are done without a valid reason. If you propose an alteration, be prepared to explain why itโ€™s necessary and how it improves the project. +- **Respect existing conventions**: Changes should align with the existing code style, design patterns, and overall project philosophy. If you want to introduce a new way of doing things, justify it clearly. + +## 3. Learn from Past Pull Requests (PRs) + +- **Check merged PRs**: Reviewing merged pull requests can give you an idea of what kind of contributions are accepted and how they are implemented. +- **Study rejected PRs**: This is especially important as it helps you avoid making similar mistakes or proposing changes that have already been considered and declined. + +## 4. Write Clean, Descriptive Commit Messages + +- **Be descriptive**: Your commit messages should clearly describe what the change does and why it was made. +- **Use the imperative mood**: For example, "Add feature X" or "Fix bug in Y", rather than "Added feature X" or "Fixed bug in Y". +- **Keep commits clean**: Avoid committing a change and then immediately following it with a fix for that change. Instead, amend your commit or squash it if needed. + +## 5. Keep Your Pull Requests (PRs) Small and Focused + +- **Make small, targeted PRs**: Focus on one feature or fix per pull request. This makes it easier to review and increases the likelihood of acceptance. +- **Avoid combining unrelated changes**: PRs that tackle multiple unrelated issues are harder to review and might be rejected because of a single problem. + +## 6. Code Review and Feedback + +- **Expect feedback**: PRs will undergo code review. Be open to feedback and willing to make adjustments as needed. +- **Participate in reviews**: If you feel comfortable, review other contributors' PRs as well. Peer review is a great way to learn and ensure high-quality contributions. + +## 7. Contributing Is More Than Just Code + +- **Test the tool**: Running tests and providing feedback on how the tool works in different environments is a valuable contribution. +- **Write well-formed issues**: Clearly describe bugs or problems you encounter, providing as much detail as possible, including steps to reproduce the issue. +- **Propose reasonable feature requests**: When suggesting new features, ensure they fit within the scope, style, and design of the project. Provide clear reasoning and use cases. + +## 8. Documentation + +- **Update the documentation**: If your change affects the functionality, please update the relevant documentation files to reflect this. + +## 9. License + +- **Agree to the license**: By contributing to Linutil, you agree that your contributions will be licensed under the project's MIT license. + +We appreciate your contributions and look forward to collaborating with you to make Linutil better! diff --git a/README.md b/README.md index b3b436fe..a2978c3c 100644 --- a/README.md +++ b/README.md @@ -5,27 +5,34 @@ ![Preview](docs/assets/preview.png) -A distro-agnostic* toolbox which helps with everyday Linux tasks. It can help you set up applications and your system for specific use cases! Written with Rust ๐Ÿฆ€ +**Linutil** is a distro-agnostic toolbox designed to simplify everyday Linux tasks. It helps you set up applications and optimize your system for specific use cases. The utility is actively developed in Rust ๐Ÿฆ€, providing performance and reliability. -\* โ€” The project is in active development, so there could be some issues. Please consider [submitting feedback](https://github.com/ChrisTitusTech/linutil/issues). +*Note:* Since the project is still in active development, you may encounter some issues. Please consider [submitting feedback](https://github.com/ChrisTitusTech/linutil/issues) if you do. ## ๐Ÿ’ก Usage -Open your terminal and paste this command: +To get started, open your terminal and run the following command: ```bash curl -fsSL https://christitus.com/linux | sh ``` +## ๐Ÿ’– Support + +If you find Linutil helpful, please consider giving it a โญ๏ธ to show your support! ## ๐ŸŽ“ Documentation -### [LinUtil Official Documentation](https://christitustech.github.io/linutil/) -## ๐Ÿ’– Support -To morally and mentally support the project, make sure to leave a โญ๏ธ! +For comprehensive information on how to use Linutil, visit the [Linutil Official Documentation](https://christitustech.github.io/linutil/). -## ๐Ÿ… Thanks to all Contributors -Thanks a lot for spending your time helping Linutil grow. Keep rocking ๐Ÿป. +## ๐Ÿ›  Contributing + +We welcome contributions from the community! Before you start, please review our [Contributing Guidelines](CONTRIBUTING.md) to understand how to make the most effective and efficient contributions. + +## ๐Ÿ… Thanks to All Contributors + +Thank you to everyone who has contributed to the development of Linutil. Your efforts are greatly appreciated, and youโ€™re helping make this tool better for everyone! [![Contributors](https://contrib.rocks/image?repo=ChrisTitusTech/linutil)](https://github.com/ChrisTitusTech/linutil/graphs/contributors) -## Credits -Rust Shell written by [@JustLinuxUser](https://github.com/JustLinuxUser) +## ๐Ÿ“œ Credits + +Linutilโ€™s Rust shell was developed by [@JustLinuxUser](https://github.com/JustLinuxUser). diff --git a/build/linutil b/build/linutil index a783b934..99045014 100755 Binary files a/build/linutil and b/build/linutil differ diff --git a/build/linutil-aarch64 b/build/linutil-aarch64 index 1801024b..b08529c9 100755 Binary files a/build/linutil-aarch64 and b/build/linutil-aarch64 differ diff --git a/docs/assets/preview.png b/docs/assets/preview.png index 399ea373..e06e3ecd 100644 Binary files a/docs/assets/preview.png and b/docs/assets/preview.png differ diff --git a/docs/updates.md b/docs/updates.md deleted file mode 100644 index 758fc4bd..00000000 --- a/docs/updates.md +++ /dev/null @@ -1,3 +0,0 @@ -# Update Log - -# \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index 5032786e..11ca622d 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -5,7 +5,6 @@ nav: - Introduction: 'index.md' - User Guide: 'userguide.md' - Contribute: 'contribute.md' - - Updates: 'updates.md' - Known Issues: 'KnownIssues.md' - FAQ: 'faq.md' diff --git a/src/commands/applications-setup/alacritty-setup.sh b/src/commands/applications-setup/alacritty-setup.sh index 69581953..6911fd3c 100755 --- a/src/commands/applications-setup/alacritty-setup.sh +++ b/src/commands/applications-setup/alacritty-setup.sh @@ -7,7 +7,7 @@ setupAlacritty() { if ! command_exists alacritty; then case ${PACKAGER} in pacman) - sudo ${PACKAGER} -S --noconfirm alacritty + sudo ${PACKAGER} -S --needed --noconfirm alacritty ;; *) sudo ${PACKAGER} install -y alacritty diff --git a/src/commands/applications-setup/dwmtitus-setup.sh b/src/commands/applications-setup/dwmtitus-setup.sh index 6421b31e..d8543fc7 100644 --- a/src/commands/applications-setup/dwmtitus-setup.sh +++ b/src/commands/applications-setup/dwmtitus-setup.sh @@ -13,7 +13,7 @@ setupDWM() { echo "Installing DWM-Titus if not already installed" case "$PACKAGER" in # Install pre-Requisites pacman) - sudo "$PACKAGER" -S --noconfirm --needed base-devel libx11 libxinerama libxft imlib2 + sudo "$PACKAGER" -S --needed --noconfirm base-devel libx11 libxinerama libxft imlib2 ;; *) sudo "$PACKAGER" install -y build-essential libx11-dev libxinerama-dev libxft-dev libimlib2-dev diff --git a/src/commands/applications-setup/kitty-setup.sh b/src/commands/applications-setup/kitty-setup.sh index f4a69d12..8088f594 100755 --- a/src/commands/applications-setup/kitty-setup.sh +++ b/src/commands/applications-setup/kitty-setup.sh @@ -7,7 +7,7 @@ setupKitty() { if ! command_exists kitty; then case ${PACKAGER} in pacman) - sudo "${PACKAGER}" -S --noconfirm kitty + sudo "${PACKAGER}" -S --needed --noconfirm kitty ;; *) sudo "${PACKAGER}" install -y kitty diff --git a/src/commands/applications-setup/rofi-setup.sh b/src/commands/applications-setup/rofi-setup.sh index a571c16d..236e42e2 100755 --- a/src/commands/applications-setup/rofi-setup.sh +++ b/src/commands/applications-setup/rofi-setup.sh @@ -7,7 +7,7 @@ setupRofi() { if ! command_exists rofi; then case "$PACKAGER" in pacman) - sudo "$PACKAGER" -S --noconfirm rofi + sudo "$PACKAGER" -S --needed --noconfirm rofi ;; *) sudo "$PACKAGER" install -y rofi diff --git a/src/commands/applications-setup/zsh-setup.sh b/src/commands/applications-setup/zsh-setup.sh index e2ec8fd8..f3e7d0c1 100644 --- a/src/commands/applications-setup/zsh-setup.sh +++ b/src/commands/applications-setup/zsh-setup.sh @@ -8,7 +8,7 @@ install_zsh() { if ! command_exists zsh; then case "$PACKAGER" in pacman) - sudo "$PACKAGER" -Sy --noconfirm zsh + sudo "$PACKAGER" -S --needed --noconfirm zsh ;; *) sudo "$PACKAGER" install -y zsh diff --git a/src/commands/security/firewall-baselines.sh b/src/commands/security/firewall-baselines.sh index 40d24fab..69963083 100644 --- a/src/commands/security/firewall-baselines.sh +++ b/src/commands/security/firewall-baselines.sh @@ -7,7 +7,7 @@ installPkg() { if ! command_exists ufw; then case ${PACKAGER} in pacman) - sudo "${PACKAGER}" -Sy --noconfirm ufw + sudo "${PACKAGER}" -S --needed --noconfirm ufw ;; *) sudo "${PACKAGER}" install -y ufw diff --git a/src/commands/system-setup/1-compile-setup.sh b/src/commands/system-setup/1-compile-setup.sh index b5f3eab7..1130cee1 100755 --- a/src/commands/system-setup/1-compile-setup.sh +++ b/src/commands/system-setup/1-compile-setup.sh @@ -33,13 +33,13 @@ installDepend() { if ! grep -q "^\s*\[multilib\]" /etc/pacman.conf; then echo "[multilib]" | sudo tee -a /etc/pacman.conf echo "Include = /etc/pacman.d/mirrorlist" | sudo tee -a /etc/pacman.conf - sudo "$PACKAGER" -Sy + sudo "$PACKAGER" -Syu else echo "Multilib is already enabled." fi if ! command_exists yay && ! command_exists paru; then echo "Installing yay as AUR helper..." - sudo "$PACKAGER" --noconfirm -S base-devel + sudo "$PACKAGER" -S --needed --noconfirm base-devel cd /opt && sudo git clone https://aur.archlinux.org/yay-git.git && sudo chown -R "$USER":"$USER" ./yay-git cd yay-git && makepkg --noconfirm -si else @@ -53,7 +53,7 @@ installDepend() { echo "No AUR helper found. Please install yay or paru." exit 1 fi - "$AUR_HELPER" --noconfirm -S "$DEPENDENCIES" + "$AUR_HELPER" -S --needed --noconfirm "$DEPENDENCIES" ;; apt-get|nala) COMPILEDEPS='build-essential' diff --git a/src/commands/system-setup/2-gaming-setup.sh b/src/commands/system-setup/2-gaming-setup.sh index 24b706b6..4393b0b0 100755 --- a/src/commands/system-setup/2-gaming-setup.sh +++ b/src/commands/system-setup/2-gaming-setup.sh @@ -9,13 +9,13 @@ installDepend() { if ! grep -q "^\s*\[multilib\]" /etc/pacman.conf; then echo "[multilib]" | sudo tee -a /etc/pacman.conf echo "Include = /etc/pacman.d/mirrorlist" | sudo tee -a /etc/pacman.conf - sudo ${PACKAGER} -Sy + sudo ${PACKAGER} -Syu else echo "Multilib is already enabled." fi if ! command_exists yay && ! command_exists paru; then echo "Installing yay as AUR helper..." - sudo ${PACKAGER} --noconfirm -S base-devel + sudo ${PACKAGER} -S --needed --noconfirm base-devel cd /opt && sudo git clone https://aur.archlinux.org/yay-git.git && sudo chown -R ${USER}:${USER} ./yay-git cd yay-git && makepkg --noconfirm -si else @@ -29,7 +29,7 @@ installDepend() { echo "No AUR helper found. Please install yay or paru." exit 1 fi - ${AUR_HELPER} --noconfirm -S wine giflib lib32-giflib libpng lib32-libpng libldap lib32-libldap gnutls lib32-gnutls \ + ${AUR_HELPER} -S --needed --noconfirm wine giflib lib32-giflib libpng lib32-libpng libldap lib32-libldap gnutls lib32-gnutls \ mpg123 lib32-mpg123 openal lib32-openal v4l-utils lib32-v4l-utils libpulse lib32-libpulse libgpg-error \ lib32-libgpg-error alsa-plugins lib32-alsa-plugins alsa-lib lib32-alsa-lib libjpeg-turbo lib32-libjpeg-turbo \ sqlite lib32-sqlite libxcomposite lib32-libxcomposite libxinerama lib32-libgcrypt libgcrypt lib32-libxinerama \ diff --git a/src/commands/system-setup/3-global-theme.sh b/src/commands/system-setup/3-global-theme.sh index 4d660a37..e255ea76 100644 --- a/src/commands/system-setup/3-global-theme.sh +++ b/src/commands/system-setup/3-global-theme.sh @@ -29,8 +29,7 @@ install_theme_tools() { sudo dnf install -y qt6ct kvantum ;; pacman) - sudo pacman -Sy - sudo pacman --noconfirm -S qt6ct kvantum + sudo pacman -S --needed --noconfirm qt6ct kvantum ;; *) printf "${RED}Unsupported package manager. Please install qt6ct and kvantum manually.${RC}\n" diff --git a/src/commands/system-setup/arch/paru-setup.sh b/src/commands/system-setup/arch/paru-setup.sh new file mode 100644 index 00000000..f0b53ae1 --- /dev/null +++ b/src/commands/system-setup/arch/paru-setup.sh @@ -0,0 +1,25 @@ +#!/bin/sh -e + +. "$(dirname "$0")/../../common-script.sh" + +installDepend() { + case $PACKAGER in + pacman) + if ! command_exists paru; then + echo "Installing paru as AUR helper..." + sudo "$PACKAGER" -S --needed --noconfirm base-devel + cd /opt && sudo git clone https://aur.archlinux.org/paru.git && sudo chown -R "$USER": ./paru + cd paru && makepkg --noconfirm -si + echo "Paru installed" + else + echo "Paru already installed" + fi + ;; + *) + echo "Unsupported package manager: $PACKAGER" + ;; + esac +} + +checkEnv +installDepend \ No newline at end of file diff --git a/src/commands/system-setup/arch/yay-setup.sh b/src/commands/system-setup/arch/yay-setup.sh new file mode 100644 index 00000000..f29ecc3f --- /dev/null +++ b/src/commands/system-setup/arch/yay-setup.sh @@ -0,0 +1,25 @@ +#!/bin/sh -e + +. "$(dirname "$0")/../../common-script.sh" + +installDepend() { + case $PACKAGER in + pacman) + if ! command_exists yay; then + echo "Installing yay as AUR helper..." + sudo "$PACKAGER" -S --needed --noconfirm base-devel + cd /opt && sudo git clone https://aur.archlinux.org/yay-git.git && sudo chown -R "$USER": ./yay-git + cd yay-git && makepkg --noconfirm -si + echo "Yay installed" + else + echo "Aur helper already installed" + fi + ;; + *) + echo "Unsupported package manager: $PACKAGER" + ;; + esac +} + +checkEnv +installDepend \ No newline at end of file diff --git a/src/commands/system-setup/system-update.sh b/src/commands/system-setup/system-update.sh index 7f93e4f7..1277143a 100755 --- a/src/commands/system-setup/system-update.sh +++ b/src/commands/system-setup/system-update.sh @@ -7,7 +7,7 @@ fastUpdate() { pacman) if ! command_exists yay && ! command_exists paru; then echo "Installing yay as AUR helper..." - sudo ${PACKAGER} --noconfirm -S base-devel || { echo -e "${RED}Failed to install base-devel${RC}"; exit 1; } + sudo ${PACKAGER} -S --needed --noconfirm base-devel || { echo -e "${RED}Failed to install base-devel${RC}"; exit 1; } cd /opt && sudo git clone https://aur.archlinux.org/yay-git.git && sudo chown -R ${USER}:${USER} ./yay-git cd yay-git && makepkg --noconfirm -si || { echo -e "${RED}Failed to install yay${RC}"; exit 1; } else @@ -21,7 +21,7 @@ fastUpdate() { echo "No AUR helper found. Please install yay or paru." exit 1 fi - ${AUR_HELPER} --noconfirm -S rate-mirrors-bin + ${AUR_HELPER} -S --needed --noconfirm rate-mirrors-bin if [ -s /etc/pacman.d/mirrorlist ]; then sudo cp /etc/pacman.d/mirrorlist /etc/pacman.d/mirrorlist.bak fi diff --git a/src/commands/utils/bluetooth-control.sh b/src/commands/utils/bluetooth-control.sh index ecfd53ad..e5e02fc6 100644 --- a/src/commands/utils/bluetooth-control.sh +++ b/src/commands/utils/bluetooth-control.sh @@ -75,7 +75,7 @@ prompt_for_mac() { fi # Display devices with numbers - IFS=$'\n' read -rd '' -a device_list <<<"$devices" + IFS=$'\n' read -r -a device_list <<<"$devices" for i in "${!device_list[@]}"; do echo "$((i+1)). ${device_list[$i]}" done @@ -128,4 +128,4 @@ remove_device() { } # Initialize -main_menu \ No newline at end of file +main_menu diff --git a/src/commands/utils/wifi-control.sh b/src/commands/utils/wifi-control.sh index 884ab360..1f80804d 100644 --- a/src/commands/utils/wifi-control.sh +++ b/src/commands/utils/wifi-control.sh @@ -102,7 +102,7 @@ prompt_for_network() { fi # Display networks with numbers - IFS=$'\n' read -rd '' -a network_list <<<"$networks" + IFS=$'\n' read -r -a network_list <<<"$networks" for i in "${!network_list[@]}"; do ssid=$(echo "${network_list[$i]}" | awk -F: '{print $1}') echo "$((i+1)). SSID: $ssid" @@ -166,4 +166,4 @@ remove_network() { } # Initialize -main_menu \ No newline at end of file +main_menu diff --git a/src/search.rs b/src/search.rs new file mode 100644 index 00000000..68827c24 --- /dev/null +++ b/src/search.rs @@ -0,0 +1,81 @@ +use crossterm::event::{KeyCode, KeyEvent}; +use ratatui::{ + layout::Rect, + style::Style, + text::Span, + widgets::{Block, Borders, Paragraph}, + Frame, +}; + +use crate::state::AppState; + +pub struct SearchBar { + search_input: String, + in_search_mode: bool, +} + +impl SearchBar { + pub fn new() -> Self { + SearchBar { + search_input: String::new(), + in_search_mode: false, + } + } + + pub fn activate_search(&mut self) { + self.in_search_mode = true; + } + + pub fn deactivate_search(&mut self) { + self.in_search_mode = false; + } + + pub fn is_search_active(&self) -> bool { + self.in_search_mode + } + + pub fn draw(&self, frame: &mut Frame, area: Rect, state: &AppState) { + //Set the search bar text (If empty use the placeholder) + let display_text = if !self.in_search_mode && self.search_input.is_empty() { + Span::raw("Press / to search") + } else { + Span::raw(&self.search_input) + }; + + //Create the search bar widget + let mut search_bar = Paragraph::new(display_text) + .block(Block::default().borders(Borders::ALL).title("Search")) + .style(Style::default().fg(state.theme.unfocused_color)); + + //Change the color if in search mode + if self.in_search_mode { + search_bar = search_bar + .clone() + .style(Style::default().fg(state.theme.focused_color)); + } + + //Render the search bar (First chunk of the screen) + frame.render_widget(search_bar, area); + } + + pub fn handle_key(&mut self, event: KeyEvent) -> String { + //Insert user input into the search bar + match event.code { + KeyCode::Char(c) => { + self.search_input.push(c); + } + KeyCode::Backspace => { + self.search_input.pop(); + } + KeyCode::Esc => { + self.search_input = String::new(); + self.in_search_mode = false; + } + KeyCode::Enter => { + self.in_search_mode = false; + } + _ => {} + } + self.search_input.clone() + } +} diff --git a/src/theme.rs b/src/theme.rs index 149dbece..0ba0c77d 100644 --- a/src/theme.rs +++ b/src/theme.rs @@ -10,6 +10,8 @@ pub struct Theme { pub tab_icon: &'static str, pub success_color: Color, pub fail_color: Color, + pub focused_color: Color, + pub unfocused_color: Color, } pub const THEMES: [Theme; 2] = [ @@ -22,6 +24,8 @@ pub const THEMES: [Theme; 2] = [ tab_icon: ">> ", success_color: Color::Green, fail_color: Color::Red, + focused_color: Color::LightBlue, + unfocused_color: Color::Gray, }, Theme { dir_color: Color::Blue, @@ -32,5 +36,7 @@ pub const THEMES: [Theme; 2] = [ tab_icon: "๎ช… ", fail_color: Color::Rgb(199, 55, 44), success_color: Color::Rgb(5, 255, 55), + focused_color: Color::LightBlue, + unfocused_color: Color::Gray, }, ];