mirror of
https://github.com/rust-lang/rustlings.git
synced 2024-12-26 00:00:03 +03:00
Fix contrast in terminals with a light theme
This commit is contained in:
parent
2a725fb137
commit
46ad25f925
|
@ -1,7 +1,9 @@
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
use crossterm::{
|
use crossterm::{
|
||||||
cursor::{MoveTo, MoveToNextLine},
|
cursor::{MoveTo, MoveToNextLine},
|
||||||
style::{Attribute, Color, ResetColor, SetAttribute, SetBackgroundColor, SetForegroundColor},
|
style::{
|
||||||
|
Attribute, Attributes, Color, ResetColor, SetAttribute, SetAttributes, SetForegroundColor,
|
||||||
|
},
|
||||||
terminal::{self, BeginSynchronizedUpdate, Clear, ClearType, EndSynchronizedUpdate},
|
terminal::{self, BeginSynchronizedUpdate, Clear, ClearType, EndSynchronizedUpdate},
|
||||||
QueueableCommand,
|
QueueableCommand,
|
||||||
};
|
};
|
||||||
|
@ -19,6 +21,9 @@ use crate::{
|
||||||
use super::scroll_state::ScrollState;
|
use super::scroll_state::ScrollState;
|
||||||
|
|
||||||
const COL_SPACING: usize = 2;
|
const COL_SPACING: usize = 2;
|
||||||
|
const SELECTED_ROW_ATTRIBUTES: Attributes = Attributes::none()
|
||||||
|
.with(Attribute::Reverse)
|
||||||
|
.with(Attribute::Bold);
|
||||||
|
|
||||||
fn next_ln(stdout: &mut StdoutLock) -> io::Result<()> {
|
fn next_ln(stdout: &mut StdoutLock) -> io::Result<()> {
|
||||||
stdout
|
stdout
|
||||||
|
@ -41,6 +46,7 @@ pub struct ListState<'a> {
|
||||||
app_state: &'a mut AppState,
|
app_state: &'a mut AppState,
|
||||||
scroll_state: ScrollState,
|
scroll_state: ScrollState,
|
||||||
name_col_padding: Vec<u8>,
|
name_col_padding: Vec<u8>,
|
||||||
|
path_col_padding: Vec<u8>,
|
||||||
filter: Filter,
|
filter: Filter,
|
||||||
term_width: u16,
|
term_width: u16,
|
||||||
term_height: u16,
|
term_height: u16,
|
||||||
|
@ -52,13 +58,18 @@ impl<'a> ListState<'a> {
|
||||||
stdout.queue(Clear(ClearType::All))?;
|
stdout.queue(Clear(ClearType::All))?;
|
||||||
|
|
||||||
let name_col_title_len = 4;
|
let name_col_title_len = 4;
|
||||||
let name_col_width = app_state
|
let path_col_title_len = 4;
|
||||||
.exercises()
|
let (name_col_width, path_col_width) = app_state.exercises().iter().fold(
|
||||||
.iter()
|
(name_col_title_len, path_col_title_len),
|
||||||
.map(|exercise| exercise.name.len())
|
|(name_col_width, path_col_width), exercise| {
|
||||||
.max()
|
(
|
||||||
.map_or(name_col_title_len, |max| max.max(name_col_title_len));
|
name_col_width.max(exercise.name.len()),
|
||||||
|
path_col_width.max(exercise.path.len()),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
);
|
||||||
let name_col_padding = vec![b' '; name_col_width + COL_SPACING];
|
let name_col_padding = vec![b' '; name_col_width + COL_SPACING];
|
||||||
|
let path_col_padding = vec![b' '; path_col_width];
|
||||||
|
|
||||||
let filter = Filter::None;
|
let filter = Filter::None;
|
||||||
let n_rows_with_filter = app_state.exercises().len();
|
let n_rows_with_filter = app_state.exercises().len();
|
||||||
|
@ -73,6 +84,7 @@ impl<'a> ListState<'a> {
|
||||||
app_state,
|
app_state,
|
||||||
scroll_state,
|
scroll_state,
|
||||||
name_col_padding,
|
name_col_padding,
|
||||||
|
path_col_padding,
|
||||||
filter,
|
filter,
|
||||||
// Set by `set_term_size`
|
// Set by `set_term_size`
|
||||||
term_width: 0,
|
term_width: 0,
|
||||||
|
@ -119,7 +131,7 @@ impl<'a> ListState<'a> {
|
||||||
writer.write_str(pre_highlight)?;
|
writer.write_str(pre_highlight)?;
|
||||||
writer.stdout.queue(SetForegroundColor(Color::Magenta))?;
|
writer.stdout.queue(SetForegroundColor(Color::Magenta))?;
|
||||||
writer.write_str(highlight)?;
|
writer.write_str(highlight)?;
|
||||||
writer.stdout.queue(ResetColor)?;
|
writer.stdout.queue(SetForegroundColor(Color::Reset))?;
|
||||||
return writer.write_str(post_highlight);
|
return writer.write_str(post_highlight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -143,14 +155,12 @@ impl<'a> ListState<'a> {
|
||||||
let mut writer = MaxLenWriter::new(stdout, self.term_width as usize);
|
let mut writer = MaxLenWriter::new(stdout, self.term_width as usize);
|
||||||
|
|
||||||
if self.scroll_state.selected() == Some(row_offset + n_displayed_rows) {
|
if self.scroll_state.selected() == Some(row_offset + n_displayed_rows) {
|
||||||
writer.stdout.queue(SetBackgroundColor(Color::Rgb {
|
|
||||||
r: 40,
|
|
||||||
g: 40,
|
|
||||||
b: 40,
|
|
||||||
}))?;
|
|
||||||
// The crab emoji has the width of two ascii chars.
|
// The crab emoji has the width of two ascii chars.
|
||||||
writer.add_to_len(2);
|
writer.add_to_len(2);
|
||||||
writer.stdout.write_all("🦀".as_bytes())?;
|
writer.stdout.write_all("🦀".as_bytes())?;
|
||||||
|
writer
|
||||||
|
.stdout
|
||||||
|
.queue(SetAttributes(SELECTED_ROW_ATTRIBUTES))?;
|
||||||
} else {
|
} else {
|
||||||
writer.write_ascii(b" ")?;
|
writer.write_ascii(b" ")?;
|
||||||
}
|
}
|
||||||
|
@ -167,9 +177,10 @@ impl<'a> ListState<'a> {
|
||||||
writer.write_ascii(b"DONE ")?;
|
writer.write_ascii(b"DONE ")?;
|
||||||
} else {
|
} else {
|
||||||
writer.stdout.queue(SetForegroundColor(Color::Yellow))?;
|
writer.stdout.queue(SetForegroundColor(Color::Yellow))?;
|
||||||
writer.write_ascii(b"PENDING ")?;
|
writer.write_ascii(b"PENDING")?;
|
||||||
}
|
}
|
||||||
writer.stdout.queue(SetForegroundColor(Color::Reset))?;
|
writer.stdout.queue(SetForegroundColor(Color::Reset))?;
|
||||||
|
writer.write_ascii(b" ")?;
|
||||||
|
|
||||||
self.draw_exericse_name(&mut writer, exercise)?;
|
self.draw_exericse_name(&mut writer, exercise)?;
|
||||||
|
|
||||||
|
@ -183,6 +194,8 @@ impl<'a> ListState<'a> {
|
||||||
exercise.terminal_file_link(&mut writer)?;
|
exercise.terminal_file_link(&mut writer)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
writer.write_ascii(&self.path_col_padding[exercise.path.len()..])?;
|
||||||
|
|
||||||
next_ln(stdout)?;
|
next_ln(stdout)?;
|
||||||
stdout.queue(ResetColor)?;
|
stdout.queue(ResetColor)?;
|
||||||
n_displayed_rows += 1;
|
n_displayed_rows += 1;
|
||||||
|
|
|
@ -20,6 +20,10 @@ use crate::{
|
||||||
|
|
||||||
use super::{terminal_event::terminal_event_handler, InputPauseGuard, WatchEvent};
|
use super::{terminal_event::terminal_event_handler, InputPauseGuard, WatchEvent};
|
||||||
|
|
||||||
|
const HEADING_ATTRIBUTES: Attributes = Attributes::none()
|
||||||
|
.with(Attribute::Bold)
|
||||||
|
.with(Attribute::Underlined);
|
||||||
|
|
||||||
#[derive(PartialEq, Eq)]
|
#[derive(PartialEq, Eq)]
|
||||||
enum DoneStatus {
|
enum DoneStatus {
|
||||||
DoneWithSolution(String),
|
DoneWithSolution(String),
|
||||||
|
@ -209,9 +213,7 @@ impl<'a> WatchState<'a> {
|
||||||
|
|
||||||
if self.show_hint {
|
if self.show_hint {
|
||||||
stdout
|
stdout
|
||||||
.queue(SetAttributes(
|
.queue(SetAttributes(HEADING_ATTRIBUTES))?
|
||||||
Attributes::from(Attribute::Bold).with(Attribute::Underlined),
|
|
||||||
))?
|
|
||||||
.queue(SetForegroundColor(Color::Cyan))?;
|
.queue(SetForegroundColor(Color::Cyan))?;
|
||||||
stdout.write_all(b"Hint")?;
|
stdout.write_all(b"Hint")?;
|
||||||
stdout.queue(ResetColor)?;
|
stdout.queue(ResetColor)?;
|
||||||
|
|
Loading…
Reference in a new issue