Skip to content

Commit

Permalink
feat: improve colors on different themes
Browse files Browse the repository at this point in the history
  • Loading branch information
radlinskii committed Jul 29, 2023
1 parent 6d7c43e commit ba03c5b
Showing 1 changed file with 43 additions and 31 deletions.
74 changes: 43 additions & 31 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,13 @@ struct App {
input: String,
/// Current input mode
input_mode: InputMode,
/// History of recorded messages
messages: Vec<String>,
}

impl Default for App {
fn default() -> App {
App {
input: String::new(),
input_mode: InputMode::Normal,
messages: Vec::new(),
}
}
}
Expand Down Expand Up @@ -82,9 +79,6 @@ fn run_app<B: Backend>(terminal: &mut Terminal<B>, 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);
}
Expand All @@ -109,66 +103,84 @@ fn ui<B: Backend>(frame: &mut Frame<B>, 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
{}

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");
Expand Down

0 comments on commit ba03c5b

Please sign in to comment.