Skip to content

Commit

Permalink
add highlighting themes
Browse files Browse the repository at this point in the history
  • Loading branch information
sigmaSd committed Jun 22, 2020
1 parent 0db2587 commit a2e9128
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 17 deletions.
71 changes: 54 additions & 17 deletions src/irust/highlight.rs
Original file line number Diff line number Diff line change
@@ -1,33 +1,44 @@
use super::printer::{Printer, PrinterItem, PrinterItemType};
use crossterm::style::Color;
use once_cell::sync::Lazy;
use std::collections::HashMap;
mod theme;

static THEME: Lazy<HashMap<String, Color>> = Lazy::new(|| theme::theme().unwrap_or_default());

pub fn highlight(c: String) -> Printer {
let mut printer = Printer::default();

for token in parse(c) {
use Token::*;
let (string, color) = match token {
Keyword(s) => (s, Color::Magenta),
Function(s) => (s, Color::Blue),
Type(s) => (s, Color::Cyan),
Number(s) => (s, Color::DarkYellow),
Symbol(c) => (c.to_string(), Color::Red),
Macro(s) => (s, Color::Yellow),
StringLiteral(s) => (s, Color::Green),
Character(c) => (c.to_string(), Color::Green),
LifeTime(s) => (s, Color::DarkMagenta),
Comment(s) => (s, Color::DarkGrey),
Const(s) => (s, Color::DarkGreen),
X(s) => (s, Color::White),
Keyword(s) => (s, THEME.get("keyword").unwrap_or(&Color::Magenta)),
Keyword2(s) => (s, THEME.get("keyword2").unwrap_or(&Color::DarkRed)),
Function(s) => (s, THEME.get("function").unwrap_or(&Color::Blue)),
Type(s) => (s, THEME.get("type").unwrap_or(&Color::Cyan)),
Number(s) => (s, THEME.get("number").unwrap_or(&Color::DarkYellow)),
Symbol(c) => (c.to_string(), THEME.get("symbol").unwrap_or(&Color::Red)),
Macro(s) => (s, THEME.get("macro").unwrap_or(&Color::Yellow)),
StringLiteral(s) => (s, THEME.get("string_literal").unwrap_or(&Color::Green)),
Character(c) => (
c.to_string(),
THEME.get("character").unwrap_or(&Color::Green),
),
LifeTime(s) => (s, THEME.get("lifetime").unwrap_or(&Color::DarkMagenta)),
Comment(s) => (s, THEME.get("comment").unwrap_or(&Color::DarkGrey)),
Const(s) => (s, THEME.get("const").unwrap_or(&Color::DarkGreen)),
X(s) => (s, THEME.get("x").unwrap_or(&Color::White)),
};

printer.push(PrinterItem::new(string, PrinterItemType::Custom(color)));
printer.push(PrinterItem::new(string, PrinterItemType::Custom(*color)));
}
printer
}

#[derive(Debug)]
enum Token {
Keyword(String),
Keyword2(String),
Function(String),
Type(String),
Number(String),
Expand Down Expand Up @@ -84,7 +95,12 @@ fn parse(s: String) -> Vec<Token> {
if !alphanumeric.is_empty() {
let token = parse_as(
alphanumeric.drain(..).collect(),
vec![TokenName::Keyword, TokenName::Type, TokenName::Number],
vec![
TokenName::Keyword2,
TokenName::Keyword,
TokenName::Type,
TokenName::Number,
],
);
tokens.push(token);
}
Expand Down Expand Up @@ -180,6 +196,7 @@ fn parse(s: String) -> Vec<Token> {
vec![
TokenName::Const,
TokenName::Keyword,
TokenName::Keyword2,
TokenName::Number,
TokenName::Type,
],
Expand All @@ -199,7 +216,12 @@ fn parse(s: String) -> Vec<Token> {
if !alphanumeric.is_empty() {
let token = parse_as(
alphanumeric.drain(..).collect(),
vec![TokenName::Keyword, TokenName::Type, TokenName::Number],
vec![
TokenName::Keyword2,
TokenName::Keyword,
TokenName::Type,
TokenName::Number,
],
);
tokens.push(token);
}
Expand Down Expand Up @@ -270,6 +292,7 @@ fn parse_string_literal(s: &mut impl Iterator<Item = char>) -> Vec<Token> {

enum TokenName {
Keyword,
Keyword2,
Type,
Number,
Const,
Expand All @@ -284,6 +307,11 @@ fn parse_as(p: String, token_names: Vec<TokenName>) -> Token {
return Token::Keyword(p.unparsed_string());
}
}
TokenName::Keyword2 => {
if is_keyword2(&p) {
return Token::Keyword2(p.unparsed_string());
}
}
TokenName::Type => {
if is_type(&p) {
return Token::Type(p.unparsed_string());
Expand Down Expand Up @@ -312,6 +340,10 @@ fn is_keyword(p: &Token) -> bool {
KEYWORDS.contains(&p.unparsed_str())
}

fn is_keyword2(p: &Token) -> bool {
KEYWORDS2.contains(&p.unparsed_str())
}

fn is_type(p: &Token) -> bool {
TYPES.contains(&p.unparsed_str())
}
Expand All @@ -322,10 +354,15 @@ fn is_const(p: &Token) -> bool {
.all(|c| c.is_uppercase() || c == '_')
}

// Spliting keywords for a nicer coloring
// red blue green blue red white
// exp: pub fn hello() let mut var
const KEYWORDS: &[&str] = &[
"self", "Self", "for", "struct", "enum", "impl", "trait", "type", "pub", "in", "const",
"static", "match", "fn", "use", "let", "mut", "continue", "loop", "break", "if", "else",
"use", "super", "self", "Self", "for", "impl", "trait", "type", "pub", "in", "const", "static",
"match", "use", "mut", "continue", "loop", "break", "if", "else",
];
const KEYWORDS2: &[&str] = &["fn", "let", "struct", "enum"];

const SYMBOLS: &[char] = &[':', '&', '?', '+', '-', '*', '/', '=', '!', ',', ';'];
const TYPES: &[&str] = &[
"bool", "char", "usize", "isize", "u8", "i8", "u32", "i32", "u64", "i64", "u128", "i128",
Expand Down
29 changes: 29 additions & 0 deletions src/irust/highlight/theme.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use crossterm::style::Color;
use std::collections::HashMap;

pub fn theme() -> Option<HashMap<String, Color>> {
let theme_file = dirs_next::config_dir()?.join("irust").join("theme");

let data = std::fs::read_to_string(theme_file).ok()?;

let mut map = HashMap::new();

for line in data.lines() {
let mut line = line.split(':');
let key = line.next()?.trim();
let mut color = line.next()?.trim().to_string();
let (r, g, b) = if color.starts_with('#') {
// Hex color name
color.remove(0);
let r = u8::from_str_radix(&color[0..2], 16).ok()?;
let g = u8::from_str_radix(&color[2..4], 16).ok()?;
let b = u8::from_str_radix(&color[4..], 16).ok()?;
(r, g, b)
} else {
todo!()
};
map.insert(key.to_string(), Color::Rgb { r, g, b });
}

Some(map)
}

0 comments on commit a2e9128

Please sign in to comment.