mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-30 15:21:12 +00:00
syntax highlight rendering, highlighting demo
This commit is contained in:
parent
729e3e358b
commit
30b87a1c93
7 changed files with 133 additions and 13 deletions
|
@ -60,6 +60,7 @@ These are potentially inspirational resources for the editor's design.
|
||||||
* Automatically create all "arms" when pattern matching after entering `when var is` based on the type.
|
* Automatically create all "arms" when pattern matching after entering `when var is` based on the type.
|
||||||
- All `when ... is` should be updated if the type is changed, e.g. adding Indigo to the Color type should add an arm everywhere where `when color is` is used.
|
- All `when ... is` should be updated if the type is changed, e.g. adding Indigo to the Color type should add an arm everywhere where `when color is` is used.
|
||||||
* When a function is called like `foo(false)`, the name of the boolean argument should be shown automatically; `foo(`*is_active:*`false)`. This should be done for booleans and numbers.
|
* When a function is called like `foo(false)`, the name of the boolean argument should be shown automatically; `foo(`*is_active:*`false)`. This should be done for booleans and numbers.
|
||||||
|
* Suggest automatically creating a function if the compiler says it does not exist.
|
||||||
|
|
||||||
|
|
||||||
### Non-Code Related Inspiration
|
### Non-Code Related Inspiration
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
pub const WHITE: (f32, f32, f32, f32) = (1.0, 1.0, 1.0, 1.0);
|
|
||||||
pub const TXT_COLOR: (f32, f32, f32, f32) = (1.0, 1.0, 1.0, 1.0);
|
|
||||||
pub const CODE_COLOR: (f32, f32, f32, f32) = (0.21, 0.55, 0.83, 1.0);
|
|
||||||
pub const CARET_COLOR: (f32, f32, f32, f32) = WHITE;
|
|
||||||
pub const SELECT_COLOR: (f32, f32, f32, f32) = (0.45, 0.61, 1.0, 1.0);
|
|
||||||
pub const BG_COLOR: (f32, f32, f32, f32) = (0.11, 0.11, 0.13, 1.0);
|
|
||||||
|
|
||||||
pub fn to_wgpu_color((r, g, b, a): (f32, f32, f32, f32)) -> wgpu::Color {
|
pub type ColorTup = (f32, f32, f32, f32);
|
||||||
|
pub const WHITE: ColorTup = (1.0, 1.0, 1.0, 1.0);
|
||||||
|
pub const BLACK: ColorTup = (0.0, 0.0, 0.0, 1.0);
|
||||||
|
pub const TXT_COLOR: ColorTup = (1.0, 1.0, 1.0, 1.0);
|
||||||
|
pub const CODE_COLOR: ColorTup = (0.21, 0.55, 0.83, 1.0);
|
||||||
|
pub const CARET_COLOR: ColorTup = WHITE;
|
||||||
|
pub const SELECT_COLOR: ColorTup = (0.45, 0.61, 1.0, 1.0);
|
||||||
|
pub const BG_COLOR: ColorTup = (0.11, 0.11, 0.13, 1.0);
|
||||||
|
|
||||||
|
pub fn to_wgpu_color((r, g, b, a): ColorTup) -> wgpu::Color {
|
||||||
wgpu::Color {
|
wgpu::Color {
|
||||||
r: r as f64,
|
r: r as f64,
|
||||||
g: g as f64,
|
g: g as f64,
|
||||||
|
@ -14,6 +17,6 @@ pub fn to_wgpu_color((r, g, b, a): (f32, f32, f32, f32)) -> wgpu::Color {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_slice((r, g, b, a): (f32, f32, f32, f32)) -> [f32; 4] {
|
pub fn to_slice((r, g, b, a): ColorTup) -> [f32; 4] {
|
||||||
[r, g, b, a]
|
[r, g, b, a]
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,3 +2,4 @@ pub mod colors;
|
||||||
pub mod lowlevel;
|
pub mod lowlevel;
|
||||||
pub mod primitives;
|
pub mod primitives;
|
||||||
pub mod style;
|
pub mod style;
|
||||||
|
mod syntax_highlight;
|
||||||
|
|
|
@ -2,12 +2,15 @@
|
||||||
// by Benjamin Hansen, licensed under the MIT license
|
// by Benjamin Hansen, licensed under the MIT license
|
||||||
|
|
||||||
use super::rect::Rect;
|
use super::rect::Rect;
|
||||||
use crate::graphics::colors::{CODE_COLOR, WHITE};
|
use crate::graphics::colors;
|
||||||
|
use colors::{CODE_COLOR, WHITE, ColorTup};
|
||||||
use crate::graphics::style::{CODE_FONT_SIZE, CODE_TXT_XY};
|
use crate::graphics::style::{CODE_FONT_SIZE, CODE_TXT_XY};
|
||||||
|
use crate::graphics::syntax_highlight;
|
||||||
use ab_glyph::{FontArc, Glyph, InvalidFont};
|
use ab_glyph::{FontArc, Glyph, InvalidFont};
|
||||||
use cgmath::{Vector2, Vector4};
|
use cgmath::{Vector2, Vector4};
|
||||||
use wgpu_glyph::{ab_glyph, GlyphBrush, GlyphBrushBuilder, GlyphCruncher, Section};
|
use wgpu_glyph::{ab_glyph, GlyphBrush, GlyphBrushBuilder, GlyphCruncher, Section};
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Text {
|
pub struct Text {
|
||||||
pub position: Vector2<f32>,
|
pub position: Vector2<f32>,
|
||||||
|
@ -82,7 +85,28 @@ fn section_from_text(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns glyphs per line
|
fn section_from_glyph_text(
|
||||||
|
text: Vec<wgpu_glyph::Text>,
|
||||||
|
screen_position: (f32, f32),
|
||||||
|
area_bounds: (f32, f32),
|
||||||
|
layout: wgpu_glyph::Layout<wgpu_glyph::BuiltInLineBreaker>,
|
||||||
|
) -> wgpu_glyph::Section {
|
||||||
|
Section {
|
||||||
|
screen_position,
|
||||||
|
bounds: area_bounds,
|
||||||
|
layout,
|
||||||
|
text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn colored_text_to_glyph_text<'a>(text_tups: &'a [(String, ColorTup)]) -> Vec<wgpu_glyph::Text<'a>> {
|
||||||
|
text_tups.iter().map(|(word_string, color_tup)| {
|
||||||
|
wgpu_glyph::Text::new(&word_string)
|
||||||
|
.with_color(colors::to_slice(*color_tup))
|
||||||
|
.with_scale(CODE_FONT_SIZE)
|
||||||
|
}).collect()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn queue_text_draw(text: &Text, glyph_brush: &mut GlyphBrush<()>) {
|
pub fn queue_text_draw(text: &Text, glyph_brush: &mut GlyphBrush<()>) {
|
||||||
let layout = layout_from_text(text);
|
let layout = layout_from_text(text);
|
||||||
|
|
||||||
|
@ -91,6 +115,23 @@ pub fn queue_text_draw(text: &Text, glyph_brush: &mut GlyphBrush<()>) {
|
||||||
glyph_brush.queue(section.clone());
|
glyph_brush.queue(section.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn queue_code_text_draw(text: &Text, glyph_brush: &mut GlyphBrush<()>) {
|
||||||
|
let layout = layout_from_text(text);
|
||||||
|
|
||||||
|
let mut all_text_tups: Vec<(String, ColorTup)> = Vec::new();
|
||||||
|
syntax_highlight::highlight_code(text, &mut all_text_tups);
|
||||||
|
let glyph_text_vec = colored_text_to_glyph_text(&all_text_tups);
|
||||||
|
|
||||||
|
let section = section_from_glyph_text(
|
||||||
|
glyph_text_vec,
|
||||||
|
text.position.into(),
|
||||||
|
text.area_bounds.into(),
|
||||||
|
layout
|
||||||
|
);
|
||||||
|
|
||||||
|
glyph_brush.queue(section.clone());
|
||||||
|
}
|
||||||
|
|
||||||
fn glyph_to_rect(glyph: &wgpu_glyph::SectionGlyph) -> Rect {
|
fn glyph_to_rect(glyph: &wgpu_glyph::SectionGlyph) -> Rect {
|
||||||
let position = glyph.glyph.position;
|
let position = glyph.glyph.position;
|
||||||
let px_scale = glyph.glyph.scale;
|
let px_scale = glyph.glyph.scale;
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
pub const CODE_FONT_SIZE: f32 = 30.0;
|
pub const CODE_FONT_SIZE: f32 = 30.0;
|
||||||
pub const CODE_TXT_XY: (f32, f32) = (30.0, 90.0);
|
pub const CODE_TXT_XY: (f32, f32) = (30.0, 30.0);
|
||||||
|
|
74
editor/src/graphics/syntax_highlight.rs
Normal file
74
editor/src/graphics/syntax_highlight.rs
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
|
||||||
|
use crate::graphics::primitives;
|
||||||
|
use crate::graphics::colors;
|
||||||
|
use colors::ColorTup;
|
||||||
|
|
||||||
|
|
||||||
|
//TODO optimize memory allocation
|
||||||
|
//TODO this is a demo function, the AST should be used for highlighting, see #904.
|
||||||
|
pub fn highlight_code(code_text: &primitives::text::Text, all_text_tups: &mut Vec<(String, ColorTup)>) {
|
||||||
|
let split_code = split_inclusive(&code_text.text);
|
||||||
|
|
||||||
|
let mut active_color = colors::WHITE;
|
||||||
|
let mut same_type_str = String::new();
|
||||||
|
|
||||||
|
for token_seq in split_code {
|
||||||
|
let new_word_color = if token_seq.contains(&'\"'.to_string()) {
|
||||||
|
colors::CODE_COLOR
|
||||||
|
} else if token_seq.contains(&'='.to_string()) {
|
||||||
|
colors::BLACK
|
||||||
|
} else {
|
||||||
|
colors::WHITE
|
||||||
|
};
|
||||||
|
|
||||||
|
if new_word_color != active_color {
|
||||||
|
all_text_tups.push(
|
||||||
|
(
|
||||||
|
same_type_str,
|
||||||
|
active_color
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
active_color = new_word_color;
|
||||||
|
same_type_str = String::new();
|
||||||
|
}
|
||||||
|
|
||||||
|
same_type_str.push_str(&token_seq);
|
||||||
|
}
|
||||||
|
|
||||||
|
if !same_type_str.is_empty() {
|
||||||
|
all_text_tups.push(
|
||||||
|
(
|
||||||
|
same_type_str,
|
||||||
|
active_color
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO use rust's split_inclusive once rust 1.50 is released
|
||||||
|
fn split_inclusive(code_str: &str) -> Vec<String> {
|
||||||
|
let mut split_vec: Vec<String> = Vec::new();
|
||||||
|
let mut temp_str = String::new();
|
||||||
|
let mut non_space_encountered = false;
|
||||||
|
|
||||||
|
for token in code_str.chars() {
|
||||||
|
if token != ' ' && token != '\n' {
|
||||||
|
non_space_encountered = true;
|
||||||
|
temp_str.push(token);
|
||||||
|
} else if non_space_encountered {
|
||||||
|
split_vec.push(temp_str);
|
||||||
|
temp_str = String::new();
|
||||||
|
temp_str.push(token);
|
||||||
|
non_space_encountered = false;
|
||||||
|
} else {
|
||||||
|
temp_str.push(token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !temp_str.is_empty() {
|
||||||
|
split_vec.push(temp_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
split_vec
|
||||||
|
}
|
|
@ -19,7 +19,7 @@ use crate::graphics::lowlevel::buffer::create_rect_buffers;
|
||||||
use crate::graphics::lowlevel::ortho::update_ortho_buffer;
|
use crate::graphics::lowlevel::ortho::update_ortho_buffer;
|
||||||
use crate::graphics::lowlevel::pipelines;
|
use crate::graphics::lowlevel::pipelines;
|
||||||
use crate::graphics::primitives::text::{
|
use crate::graphics::primitives::text::{
|
||||||
build_glyph_brush, example_code_glyph_rect, queue_text_draw, Text,
|
build_glyph_brush, example_code_glyph_rect, queue_text_draw, queue_code_text_draw, Text,
|
||||||
};
|
};
|
||||||
use crate::graphics::style::CODE_FONT_SIZE;
|
use crate::graphics::style::CODE_FONT_SIZE;
|
||||||
use crate::graphics::style::CODE_TXT_XY;
|
use crate::graphics::style::CODE_TXT_XY;
|
||||||
|
@ -392,7 +392,7 @@ fn queue_editor_text(
|
||||||
|
|
||||||
queue_text_draw(&caret_pos_label, glyph_brush);
|
queue_text_draw(&caret_pos_label, glyph_brush);
|
||||||
|
|
||||||
queue_text_draw(&code_text, glyph_brush);
|
queue_code_text_draw(&code_text, glyph_brush);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn queue_no_file_text(
|
fn queue_no_file_text(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue