mirror of
https://github.com/ChrisTitusTech/linutil.git
synced 2024-11-21 12:59:41 +00:00
Compare commits
10 Commits
fcecbf6e32
...
c4a661ab4e
Author | SHA1 | Date | |
---|---|---|---|
|
c4a661ab4e | ||
|
e3688e9b3d | ||
|
51631a16cb | ||
|
d39ffad527 | ||
|
c0982a787f | ||
|
4f7de594a6 | ||
|
fa2f838b63 | ||
|
fa8bb74527 | ||
|
3796c7abdb | ||
|
8edd12f0b4 |
2
.github/CONTRIBUTING.md
vendored
2
.github/CONTRIBUTING.md
vendored
|
@ -16,6 +16,7 @@ cd linutil
|
|||
```
|
||||
|
||||
## 3. Make your changes
|
||||
|
||||
- **Edit the files you want to change**: Make your changes to the relevant files.
|
||||
- **Test your changes**: Run `cargo run` to test your modifications in a local environment and ensure everything works as expected.
|
||||
|
||||
|
@ -60,6 +61,7 @@ cd linutil
|
|||
## 11. Documentation
|
||||
|
||||
- **Update the documentation**: If your change affects the functionality, please update the relevant documentation files to reflect this.
|
||||
- **Automatic generation**: If you decide to add functionality through a new shell script, make sure to fill out all fields in `tab_data.toml` and run `cargo xtask docgen`.
|
||||
|
||||
## 12. License
|
||||
|
||||
|
|
2
.github/workflows/github-pages.yml
vendored
2
.github/workflows/github-pages.yml
vendored
|
@ -22,7 +22,7 @@ jobs:
|
|||
|
||||
- name: Copy Contributing Guidelines
|
||||
run: |
|
||||
echo "<!-- THIS FILE IS GENERATED AUTOMATICALLY. EDIT .github/CONTRIBUTING.md -->\n\n$(cat .github/CONTRIBUTING.md)" > 'docs/contributing.md'
|
||||
echo -e "<!-- THIS FILE IS GENERATED AUTOMATICALLY. EDIT .github/CONTRIBUTING.md -->\n\n$(cat .github/CONTRIBUTING.md)" > 'docs/contributing.md'
|
||||
|
||||
- uses: stefanzweifel/git-auto-commit-action@v5
|
||||
with:
|
||||
|
|
|
@ -33,30 +33,18 @@ pub fn get_tabs(validate: bool) -> (TempDir, Vec<Tab>) {
|
|||
|
||||
let tabs: Vec<Tab> = tabs
|
||||
.into_iter()
|
||||
.map(
|
||||
|(
|
||||
TabEntry {
|
||||
name,
|
||||
data,
|
||||
multi_selectable,
|
||||
},
|
||||
directory,
|
||||
)| {
|
||||
let mut tree = Tree::new(Rc::new(ListNode {
|
||||
name: "root".to_string(),
|
||||
description: String::new(),
|
||||
command: Command::None,
|
||||
task_list: String::new(),
|
||||
}));
|
||||
let mut root = tree.root_mut();
|
||||
create_directory(data, &mut root, &directory, validate);
|
||||
Tab {
|
||||
name,
|
||||
tree,
|
||||
multi_selectable,
|
||||
}
|
||||
},
|
||||
)
|
||||
.map(|(TabEntry { name, data }, directory)| {
|
||||
let mut tree = Tree::new(Rc::new(ListNode {
|
||||
name: "root".to_string(),
|
||||
description: String::new(),
|
||||
command: Command::None,
|
||||
task_list: String::new(),
|
||||
multi_select: false,
|
||||
}));
|
||||
let mut root = tree.root_mut();
|
||||
create_directory(data, &mut root, &directory, validate, true);
|
||||
Tab { name, tree }
|
||||
})
|
||||
.collect();
|
||||
|
||||
if tabs.is_empty() {
|
||||
|
@ -74,12 +62,6 @@ struct TabList {
|
|||
struct TabEntry {
|
||||
name: String,
|
||||
data: Vec<Entry>,
|
||||
#[serde(default = "default_multi_selectable")]
|
||||
multi_selectable: bool,
|
||||
}
|
||||
|
||||
fn default_multi_selectable() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
|
@ -94,6 +76,12 @@ struct Entry {
|
|||
entry_type: EntryType,
|
||||
#[serde(default)]
|
||||
task_list: String,
|
||||
#[serde(default = "default_true")]
|
||||
multi_select: bool,
|
||||
}
|
||||
|
||||
fn default_true() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
|
@ -174,8 +162,11 @@ fn create_directory(
|
|||
node: &mut NodeMut<Rc<ListNode>>,
|
||||
command_dir: &Path,
|
||||
validate: bool,
|
||||
parent_multi_select: bool,
|
||||
) {
|
||||
for entry in data {
|
||||
let multi_select = parent_multi_select && entry.multi_select;
|
||||
|
||||
match entry.entry_type {
|
||||
EntryType::Entries(entries) => {
|
||||
let mut node = node.append(Rc::new(ListNode {
|
||||
|
@ -183,8 +174,9 @@ fn create_directory(
|
|||
description: entry.description,
|
||||
command: Command::None,
|
||||
task_list: String::new(),
|
||||
multi_select,
|
||||
}));
|
||||
create_directory(entries, &mut node, command_dir, validate);
|
||||
create_directory(entries, &mut node, command_dir, validate, multi_select);
|
||||
}
|
||||
EntryType::Command(command) => {
|
||||
node.append(Rc::new(ListNode {
|
||||
|
@ -192,6 +184,7 @@ fn create_directory(
|
|||
description: entry.description,
|
||||
command: Command::Raw(command),
|
||||
task_list: String::new(),
|
||||
multi_select,
|
||||
}));
|
||||
}
|
||||
EntryType::Script(script) => {
|
||||
|
@ -210,6 +203,7 @@ fn create_directory(
|
|||
file: script,
|
||||
},
|
||||
task_list: entry.task_list,
|
||||
multi_select,
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,6 @@ pub enum Command {
|
|||
pub struct Tab {
|
||||
pub name: String,
|
||||
pub tree: Tree<Rc<ListNode>>,
|
||||
pub multi_selectable: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Hash, Eq, PartialEq)]
|
||||
|
@ -32,4 +31,5 @@ pub struct ListNode {
|
|||
pub description: String,
|
||||
pub command: Command,
|
||||
pub task_list: String,
|
||||
pub multi_select: bool,
|
||||
}
|
||||
|
|
|
@ -35,10 +35,10 @@ installLinutil() {
|
|||
printf "%b\n" "${YELLOW}Installing rustup...${RC}"
|
||||
case "$PACKAGER" in
|
||||
pacman)
|
||||
"$ESCALATION_TOOL" "$PACKAGER" -S --needed --noconfirm rustup
|
||||
"$ESCALATION_TOOL" "$PACKAGER" -S --needed --noconfirm curl rustup man-db
|
||||
;;
|
||||
dnf)
|
||||
"$ESCALATION_TOOL" "$PACKAGER" install -y rustup
|
||||
"$ESCALATION_TOOL" "$PACKAGER" install -y curl rustup man-pages man-db man
|
||||
;;
|
||||
zypper)
|
||||
"$ESCALATION_TOOL" "$PACKAGER" install -n curl gcc make
|
||||
|
@ -54,12 +54,23 @@ installLinutil() {
|
|||
rustup default stable
|
||||
cargo install --force linutil_tui
|
||||
printf "%b\n" "${GREEN}Installed successfully.${RC}"
|
||||
installExtra
|
||||
;;
|
||||
*) printf "%b\n" "${RED}Linutil not installed.${RC}" ;;
|
||||
esac
|
||||
esac
|
||||
}
|
||||
|
||||
installExtra() {
|
||||
printf "%b\n" "${YELLOW}Installing the manpage...${RC}"
|
||||
"$ESCALATION_TOOL" mkdir -p /usr/share/man/man1
|
||||
curl 'https://raw.githubusercontent.com/ChrisTitusTech/linutil/refs/heads/main/man/linutil.1' | "$ESCALATION_TOOL" tee '/usr/share/man/man1/linutil.1' > /dev/null
|
||||
printf "%b\n" "${YELLOW}Creating a Desktop Entry...${RC}"
|
||||
"$ESCALATION_TOOL" mkdir -p /usr/share/applications
|
||||
curl 'https://raw.githubusercontent.com/ChrisTitusTech/linutil/refs/heads/main/linutil.desktop' | "$ESCALATION_TOOL" tee /usr/share/applications/linutil.desktop > /dev/null
|
||||
printf "%b\n" "${GREEN}Done.${RC}"
|
||||
}
|
||||
|
||||
checkEnv
|
||||
checkEscalationTool
|
||||
checkAURHelper
|
||||
|
|
23
core/tabs/system-setup/system-cleanup.sh
Normal file → Executable file
23
core/tabs/system-setup/system-cleanup.sh
Normal file → Executable file
|
@ -26,16 +26,21 @@ cleanup_system() {
|
|||
"$ESCALATION_TOOL" "$PACKAGER" -Rns $(pacman -Qtdq) --noconfirm > /dev/null 2>&1
|
||||
;;
|
||||
*)
|
||||
printf "%b\n" "${RED}Unsupported package manager: ""$PACKAGER""${RC}"
|
||||
return 1
|
||||
printf "%b\n" "${RED}Unsupported package manager: ${PACKAGER}. Skipping.${RC}"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
common_cleanup() {
|
||||
"$ESCALATION_TOOL" find /var/tmp -type f -atime +5 -delete
|
||||
"$ESCALATION_TOOL" find /tmp -type f -atime +5 -delete
|
||||
"$ESCALATION_TOOL" find /var/log -type f -name "*.log" -exec truncate -s 0 {} \;
|
||||
if [ -d /var/tmp ]; then
|
||||
"$ESCALATION_TOOL" find /var/tmp -type f -atime +5 -delete
|
||||
fi
|
||||
if [ -d /tmp ]; then
|
||||
"$ESCALATION_TOOL" find /tmp -type f -atime +5 -delete
|
||||
fi
|
||||
if [ -d /var/log ]; then
|
||||
"$ESCALATION_TOOL" find /var/log -type f -name "*.log" -exec truncate -s 0 {} \;
|
||||
fi
|
||||
"$ESCALATION_TOOL" journalctl --vacuum-time=3d
|
||||
}
|
||||
|
||||
|
@ -45,8 +50,12 @@ clean_data() {
|
|||
case $clean_response in
|
||||
y|Y)
|
||||
printf "%b\n" "${YELLOW}Cleaning up old cache files and emptying trash...${RC}"
|
||||
find "$HOME/.cache/" -type f -atime +5 -delete
|
||||
find "$HOME/.local/share/Trash" -mindepth 1 -delete
|
||||
if [ -d "$HOME/.cache" ]; then
|
||||
find "$HOME/.cache/" -type f -atime +5 -delete
|
||||
fi
|
||||
if [ -d "$HOME/.local/share/Trash" ]; then
|
||||
find "$HOME/.local/share/Trash" -mindepth 1 -delete
|
||||
fi
|
||||
printf "%b\n" "${GREEN}Cache and trash cleanup completed.${RC}"
|
||||
;;
|
||||
*)
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
name = "System Setup"
|
||||
multi_selectable = false
|
||||
|
||||
[[data]]
|
||||
name = "Arch Linux"
|
||||
|
@ -14,6 +13,7 @@ name = "Arch Server Setup"
|
|||
description = "This command installs a minimal arch server setup under 5 minutes."
|
||||
script = "arch/server-setup.sh"
|
||||
task_list = "SI D"
|
||||
multi_select = false
|
||||
|
||||
[[data.entries]]
|
||||
name = "Paru AUR Helper"
|
||||
|
@ -76,12 +76,14 @@ name = "Full System Cleanup"
|
|||
description = "This script is designed to remove unnecessary packages, clean old cache files, remove temporary files, and to empty the trash."
|
||||
script = "system-cleanup.sh"
|
||||
task_list = "RP PFM"
|
||||
multi_select = false
|
||||
|
||||
[[data]]
|
||||
name = "Full System Update"
|
||||
description = "This command updates your system to the latest packages available for your distro"
|
||||
script = "system-update.sh"
|
||||
task_list = "PFM"
|
||||
multi_select = false
|
||||
|
||||
[[data]]
|
||||
name = "Gaming Dependencies"
|
||||
|
|
|
@ -13,7 +13,7 @@ change_orientation() {
|
|||
printf "%b\n" "${YELLOW}=========================================${RC}"
|
||||
printf "%b\n" "${YELLOW} Change Monitor Orientation${RC}"
|
||||
printf "%b\n" "${YELLOW}=========================================${RC}"
|
||||
printf "%b" "${YELLOW}Choose a monitor to configure: ${RC}"
|
||||
printf "%b\n" "${YELLOW}Choose a monitor to configure: ${RC}"
|
||||
i=1
|
||||
for monitor in $monitor_array; do
|
||||
printf "%b\n" "$i. ${GREEN}$monitor${RC}"
|
||||
|
|
|
@ -13,7 +13,7 @@ disable_monitor() {
|
|||
printf "%b\n" "${YELLOW}=========================================${RC}"
|
||||
printf "%b\n" "${YELLOW} Disable Monitor${RC}"
|
||||
printf "%b\n" "${YELLOW}=========================================${RC}"
|
||||
printf "%b" "Choose a monitor to disable: "
|
||||
printf "%b\n" "Choose a monitor to disable: "
|
||||
i=1
|
||||
for monitor in $monitor_array; do
|
||||
printf "%b\n" "$i. ${GREEN}$monitor${RC}"
|
||||
|
|
|
@ -13,7 +13,7 @@ enable_monitor() {
|
|||
printf "%b\n" "${YELLOW}=========================================${RC}"
|
||||
printf "%b\n" "${YELLOW} Enable Monitor${RC}"
|
||||
printf "%b\n" "${YELLOW}=========================================${RC}"
|
||||
printf "%b" "${YELLOW}Choose a monitor to enable: ${RC}"
|
||||
printf "%b\n" "${YELLOW}Choose a monitor to enable: ${RC}"
|
||||
|
||||
i=1
|
||||
for monitor in $monitor_array; do
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/sh -e
|
||||
|
||||
. ./utility_functions.sh
|
||||
. ../utility_functions.sh
|
||||
|
||||
. ../../common-script.sh
|
||||
|
||||
|
|
|
@ -13,10 +13,10 @@ manage_arrangement() {
|
|||
printf "%b\n" "${YELLOW}=========================================${RC}"
|
||||
printf "%b\n" "${YELLOW} Manage Monitor Arrangement${RC}"
|
||||
printf "%b\n" "${YELLOW}=========================================${RC}"
|
||||
printf "%b" "${YELLOW}Choose the monitor to arrange: ${RC}"
|
||||
printf "%b\n" "${YELLOW}Choose the monitor to arrange: ${RC}"
|
||||
i=1
|
||||
for monitor in $monitor_array; do
|
||||
printf "%b\n" "$i. ${YELLOW}$monitor${RC}"
|
||||
printf "%b\n" "$i. ${GREEN}$monitor${RC}"
|
||||
i=$((i + 1))
|
||||
done
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ set_primary_monitor() {
|
|||
printf "%b\n" "${YELLOW}Choose a monitor to set as primary:${RC}"
|
||||
i=1
|
||||
for monitor in $monitor_array; do
|
||||
printf "%b\n" "$i. ${YELLOW}$monitor${RC}"
|
||||
printf "%b\n" "$i. ${GREEN}$monitor${RC}"
|
||||
i=$((i + 1))
|
||||
done
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
name = "Utilities"
|
||||
multi_selectable = false
|
||||
|
||||
[[data]]
|
||||
name = "Monitor Control"
|
||||
multi_select = false
|
||||
|
||||
[[data.preconditions]]
|
||||
matches = true
|
||||
|
@ -78,6 +78,7 @@ script = "monitor-control/set_resolutions.sh"
|
|||
|
||||
[[data]]
|
||||
name = "User Account Manager"
|
||||
multi_select = false
|
||||
|
||||
[[data.entries]]
|
||||
name = "Add User"
|
||||
|
@ -104,6 +105,7 @@ name = "Auto Mount Drive"
|
|||
description = "This utility is designed to help with automating the process of mounting a drive on to your system."
|
||||
script = "auto-mount.sh"
|
||||
task_list = "PFM"
|
||||
multi_select = false
|
||||
|
||||
[[data]]
|
||||
name = "Auto Login"
|
||||
|
@ -120,6 +122,7 @@ name = "Bluetooth Manager"
|
|||
description = "This utility is designed to manage bluetooth in your system"
|
||||
script = "bluetooth-control.sh"
|
||||
task_list = "I SS"
|
||||
multi_select = false
|
||||
|
||||
[[data]]
|
||||
name = "Bootable USB Creator"
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
<!-- THIS FILE IS GENERATED AUTOMATICALLY. EDIT .github/CONTRIBUTING.md -->\n\n# Contributing Guidelines for Linutil
|
||||
<!-- THIS FILE IS GENERATED AUTOMATICALLY. EDIT .github/CONTRIBUTING.md -->
|
||||
|
||||
# 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:
|
||||
|
||||
|
@ -16,6 +18,7 @@ cd linutil
|
|||
```
|
||||
|
||||
## 3. Make your changes
|
||||
|
||||
- **Edit the files you want to change**: Make your changes to the relevant files.
|
||||
- **Test your changes**: Run `cargo run` to test your modifications in a local environment and ensure everything works as expected.
|
||||
|
||||
|
@ -60,6 +63,7 @@ cd linutil
|
|||
## 11. Documentation
|
||||
|
||||
- **Update the documentation**: If your change affects the functionality, please update the relevant documentation files to reflect this.
|
||||
- **Automatic generation**: If you decide to add functionality through a new shell script, make sure to fill out all fields in `tab_data.toml` and run `cargo xtask docgen`.
|
||||
|
||||
## 12. License
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::{state::ListEntry, theme::Theme};
|
||||
use crossterm::event::{KeyCode, KeyEvent};
|
||||
use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
|
||||
use ego_tree::NodeId;
|
||||
use linutil_core::Tab;
|
||||
use ratatui::{
|
||||
|
@ -116,21 +116,27 @@ impl Filter {
|
|||
pub fn handle_key(&mut self, event: &KeyEvent) -> SearchAction {
|
||||
//Insert user input into the search bar
|
||||
match event.code {
|
||||
KeyCode::Char('c') if event.modifiers.contains(KeyModifiers::CONTROL) => {
|
||||
return self.exit_search()
|
||||
}
|
||||
KeyCode::Char(c) => self.insert_char(c),
|
||||
KeyCode::Backspace => self.remove_previous(),
|
||||
KeyCode::Delete => self.remove_next(),
|
||||
KeyCode::Left => return self.cursor_left(),
|
||||
KeyCode::Right => return self.cursor_right(),
|
||||
KeyCode::Esc => {
|
||||
self.input_position = 0;
|
||||
self.search_input.clear();
|
||||
return SearchAction::Exit;
|
||||
}
|
||||
KeyCode::Enter => return SearchAction::Exit,
|
||||
KeyCode::Esc => return self.exit_search(),
|
||||
_ => return SearchAction::None,
|
||||
};
|
||||
SearchAction::Update
|
||||
}
|
||||
|
||||
fn exit_search(&mut self) -> SearchAction {
|
||||
self.input_position = 0;
|
||||
self.search_input.clear();
|
||||
SearchAction::Exit
|
||||
}
|
||||
|
||||
fn cursor_left(&mut self) -> SearchAction {
|
||||
self.input_position = self.input_position.saturating_sub(1);
|
||||
SearchAction::None
|
||||
|
|
|
@ -119,7 +119,10 @@ impl AppState {
|
|||
match self.focus {
|
||||
Focus::Search => (
|
||||
"Search bar",
|
||||
Box::new([Shortcut::new("Finish search", ["Enter"])]),
|
||||
Box::new([
|
||||
Shortcut::new("Abort search", ["Esc", "CTRL-c"]),
|
||||
Shortcut::new("Search", ["Enter"]),
|
||||
]),
|
||||
),
|
||||
|
||||
Focus::List => {
|
||||
|
@ -143,12 +146,10 @@ impl AppState {
|
|||
hints.push(Shortcut::new("Select item below", ["j", "Down"]));
|
||||
hints.push(Shortcut::new("Next theme", ["t"]));
|
||||
hints.push(Shortcut::new("Previous theme", ["T"]));
|
||||
|
||||
if self.is_current_tab_multi_selectable() {
|
||||
hints.push(Shortcut::new("Toggle multi-selection mode", ["v"]));
|
||||
hints.push(Shortcut::new("Multi-selection mode", ["v"]));
|
||||
if self.multi_select {
|
||||
hints.push(Shortcut::new("Select multiple commands", ["Space"]));
|
||||
}
|
||||
|
||||
hints.push(Shortcut::new("Next tab", ["Tab"]));
|
||||
hints.push(Shortcut::new("Previous tab", ["Shift-Tab"]));
|
||||
hints.push(Shortcut::new("Important actions guide", ["g"]));
|
||||
|
@ -320,7 +321,12 @@ impl AppState {
|
|||
let (indicator, style) = if is_selected {
|
||||
(self.theme.multi_select_icon(), Style::default().bold())
|
||||
} else {
|
||||
("", Style::new())
|
||||
let ms_style = if self.multi_select && !node.multi_select {
|
||||
Style::default().fg(self.theme.multi_select_disabled_color())
|
||||
} else {
|
||||
Style::new()
|
||||
};
|
||||
("", ms_style)
|
||||
};
|
||||
if *has_children {
|
||||
Line::from(format!(
|
||||
|
@ -330,6 +336,7 @@ impl AppState {
|
|||
indicator
|
||||
))
|
||||
.style(self.theme.dir_color())
|
||||
.patch_style(style)
|
||||
} else {
|
||||
Line::from(format!(
|
||||
"{} {} {}",
|
||||
|
@ -347,13 +354,21 @@ impl AppState {
|
|||
|ListEntry {
|
||||
node, has_children, ..
|
||||
}| {
|
||||
let ms_style = if self.multi_select && !node.multi_select {
|
||||
Style::default().fg(self.theme.multi_select_disabled_color())
|
||||
} else {
|
||||
Style::new()
|
||||
};
|
||||
if *has_children {
|
||||
Line::from(" ").style(self.theme.dir_color())
|
||||
Line::from(" ")
|
||||
.style(self.theme.dir_color())
|
||||
.patch_style(ms_style)
|
||||
} else {
|
||||
Line::from(format!("{} ", node.task_list))
|
||||
.alignment(Alignment::Right)
|
||||
.style(self.theme.cmd_color())
|
||||
.bold()
|
||||
.patch_style(ms_style)
|
||||
}
|
||||
},
|
||||
));
|
||||
|
@ -465,6 +480,13 @@ impl AppState {
|
|||
// enabled, need to clear it to prevent state corruption
|
||||
if !self.multi_select {
|
||||
self.selected_commands.clear()
|
||||
} else {
|
||||
// Prevents non multi_selectable cmd from being pushed into the selected list
|
||||
if let Some(node) = self.get_selected_node() {
|
||||
if !node.multi_select {
|
||||
self.selected_commands.retain(|cmd| cmd.name != node.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ConfirmStatus::Confirm => self.handle_confirm_command(),
|
||||
|
@ -522,41 +544,30 @@ impl AppState {
|
|||
}
|
||||
|
||||
fn toggle_multi_select(&mut self) {
|
||||
if self.is_current_tab_multi_selectable() {
|
||||
self.multi_select = !self.multi_select;
|
||||
if !self.multi_select {
|
||||
self.selected_commands.clear();
|
||||
}
|
||||
self.multi_select = !self.multi_select;
|
||||
if !self.multi_select {
|
||||
self.selected_commands.clear();
|
||||
}
|
||||
}
|
||||
|
||||
fn toggle_selection(&mut self) {
|
||||
if let Some(command) = self.get_selected_node() {
|
||||
if self.selected_commands.contains(&command) {
|
||||
self.selected_commands.retain(|c| c != &command);
|
||||
} else {
|
||||
self.selected_commands.push(command);
|
||||
if let Some(node) = self.get_selected_node() {
|
||||
if node.multi_select {
|
||||
if self.selected_commands.contains(&node) {
|
||||
self.selected_commands.retain(|c| c != &node);
|
||||
} else {
|
||||
self.selected_commands.push(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_current_tab_multi_selectable(&self) -> bool {
|
||||
let index = self.current_tab.selected().unwrap_or(0);
|
||||
self.tabs
|
||||
.get(index)
|
||||
.map_or(false, |tab| tab.multi_selectable)
|
||||
}
|
||||
|
||||
fn update_items(&mut self) {
|
||||
self.filter.update_items(
|
||||
&self.tabs,
|
||||
self.current_tab.selected().unwrap(),
|
||||
*self.visit_stack.last().unwrap(),
|
||||
);
|
||||
if !self.is_current_tab_multi_selectable() {
|
||||
self.multi_select = false;
|
||||
self.selected_commands.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks either the current tree node is the root node (can we go up the tree or no)
|
||||
|
|
|
@ -28,6 +28,13 @@ impl Theme {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn multi_select_disabled_color(&self) -> Color {
|
||||
match self {
|
||||
Theme::Default => Color::DarkGray,
|
||||
Theme::Compatible => Color::DarkGray,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tab_color(&self) -> Color {
|
||||
match self {
|
||||
Theme::Default => Color::Rgb(255, 255, 85),
|
||||
|
|
Loading…
Reference in New Issue
Block a user