89 lines
3.1 KiB
Rust
89 lines
3.1 KiB
Rust
//! Cross-frontend tab-stop acceptance for core/TUI rendering.
|
|
|
|
use std::sync::{Arc, Mutex};
|
|
|
|
use pmacs::buffer::{Buffer, BufferId};
|
|
use pmacs::cell::{Cell, CellCoord, CellGrid, CellSize, Glyph, Style};
|
|
use pmacs::overlay::{BufferStyleOverlay, BufferStyleSpan, SharedBufferStyleSpans};
|
|
use pmacs::text_view::TextView;
|
|
use pmacs::view::{DisplayCoord, View, Viewport};
|
|
|
|
fn viewport(rows: u32, cols: u32, buffer_end: u64) -> Viewport<'static> {
|
|
Viewport {
|
|
buffer_start: 0,
|
|
buffer_end,
|
|
cell_origin: CellCoord::new(0, 0),
|
|
cell_size: CellSize::new(rows, cols),
|
|
gutter_w: 0,
|
|
folds: None,
|
|
}
|
|
}
|
|
|
|
fn render_text(buf: &Buffer, rows: u32, cols: u32) -> Vec<Cell> {
|
|
let mut cells = vec![Cell::default(); (rows * cols) as usize];
|
|
let mut grid = CellGrid {
|
|
cells: &mut cells,
|
|
stride: cols,
|
|
size: CellSize::new(rows, cols),
|
|
};
|
|
TextView::new(buf).render(buf, viewport(rows, cols, buf.len()), &mut grid);
|
|
cells
|
|
}
|
|
|
|
#[test]
|
|
fn plain_text_projects_tabs_without_changing_source_bytes() {
|
|
let source = b"\tx\n1234567\ty\n12345678\tz";
|
|
let buf = Buffer::from_bytes(BufferId::next(), "tabs", source);
|
|
let cells = render_text(&buf, 3, 20);
|
|
let view = TextView::new(&buf);
|
|
assert_eq!(view.pos_to_display(&buf, 1), Some(DisplayCoord::new(0, 8)));
|
|
assert_eq!(view.pos_to_display(&buf, 11), Some(DisplayCoord::new(1, 8)));
|
|
assert_eq!(
|
|
view.pos_to_display(&buf, 22),
|
|
Some(DisplayCoord::new(2, 16))
|
|
);
|
|
|
|
for cell in cells.iter().take(8) {
|
|
assert_eq!(cell.glyph, Glyph::Char(' '));
|
|
}
|
|
assert_eq!(cells[8].glyph, Glyph::Char('x'));
|
|
assert_eq!(cells[20 + 8].glyph, Glyph::Char('y'));
|
|
assert_eq!(cells[40 + 16].glyph, Glyph::Char('z'));
|
|
|
|
let mut retained = vec![0; buf.len() as usize];
|
|
buf.snapshot_rope().slice(0, buf.len(), &mut retained);
|
|
assert_eq!(retained, source, "rendering must not replace source tabs");
|
|
}
|
|
|
|
#[test]
|
|
fn buffer_style_overlay_covers_the_same_expanded_tab_columns_as_plain_text() {
|
|
let source = b"a\tb";
|
|
let buf = Buffer::from_bytes(BufferId::next(), "styled-tab", source);
|
|
let mut cells = render_text(&buf, 1, 12);
|
|
let spans: SharedBufferStyleSpans = Arc::new(Mutex::new(vec![BufferStyleSpan {
|
|
start: 1,
|
|
end: 2,
|
|
style: Style {
|
|
bold: true,
|
|
..Style::default()
|
|
},
|
|
}]));
|
|
let mut overlay = BufferStyleOverlay::new(spans);
|
|
let mut grid = CellGrid {
|
|
cells: &mut cells,
|
|
stride: 12,
|
|
size: CellSize::new(1, 12),
|
|
};
|
|
overlay.render(&buf, viewport(1, 12, buf.len()), &mut grid);
|
|
|
|
assert_eq!(grid.get(CellCoord::new(0, 0)).glyph, Glyph::Char('a'));
|
|
assert!(!grid.get(CellCoord::new(0, 0)).style.bold);
|
|
for col in 1..8 {
|
|
let cell = grid.get(CellCoord::new(0, col));
|
|
assert_eq!(cell.glyph, Glyph::Char(' '), "expanded tab column {col}");
|
|
assert!(cell.style.bold, "overlay missed expanded tab column {col}");
|
|
}
|
|
assert_eq!(grid.get(CellCoord::new(0, 8)).glyph, Glyph::Char('b'));
|
|
assert!(!grid.get(CellCoord::new(0, 8)).style.bold);
|
|
}
|