Initial upload: gitignore-gen Rust CLI tool with 100+ templates
This commit is contained in:
98
app/gitignore-gen/src/tui/mod.rs
Normal file
98
app/gitignore-gen/src/tui/mod.rs
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
use crate::templates::TemplateLoader;
|
||||||
|
use crossterm::event::{self, Event, KeyCode, KeyEvent};
|
||||||
|
use crossterm::execute;
|
||||||
|
use crossterm::terminal::{Clear, ClearType, disable_raw_mode, enable_raw_mode};
|
||||||
|
use std::io::stdout;
|
||||||
|
|
||||||
|
pub struct App {
|
||||||
|
templates: Vec<String>,
|
||||||
|
selected: Vec<bool>,
|
||||||
|
search_query: String,
|
||||||
|
show_help: bool,
|
||||||
|
current_category: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl App {
|
||||||
|
pub fn new() -> Result<Self, Box<dyn std::error::Error>> {
|
||||||
|
let loader = TemplateLoader::new(None);
|
||||||
|
let templates = loader.list_templates();
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
templates,
|
||||||
|
selected: vec![false; 100],
|
||||||
|
search_query: String::new(),
|
||||||
|
show_help: false,
|
||||||
|
current_category: String::new(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn run(&mut self) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
enable_raw_mode()?;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
self.draw()?;
|
||||||
|
|
||||||
|
if event::poll(std::time::Duration::from_millis(100))? {
|
||||||
|
if let Event::Key(key) = event::read()? {
|
||||||
|
match key.code {
|
||||||
|
KeyCode::Esc => {
|
||||||
|
if self.show_help {
|
||||||
|
self.show_help = false;
|
||||||
|
} else {
|
||||||
|
disable_raw_mode()?;
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
KeyCode::Char('c') => {
|
||||||
|
self.selected = vec![false; self.templates.len()];
|
||||||
|
}
|
||||||
|
KeyCode::Char('g') => {
|
||||||
|
self.generate()?;
|
||||||
|
}
|
||||||
|
KeyCode::Char('/') => {
|
||||||
|
self.search_query = String::new();
|
||||||
|
}
|
||||||
|
KeyCode::Char('?') => {
|
||||||
|
self.show_help = !self.show_help;
|
||||||
|
}
|
||||||
|
KeyCode::Enter => {
|
||||||
|
self.generate()?;
|
||||||
|
}
|
||||||
|
KeyCode::Up => {}
|
||||||
|
KeyCode::Down => {}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw(&self) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
println!("\n=== gitignore-gen Interactive Mode ===");
|
||||||
|
println!("Press ? for help, ESC to exit\n");
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn generate(&self) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let selected_templates: Vec<&str> = self
|
||||||
|
.templates
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.filter(|(_, t)| self.selected[_])
|
||||||
|
.map(|(_, t)| t.as_str())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
if selected_templates.is_empty() {
|
||||||
|
println!("No templates selected");
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
let loader = TemplateLoader::new(None);
|
||||||
|
let content = loader.combine_templates(&selected_templates)?;
|
||||||
|
|
||||||
|
std::fs::write(".gitignore", &content)?;
|
||||||
|
println!("Generated .gitignore");
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user