Many updates
This commit is contained in:
parent
a8672a3197
commit
aad4453681
12
Cargo.lock
generated
12
Cargo.lock
generated
@ -226,8 +226,10 @@ name = "live-cli"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ansi4tui",
|
||||
"anyhow",
|
||||
"atty",
|
||||
"crossterm",
|
||||
"shellwords",
|
||||
"tui",
|
||||
]
|
||||
|
||||
@ -539,6 +541,16 @@ dependencies = [
|
||||
"opaque-debug",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shellwords"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89e515aa4699a88148ed5ef96413ceef0048ce95b43fbc955a33bde0a70fcae6"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook"
|
||||
version = "0.1.17"
|
||||
|
@ -10,3 +10,5 @@ tui = "0.19"
|
||||
crossterm = "0.25"
|
||||
atty = "0.2.14"
|
||||
ansi4tui = {path = "./ansi4tui/"}
|
||||
anyhow = "1.0.66"
|
||||
shellwords = "1.1.0"
|
||||
|
@ -24,9 +24,22 @@ impl Default for CommandResult<'_> {
|
||||
}
|
||||
|
||||
pub fn run(app: &mut App) {
|
||||
let mut child = Command::new("jq")
|
||||
.arg("-C")
|
||||
.arg(&app.cmdline)
|
||||
let args = match shellwords::split(&app.cmdline) {
|
||||
Ok(a) => a,
|
||||
Err(e) => {
|
||||
app.command_result = CommandResult {
|
||||
status_success: false,
|
||||
stdout: Paragraph::new(""),
|
||||
stderr: Paragraph::new(format!("Argument error: {e:?}")),
|
||||
};
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let mut child = Command::new(&app.hidden_command)
|
||||
.args(&app.hidden_options)
|
||||
// .arg(&app.cmdline)
|
||||
.args(args)
|
||||
.stdin(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::piped())
|
||||
|
114
src/main.rs
114
src/main.rs
@ -3,6 +3,8 @@
|
||||
#![allow(clippy::module_name_repetitions, clippy::cast_possible_truncation)]
|
||||
|
||||
mod command;
|
||||
use anyhow::bail;
|
||||
use anyhow::Result;
|
||||
use command::CommandResult;
|
||||
use std::{
|
||||
io::{self, Write},
|
||||
@ -27,6 +29,12 @@ use crossterm::{
|
||||
|
||||
/// The state of the application
|
||||
pub struct App<'a> {
|
||||
/// The actual command to be called
|
||||
hidden_command: String,
|
||||
|
||||
// A list of hidden options passed to the command
|
||||
hidden_options: Vec<&'static str>,
|
||||
|
||||
/// The line the user inputs
|
||||
cmdline: String,
|
||||
|
||||
@ -38,28 +46,103 @@ pub struct App<'a> {
|
||||
|
||||
/// Should every keystroke transform the original text?
|
||||
autorun: bool,
|
||||
|
||||
/// Should this command be run when the program starts
|
||||
run_initial: bool,
|
||||
}
|
||||
|
||||
impl App<'_> {
|
||||
#[must_use]
|
||||
pub fn new_with_input(input: String) -> Self {
|
||||
Self {
|
||||
cmdline: String::new(),
|
||||
text_orig: Arc::new(input),
|
||||
command_result: CommandResult::default(),
|
||||
autorun: true,
|
||||
pub fn from_template(input: String, template: &Template) -> Self {
|
||||
let text_orig = Arc::new(input);
|
||||
let command_result = CommandResult::default();
|
||||
let hidden_command = template.command();
|
||||
|
||||
match template {
|
||||
Template::Generic(_) => Self {
|
||||
cmdline: String::new(),
|
||||
text_orig,
|
||||
command_result: CommandResult::default(),
|
||||
autorun: true,
|
||||
hidden_command,
|
||||
hidden_options: vec![],
|
||||
run_initial: true,
|
||||
},
|
||||
Template::Jq => Self {
|
||||
cmdline: String::from("."),
|
||||
text_orig,
|
||||
command_result,
|
||||
autorun: true,
|
||||
hidden_command,
|
||||
hidden_options: vec!["-C"],
|
||||
run_initial: true,
|
||||
},
|
||||
Template::Grep | Template::Rg => Self {
|
||||
cmdline: String::new(),
|
||||
text_orig,
|
||||
command_result: CommandResult::default(),
|
||||
autorun: true,
|
||||
hidden_command,
|
||||
hidden_options: vec!["--color=always"],
|
||||
run_initial: false,
|
||||
},
|
||||
Template::Sed | Template::Awk => Self {
|
||||
cmdline: String::new(),
|
||||
text_orig,
|
||||
command_result: CommandResult::default(),
|
||||
autorun: true,
|
||||
hidden_command,
|
||||
hidden_options: vec![],
|
||||
run_initial: false,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() -> Result<(), io::Error> {
|
||||
if atty::is(atty::Stream::Stdin) {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
"You must send stdin to this command",
|
||||
));
|
||||
pub enum Template {
|
||||
Generic(String),
|
||||
Jq,
|
||||
Grep,
|
||||
Rg,
|
||||
Sed,
|
||||
Awk,
|
||||
}
|
||||
|
||||
impl Template {
|
||||
pub fn from(s: String) -> Self {
|
||||
match s.to_lowercase().trim() {
|
||||
"jq" => Self::Jq,
|
||||
"grep" => Self::Grep,
|
||||
"rg" => Self::Rg,
|
||||
"sed" => Self::Sed,
|
||||
c => Self::Generic(c.to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn command(&self) -> String {
|
||||
match self {
|
||||
Template::Generic(c) => c.to_string(),
|
||||
Template::Jq => String::from("jq"),
|
||||
Template::Grep => String::from("grep"),
|
||||
Template::Rg => String::from("rg"),
|
||||
Template::Sed => String::from("sed"),
|
||||
Template::Awk => String::from("awk"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
// Error if we aren't getting any stdin
|
||||
if atty::is(atty::Stream::Stdin) {
|
||||
bail!("You must send stdin to this command");
|
||||
}
|
||||
|
||||
// Get the arguments
|
||||
let arg = match std::env::args().nth(1) {
|
||||
Some(a) => a,
|
||||
None => bail!("You must pass a command"),
|
||||
};
|
||||
|
||||
enable_raw_mode()?;
|
||||
let mut stdout = io::stdout();
|
||||
// execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?;
|
||||
@ -71,7 +154,7 @@ fn main() -> Result<(), io::Error> {
|
||||
let text_orig = io::read_to_string(io::stdin())?;
|
||||
|
||||
// Run the actual application
|
||||
let app = App::new_with_input(text_orig);
|
||||
let app = App::from_template(text_orig, &Template::from(arg));
|
||||
let _res = run_app(&mut terminal, app);
|
||||
|
||||
// Restore terminal
|
||||
@ -87,6 +170,10 @@ fn main() -> Result<(), io::Error> {
|
||||
}
|
||||
|
||||
fn run_app<B: Backend>(terminal: &mut Terminal<B>, mut app: App) -> io::Result<Option<String>> {
|
||||
if app.run_initial {
|
||||
command::run(&mut app);
|
||||
}
|
||||
|
||||
loop {
|
||||
terminal.draw(|f| ui(f, &app))?;
|
||||
|
||||
@ -119,7 +206,6 @@ fn run_app<B: Backend>(terminal: &mut Terminal<B>, mut app: App) -> io::Result<O
|
||||
fn ui<B: Backend>(f: &mut Frame<B>, app: &App) {
|
||||
let vertical_chunks = Layout::default()
|
||||
.direction(Direction::Vertical)
|
||||
.margin(2)
|
||||
.constraints([Constraint::Min(3), Constraint::Length(3)].as_ref())
|
||||
.split(f.size());
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user