Show invisibles in editor (#19298)

Release Notes:

- Added highlighting for "invisible" unicode characters

Closes #16310

---------

Co-authored-by: dovakin0007 <dovakin0007@gmail.com>
Co-authored-by: dovakin0007 <73059450+dovakin0007@users.noreply.github.com>
This commit is contained in:
Conrad Irwin 2024-10-22 13:23:13 -06:00 committed by GitHub
parent e93d62680d
commit 6dcec47235
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 552 additions and 248 deletions

View file

@ -1,6 +1,7 @@
use crate::{
black, fill, point, px, size, Bounds, Hsla, LineLayout, Pixels, Point, Result, SharedString,
StrikethroughStyle, UnderlineStyle, WindowContext, WrapBoundary, WrappedLineLayout,
black, fill, point, px, size, Bounds, Half, Hsla, LineLayout, Pixels, Point, Result,
SharedString, StrikethroughStyle, UnderlineStyle, WindowContext, WrapBoundary,
WrappedLineLayout,
};
use derive_more::{Deref, DerefMut};
use smallvec::SmallVec;
@ -129,8 +130,9 @@ fn paint_line(
let text_system = cx.text_system().clone();
let mut glyph_origin = origin;
let mut prev_glyph_position = Point::default();
let mut max_glyph_size = size(px(0.), px(0.));
for (run_ix, run) in layout.runs.iter().enumerate() {
let max_glyph_size = text_system.bounding_box(run.font_id, layout.font_size).size;
max_glyph_size = text_system.bounding_box(run.font_id, layout.font_size).size;
for (glyph_ix, glyph) in run.glyphs.iter().enumerate() {
glyph_origin.x += glyph.position.x - prev_glyph_position.x;
@ -139,6 +141,9 @@ fn paint_line(
wraps.next();
if let Some((background_origin, background_color)) = current_background.as_mut()
{
if glyph_origin.x == background_origin.x {
background_origin.x -= max_glyph_size.width.half()
}
cx.paint_quad(fill(
Bounds {
origin: *background_origin,
@ -150,6 +155,9 @@ fn paint_line(
background_origin.y += line_height;
}
if let Some((underline_origin, underline_style)) = current_underline.as_mut() {
if glyph_origin.x == underline_origin.x {
underline_origin.x -= max_glyph_size.width.half();
};
cx.paint_underline(
*underline_origin,
glyph_origin.x - underline_origin.x,
@ -161,6 +169,9 @@ fn paint_line(
if let Some((strikethrough_origin, strikethrough_style)) =
current_strikethrough.as_mut()
{
if glyph_origin.x == strikethrough_origin.x {
strikethrough_origin.x -= max_glyph_size.width.half();
};
cx.paint_strikethrough(
*strikethrough_origin,
glyph_origin.x - strikethrough_origin.x,
@ -179,7 +190,18 @@ fn paint_line(
let mut finished_underline: Option<(Point<Pixels>, UnderlineStyle)> = None;
let mut finished_strikethrough: Option<(Point<Pixels>, StrikethroughStyle)> = None;
if glyph.index >= run_end {
if let Some(style_run) = decoration_runs.next() {
let mut style_run = decoration_runs.next();
// ignore style runs that apply to a partial glyph
while let Some(run) = style_run {
if glyph.index < run_end + (run.len as usize) {
break;
}
run_end += run.len as usize;
style_run = decoration_runs.next();
}
if let Some(style_run) = style_run {
if let Some((_, background_color)) = &mut current_background {
if style_run.background_color.as_ref() != Some(background_color) {
finished_background = current_background.take();
@ -240,10 +262,14 @@ fn paint_line(
}
if let Some((background_origin, background_color)) = finished_background {
let mut width = glyph_origin.x - background_origin.x;
if width == px(0.) {
width = px(5.)
};
cx.paint_quad(fill(
Bounds {
origin: background_origin,
size: size(glyph_origin.x - background_origin.x, line_height),
size: size(width, line_height),
},
background_color,
));
@ -299,7 +325,10 @@ fn paint_line(
last_line_end_x -= glyph.position.x;
}
if let Some((background_origin, background_color)) = current_background.take() {
if let Some((mut background_origin, background_color)) = current_background.take() {
if last_line_end_x == background_origin.x {
background_origin.x -= max_glyph_size.width.half()
};
cx.paint_quad(fill(
Bounds {
origin: background_origin,
@ -309,7 +338,10 @@ fn paint_line(
));
}
if let Some((underline_start, underline_style)) = current_underline.take() {
if let Some((mut underline_start, underline_style)) = current_underline.take() {
if last_line_end_x == underline_start.x {
underline_start.x -= max_glyph_size.width.half()
};
cx.paint_underline(
underline_start,
last_line_end_x - underline_start.x,
@ -317,7 +349,10 @@ fn paint_line(
);
}
if let Some((strikethrough_start, strikethrough_style)) = current_strikethrough.take() {
if let Some((mut strikethrough_start, strikethrough_style)) = current_strikethrough.take() {
if last_line_end_x == strikethrough_start.x {
strikethrough_start.x -= max_glyph_size.width.half()
};
cx.paint_strikethrough(
strikethrough_start,
last_line_end_x - strikethrough_start.x,