Preserve current position when new items are added to a buffer
This commit is contained in:
@ -31,6 +31,23 @@ fn rect(x: u16, y: u16, width: u16, height: u16) -> Rect {
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! items_iter {
|
||||
[ $($item: expr),* ] => {
|
||||
|| vec![
|
||||
$(
|
||||
{
|
||||
let BufferItem { content, prerender, unique_id } = &$item;
|
||||
BufferItem {
|
||||
content: content.clone(),
|
||||
prerender,
|
||||
unique_id: *unique_id,
|
||||
}
|
||||
},
|
||||
)*
|
||||
].into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_single_item() {
|
||||
let mut bl = Backlog::default();
|
||||
@ -38,9 +55,10 @@ fn test_single_item() {
|
||||
let item = BufferItem {
|
||||
content: BufferItemContent::Text(Text::raw("hello")),
|
||||
prerender: &prerender,
|
||||
unique_id: None,
|
||||
};
|
||||
let mut buf = Buffer::empty(rect(0, 0, 18, 8));
|
||||
bl.draw_items(&mut buf, rect(3, 2, 12, 4), vec![item].into_iter())
|
||||
bl.draw_items(&mut buf, rect(3, 2, 12, 4), items_iter![item])
|
||||
.context("Failed to draw")
|
||||
.unwrap();
|
||||
|
||||
@ -64,10 +82,11 @@ fn test_single_item_cached() {
|
||||
let item = BufferItem {
|
||||
content: BufferItemContent::Text(Text::raw("hello")),
|
||||
prerender: &prerender,
|
||||
unique_id: None,
|
||||
};
|
||||
let mut buf = Buffer::empty(rect(0, 0, 18, 8));
|
||||
let area = rect(3, 2, 12, 4);
|
||||
bl.draw_items(&mut buf, area, vec![item].into_iter())
|
||||
bl.draw_items(&mut buf, area, items_iter![item])
|
||||
.context("Failed to draw")
|
||||
.unwrap();
|
||||
|
||||
@ -88,9 +107,10 @@ fn test_single_item_cached() {
|
||||
let item = BufferItem {
|
||||
content: BufferItemContent::Text(Text::raw("hello")),
|
||||
prerender: &prerender,
|
||||
unique_id: None,
|
||||
};
|
||||
let mut buf = Buffer::empty(rect(0, 0, 18, 8));
|
||||
bl.draw_items(&mut buf, area, vec![item].into_iter())
|
||||
bl.draw_items(&mut buf, area, items_iter![item])
|
||||
.context("Failed to draw")
|
||||
.unwrap();
|
||||
assert_eq!(buf, expected);
|
||||
@ -105,16 +125,18 @@ fn test_only_necessary_width() {
|
||||
let item1 = BufferItem {
|
||||
content: BufferItemContent::Text(Text::raw("hi\nworld")),
|
||||
prerender: &prerender1,
|
||||
unique_id: None,
|
||||
};
|
||||
let item2 = BufferItem {
|
||||
content: BufferItemContent::Text(Text::raw(":)")),
|
||||
prerender: &prerender2,
|
||||
unique_id: None,
|
||||
};
|
||||
let mut cell = ratatui::buffer::Cell::default();
|
||||
cell.set_char('.');
|
||||
let mut buf = Buffer::filled(rect(0, 0, 18, 7), &cell); // poisoned buffer
|
||||
let area = rect(3, 1, 12, 5);
|
||||
bl.draw_items(&mut buf, area, vec![item2, item1].into_iter())
|
||||
bl.draw_items(&mut buf, area, items_iter![item2, item1])
|
||||
.context("Failed to draw")
|
||||
.unwrap();
|
||||
|
||||
@ -134,13 +156,15 @@ fn test_only_necessary_width() {
|
||||
let item1 = BufferItem {
|
||||
content: BufferItemContent::Text(Text::raw("hi\nworld")),
|
||||
prerender: &prerender1,
|
||||
unique_id: None,
|
||||
};
|
||||
let item2 = BufferItem {
|
||||
content: BufferItemContent::Text(Text::raw(":)")),
|
||||
prerender: &prerender2,
|
||||
unique_id: None,
|
||||
};
|
||||
let mut buf = Buffer::empty(rect(0, 0, 18, 7));
|
||||
bl.draw_items(&mut buf, area, vec![item2, item1].into_iter())
|
||||
bl.draw_items(&mut buf, area, items_iter![item2, item1])
|
||||
.context("Failed to draw")
|
||||
.unwrap();
|
||||
let expected = Buffer::with_lines(vec![
|
||||
@ -162,9 +186,10 @@ fn test_single_item_tight() {
|
||||
let item = BufferItem {
|
||||
content: BufferItemContent::Text(Text::raw("hello")),
|
||||
prerender: &prerender,
|
||||
unique_id: None,
|
||||
};
|
||||
let mut buf = Buffer::empty(rect(0, 0, 13, 7));
|
||||
bl.draw_items(&mut buf, rect(3, 2, 7, 3), vec![item].into_iter())
|
||||
bl.draw_items(&mut buf, rect(3, 2, 7, 3), items_iter![item])
|
||||
.context("Failed to draw")
|
||||
.unwrap();
|
||||
|
||||
@ -187,14 +212,16 @@ fn test_two_items() {
|
||||
let item1 = BufferItem {
|
||||
content: BufferItemContent::Text(Text::raw("hi")),
|
||||
prerender: &prerender1,
|
||||
unique_id: None,
|
||||
};
|
||||
let prerender2 = Prerender::new();
|
||||
let item2 = BufferItem {
|
||||
content: BufferItemContent::Text(Text::raw("world")),
|
||||
prerender: &prerender2,
|
||||
unique_id: None,
|
||||
};
|
||||
let mut buf = Buffer::empty(rect(0, 0, 14, 7));
|
||||
bl.draw_items(&mut buf, rect(1, 1, 12, 5), vec![item2, item1].into_iter())
|
||||
bl.draw_items(&mut buf, rect(1, 1, 12, 5), items_iter![item2, item1])
|
||||
.context("Failed to draw")
|
||||
.unwrap();
|
||||
|
||||
@ -219,13 +246,15 @@ fn test_two_items_scroll() {
|
||||
let item1 = BufferItem {
|
||||
content: BufferItemContent::Text(Text::raw("hi")),
|
||||
prerender: &prerender1,
|
||||
unique_id: Some(123),
|
||||
};
|
||||
let item2 = BufferItem {
|
||||
content: BufferItemContent::Text(Text::raw("world")),
|
||||
prerender: &prerender2,
|
||||
unique_id: Some(456),
|
||||
};
|
||||
let mut buf = Buffer::empty(rect(0, 0, 14, 7));
|
||||
bl.draw_items(&mut buf, rect(1, 1, 12, 5), vec![item2, item1].into_iter())
|
||||
bl.draw_items(&mut buf, rect(1, 1, 12, 5), items_iter![item2, item1])
|
||||
.context("Failed to draw")
|
||||
.unwrap();
|
||||
|
||||
@ -245,13 +274,15 @@ fn test_two_items_scroll() {
|
||||
let item1 = BufferItem {
|
||||
content: BufferItemContent::Text(Text::raw("hi")),
|
||||
prerender: &prerender1,
|
||||
unique_id: Some(123),
|
||||
};
|
||||
let item2 = BufferItem {
|
||||
content: BufferItemContent::Text(Text::raw("world")),
|
||||
prerender: &prerender2,
|
||||
unique_id: Some(456),
|
||||
};
|
||||
let mut buf = Buffer::empty(rect(0, 0, 14, 7));
|
||||
bl.draw_items(&mut buf, rect(1, 1, 12, 5), vec![item2, item1].into_iter())
|
||||
bl.draw_items(&mut buf, rect(1, 1, 12, 5), items_iter![item2, item1])
|
||||
.context("Failed to draw")
|
||||
.unwrap();
|
||||
|
||||
@ -271,13 +302,15 @@ fn test_two_items_scroll() {
|
||||
let item1 = BufferItem {
|
||||
content: BufferItemContent::Text(Text::raw("hi")),
|
||||
prerender: &prerender1,
|
||||
unique_id: Some(123),
|
||||
};
|
||||
let item2 = BufferItem {
|
||||
content: BufferItemContent::Text(Text::raw("world")),
|
||||
prerender: &prerender2,
|
||||
unique_id: Some(456),
|
||||
};
|
||||
let mut buf = Buffer::empty(rect(0, 0, 14, 7));
|
||||
bl.draw_items(&mut buf, rect(1, 1, 12, 5), vec![item2, item1].into_iter())
|
||||
bl.draw_items(&mut buf, rect(1, 1, 12, 5), items_iter![item2, item1])
|
||||
.context("Failed to draw")
|
||||
.unwrap();
|
||||
|
||||
@ -300,14 +333,16 @@ fn test_two_items_multiline() {
|
||||
let item1 = BufferItem {
|
||||
content: BufferItemContent::Text(Text::raw("hi")),
|
||||
prerender: &prerender1,
|
||||
unique_id: None,
|
||||
};
|
||||
let prerender2 = Prerender::new();
|
||||
let item2 = BufferItem {
|
||||
content: BufferItemContent::Text(Text::raw("world\n!")),
|
||||
prerender: &prerender2,
|
||||
unique_id: None,
|
||||
};
|
||||
let mut buf = Buffer::empty(rect(0, 0, 14, 7));
|
||||
bl.draw_items(&mut buf, rect(1, 1, 12, 5), vec![item2, item1].into_iter())
|
||||
bl.draw_items(&mut buf, rect(1, 1, 12, 5), items_iter![item2, item1])
|
||||
.context("Failed to draw")
|
||||
.unwrap();
|
||||
|
||||
@ -330,14 +365,16 @@ fn test_two_items_tight() {
|
||||
let item1 = BufferItem {
|
||||
content: BufferItemContent::Text(Text::raw("hi")),
|
||||
prerender: &prerender1,
|
||||
unique_id: None,
|
||||
};
|
||||
let prerender2 = Prerender::new();
|
||||
let item2 = BufferItem {
|
||||
content: BufferItemContent::Text(Text::raw("world")),
|
||||
prerender: &prerender2,
|
||||
unique_id: None,
|
||||
};
|
||||
let mut buf = Buffer::empty(rect(0, 0, 9, 6));
|
||||
bl.draw_items(&mut buf, rect(1, 1, 7, 4), vec![item2, item1].into_iter())
|
||||
bl.draw_items(&mut buf, rect(1, 1, 7, 4), items_iter![item2, item1])
|
||||
.context("Failed to draw")
|
||||
.unwrap();
|
||||
|
||||
@ -359,11 +396,12 @@ fn test_cache_moved() {
|
||||
let item1 = BufferItem {
|
||||
content: BufferItemContent::Text(Text::raw("hi")),
|
||||
prerender: &prerender1,
|
||||
unique_id: None,
|
||||
};
|
||||
|
||||
// Draw once
|
||||
let mut buf = Buffer::empty(rect(0, 0, 14, 7));
|
||||
bl.draw_items(&mut buf, rect(1, 1, 12, 5), vec![item1].into_iter())
|
||||
bl.draw_items(&mut buf, rect(1, 1, 12, 5), items_iter![item1])
|
||||
.context("Failed to draw")
|
||||
.unwrap();
|
||||
let expected = Buffer::with_lines(vec![
|
||||
@ -381,14 +419,16 @@ fn test_cache_moved() {
|
||||
let item1 = BufferItem {
|
||||
content: BufferItemContent::Text(Text::raw("hi")),
|
||||
prerender: &prerender1,
|
||||
unique_id: None,
|
||||
};
|
||||
let prerender2 = Prerender::new();
|
||||
let item2 = BufferItem {
|
||||
content: BufferItemContent::Text(Text::raw("world")),
|
||||
prerender: &prerender2,
|
||||
unique_id: None,
|
||||
};
|
||||
let mut buf = Buffer::empty(rect(0, 0, 14, 7));
|
||||
bl.draw_items(&mut buf, rect(1, 1, 12, 5), vec![item2, item1].into_iter())
|
||||
bl.draw_items(&mut buf, rect(1, 1, 12, 5), items_iter![item2, item1])
|
||||
.context("Failed to draw")
|
||||
.unwrap();
|
||||
let expected = Buffer::with_lines(vec![
|
||||
@ -413,20 +453,23 @@ fn test_overflow_and_scroll() {
|
||||
let item1 = BufferItem {
|
||||
content: BufferItemContent::Text(Text::raw("line1 x")),
|
||||
prerender: &prerender1,
|
||||
unique_id: None,
|
||||
};
|
||||
let item2 = BufferItem {
|
||||
content: BufferItemContent::Text(Text::raw("line2 y\nline3 y\nline4 y")),
|
||||
prerender: &prerender2,
|
||||
unique_id: None,
|
||||
};
|
||||
let item3 = BufferItem {
|
||||
content: BufferItemContent::Text(Text::raw("line5 z")),
|
||||
prerender: &prerender3,
|
||||
unique_id: None,
|
||||
};
|
||||
let mut buf = Buffer::empty(rect(0, 0, 14, 7));
|
||||
bl.draw_items(
|
||||
&mut buf,
|
||||
rect(1, 1, 12, 5),
|
||||
vec![item3, item2, item1].into_iter(),
|
||||
items_iter![item3, item2, item1],
|
||||
)
|
||||
.context("Failed to draw")
|
||||
.unwrap();
|
||||
@ -446,20 +489,23 @@ fn test_overflow_and_scroll() {
|
||||
let item1 = BufferItem {
|
||||
content: BufferItemContent::Text(Text::raw("line1 x")),
|
||||
prerender: &prerender1,
|
||||
unique_id: None,
|
||||
};
|
||||
let item2 = BufferItem {
|
||||
content: BufferItemContent::Text(Text::raw("line2 y\nline3 y\nline4 y")),
|
||||
prerender: &prerender2,
|
||||
unique_id: None,
|
||||
};
|
||||
let item3 = BufferItem {
|
||||
content: BufferItemContent::Text(Text::raw("line5 z")),
|
||||
prerender: &prerender3,
|
||||
unique_id: None,
|
||||
};
|
||||
let mut buf = Buffer::empty(rect(0, 0, 14, 7));
|
||||
bl.draw_items(
|
||||
&mut buf,
|
||||
rect(1, 1, 12, 5),
|
||||
vec![item3, item2, item1].into_iter(),
|
||||
items_iter![item3, item2, item1],
|
||||
)
|
||||
.context("Failed to draw")
|
||||
.unwrap();
|
||||
@ -479,20 +525,23 @@ fn test_overflow_and_scroll() {
|
||||
let item1 = BufferItem {
|
||||
content: BufferItemContent::Text(Text::raw("line1 x")),
|
||||
prerender: &prerender1,
|
||||
unique_id: None,
|
||||
};
|
||||
let item2 = BufferItem {
|
||||
content: BufferItemContent::Text(Text::raw("line2 y\nline3 y\nline4 y")),
|
||||
prerender: &prerender2,
|
||||
unique_id: None,
|
||||
};
|
||||
let item3 = BufferItem {
|
||||
content: BufferItemContent::Text(Text::raw("line5 z")),
|
||||
prerender: &prerender3,
|
||||
unique_id: None,
|
||||
};
|
||||
let mut buf = Buffer::empty(rect(0, 0, 14, 7));
|
||||
bl.draw_items(
|
||||
&mut buf,
|
||||
rect(1, 1, 12, 5),
|
||||
vec![item3, item2, item1].into_iter(),
|
||||
items_iter![item3, item2, item1],
|
||||
)
|
||||
.context("Failed to draw")
|
||||
.unwrap();
|
||||
@ -511,20 +560,23 @@ fn test_overflow_and_scroll() {
|
||||
let item1 = BufferItem {
|
||||
content: BufferItemContent::Text(Text::raw("line1 x")),
|
||||
prerender: &prerender1,
|
||||
unique_id: None,
|
||||
};
|
||||
let item2 = BufferItem {
|
||||
content: BufferItemContent::Text(Text::raw("line2 y\nline3 y\nline4 y")),
|
||||
prerender: &prerender2,
|
||||
unique_id: None,
|
||||
};
|
||||
let item3 = BufferItem {
|
||||
content: BufferItemContent::Text(Text::raw("line5 z")),
|
||||
prerender: &prerender3,
|
||||
unique_id: None,
|
||||
};
|
||||
let mut buf = Buffer::empty(rect(0, 0, 14, 7));
|
||||
bl.draw_items(
|
||||
&mut buf,
|
||||
rect(1, 1, 12, 5),
|
||||
vec![item3, item2, item1].into_iter(),
|
||||
items_iter![item3, item2, item1],
|
||||
)
|
||||
.context("Failed to draw")
|
||||
.unwrap();
|
||||
@ -539,3 +591,79 @@ fn test_overflow_and_scroll() {
|
||||
]);
|
||||
assert_eq!(buf, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_scrolledup_new_line() {
|
||||
let mut bl = Backlog::default();
|
||||
let prerender1 = Prerender::new();
|
||||
let item1 = BufferItem {
|
||||
content: BufferItemContent::Text(Text::raw("hi\nworld")),
|
||||
prerender: &prerender1,
|
||||
unique_id: Some(123),
|
||||
};
|
||||
|
||||
// Draw once
|
||||
let mut buf = Buffer::empty(rect(0, 0, 14, 7));
|
||||
bl.draw_items(&mut buf, rect(1, 1, 12, 5), items_iter![item1])
|
||||
.context("Failed to draw")
|
||||
.unwrap();
|
||||
let expected = Buffer::with_lines(vec![
|
||||
" ",
|
||||
" ┌──────────┐ ",
|
||||
" │ │ ",
|
||||
" │hi │ ",
|
||||
" │world │ ",
|
||||
" └──────────┘ ",
|
||||
" ",
|
||||
]);
|
||||
assert_eq!(buf, expected);
|
||||
|
||||
// Scroll up one line
|
||||
bl.scroll_up(1);
|
||||
let item1 = BufferItem {
|
||||
content: BufferItemContent::Text(Text::raw("hi\nworld")),
|
||||
prerender: &prerender1,
|
||||
unique_id: Some(123),
|
||||
};
|
||||
let mut buf = Buffer::empty(rect(0, 0, 14, 7));
|
||||
bl.draw_items(&mut buf, rect(1, 1, 12, 5), items_iter![item1])
|
||||
.context("Failed to draw")
|
||||
.unwrap();
|
||||
let expected = Buffer::with_lines(vec![
|
||||
" ",
|
||||
" ┌──────────┐ ",
|
||||
" │ │ ",
|
||||
" │ │ ",
|
||||
" │hi │ ",
|
||||
" └──────────┘ ",
|
||||
" ",
|
||||
]);
|
||||
assert_eq!(buf, expected);
|
||||
|
||||
// New item added at bottom, displayed paragraph should not move up
|
||||
let item1 = BufferItem {
|
||||
content: BufferItemContent::Text(Text::raw("hi\nworld")),
|
||||
prerender: &prerender1,
|
||||
unique_id: Some(123),
|
||||
};
|
||||
let prerender2 = Prerender::new();
|
||||
let item2 = BufferItem {
|
||||
content: BufferItemContent::Text(Text::raw("!")),
|
||||
prerender: &prerender2,
|
||||
unique_id: Some(456),
|
||||
};
|
||||
let mut buf = Buffer::empty(rect(0, 0, 14, 7));
|
||||
bl.draw_items(&mut buf, rect(1, 1, 12, 5), items_iter![item2, item1])
|
||||
.context("Failed to draw")
|
||||
.unwrap();
|
||||
let expected = Buffer::with_lines(vec![
|
||||
" ",
|
||||
" ┌──────────┐ ",
|
||||
" │ │ ",
|
||||
" │ │ ",
|
||||
" │hi │ ",
|
||||
" └──────────┘ ",
|
||||
" ",
|
||||
]);
|
||||
assert_eq!(buf, expected);
|
||||
}
|
||||
|
Reference in New Issue
Block a user