Skip to content

Commit

Permalink
Fix conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
jeevithakannan2 committed Sep 16, 2024
1 parent 6838811 commit c3dfb00
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 26 deletions.
10 changes: 8 additions & 2 deletions core/src/inner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@ pub fn get_tabs(validate: bool) -> Vec<Tab> {
});

let tabs: Vec<Tab> = tabs
.map(|(TabEntry { name, data }, directory)| {
.map(|(TabEntry { name, data, multi_selectable }, 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 }
Tab { name, tree, multi_selectable }
})
.collect();

Expand All @@ -47,6 +47,12 @@ 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)]
Expand Down
1 change: 1 addition & 0 deletions core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pub enum Command {
pub struct Tab {
pub name: String,
pub tree: Tree<ListNode>,
pub multi_selectable: bool,
}

#[derive(Clone, Hash, Eq, PartialEq)]
Expand Down
1 change: 1 addition & 0 deletions tabs/utils/tab_data.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
name = "Utilities"
multi_selectable = false

[[data]]
name = "WiFi Manager"
Expand Down
4 changes: 4 additions & 0 deletions tui/src/hint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,10 @@ pub fn draw_shortcuts(state: &AppState, frame: &mut Frame, area: Rect) {
hints.push(Shortcut::new(vec!["j", "Down"], "Select item below"));
hints.push(Shortcut::new(vec!["t"], "Next theme"));
hints.push(Shortcut::new(vec!["T"], "Previous theme"));
if state.is_current_tab_multi_selectable() {
hints.push(Shortcut::new(vec!["v"], "Toggle multi-selection mode"));
hints.push(Shortcut::new(vec!["Space"], "Select multiple commands"));
}
ShortcutList {
scope_name: "Item list",
hints,
Expand Down
32 changes: 19 additions & 13 deletions tui/src/running_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,25 +136,31 @@ impl FloatContent for RunningCommand {
}

impl RunningCommand {
pub fn new(command: Command) -> Self {
pub fn new(commands: Vec<Command>) -> Self {
let pty_system = NativePtySystem::default();

// Build the command based on the provided Command enum variant
let mut cmd = CommandBuilder::new("sh");
match command {
Command::Raw(prompt) => {
cmd.arg("-c");
cmd.arg(prompt);
}
Command::LocalFile(file) => {
cmd.arg(&file);
if let Some(parent) = file.parent() {
cmd.cwd(parent);
// Create a command to execute all the selected commands
let mut cmd: CommandBuilder = CommandBuilder::new("sh");
cmd.arg("-c");

// Initialize an empty string to hold the merged commands
// All the merged commands are passed as a single argument to reduce the overhead of rebuilding the command arguments for each and every command
let mut script = String::new();
for command in commands {
match command {
Command::Raw(prompt) => script.push_str(&format!("{}\n", prompt)), // Merge raw commands
Command::LocalFile(file) => {
if let Some(parent) = file.parent() {
script.push_str(&format!("cd {}\n", parent.display())); // Merge local file path
}
script.push_str(&format!("sh {}\n", file.display()));
}
Command::None => panic!("Command::None was treated as a command"),
}
Command::None => panic!("Command::None was treated as a command"),
}

cmd.arg(script);

// Open a pseudo-terminal with initial size
let pair = pty_system
.openpty(PtySize {
Expand Down
82 changes: 71 additions & 11 deletions tui/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ pub struct AppState {
/// widget
selection: ListState,
filter: Filter,
multi_select: bool, // This keeps track of Multi select toggle
selected_commands: Vec<Command>, // This field is to store selected commands
}

pub enum Focus {
Expand Down Expand Up @@ -60,6 +62,8 @@ impl AppState {
visit_stack: vec![root_id],
selection: ListState::default().with_selected(Some(0)),
filter: Filter::new(),
multi_select: false,
selected_commands: Vec::new(), // Initialize with an empty vector
};
state.update_items();
state
Expand Down Expand Up @@ -154,12 +158,29 @@ impl AppState {
|ListEntry {
node, has_children, ..
}| {
let is_selected = self.selected_commands.contains(&node.command);
let (indicator, style) = if is_selected {
(self.theme.multi_select_icon(), Style::default().bold())
} else {
("", Style::new())
};
if *has_children {
Line::from(format!("{} {}", self.theme.dir_icon(), node.name))
.style(self.theme.dir_color())
Line::from(format!(
"{} {} {}",
self.theme.dir_icon(),
node.name,
indicator
))
.style(self.theme.dir_color())
} else {
Line::from(format!("{} {}", self.theme.cmd_icon(), node.name))
.style(self.theme.cmd_color())
Line::from(format!(
"{} {} {}",
self.theme.cmd_icon(),
node.name,
indicator
))
.style(self.theme.cmd_color())
.patch_style(style)
}
},
));
Expand All @@ -171,11 +192,15 @@ impl AppState {
} else {
Style::new()
})
.block(
Block::default()
.borders(Borders::ALL)
.title(format!("Linux Toolbox - {}", env!("BUILD_DATE"))),
)
.block(Block::default().borders(Borders::ALL).title(format!(
"Linux Toolbox - {} {}",
env!("BUILD_DATE"),
if self.multi_select {
"[Multi-Select]"
} else {
""
}
)))
.scroll_padding(1);
frame.render_stateful_widget(list, chunks[1], &mut self.selection);

Expand Down Expand Up @@ -233,18 +258,47 @@ impl AppState {
KeyCode::Tab => self.focus = Focus::TabList,
KeyCode::Char('t') => self.theme.next(),
KeyCode::Char('T') => self.theme.prev(),
KeyCode::Char('v') | KeyCode::Char('V') => self.toggle_multi_select(),
KeyCode::Char(' ') if self.multi_select => self.toggle_selection(),
_ => {}
},
_ => {}
};
true
}
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();
}
}
}
fn toggle_selection(&mut self) {
if let Some(command) = self.get_selected_command() {
if self.selected_commands.contains(&command) {
self.selected_commands.retain(|c| c != &command);
} else {
self.selected_commands.push(command);
}
}
}
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 ehther the current tree node is the root node (can we go up the tree or no)
/// Returns `true` if we can't go up the tree (we are at the tree root)
Expand Down Expand Up @@ -342,9 +396,15 @@ impl AppState {
}
}
fn handle_enter(&mut self) {
if let Some(cmd) = self.get_selected_command() {
let command = RunningCommand::new(cmd);
if self.selected_commands.is_empty() {
// If no commands are selected, run the currently by pushing them into vector
if let Some(cmd) = self.get_selected_command() {
self.selected_commands.push(cmd);
}

let command = RunningCommand::new(self.selected_commands.clone());
self.spawn_float(command, 80, 80);
self.selected_commands.clear();
} else {
self.go_to_selected_dir();
}
Expand Down
7 changes: 7 additions & 0 deletions tui/src/theme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,13 @@ impl Theme {
}
}

pub fn multi_select_icon(&self) -> &'static str {
match self {
Theme::Default => "",
Theme::Compatible => "*",
}
}

pub fn success_color(&self) -> Color {
match self {
Theme::Default => Color::Rgb(199, 55, 44),
Expand Down

0 comments on commit c3dfb00

Please sign in to comment.