Skip to content

Commit

Permalink
support both rustc_lexer, syntect to highlight
Browse files Browse the repository at this point in the history
  • Loading branch information
light4 committed Nov 5, 2022
1 parent 79109fd commit c366ee2
Show file tree
Hide file tree
Showing 11 changed files with 373 additions and 133 deletions.
16 changes: 16 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 6 additions & 2 deletions crates/irust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,17 @@ crossterm = { version = "0.25.0", features = ["serde"] }
dirs = "4.0.0"
once_cell = "1.16.0"
rscript = "0.17.0"
rustc_lexer = { version = "727.0.0", optional = true, package = "rustc-ap-rustc_lexer" }
serde = { version = "1.0.145", features = ["derive"] }
syntect = { version = "5.0.0", default-features = false, features = ["default-fancy"]}
syntect = { version = "5.0.0", optional = true, default-features = false, features = ["default-fancy"]}
toml = "0.5.9"

[target.'cfg(unix)'.dependencies]
libc = "0.2.135"

# flamegraph
[features]
default = ["rustc_lexer"]
change_highlight = ["rustc_lexer", "syntect"]

# [profile.release]
# debug = true
15 changes: 11 additions & 4 deletions crates/irust/src/irust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ use engine::Engine;
mod art;
mod format;
mod help;
pub mod highlight;
mod highlight;
mod history;
pub mod options;
mod parser;
mod racer;
mod script;
use crossterm::event::{Event, KeyCode, KeyEvent, KeyEventKind, KeyEventState, KeyModifiers};
use highlight::theme::Theme;
use highlight::{theme::Theme, Highlight};
use history::History;
use irust_api::{Command, GlobalVariables};
use irust_repl::Repl;
Expand All @@ -25,6 +25,7 @@ use racer::Racer;
use script::Script;

pub use format::format_err;

pub type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;

