Skip to content

Commit 6b572b1

Browse files
author
nyx
authored
refactor: misc restructering (#1015)
Changes: Separate cli flags and put them in their own module. Add a rustfmt configuration file for grouping imports into crates (so we dont have to do this manually, and it seems we were already doing it manually so might as well) Use comments to describe cli flags instead of using ugly syntax (they both work the same but one is less ugly and more readable) Add a --mouse flag to enable mouse interaction (mouse interaction is now off by default) Add a --bypass-root flag to disable the annoying popup when you run the utility as root Fix an issue where you can't reach the bottom of the list in a subdir (i also reduced the nesting in those functions as well for readability) Add help feature to clap dependency to enable --help / -h Add usage feature to clap dependency to enable usage example when running with --help / -h Remove CLI arg examples from readme, and add instructions on how to view them on CLI to prevent it from bloating up the readme
1 parent efa6ff9 commit 6b572b1

File tree

10 files changed

+107
-67
lines changed

10 files changed

+107
-67
lines changed

README.md

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,23 +27,16 @@ curl -fsSL https://christitus.com/linuxdev | sh
2727

2828
### CLI arguments
2929

30-
Linutil supports various command-line arguments to customize its behavior. Here are some common arguments you can use:
31-
32-
- `-c, --config <CONFIG>` : Path to the configuration file.
33-
- `--override-validation` : Show all available options, disregarding compatibility checks (UNSAFE).
34-
- `--size-bypass` : Bypass the terminal size limit.
35-
- `-y, --skip-confirmation` : Skip confirmation prompt before executing commands.
36-
- `-t, --theme <THEME>` : Set the theme to use in the application [default: `default`] [possible values: `default`, `compatible`].
37-
- `-h, --help` : Print help.
38-
39-
For more detailed usage, run:
30+
View available options by running:
4031

4132
```bash
42-
curl -fsSL https://christitus.com/linux | sh -s -- --help
33+
linutil --help
4334
```
4435

36+
For installer options:
37+
4538
```bash
46-
linutil --help
39+
curl -fsSL https://christitus.com/linux | sh -s -- --help
4740
```
4841

4942
## ⬇️ Installation
@@ -142,7 +135,7 @@ Docs are now [here](https://github.com/Chris-Titus-Docs/linutil-docs)
142135

143136
## 🏅 Thanks to All Contributors
144137

145-
Thank you to everyone who has contributed to the development of Linutil. Your efforts are greatly appreciated, and youre helping make this tool better for everyone!
138+
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!
146139

147140
[![Contributors](https://contrib.rocks/image?repo=ChrisTitusTech/linutil)](https://github.com/ChrisTitusTech/linutil/graphs/contributors)
148141

core/src/inner.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ enum EntryType {
120120

121121
impl Entry {
122122
fn is_supported(&self) -> bool {
123-
self.preconditions.as_deref().map_or(true, |preconditions| {
123+
self.preconditions.as_deref().is_none_or(|preconditions| {
124124
preconditions.iter().all(
125125
|Precondition {
126126
matches,

rustfmt.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
imports_granularity = "Crate"

tui/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ default = ["tips"]
1414
tips = ["rand"]
1515

1616
[dependencies]
17-
clap = { version = "4.5.20", features = ["derive", "std"], default-features = false }
17+
clap = { version = "4.5.20", features = ["derive", "std", "help", "usage"], default-features = false }
1818
oneshot = { version = "0.1.8", features = ["std"], default-features = false }
1919
portable-pty = "0.8.1"
2020
ratatui = { version = "0.29.0", features = ["crossterm"], default-features = false }

tui/src/cli.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
use crate::theme::Theme;
2+
use clap::Parser;
3+
use std::path::PathBuf;
4+
5+
#[derive(Debug, Parser, Clone)]
6+
pub struct Args {
7+
/// Path to the configuration file
8+
#[arg(short, long)]
9+
pub config: Option<PathBuf>,
10+
11+
/// Set the theme to use in the application
12+
#[arg(short, long, value_enum)]
13+
#[arg(default_value_t = Theme::Default)]
14+
pub theme: Theme,
15+
16+
/// Skip confirmation prompt before executing commands
17+
#[arg(short = 'y', long)]
18+
pub skip_confirmation: bool,
19+
20+
/// Show all available options, disregarding compatibility checks (UNSAFE)
21+
#[arg(short = 'u', long)]
22+
pub override_validation: bool,
23+
24+
/// Bypass the terminal size limit
25+
#[arg(short = 's', long)]
26+
pub size_bypass: bool,
27+
28+
/// Enable mouse interaction
29+
#[arg(short = 'm', long)]
30+
pub mouse: bool,
31+
32+
/// Bypass root user check
33+
#[arg(short = 'r', long)]
34+
pub bypass_root: bool,
35+
}

tui/src/main.rs

Lines changed: 9 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
mod cli;
12
mod confirmation;
23
mod filter;
34
mod float;
@@ -11,7 +12,7 @@ mod theme;
1112
#[cfg(feature = "tips")]
1213
mod tips;
1314

14-
use crate::theme::Theme;
15+
use crate::cli::Args;
1516
use clap::Parser;
1617
use ratatui::{
1718
backend::CrosstermBackend,
@@ -26,40 +27,17 @@ use ratatui::{
2627
use state::AppState;
2728
use std::{
2829
io::{stdout, Result, Stdout},
29-
path::PathBuf,
3030
time::Duration,
3131
};
3232

33-
// Linux utility toolbox
34-
#[derive(Debug, Parser)]
35-
pub struct Args {
36-
#[arg(short, long, help = "Path to the configuration file")]
37-
config: Option<PathBuf>,
38-
#[arg(short, long, value_enum)]
39-
#[arg(default_value_t = Theme::Default)]
40-
#[arg(help = "Set the theme to use in the application")]
41-
theme: Theme,
42-
#[arg(
43-
short = 'y',
44-
long,
45-
help = "Skip confirmation prompt before executing commands"
46-
)]
47-
skip_confirmation: bool,
48-
#[arg(long, default_value_t = false)]
49-
#[clap(help = "Show all available options, disregarding compatibility checks (UNSAFE)")]
50-
override_validation: bool,
51-
#[arg(long, default_value_t = false)]
52-
#[clap(help = "Bypass the terminal size limit")]
53-
size_bypass: bool,
54-
}
55-
5633
fn main() -> Result<()> {
5734
let args = Args::parse();
58-
59-
let mut state = AppState::new(args);
35+
let mut state = AppState::new(args.clone());
6036

6137
stdout().execute(EnterAlternateScreen)?;
62-
stdout().execute(EnableMouseCapture)?;
38+
if args.mouse {
39+
stdout().execute(EnableMouseCapture)?;
40+
}
6341

6442
enable_raw_mode()?;
6543
let mut terminal = Terminal::new(CrosstermBackend::new(stdout()))?;
@@ -70,7 +48,9 @@ fn main() -> Result<()> {
7048
// restore terminal
7149
disable_raw_mode()?;
7250
terminal.backend_mut().execute(LeaveAlternateScreen)?;
73-
terminal.backend_mut().execute(DisableMouseCapture)?;
51+
if args.mouse {
52+
terminal.backend_mut().execute(DisableMouseCapture)?;
53+
}
7454
terminal.backend_mut().execute(ResetColor)?;
7555
terminal.show_cursor()?;
7656

tui/src/root.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,12 @@ This means you have full system access and commands can potentially damage your
88
Please proceed with caution and make sure you understand what each script does before executing it.";
99

1010
#[cfg(unix)]
11-
pub fn check_root_status<'a>() -> Option<FloatingText<'a>> {
12-
(Uid::effective().is_root()).then_some(FloatingText::new(
11+
pub fn check_root_status(bypass_root: bool) -> Option<FloatingText<'static>> {
12+
if bypass_root {
13+
return None;
14+
}
15+
16+
Uid::effective().is_root().then_some(FloatingText::new(
1317
ROOT_WARNING.into(),
1418
"Root User Warning",
1519
true,

tui/src/state.rs

Lines changed: 43 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ pub struct AppState {
6666
tip: &'static str,
6767
size_bypass: bool,
6868
skip_confirmation: bool,
69+
mouse_enabled: bool,
6970
}
7071

7172
pub enum Focus {
@@ -94,8 +95,18 @@ enum SelectedItem {
9495
None,
9596
}
9697

98+
enum ScrollDir {
99+
Up,
100+
Down,
101+
}
102+
97103
impl AppState {
98104
pub fn new(args: Args) -> Self {
105+
#[cfg(unix)]
106+
let root_warning = check_root_status(args.bypass_root);
107+
#[cfg(not(unix))]
108+
let root_warning = None;
109+
99110
let tabs = linutil_core::get_tabs(!args.override_validation);
100111
let root_id = tabs[0].tree.root().id();
101112

@@ -122,10 +133,11 @@ impl AppState {
122133
tip: crate::tips::get_random_tip(),
123134
size_bypass: args.size_bypass,
124135
skip_confirmation: args.skip_confirmation,
136+
mouse_enabled: args.mouse,
125137
};
126138

127139
#[cfg(unix)]
128-
if let Some(root_warning) = check_root_status() {
140+
if let Some(root_warning) = root_warning {
129141
state.spawn_float(root_warning, FLOAT_SIZE, FLOAT_SIZE);
130142
}
131143

@@ -440,6 +452,10 @@ impl AppState {
440452
}
441453

442454
pub fn handle_mouse(&mut self, event: &MouseEvent) -> bool {
455+
if !self.mouse_enabled {
456+
return true;
457+
}
458+
443459
if !self.drawable {
444460
return true;
445461
}
@@ -597,24 +613,35 @@ impl AppState {
597613
true
598614
}
599615

600-
fn scroll_down(&mut self) {
601-
if let Some(selected) = self.selection.selected() {
602-
if selected == self.filter.item_list().len() - 1 {
603-
self.selection.select_first();
604-
} else {
605-
self.selection.select_next();
606-
}
607-
}
616+
fn scroll(&mut self, direction: ScrollDir) {
617+
let Some(selected) = self.selection.selected() else {
618+
return;
619+
};
620+
let list_len = if !self.at_root() {
621+
self.filter.item_list().len() + 1
622+
} else {
623+
self.filter.item_list().len()
624+
};
625+
626+
if list_len == 0 {
627+
return;
628+
};
629+
630+
let next_selection = match direction {
631+
ScrollDir::Up if selected == 0 => list_len - 1,
632+
ScrollDir::Down if selected >= list_len - 1 => 0,
633+
ScrollDir::Up => selected - 1,
634+
ScrollDir::Down => selected + 1,
635+
};
636+
self.selection.select(Some(next_selection));
608637
}
609638

610639
fn scroll_up(&mut self) {
611-
if let Some(selected) = self.selection.selected() {
612-
if selected == 0 {
613-
self.selection.select_last();
614-
} else {
615-
self.selection.select_previous();
616-
}
617-
}
640+
self.scroll(ScrollDir::Up)
641+
}
642+
643+
fn scroll_down(&mut self) {
644+
self.scroll(ScrollDir::Down)
618645
}
619646

620647
fn toggle_multi_select(&mut self) {

xtask/src/docgen.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@ use std::fs;
22

33
use linutil_core::Command;
44

5-
use crate::path;
6-
use crate::DynError;
5+
use crate::{path, DynError};
76

87
pub const USER_GUIDE: &str = "userguide.md";
98

xtask/src/main.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@ use std::{env, error::Error};
66
type DynError = Box<dyn Error>;
77

88
pub mod tasks {
9-
use crate::docgen::USER_GUIDE;
10-
use crate::docgen::{userguide, write};
11-
use crate::DynError;
9+
use crate::{
10+
docgen::{userguide, write, USER_GUIDE},
11+
DynError,
12+
};
1213

1314
pub fn docgen() -> Result<(), DynError> {
1415
write(USER_GUIDE, &userguide()?);

0 commit comments

Comments
 (0)