diff --git a/compiler/erg_common/color.rs b/compiler/erg_common/color.rs deleted file mode 100644 index 3fb6b402..00000000 --- a/compiler/erg_common/color.rs +++ /dev/null @@ -1,9 +0,0 @@ -//! Escape sequences change the color of the terminal - -pub const RESET: &str = "\x1b[m"; -pub const DEEP_RED: &str = "\x1b[31m"; -pub const RED: &str = "\x1b[91m"; -pub const GREEN: &str = "\x1b[92m"; -pub const YELLOW: &str = "\x1b[93m"; -pub const BLUE: &str = "\x1b[94m"; -pub const CYAN: &str = "\x1b[96m"; diff --git a/compiler/erg_common/error.rs b/compiler/erg_common/error.rs index 2ebd3c94..a926031f 100644 --- a/compiler/erg_common/error.rs +++ b/compiler/erg_common/error.rs @@ -7,8 +7,12 @@ use std::fmt::Write as _; use std::io::{stderr, BufWriter, Write as _}; use crate::astr::AtomicStr; -use crate::color::*; use crate::config::Input; +use crate::style::Color; +use crate::style::Color::{Cyan, Green, Magenta, Red, Yellow}; +use crate::style::Spans; +use crate::style::RESET; +use crate::style::{ATT_RESET, UNDERLINE}; use crate::traits::{Locational, Stream}; use crate::{fmt_option, impl_display_from_debug, switch_lang}; diff --git a/compiler/erg_common/lib.rs b/compiler/erg_common/lib.rs index 389af0a1..fb17b9a5 100644 --- a/compiler/erg_common/lib.rs +++ b/compiler/erg_common/lib.rs @@ -3,7 +3,6 @@ use std::fmt; pub mod astr; pub mod cache; -pub mod color; pub mod config; pub mod datetime; pub mod dict; @@ -24,6 +23,7 @@ pub mod set; pub mod shared; pub mod stdin; pub mod str; +pub mod style; pub mod traits; pub mod tsort; pub mod tty; diff --git a/compiler/erg_common/macros.rs b/compiler/erg_common/macros.rs index caed3350..4ab4eee0 100644 --- a/compiler/erg_common/macros.rs +++ b/compiler/erg_common/macros.rs @@ -353,7 +353,7 @@ macro_rules! debug_enum_assert { macro_rules! debug_info { ($output:ident) => {{ #[allow(unused_imports)] - use $crate::color::{CYAN, RESET}; + use $crate::style::{CYAN, RESET}; write!( $output, "[{}DEBUG{}] {}:{:04}: ", @@ -366,7 +366,7 @@ macro_rules! debug_info { }}; () => {{ #[allow(unused_imports)] - use $crate::color::{CYAN, RESET}; + use $crate::style::{CYAN, RESET}; print!("[{}DEBUG{}] {}:{:04}: ", CYAN, RESET, file!(), line!()); }}; } @@ -410,7 +410,7 @@ macro_rules! log { (c $color:ident, $($arg: tt)*) => {{ if cfg!(feature = "debug") { - use $crate::color::*; + use $crate::style::*; $crate::debug_info!(); print!("{}", $color); println!($($arg)*); @@ -420,7 +420,7 @@ macro_rules! log { (f+c $output:ident, $color:ident, $($arg: tt)*) => {{ if cfg!(feature = "debug") { - use $crate::color::*; + use $crate::style::*; $crate::debug_info!($output); write!($output, "{}", $color).unwrap(); write!($output, $($arg)*).unwrap(); @@ -431,7 +431,7 @@ macro_rules! log { ($($arg: tt)*) => {{ if cfg!(feature = "debug") { - use $crate::color::*; + use $crate::style::*; $crate::debug_info!(); println!($($arg)*); print!("{}", RESET); // reset color anyway diff --git a/compiler/erg_common/style.rs b/compiler/erg_common/style.rs new file mode 100644 index 00000000..479672c5 --- /dev/null +++ b/compiler/erg_common/style.rs @@ -0,0 +1,114 @@ +use std::fmt::Display; + +pub const ATT_RESET: &str = "\x1b[0m"; +pub const BOLD: &str = "\x1b[1m"; +pub const UNDERLINE: &str = "\x1b[4m"; + +// Escape sequences change the color of the terminal +pub const RESET: &str = "\x1b[m"; +pub const BLACK: &str = "\x1b[30m"; +pub const DEEP_RED: &str = "\x1b[31m"; +pub const DEEP_GREEN: &str = "\x1b[32m"; +pub const DEEP_YELLOW: &str = "\x1b[33m"; +pub const DEEP_BLUE: &str = "\x1b[34m"; +pub const DEEP_MAGENTA: &str = "\x1b[35m"; +pub const DEEP_CYAN: &str = "\x1b[36m"; +pub const GRAY: &str = "\x1b[37m"; +pub const RED: &str = "\x1b[91m"; +pub const GREEN: &str = "\x1b[92m"; +pub const YELLOW: &str = "\x1b[93m"; +pub const BLUE: &str = "\x1b[94m"; +pub const MAGENTA: &str = "\x1b[95m"; +pub const CYAN: &str = "\x1b[96m"; +pub const WHITE: &str = "\x1b[97m"; + +#[derive(Debug)] +pub enum Color { + Cyan, + Green, + Gray, + Magenta, + Red, + Yellow, +} + +impl Color { + fn as_str<'a>(self) -> &'a str { + match self { + Color::Cyan => CYAN, + Color::Green => GREEN, + Color::Gray => GRAY, + Color::Magenta => MAGENTA, + Color::Red => RED, + Color::Yellow => YELLOW, + } + } +} + +pub struct Span<'a> { + text: &'a str, + color: Color, +} + +impl<'a> Span<'a> { + pub fn new(text: &'a str, color: Color) -> Self { + Self { text, color } + } +} + +impl Display for Span<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let color = self.color.as_str(); + write!(f, "{}{}{RESET}", color, self.text) + } +} + +pub struct Spans<'a>(Vec>); + +impl<'a> Spans<'a> { + pub fn new() -> Self { + Self(Vec::new()) + } + + pub fn from(s: Vec>) -> Self { + Self(s) + } + + pub fn push_str(&mut self, text: &str, color: Color) { + let span = Span::new(text, color); + } + + pub fn push_span(&mut self, span: Span<'a>) { + self.0.push(span); + } + + fn connect(self) -> String { + let mut s = String::new(); + for x in self.0.into_iter() { + s.push_str(x.color.as_str()); + s.push_str(x.text); + } + s + RESET + } +} + +#[cfg(test)] +mod tests { + use super::*; + #[test] + fn colorings_fg() { + println!("{DEEP_RED}Hello{RESET}, {RED}World{RESET}"); + println!("{DEEP_GREEN}Hello{RESET}, {GREEN}World{RESET}"); + println!("{YELLOW}Hello{RESET}, {DEEP_YELLOW}World{RESET}"); + println!("{DEEP_BLUE}Hello{RESET}, {BLUE}World{RESET}"); + println!("{CYAN}Hello{RESET}, {DEEP_CYAN}World{RESET}"); + println!("{MAGENTA}Hello{RESET}, {DEEP_MAGENTA}World{RESET}"); + println!("{GRAY}Hello{RESET}, {WHITE}World{RESET}"); + } + + #[test] + fn style_test() { + println!("{BOLD}bold{ATT_RESET}"); + println!("{UNDERLINE}UNDERLINED{ATT_RESET}"); + } +} diff --git a/compiler/erg_compiler/context/initialize/const_func.rs b/compiler/erg_compiler/context/initialize/const_func.rs index cd7388b2..4313f863 100644 --- a/compiler/erg_compiler/context/initialize/const_func.rs +++ b/compiler/erg_compiler/context/initialize/const_func.rs @@ -7,8 +7,8 @@ use crate::ty::constructors::{and, mono}; use crate::ty::value::{EvalValueResult, GenTypeObj, TypeObj, ValueObj}; use crate::ty::ValueArgs; use erg_common::astr::AtomicStr; -use erg_common::color::{RED, RESET, YELLOW}; use erg_common::error::{ErrorCore, ErrorKind, Location}; +use erg_common::style::{RED, RESET, YELLOW}; /// Requirement: Type, Impl := Type -> ClassType pub fn class_func(mut args: ValueArgs, ctx: &Context) -> EvalValueResult { diff --git a/compiler/erg_compiler/error.rs b/compiler/erg_compiler/error.rs index f4df5bb0..c9bfbe43 100644 --- a/compiler/erg_compiler/error.rs +++ b/compiler/erg_compiler/error.rs @@ -1,10 +1,10 @@ use std::fmt::Display; use erg_common::astr::AtomicStr; -use erg_common::color::{GREEN, RED, RESET, YELLOW}; use erg_common::config::Input; use erg_common::error::{ErrorCore, ErrorDisplay, ErrorKind::*, Location, MultiErrorDisplay}; use erg_common::set::Set; +use erg_common::style::{GREEN, RED, RESET, YELLOW}; use erg_common::traits::{Locational, Stream}; use erg_common::vis::Visibility; use erg_common::{ diff --git a/compiler/erg_parser/error.rs b/compiler/erg_parser/error.rs index 03b97e85..4f007dab 100644 --- a/compiler/erg_parser/error.rs +++ b/compiler/erg_parser/error.rs @@ -2,9 +2,9 @@ //! //! パーサーが出すエラーを定義 use erg_common::astr::AtomicStr; -use erg_common::color::{RED, RESET}; use erg_common::config::Input; use erg_common::error::{ErrorCore, ErrorDisplay, ErrorKind::*, Location, MultiErrorDisplay}; +use erg_common::style::{RED, RESET}; use erg_common::traits::Stream; use erg_common::{impl_display_and_error, impl_stream_for_wrapper, switch_lang};