Skip to content

Commit 8ef4168

Browse files
feat: Add automation based on config file
1 parent 79eb752 commit 8ef4168

File tree

5 files changed

+67
-2
lines changed

5 files changed

+67
-2
lines changed

Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tui/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ ego-tree = { workspace = true }
2121
oneshot = "0.1.8"
2222
portable-pty = "0.8.1"
2323
ratatui = "0.28.1"
24+
serde = { version = "1.0.205", features = ["derive"], default-features = false }
25+
toml = { version = "0.8.19", features = ["parse"], default-features = false }
2426
tui-term = "0.1.12"
2527
temp-dir = "0.1.14"
2628
unicode-width = "0.2.0"

tui/src/config.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
use serde::Deserialize;
2+
use std::path::Path;
3+
4+
#[derive(Deserialize)]
5+
pub struct Config {
6+
pub auto_select: Vec<String>,
7+
}
8+
9+
impl Config {
10+
pub fn from_file(path: &Path) -> Result<Self, Box<dyn std::error::Error>> {
11+
let content = std::fs::read_to_string(path)?;
12+
let config: Config = toml::from_str(&content)?;
13+
Ok(config)
14+
}
15+
}

tui/src/main.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
mod config;
12
mod confirmation;
23
mod filter;
34
mod float;
@@ -9,6 +10,7 @@ mod theme;
910

1011
use std::{
1112
io::{self, stdout},
13+
path::PathBuf,
1214
time::Duration,
1315
};
1416

@@ -26,6 +28,11 @@ use state::AppState;
2628
// Linux utility toolbox
2729
#[derive(Debug, Parser)]
2830
struct Args {
31+
#[arg(
32+
long,
33+
help = "Path to the configuration file for automatic command selection"
34+
)]
35+
config: Option<PathBuf>,
2936
#[arg(short, long, value_enum)]
3037
#[arg(default_value_t = Theme::Default)]
3138
#[arg(help = "Set the theme to use in the application")]
@@ -38,7 +45,7 @@ struct Args {
3845
fn main() -> io::Result<()> {
3946
let args = Args::parse();
4047

41-
let mut state = AppState::new(args.theme, args.override_validation);
48+
let mut state = AppState::new(args.theme, args.override_validation, args.config);
4249

4350
stdout().execute(EnterAlternateScreen)?;
4451
enable_raw_mode()?;

tui/src/state.rs

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::config::Config;
12
use crate::{
23
confirmation::{ConfirmPrompt, ConfirmStatus},
34
filter::{Filter, SearchAction},
@@ -19,6 +20,7 @@ use ratatui::{
1920
widgets::{Block, Borders, List, ListState, Paragraph},
2021
Frame,
2122
};
23+
use std::path::PathBuf;
2224
use std::rc::Rc;
2325
use temp_dir::TempDir;
2426

@@ -60,6 +62,7 @@ pub struct AppState {
6062
multi_select: bool,
6163
selected_commands: Vec<Rc<ListNode>>,
6264
drawable: bool,
65+
auto_select: Option<Vec<String>>,
6366
#[cfg(feature = "tips")]
6467
tip: &'static str,
6568
}
@@ -79,10 +82,16 @@ pub struct ListEntry {
7982
}
8083

8184
impl AppState {
82-
pub fn new(theme: Theme, override_validation: bool) -> Self {
85+
pub fn new(theme: Theme, override_validation: bool, config_path: Option<PathBuf>) -> Self {
8386
let (temp_dir, tabs) = linutil_core::get_tabs(!override_validation);
8487
let root_id = tabs[0].tree.root().id();
8588

89+
let auto_select = config_path.and_then(|path| {
90+
Config::from_file(&path)
91+
.map(|config| config.auto_select)
92+
.ok()
93+
});
94+
8695
let mut state = Self {
8796
_temp_dir: temp_dir,
8897
theme,
@@ -95,14 +104,44 @@ impl AppState {
95104
multi_select: false,
96105
selected_commands: Vec::new(),
97106
drawable: false,
107+
auto_select,
98108
#[cfg(feature = "tips")]
99109
tip: get_random_tip(),
100110
};
101111

102112
state.update_items();
113+
114+
if let Some(auto_select) = state.auto_select.clone() {
115+
state.handle_initial_auto_select(&auto_select);
116+
}
117+
103118
state
104119
}
105120

121+
fn handle_initial_auto_select(&mut self, auto_select: &[String]) {
122+
let item_list = self.filter.item_list();
123+
self.selected_commands = auto_select
124+
.iter()
125+
.filter_map(|name| {
126+
item_list
127+
.iter()
128+
.find(|item| item.node.name == *name)
129+
.map(|item| item.node.clone())
130+
})
131+
.collect();
132+
133+
if !self.selected_commands.is_empty() {
134+
let cmd_names = self
135+
.selected_commands
136+
.iter()
137+
.map(|node| node.name.as_str())
138+
.collect::<Vec<_>>();
139+
140+
let prompt = ConfirmPrompt::new(&cmd_names);
141+
self.focus = Focus::ConfirmationPrompt(Float::new(Box::new(prompt), 40, 40));
142+
}
143+
}
144+
106145
fn get_list_item_shortcut(&self) -> Box<[Shortcut]> {
107146
if self.selected_item_is_dir() {
108147
Box::new([Shortcut::new("Go to selected dir", ["l", "Right", "Enter"])])

0 commit comments

Comments
 (0)