pub struct IRust {
Expand All @@ -39,6 +40,7 @@ pub struct IRust {
history: History,
racer: Option<Racer>,
script_mg: Option<Box<dyn Script>>,
highlight: Highlight,
}

impl IRust {
Expand Down Expand Up @@ -83,6 +85,7 @@ impl IRust {
let exit_flag = false;
let theme = highlight::theme::theme().unwrap_or_default();
let history = History::new().unwrap_or_default();
let highlight = Highlight::new(&options.highlight_engine);

IRust {
options,
Expand All @@ -96,6 +99,7 @@ impl IRust {
history,
racer,
script_mg,
highlight,
}
}

Expand All @@ -108,6 +112,7 @@ impl IRust {
};
self.printer.writer.raw.set_title(&title)?;
self.welcome()?;
self.warn_highlight_engine()?;
self.printer.print_prompt_if_set()?;

// Scripts might want run some startup commands, give them a chance here
Expand All @@ -119,8 +124,10 @@ impl IRust {
/// Wrapper over printer.print_input that highlights rust code using current theme
pub fn print_input(&mut self) -> Result<()> {
let theme = &self.theme;
self.printer
.print_input(&|buffer| highlight::highlight(buffer, theme), &self.buffer)?;
self.printer.print_input(
&|buffer| self.highlight.highlight(buffer, theme),
&self.buffer,
)?;
Ok(())
}

Expand Down
26 changes: 26 additions & 0 deletions crates/irust/src/irust/art.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,32 @@ impl IRust {
Ok(())
}

pub fn warn_highlight_engine(&mut self) -> Result<()> {
#[cfg(feature = "rustc_lexer")]
#[cfg(not(feature = "change_highlight"))]
let supported = ["rustc_lexer"];
#[cfg(feature = "syntect")]
#[cfg(not(feature = "change_highlight"))]
let supported = ["syntect"];
#[cfg(feature = "change_highlight")]
let supported = ["default", "syntect", "rustc_lexer"];

if !supported.contains(&self.options.highlight_engine.as_str()) {
let msg = format!(
"highlight engine {} is not supported, use {} instead",
&self.options.highlight_engine, supported[0]
);
self.printer.writer.raw.set_fg(self.options.err_color)?;
self.printer.writer.raw.write(&msg)?;
self.printer.writer.raw.reset_color()?;

self.printer.write_newline(&self.buffer);
self.printer.write_newline(&self.buffer);
}

Ok(())
}

pub fn ferris(&mut self) -> String {
r#"
_~^~^~_
Expand Down
173 changes: 87 additions & 86 deletions crates/irust/src/irust/help.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::highlight::{highlight, theme::Theme};
use super::highlight::theme::Theme;
use crate::irust::{IRust, Result};
use crossterm::style::Color;
use printer::{
Expand All @@ -15,106 +15,107 @@ impl IRust {

let compact = !buffer.contains("full");

Ok(parse_markdown(&readme.into(), &self.theme, compact))
Ok(self.parse_markdown(&readme.into(), &self.theme, compact))
}
}

fn parse_markdown(buffer: &Buffer, theme: &Theme, compact: bool) -> PrintQueue {
let mut queue = PrintQueue::default();

let buffer = buffer.to_string();
let mut buffer = buffer.lines();
fn parse_markdown(&self, buffer: &Buffer, theme: &Theme, compact: bool) -> PrintQueue {
let mut queue = PrintQueue::default();

(|| -> Option<()> {
loop {
let line = buffer.next()?;
if compact && line.starts_with("<img") {
break Some(());
}

if line.trim_start().starts_with("##") {
queue.push(PrinterItem::String(line.to_string(), Color::Yellow));
} else if line.trim_start().starts_with('#') {
queue.push(PrinterItem::String(line.to_string(), Color::Red));
} else if line.trim_start().starts_with("```rust") {
queue.push(PrinterItem::String(line.to_string(), Color::Cyan));
// highlight rust code
queue.add_new_line(1);
let buffer = buffer.to_string();
let mut buffer = buffer.lines();

// take_while takes ownership of the iterator
let mut skipped_lines = 0;

let code = buffer
.clone()
.take_while(|line| {
skipped_lines += 1;
!line.starts_with("```")
})
.collect::<Vec<&str>>()
.join("\n");

for _ in 0..skipped_lines {
let _ = buffer.next();
(|| -> Option<()> {
loop {
let line = buffer.next()?;
if compact && line.starts_with("<img") {
break Some(());
}

queue.append(&mut highlight(&code.into(), theme));
} else {
let mut line = line.chars().peekable();

(|| -> Option<()> {
loop {
let c = line.next()?;
match c {
'*' => {
let mut star = String::new();
star.push('*');

let mut pending = None;
let mut post_start_count = 0;

while line.peek().is_some() {
let c = line.next().unwrap();
if pending.is_none() && c != '*' {
pending = Some(star.len());
}
star.push(c);
if line.trim_start().starts_with("##") {
queue.push(PrinterItem::String(line.to_string(), Color::Yellow));
} else if line.trim_start().starts_with('#') {
queue.push(PrinterItem::String(line.to_string(), Color::Red));
} else if line.trim_start().starts_with("```rust") {
queue.push(PrinterItem::String(line.to_string(), Color::Cyan));
// highlight rust code
queue.add_new_line(1);

// take_while takes ownership of the iterator
let mut skipped_lines = 0;

let code = buffer
.clone()
.take_while(|line| {
skipped_lines += 1;
!line.starts_with("```")
})
.collect::<Vec<&str>>()
.join("\n");

for _ in 0..skipped_lines {
let _ = buffer.next();
}

if let Some(pending) = pending {
if c == '*' {
post_start_count += 1;
if pending == post_start_count {
break;
queue.append(&mut self.highlight.highlight(&code.into(), theme));
} else {
let mut line = line.chars().peekable();

(|| -> Option<()> {
loop {
let c = line.next()?;
match c {
'*' => {
let mut star = String::new();
star.push('*');

let mut pending = None;
let mut post_start_count = 0;

while line.peek().is_some() {
let c = line.next().unwrap();
if pending.is_none() && c != '*' {
pending = Some(star.len());
}
star.push(c);

if let Some(pending) = pending {
if c == '*' {
post_start_count += 1;
if pending == post_start_count {
break;
}
} else {
post_start_count =
post_start_count.saturating_sub(1);
}
} else {
post_start_count = post_start_count.saturating_sub(1);
}
}
queue.push(PrinterItem::String(star, Color::Magenta));
}
queue.push(PrinterItem::String(star, Color::Magenta));
}
'`' => {
let mut quoted = String::new();
quoted.push('`');
'`' => {
let mut quoted = String::new();
quoted.push('`');

while line.peek().is_some() && line.peek() != Some(&'`') {
quoted.push(line.next().unwrap());
while line.peek().is_some() && line.peek() != Some(&'`') {
quoted.push(line.next().unwrap());
}
//push the closing quote
if line.peek().is_some() {
quoted.push(line.next().unwrap());
}
queue.push(PrinterItem::String(quoted, Color::DarkGreen));
}
//push the closing quote
if line.peek().is_some() {
quoted.push(line.next().unwrap());
'=' | '>' | '(' | ')' | '-' | '|' => {
queue.push(PrinterItem::Char(c, Color::DarkRed))
}
queue.push(PrinterItem::String(quoted, Color::DarkGreen));
}
'=' | '>' | '(' | ')' | '-' | '|' => {
queue.push(PrinterItem::Char(c, Color::DarkRed))
c => queue.push(PrinterItem::Char(c, Color::White)),
}
c => queue.push(PrinterItem::Char(c, Color::White)),
}
}
})();
})();
}
queue.add_new_line(1);
}
queue.add_new_line(1);
}
})();
queue
})();
queue
}
}
Loading

0 comments on commit c366ee2

Please sign in to comment.