rsmoji 0.3.3

Gitmoji, but oxidized!
mod commit;
mod emojis;
mod globals;
mod selection;
mod ui_state;

use crossterm::cursor::MoveDown;
use crossterm::event::{Event, KeyCode, KeyEventKind, read};
use crossterm::execute;
use crossterm::style::{Attribute, Print, SetAttribute, SetForegroundColor};
use crossterm::terminal::{Clear, ClearType, disable_raw_mode, enable_raw_mode};
use emojis::return_emojis;
use globals::{CATPPUCCIN_ACTIVE, cursor_to_start};
use selection::draw_menu;
use std::io;
use std::process::Command;
use unicode_segmentation::UnicodeSegmentation;

use crate::commit::handlers::{
	handle_backspace_commit, handle_char_commit, handle_left_commit, handle_right_commit,
};
use crate::commit::reload_commit_message;
use crate::selection::handlers::{
	handle_backspace, handle_char, handle_enter, handle_keydown, handle_keyup, handle_left,
	handle_right,
};
use crate::ui_state::instantiate_state;

fn main() -> io::Result<()> {
	let emojis: Vec<&'static str> = return_emojis();

	let mut state = instantiate_state().expect("failed to instantiate state");
	state.filter_emojis(&emojis);
	draw_menu(&state);

	enable_raw_mode().expect("Failed to enable raw mode");
	loop {
		let Event::Key(event) = read()? else {
			continue;
		};

		if event.kind != KeyEventKind::Press {
			continue;
		}

		match event.code {
			KeyCode::Down => handle_keydown(&mut state),
			KeyCode::Up => handle_keyup(&mut state),
			KeyCode::Left => handle_left(&mut state),
			KeyCode::Right => handle_right(&mut state),
			KeyCode::Char(c) => handle_char(c, &mut state, event, &emojis),
			KeyCode::Backspace => handle_backspace(&mut state, &emojis),
			KeyCode::Enter => {
				let result = handle_enter(&state);
				if result {
					break;
				}
			}

			_ => {}
		}
	}

	let gitmoji: Vec<&str> = state.filtered_emojis[state.offset + state.selection]
		.graphemes(true)
		.collect();
	let gitmoji = gitmoji[0].to_string();
	let headline = "? Gitmoji: ".to_string() + &gitmoji + "!";
	cursor_to_start();
	execute!(
		io::stdout(),
		SetAttribute(Attribute::Bold),
		SetForegroundColor(CATPPUCCIN_ACTIVE),
		Print(headline),
		SetAttribute(Attribute::Reset),
	)
	.expect("failed to print selected gitmoji");

	execute!(io::stdout(), MoveDown(1)).expect("Failed to move cursor down by one line");
	let mut commit_message: String = String::new();
	reload_commit_message(&commit_message, state.insert_offset, false);
	state.insert_offset = 0;
	loop {
		let Event::Key(event) = read()? else {
			continue;
		};

		if event.kind != KeyEventKind::Press {
			continue;
		}

		match event.code {
			KeyCode::Char(c) => handle_char_commit(c, event, &mut state, &mut commit_message),
			KeyCode::Backspace => handle_backspace_commit(&mut state, &mut commit_message),
			KeyCode::Left => handle_left_commit(&mut state, &commit_message),
			KeyCode::Right => handle_right_commit(&mut state, &commit_message),
			KeyCode::Enter => {
				reload_commit_message(&commit_message, state.insert_offset, true);
				break;
			}
			_ => {}
		}
	}

	let final_commit_message = gitmoji + " " + &commit_message;

	execute!(io::stdout(), MoveDown(1)).expect("Failed to move cursor down by one line");
	cursor_to_start();
	disable_raw_mode().expect("Failed to disable raw mode");
	Command::new("git")
		.args(["commit", "-m", final_commit_message.as_str()])
		.status()
		.expect("Failed to run git");

	return Ok(());
}