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