mirror of
https://github.com/ChrisTitusTech/linutil.git
synced 2024-11-05 21:28:48 +00:00
Added AppState, made theme use AppState
This commit is contained in:
parent
8e8476cda5
commit
bfc8e5ea82
15
src/list.rs
15
src/list.rs
|
@ -1,4 +1,4 @@
|
||||||
use crate::{float::floating_window, theme::*};
|
use crate::{float::floating_window, state::AppState};
|
||||||
use crossterm::event::{KeyCode, KeyEvent, KeyEventKind};
|
use crossterm::event::{KeyCode, KeyEvent, KeyEventKind};
|
||||||
use ego_tree::{tree, NodeId};
|
use ego_tree::{tree, NodeId};
|
||||||
use ratatui::{
|
use ratatui::{
|
||||||
|
@ -130,9 +130,8 @@ impl CustomList {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Draw our custom widget to the frame
|
/// Draw our custom widget to the frame
|
||||||
pub fn draw(&mut self, frame: &mut Frame, area: Rect) {
|
pub fn draw(&mut self, frame: &mut Frame, area: Rect, state: &AppState) {
|
||||||
// Get the last element in the `visit_stack` vec
|
// Get the last element in the `visit_stack` vec
|
||||||
let theme = get_theme();
|
|
||||||
let curr = self
|
let curr = self
|
||||||
.inner_tree
|
.inner_tree
|
||||||
.get(*self.visit_stack.last().unwrap())
|
.get(*self.visit_stack.last().unwrap())
|
||||||
|
@ -143,7 +142,7 @@ impl CustomList {
|
||||||
// to go up the tree
|
// to go up the tree
|
||||||
// icons:
|
// icons:
|
||||||
if !self.at_root() {
|
if !self.at_root() {
|
||||||
items.push(Line::from(format!("{} ..", theme.dir_icon)).style(theme.dir_color));
|
items.push(Line::from(format!("{} ..", state.theme.dir_icon)).style(state.theme.dir_color));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Iterate through all the children
|
// Iterate through all the children
|
||||||
|
@ -152,13 +151,13 @@ impl CustomList {
|
||||||
// it's a directory and will be handled as such
|
// it's a directory and will be handled as such
|
||||||
if node.has_children() {
|
if node.has_children() {
|
||||||
items.push(
|
items.push(
|
||||||
Line::from(format!("{} {}", theme.dir_icon, node.value().name))
|
Line::from(format!("{} {}", state.theme.dir_icon, node.value().name))
|
||||||
.style(theme.dir_color),
|
.style(state.theme.dir_color),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
items.push(
|
items.push(
|
||||||
Line::from(format!("{} {}", theme.cmd_icon, node.value().name))
|
Line::from(format!("{} {}", state.theme.cmd_icon, node.value().name))
|
||||||
.style(theme.cmd_color),
|
.style(state.theme.cmd_color),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
25
src/main.rs
25
src/main.rs
|
@ -1,6 +1,7 @@
|
||||||
mod float;
|
mod float;
|
||||||
mod list;
|
mod list;
|
||||||
mod running_command;
|
mod running_command;
|
||||||
|
pub mod state;
|
||||||
mod theme;
|
mod theme;
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
|
@ -22,7 +23,8 @@ use ratatui::{
|
||||||
Terminal,
|
Terminal,
|
||||||
};
|
};
|
||||||
use running_command::RunningCommand;
|
use running_command::RunningCommand;
|
||||||
use theme::set_theme;
|
use state::AppState;
|
||||||
|
use theme::THEMES;
|
||||||
|
|
||||||
/// This is a binary :), Chris, change this to update the documentation on -h
|
/// This is a binary :), Chris, change this to update the documentation on -h
|
||||||
#[derive(Debug, Parser)]
|
#[derive(Debug, Parser)]
|
||||||
|
@ -34,16 +36,23 @@ struct Args {
|
||||||
|
|
||||||
fn main() -> std::io::Result<()> {
|
fn main() -> std::io::Result<()> {
|
||||||
let args = Args::parse();
|
let args = Args::parse();
|
||||||
if args.compat {
|
|
||||||
set_theme(0);
|
let theme = if args.compat {
|
||||||
}
|
THEMES[0].clone()
|
||||||
|
} else {
|
||||||
|
THEMES[1].clone()
|
||||||
|
};
|
||||||
|
|
||||||
|
let state = AppState {
|
||||||
|
theme,
|
||||||
|
};
|
||||||
|
|
||||||
stdout().execute(EnterAlternateScreen)?;
|
stdout().execute(EnterAlternateScreen)?;
|
||||||
enable_raw_mode()?;
|
enable_raw_mode()?;
|
||||||
let mut terminal = Terminal::new(CrosstermBackend::new(stdout()))?;
|
let mut terminal = Terminal::new(CrosstermBackend::new(stdout()))?;
|
||||||
terminal.clear()?;
|
terminal.clear()?;
|
||||||
|
|
||||||
run(&mut terminal)?;
|
run(&mut terminal, &state)?;
|
||||||
|
|
||||||
// restore terminal
|
// restore terminal
|
||||||
disable_raw_mode()?;
|
disable_raw_mode()?;
|
||||||
|
@ -55,7 +64,7 @@ fn main() -> std::io::Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run<B: Backend>(terminal: &mut Terminal<B>) -> io::Result<()> {
|
fn run<B: Backend>(terminal: &mut Terminal<B>, state: &AppState) -> io::Result<()> {
|
||||||
let mut command_opt: Option<RunningCommand> = None;
|
let mut command_opt: Option<RunningCommand> = None;
|
||||||
|
|
||||||
let mut custom_list = CustomList::new();
|
let mut custom_list = CustomList::new();
|
||||||
|
@ -63,9 +72,9 @@ fn run<B: Backend>(terminal: &mut Terminal<B>) -> io::Result<()> {
|
||||||
// Always redraw
|
// Always redraw
|
||||||
terminal
|
terminal
|
||||||
.draw(|frame| {
|
.draw(|frame| {
|
||||||
custom_list.draw(frame, frame.size());
|
custom_list.draw(frame, frame.size(), state);
|
||||||
if let Some(ref mut command) = &mut command_opt {
|
if let Some(ref mut command) = &mut command_opt {
|
||||||
command.draw(frame);
|
command.draw(frame, state);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
|
@ -11,7 +11,7 @@ use portable_pty::{
|
||||||
};
|
};
|
||||||
use ratatui::{
|
use ratatui::{
|
||||||
layout::Size,
|
layout::Size,
|
||||||
style::{Color, Style, Stylize},
|
style::{Style, Stylize},
|
||||||
text::{Line, Span},
|
text::{Line, Span},
|
||||||
widgets::{Block, Borders},
|
widgets::{Block, Borders},
|
||||||
Frame,
|
Frame,
|
||||||
|
@ -21,7 +21,14 @@ use tui_term::{
|
||||||
widget::PseudoTerminal,
|
widget::PseudoTerminal,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{float::floating_window, theme::get_theme};
|
use crate::{float::floating_window, state::AppState};
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub enum Command {
|
||||||
|
Raw(&'static str),
|
||||||
|
LocalFile(&'static str),
|
||||||
|
None, // Directory
|
||||||
|
}
|
||||||
|
|
||||||
/// This is a struct for storing everything connected to a running command
|
/// This is a struct for storing everything connected to a running command
|
||||||
// Create a new instance on every new command you want to run
|
// Create a new instance on every new command you want to run
|
||||||
|
@ -50,14 +57,22 @@ pub struct RunningCommand {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RunningCommand {
|
impl RunningCommand {
|
||||||
pub fn new(command: &str) -> Self {
|
pub fn new(command: Command, state: &AppState) -> Self {
|
||||||
let pty_system = NativePtySystem::default();
|
let pty_system = NativePtySystem::default();
|
||||||
let mut cmd = CommandBuilder::new("sh");
|
|
||||||
cmd.arg("-c");
|
|
||||||
cmd.arg(command);
|
|
||||||
|
|
||||||
let cwd = std::env::current_dir().unwrap();
|
let mut cmd = CommandBuilder::new("sh");
|
||||||
cmd.cwd(cwd);
|
match command {
|
||||||
|
Command::Raw(prompt) => {
|
||||||
|
cmd.arg("-c");
|
||||||
|
cmd.arg(prompt);
|
||||||
|
}
|
||||||
|
Command::LocalFile(file) => {
|
||||||
|
cmd.arg(file);
|
||||||
|
}
|
||||||
|
Command::None => panic!("Command::None was treated as a command"),
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.cwd(&state.temp_path);
|
||||||
|
|
||||||
let pair = pty_system
|
let pair = pty_system
|
||||||
.openpty(PtySize {
|
.openpty(PtySize {
|
||||||
|
@ -153,59 +168,57 @@ impl RunningCommand {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw(&mut self, frame: &mut Frame) {
|
pub fn draw(&mut self, frame: &mut Frame, state: &AppState) {
|
||||||
{
|
// Funny name
|
||||||
let theme = get_theme();
|
let floater = floating_window(frame.size());
|
||||||
// Funny name
|
|
||||||
let floater = floating_window(frame.size());
|
|
||||||
|
|
||||||
let inner_size = Size {
|
let inner_size = Size {
|
||||||
width: floater.width - 2, // Because we add a `Block` with a border
|
width: floater.width - 2, // Because we add a `Block` with a border
|
||||||
height: floater.height - 2,
|
height: floater.height - 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
// When the command is running
|
// When the command is running
|
||||||
let term_border = if !self.is_finished() {
|
let term_border = if !self.is_finished() {
|
||||||
Block::default()
|
Block::default()
|
||||||
.borders(Borders::ALL)
|
.borders(Borders::ALL)
|
||||||
.title_top(Line::from("Running the command....").centered())
|
.title_top(Line::from("Running the command....").centered())
|
||||||
.title_style(Style::default().reversed())
|
.title_style(Style::default().reversed())
|
||||||
.title_bottom(Line::from("Press Ctrl-C to KILL the command"))
|
.title_bottom(Line::from("Press Ctrl-C to KILL the command"))
|
||||||
} else {
|
} else {
|
||||||
// This portion is just for pretty colors.
|
// This portion is just for pretty colors.
|
||||||
// You can use multiple `Span`s with different styles each, to construct a line,
|
// You can use multiple `Span`s with different styles each, to construct a line,
|
||||||
// which can be used as a list item, or in this case a `Block` title
|
// which can be used as a list item, or in this case a `Block` title
|
||||||
|
|
||||||
let mut title_line = if self.get_exit_status().success() {
|
let mut title_line = if self.get_exit_status().success() {
|
||||||
Line::from(
|
Line::from(
|
||||||
Span::default()
|
|
||||||
.content("SUCCESS!")
|
|
||||||
.style(Style::default().fg(theme.success_color).reversed()),
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
Line::from(
|
|
||||||
Span::default()
|
|
||||||
.content("FAILED!")
|
|
||||||
.style(Style::default().fg(theme.fail_color).reversed()),
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
title_line.push_span(
|
|
||||||
Span::default()
|
Span::default()
|
||||||
.content(" press <ENTER> to close this window ")
|
.content("SUCCESS!")
|
||||||
.style(Style::default()),
|
.style(Style::default().fg(state.theme.success_color).reversed()),
|
||||||
);
|
)
|
||||||
|
} else {
|
||||||
Block::default()
|
Line::from(
|
||||||
.borders(Borders::ALL)
|
Span::default()
|
||||||
.title_top(title_line.centered())
|
.content("FAILED!")
|
||||||
|
.style(Style::default().fg(state.theme.fail_color).reversed()),
|
||||||
|
)
|
||||||
};
|
};
|
||||||
let screen = self.screen(inner_size); // when the terminal is changing a lot, there
|
|
||||||
// will be 1 frame of lag on resizing
|
title_line.push_span(
|
||||||
let pseudo_term = PseudoTerminal::new(&screen).block(term_border);
|
Span::default()
|
||||||
frame.render_widget(pseudo_term, floater);
|
.content(" press <ENTER> to close this window ")
|
||||||
}
|
.style(Style::default()),
|
||||||
|
);
|
||||||
|
|
||||||
|
Block::default()
|
||||||
|
.borders(Borders::ALL)
|
||||||
|
.title_top(title_line.centered())
|
||||||
|
};
|
||||||
|
let screen = self.screen(inner_size); // when the terminal is changing a lot, there
|
||||||
|
// will be 1 frame of lag on resizing
|
||||||
|
let pseudo_term = PseudoTerminal::new(&screen).block(term_border);
|
||||||
|
frame.render_widget(pseudo_term, floater);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Send SIGHUB signal, *not* SIGKILL or SIGTERM, to the child process
|
/// Send SIGHUB signal, *not* SIGKILL or SIGTERM, to the child process
|
||||||
pub fn kill_child(&mut self) {
|
pub fn kill_child(&mut self) {
|
||||||
if !self.is_finished() {
|
if !self.is_finished() {
|
||||||
|
|
6
src/state.rs
Normal file
6
src/state.rs
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
use crate::theme::Theme;
|
||||||
|
|
||||||
|
pub struct AppState {
|
||||||
|
/// Selected theme
|
||||||
|
pub theme: Theme,
|
||||||
|
}
|
11
src/theme.rs
11
src/theme.rs
|
@ -1,7 +1,6 @@
|
||||||
use ratatui::style::Color;
|
use ratatui::style::Color;
|
||||||
|
|
||||||
pub static mut THEME_IDX: usize = 1;
|
#[derive(Clone)]
|
||||||
|
|
||||||
pub struct Theme {
|
pub struct Theme {
|
||||||
pub dir_color: Color,
|
pub dir_color: Color,
|
||||||
pub cmd_color: Color,
|
pub cmd_color: Color,
|
||||||
|
@ -29,11 +28,3 @@ pub const THEMES: [Theme; 2] = [
|
||||||
success_color: Color::Rgb(5, 255, 55),
|
success_color: Color::Rgb(5, 255, 55),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
pub fn get_theme() -> &'static Theme {
|
|
||||||
&THEMES[unsafe { THEME_IDX }]
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_theme(idx: usize) {
|
|
||||||
unsafe { THEME_IDX = idx };
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user