From ba03c5b39b398e273d54e4dd6d21ac3f12d5222d Mon Sep 17 00:00:00 2001 From: radlinskii Date: Sat, 29 Jul 2023 19:56:12 +0200 Subject: [PATCH] feat: improve colors on different themes --- src/main.rs | 74 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 43 insertions(+), 31 deletions(-) diff --git a/src/main.rs b/src/main.rs index 9aef480..6674d61 100644 --- a/src/main.rs +++ b/src/main.rs @@ -24,8 +24,6 @@ struct App { input: String, /// Current input mode input_mode: InputMode, - /// History of recorded messages - messages: Vec, } impl Default for App { @@ -33,7 +31,6 @@ impl Default for App { App { input: String::new(), input_mode: InputMode::Normal, - messages: Vec::new(), } } } @@ -82,9 +79,6 @@ fn run_app(terminal: &mut Terminal, mut app: App) -> io::Result<( _ => {} }, InputMode::Editing => match key.code { - KeyCode::Enter => { - app.messages.push(app.input.drain(..).collect()); - } KeyCode::Char(c) => { app.input.push(c); } @@ -109,55 +103,72 @@ fn ui(frame: &mut Frame, app: &App) { let frame_width = frame.size().width as usize; let input_len = app.input.len(); - let input_line_index = (input_len / frame_width) as u16; + let current_line_index = (input_len / frame_width) as u16; let input_current_line_len = input_len % frame_width; - let expected_input_str: String = format!("frame_width: {}, input_len: {}, input_line_index: {}, input_current_line_len: {}, chunks[0]: {:?} input example input example input example input example input example input example input example input example input example input example input example input", frame_width,input_len, input_line_index, input_current_line_len, chunks[0]); + let expected_input_str: String = format!("example input "); + let expected_input_str = expected_input_str.repeat(frame_width / expected_input_str.len() + 1); let (expected_input_str, _) = expected_input_str.split_at(frame_width); let expected_input_str = expected_input_str .to_string() - .repeat(input_line_index as usize + 2); - - let (expected_input_first_line, expected_input_rest) = - expected_input_str.split_at(((input_line_index as usize) + 1) * frame_width); - let (_expected_input_first_line_already_typed, expected_input_first_line_rest) = - expected_input_first_line.split_at(input_len); - - let input = Paragraph::new(app.input.as_ref()) - .style(match app.input_mode { - InputMode::Normal => Style::default(), - InputMode::Editing => Style::default().fg(Color::White), - }) - .block(Block::default()) - .wrap(Wrap { trim: false }); - frame.render_widget(input, chunks[0]); - - let mut expected_input_current_line_text = Text::from(expected_input_first_line_rest); - expected_input_current_line_text.patch_style(Style::default().fg(Color::LightGreen)); + .repeat(current_line_index as usize + 2); + + let (expected_input_current_line, expected_input_rest) = + expected_input_str.split_at(((current_line_index as usize) + 1) * frame_width); + let (_expected_input_current_line_already_typed, expected_input_current_line_rest) = + expected_input_current_line.split_at(input_len); + + // iterate over chars in input and expected input and compare them + for ((input_char_index, input_char), (_, expected_input_char)) in app + .input + .char_indices() + .zip(_expected_input_current_line_already_typed.char_indices()) + { + let input = + Paragraph::new(input_char.to_string()).style(match input_char == expected_input_char { + true => Style::default().fg(Color::Green), + false => Style::default().fg(Color::Red), + }); + frame.render_widget( + input, + Rect { + x: (chunks[0].x + input_char_index as u16) % frame_width as u16, + y: chunks[0].y + input_char_index as u16 / frame_width as u16, + width: 1, + height: 1, + }, + ); + } + + // print the current line of the expected input + let mut expected_input_current_line_text = Text::from(expected_input_current_line_rest); + expected_input_current_line_text.patch_style(Style::default().fg(Color::Gray)); let paragraph = Paragraph::new(expected_input_current_line_text); frame.render_widget( paragraph, Rect { x: chunks[0].x + input_current_line_len as u16, - y: chunks[0].y + input_line_index, + y: chunks[0].y + current_line_index, width: frame_width as u16 - input_current_line_len as u16, height: 1, }, ); + // print the rest of the expected input in the lines below input let mut expected_input_rest_text = Text::from(expected_input_rest); - expected_input_rest_text.patch_style(Style::default().fg(Color::LightBlue)); + expected_input_rest_text.patch_style(Style::default().fg(Color::DarkGray)); let paragraph = Paragraph::new(expected_input_rest_text).wrap(Wrap { trim: false }); frame.render_widget( paragraph, Rect { x: chunks[0].x, - y: chunks[0].y + input_line_index + 1, - height: chunks[0].height - input_line_index - 1, + y: chunks[0].y + current_line_index + 1, + height: chunks[0].height - current_line_index - 1, width: chunks[0].width, }, ); + // move cursor match app.input_mode { InputMode::Normal => // Don't need to do anything here, because `Frame` already hid the cursor @@ -165,10 +176,11 @@ fn ui(frame: &mut Frame, app: &App) { InputMode::Editing => frame.set_cursor( chunks[0].x + input_current_line_len as u16, - chunks[0].y + input_line_index, + chunks[0].y + current_line_index, ), } + // print help message match app.input_mode { InputMode::Normal => { let mut text = Text::from("press 'e' to start editing, press 'q' to quit");